Skip to content

Commit

Permalink
feat: add garasign and where your software come from
Browse files Browse the repository at this point in the history
  • Loading branch information
shenxianpeng committed Jun 10, 2024
1 parent 35d6ac3 commit d16a21c
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 0 deletions.
171 changes: 171 additions & 0 deletions source/_posts/2024/06/garasign.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
title: 代码签名(Code Signing) - GaraSign
tags:
- DevSecOps
- SLSA
categories:
- DevSecOps
author: shenxianpeng
date: 2024-06-10 11:27:18
---

上次我在 [代码签名(Code Signing)](2024/04/code-signing/)的文章中时候提到了 GaraSign,这是我在工作中使用到的另一个代码签名工具。

鉴于关于 GaraSign 的使用并没有多少中文资料,本篇我将介绍关于 GaraSign 的一些实线,希望对你有帮助。

## 代码签名

这里再次说明什么是代码签名。代码签名证书用于对应用程序、驱动程序、可执行文件和软件程序进行数字签名,客户可通过这种方式验证他们收到的代码未被网络罪犯和黑客篡改或破坏。签名后的交付产品结合了加密令牌和证书,用户可在安装产品前对其进行验证。代码签名可确认谁是软件作者,并证明代码在签名后未被修改或篡改。

## Garasign 解决方案

GaraSign 是一个基于 SaaS 的安全协调平台,可对企业基础设施、服务和数据进行集中管理。GaraSign 可与所有主要操作系统、平台和工具的本地客户端集成,确保现有工作流不受干扰,同时改善其整体安全态势和合规性。

### GaraSign 由以下组件组成:

* 加密令牌 - 存储签名密钥的加密设备(通常是一个或多个 HSM - Hardware Security Modules)
* GaraSign 签名服务器 - 位于存储签名密钥的加密令牌前的 REST 服务器
* GaraSign Signing 客户端 - 允许与之集成的签名工具在本地散列数据并将签名生成脱载至 GaraSign Signing 服务器的客户端。

![garasign components](garasign/garasign-components.png)

Garasign 代码签名散列方法 - 大幅提高速度

![garasign approach](garasign/garasign-approach.png)

## 安装 GaraSign

关于如何安装 GaraSign 这里不过去介绍,可以到官网找相关的安装文档。这里要注意目前 GaraSign 对操作系统版本的要求还是很高的,比如

* Windows 最低要求是 Windows 2019, Win10 and Win11
* Linux 最低要求是 RHEL 7.9, 8.0, 9.0,CentOS 7.9, 8.0, 9.0,Rocky 8.0

如果你的构建环境还是比较旧的或是不符合其支持的版本,建议你向我一样设置一台专用的 GaraSign 机器(推荐 Linux)。

如果你使用 Jenkins 来构建,可以将这台机器设置为一台 Jenkins agent,通过创建一个 Jenkins pipeline,这样其他所有的要需要发布的包都可以通过这个 pipeline 来进行签名。

## 如何签署独立签名

如果你已经设置好了 GaraSign 环境,以 Linux 为例,那么就可以通过下面的命令进行签署。

> 注:在 Windows 与 Linux 在签署不同的类型文件所使用到的命令不同,因此推荐在 Linux 进行签名会更加简单。
```bash
openssl dgst -sign <private key file> -keyform PEM -sha256 -out <signature-file-name.sig> -binary <binary file to sign>
```
### 具体的实施

加入你的 Artifacts 存在 Artifactory 上面,下面就 Jenkins 为例,来实施一个可以自动签名的 pipeline。包括:

1. 从 Artifactory 上下载需要签名的 Artifacts
2. 使用 GaraSign 进行签名
3. 验证 GaraSign 是否成功
4. 上传签名文件和公钥到 Artifactory 上的同一个目录下

```groovy
pipeline{
agent {
node {
label 'garasign'
}
}
parameters {
string(
name: 'REPO_PATH',
defaultValue: '',
description: 'Repository Path on Artifactory. eg. generic-stage/test_repo/devel/54/mybuild_1.1.0_752d0821_64bit.exe'
)
}
environment {
BOT = credentials("BOT-credential")
ART_URL = "https://my.org.com/artifactory"
}
stages {
stage('GaraSign'){
steps {
script {
if (! params.REPO_PATH){
error "REPO_PATH can not empty, exit!"
}
// Update Job description
def manualTrigger = true
currentBuild.upstreamBuilds?.each { b ->
currentBuild.description = "Triggered by: ${b.getFullDisplayName()}\n${REPO_PATH}"
manualTrigger = false
}
if (manualTrigger == true) { currentBuild.description = "Manual sign: ${REPO_PATH}" }
sh '''
# download artifacts
curl -u${BOT_USR}:${BOT_PSW} -O ${ART_URL}/${REPO_PATH}
file_name=$(basename ${REPO_PATH})
repo_folder=$(dirname ${REPO_PATH})
# garasign
openssl dgst -sign grs.privkey.pem -keyform PEM -sha256 -out $file_name.sig -binary $file_name
# verify
grs.pem.pub.key
output=$(openssl dgst -verify grs.pem.pub.key -keyform PEM -sha256 -signature $file_name.sig -binary $file_name)
if echo "$output" | grep -q "Verified OK"; then
echo "Output is Verified OK"
else
echo "Output is not Verified OK"
exit 1
fi
# upload signature file (.sig) and public key (.pem.pub.key)
curl -u${BOT_USR}:${BOT_PSW} -T $file_name.sig ${ART_URL}/${repo_folder}/
curl -u${BOT_USR}:${BOT_PSW} -T grs.pem.pub.key ${ART_URL}/${repo_folder}/
'''
}
}
}
}
}
```

## 如何验证独立签名

还是以 Linux 为例,使用如下命令可以进行签名的验证。

```bash
openssl dgst -verify <public key file> -signature <signature> <file to verify>
```

当你的 Artifacts 已经进行了签名,在提供给客户的时候,你不但需要提供发布的包,而且需要提供签名文件 (.sig) 和公钥 (.pem.pub.key)。

举个例子,如下 CLI 产品分别提供了 Windows,Linux 和 AIX 三个平台的安装包,客户可以参考如下进行签名验证。

```bash
# 下载安装包、签名文件和公钥
$ ls
cli.pem.pub.key CLI_AIX_1.1.0.zip CLI_AIX_1.1.0.zip.sig CLI_LINUXX86_1.1.0.zip CLI_LINUXX86_1.1.0.zip.sig CLI_WINDOWS_1.1.0.zip CLI_WINDOWS_1.1.0.zip.sig

# 验证签名
openssl dgst -verify cli.pem.pub.key -signature CLI_AIX_1.1.0.zip.sig CLI_AIX_1.1.0.zip
Verified OK

openssl dgst -verify cli.pem.pub.key -signature CLI_LINUXX86_1.1.0.zip.sig CLI_LINUXX86_1.1.0.zip
Verified OK

openssl dgst -verify cli.pem.pub.key -signature CLI_WINDOWS_1.1.0.zip.sig CLI_WINDOWS_1.1.0.zip
Verified OK

# 当包和签名文件不符时会验证失败
openssl dgst -verify cli.pem.pub.key -signature CLI_AIX_1.1.0.zip.sig CLI_LINUXX86_1.1.0.zip
Verification Failure
```

---

以上就是关于 GaraSign 的实现分享,如有任何问题或是建议咱们评论区见。


---

转载本站文章请注明作者和出处,请勿用于任何商业用途。欢迎关注公众号「DevOps攻城狮」
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 86 additions & 0 deletions source/_posts/2024/06/where-does-your-software-come-from.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: 你的软件(究竟)从何而来?
tags:
- SLSA
- DevSecOps
categories:
- DevOps
author: shenxianpeng
date: 2024-06-04 11:27:18
---

# 软件的信任之路:从源代码到运行的可靠性保障

软件真是个有趣又深奥的东西,它由看似神奇的代码片段组成,这些代码运行在最终的终端上,本身却并非生命体,但拥有自己的生命周期。

软件最初是源代码的形式,仅仅是存放在某个仓库的文本文件,然后通过独特的构建过程,这些源代码会转变为其他形式。例如交付到 web 服务器的压缩 JavaScript 代码块、包含框架代码和业务逻辑的容器镜像,或者针对特定处理器架构编译的原始二进制文件。

这种最终的形态转变,也就是源代码生成的其他形式,通常被称为“软件制品”。在创建之后,制品通常会处于休眠状态,等待被使用。它们可能会被放置在软件包注册表(例如 npm、RubyGems、PyPI 等)或容器注册表(例如 GitHub Packages、Azure Container Registry、AWS ECR 等)中,也可能作为附加到 GitHub 版本发布的二进制文件,或者仅仅以 ZIP 文件的形式存储在某个 Blob 存储服务中。

最终,有人会决定拾取该制品并使用它。他们可能会解压缩包、执行代码、启动容器、安装驱动程序、更新固件 - 无论采用何种方式,构建完成的软件都将开始运行。

这标志着生产生命周期的顶峰,该周期可能需要大量人力投入、巨额资金,并且鉴于现代世界依赖软件运行,其重要性不言而喻。

然而,在许多情况下,我们并不能完全保证所运行的制品就是我们构建的制品。制品经历的旅程细节要么丢失,要么模糊不清,很难将制品与其来源的源代码和构建指令联系起来。

这种缺乏对制品生命周期的可见性是当今许多最严峻的安全挑战的根源。在整个软件开发生命周期 (SDLC) 中,有机会保护代码转换为制品的流程 - 如此一来,可以消除威胁行为者破坏最终软件并造成严重后果的风险。一些网络安全挑战似乎难以成功应对,但这种情况并非如此。让我们深入了解一些背景知识。

## 哈希值和签名

假设你的目录中有一个文件,并且你想要确保它明天与今天完全相同。你该怎么做?一个好的方法是通过安全的哈希算法生成文件的哈希值。

以下是如何使用 OpenSSL 和 SHA-256 算法完成此操作:

```bash
openssl dgst -sha256 ~/important-file.txt
```

现在,你拥有了一个哈希值(也称为散列值),它是一个由字母和数字组成的 64 字符字符串,代表该文件的唯一指纹。只要更改该文件中的任何内容,然后再次运行哈希函数,你就会得到不同的字符串。你可以将哈希值写在某个地方,然后第二天回来尝试相同的过程。如果你两次没有得到相同的哈希值字符串,则文件中的某些内容已发生更改。

到目前为止,我们可以确定某个文件是否被篡改。如果我们想要对制品进行声明怎么办?如果我们想说“我今天看到了这个制品,我(系统或人)保证这个东西就是我看到的东西”,该怎么办?此时,你需要的是软件制品签名;你需要将哈希值字符串通过加密算法进行处理,以生成另一个字符串,代表使用唯一密钥“签名”该指纹的过程。
如果你随后希望其他人能够确认你的签名,则需要使用非对称加密:使用你的私钥签名哈希值,并提供相应的公钥,以便任何获取你文件的人都可以进行验证。

你可能已经知道,非对称加密是互联网上几乎所有信任的基础。它可以帮助你安全地与银行互动,也可以帮助 GitHub 安全地交付你的存储库内容。我们使用非对称加密来支持诸如 TLS 和 SSH 等技术,以创建可信赖的通信通道,但我们也使用它通过签名来创建信任软件的基础。

Windows、macOS、iOS、Android 等操作系统都具有用于确保可执行软件制品的可信来源的机制,方法是强制要求存在签名。这些系统是现代软件世界中极其重要的组件,构建它们非常困难。

## 不仅仅是签名 - 还要证明

当我们思考如何展示关于软件制品的更多可信赖信息时,签名是一个好的开端。它表示“某个可信赖的系统确实看到了这个东西”。但是,如果你真的想在整个软件开发生命周期 (SDLC) 的安全性方面取得重大进步,那么你就需要超越简单的签名,而是要考虑证明。

证明是一种事实断言,是对制品或制品所做的声明,并由可被认证的实体创建。之所以可以进行认证,是因为声明已签名,并且用于签名的密钥是可信的。

最重要和最基础的证明类型之一是断言有关制品来源和创建的事实 - 它来自的源代码和将源代码转换为制品的构建指令,我们称之为来源证明。

我们选择的来源证明规范来自 SLSA 项目。SLSA 是考虑软件供应链安全性的绝佳方式,因为它为软件的生产者和消费者提供了一个通用的框架,用于推理安全保证和边界,而这与特定的系统和技术栈无关。

SLSA 基于 in-toto 项目的工作,提供了一种用于生成软件制品来源证明的标准化架构。in-toto 是一个 CNCF 毕业项目,其存在目的之一是提供一系列有关供应链和构建过程的相关信息的标准化元数据架构。

## 构建这样的东西需要什么?

GitHub 作为托管大量代码和构建管道的全球最大软件开发平台,对此进行了大量的思考。构建认证服务需要许多活动部件。

这样做意味着有一种方法可以:

* 颁发证书(本质上是绑定到某个经过身份验证的身份的公钥)。
* 确保这些证书不会被滥用。
* 在众所周知的上下文中启用工件的安全签名。
* 以最终用户可以信任的方式验证这些签名。

这意味着设置证书颁发机构 (CA) 并拥有某种客户端应用程序,你可以使用它来验证与该颁发机构颁发的证书相关联的签名。

为了防止证书被滥用,你需要 (1) 维护证书吊销列表或 (2) 确保签名证书是短期的,这意味着需要某种时间戳机构的反签名(可以提供权威印章,表明证书仅在其有效期内用于生成签名)。

这就是 Sigstore 的作用所在,它是一个开源项目,提供 X.509 CA 和基于 RFC 3161 的时间戳机构。它还允许你使用 OIDC 令牌进行身份验证,许多 CI 系统已经生成了令牌并将其与其工作负载相关联。

Sigstore 对软件签名的作用与 Let’s Encrypt 对 TLS 证书的作用相同:使其简单、透明且易于采用。

GitHub 通过我们在技术指导委员会中的席位帮助监督 Sigstore 项目的治理,是服务器应用程序和多个客户端库的维护者,并且(与来自 Chainguard、Google、RedHat 和 Stacklok 的人员一起)组成了 Sigstore 公共物品实例的运营团队,该团队的存在是为了支持 OSS 项目的公共证明。

Sigstore 需要符合更新框架 (TUF) 规定的标准的安全信任根。这允许客户端跟上 CA 底层密钥的轮换,而无需更新其代码。TUF 的存在是为了缓解在现场更新代码时可能出现的大量攻击媒介。许多项目都使用它来更新长期运行的遥测代理、提供安全的固件更新等。

有了 Sigstore,就可以创建防篡改的纸质记录,将工件链接回 CI。这真的很重要,因为签署软件并以不可伪造的方式捕获来源细节意味着软件消费者有办法执行他们自己关于正在执行的代码来源的规则。

---

转载本站文章请注明作者和出处,请勿用于任何商业用途。欢迎关注公众号「DevOps攻城狮」

0 comments on commit d16a21c

Please sign in to comment.