怎么做彩票网站,青海做网站公司,计算机网站开发方向,在线网站软件免费下载目录 背景
方案
编码存储
逐行存储
合并存储
打马赛克
结论 背景 使用极狐GitLab CI/CD#xff0c;在部署方面#xff0c;主要有两种方式#xff1a; 部署到K8S集群 Push模式#xff1a;流水线通过kubectl执行命令部署#xff0c;这需要把K8S的权限给流水线#xf…目录 背景
方案
编码存储
逐行存储
合并存储
打马赛克
结论 背景 使用极狐GitLab CI/CD在部署方面主要有两种方式 部署到K8S集群 Push模式流水线通过kubectl执行命令部署这需要把K8S的权限给流水线存在安全风险 Pull模式使用极狐GitLab Agent for Kubernetes 或ArgoCD通过GitOps的方式“监听”极狐GitLab的变化触发部署 部署到服务器
目前仍有不少企业因为行业性质或者场景所限没有使用K8S等云原生技术还在采用传统的服务器方式进行部署。一般使用ssh、scp、rsync等命令部署到服务器。极狐GitLab也提供了基于SSH keys的部署。详见Using SSH keys with JiHu GitLab CI/CD。
需要说明的是如果是使用专用的编译机进行编译构建然后部署到指定的服务器只需要实现编译机和部署服务器的免密SSH登陆即可相对简单。但如果使用容器进行编译构建然后部署到服务器就需要按照上面文档中提到的配合极狐GitLab CI/CD环境变量将SSH_PRIVATE_KEY等变量存储到极狐GitLab Project、Group或Instance中实现复用。且可以通过极狐GitLab CI/CD环境变量的Mask设置掩藏这些变量在CI/CD日志中的显示。详见极狐GitLab CI/CD variables。
但遗憾的是Mask功能目前是有限制的对于SSH_PRIVATE_KEY这种多行的变量无法直接使用Mask功能。这样开发人员就可以在.gitlab-cti.yml文件的脚本中执行echo $SSH_PRIVATE_KEY在流水线的日志中输出SSH Keys存在密钥泄露风险。 The value of the variable must: Be a single line. Be 8 characters or longer, consisting only of: Characters from the Base64 alphabet (RFC4648). The and : characters (In GitLab 12.2 and later). The . character (In GitLab 12.10 and later). The ~ character (In GitLab 13.12 and later). Not match the name of an existing predefined or custom CI/CD variable. 这个问题在极狐GitLab的Issue上挂了有一年多 看样子短时间没法解决。有没有其他方式Mask SSH_PRIVATE_KEY于是开始了各种折腾。 方案 编码存储
SSH Keys不能直接Mask但Mask的要求里面是支持Base64的。所以把SSH Keys先用Base64编码存到CI/CD环境变量中这样就可以Mask了然后在.gitlab-ci.yml中解码就可以在不影响功能的前提下实现效果。看看操作步骤 Base64编码SSH_PRIVATE_KEY
# 输入示例
echo -----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsWchpjSe6HW8dS/DdmokMqET2eCvD8ysOeju3Ur3cbXtZF1
*****
pbPfj6ifaMGc1wbPSvh8P5bcWTJZvZcP87D/HRmSFz6xcT014
-----END RSA PRIVATE KEY----- | base64
# 输出示例Base64编码
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBc1djaHBqU2U2SFc4ZFMvRG
*****
cjRzNmVjY25ZRUZxb1NSTGVNU2xMb1ZreU5VZEpQUjJRa1djQzRkVDVQZwpwYlBmajZpK2ZhTUdjMXdiUCtTdmg4UDViY1dUSlp2WmNQODdEL0hSbVNGejZ4Y1QwMTQ9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg将输出的Base64编码作为SSH_PRIVATE_KEY存储在极狐GitLab CI/CD环境变量并Mask 修改.gitlab-ci.yml
before_script:- command -v ssh-agent /dev/null || ( apt-get update -y apt-get install openssh-client -y )- eval $(ssh-agent -s)# - echo $SSH_PRIVATE_KEY | tr -d \r | ssh-add -- echo $SSH_PRIVATE_KEY | base64 -d | ssh-add -- mkdir -p ~/.ssh- chmod 700 ~/.ssh- echo $SSH_KNOWN_HOSTS ~/.ssh/known_hosts- chmod 644 ~/.ssh/known_hosts运行测试大功告成
这看上去是个不错的方案但真的保证了SSH_PRIVATE_KEY安全么我们本着Geek(作死)精神测试一下 修改.gitlab-ci.yml通过各种方式看看能不能打印出SSH_PRIVATE_KEY
before_script:- command -v ssh-agent /dev/null || ( apt-get update -y apt-get install openssh-client -y )- eval $(ssh-agent -s)# --- test begin ---- echo $SSH_PRIVATE_KEY - echo $SSH_PRIVATE_KEY output.txt- cat output.txt- echo $SSH_PRIVATE_KEY | base64 -d# --- test end ---- echo $SSH_PRIVATE_KEY | base64 -d | ssh-add -- mkdir -p ~/.ssh- chmod 700 ~/.ssh- echo $SSH_KNOWN_HOSTS ~/.ssh/known_hosts- chmod 644 ~/.ssh/known_hosts运行测试 直接输出SSH_PRIVATE_KEY是被Mask了但执行echo $SSH_PRIVATE_KEY | base64 -d居然把SSH_PRIVATE_KEY打印了出来所以这个方法还是存在一定的问题。
逐行存储
SSH Keys头部和尾部的-----BEGIN RSA PRIVATE KEY-----、-----END RSA PRIVATE KEY-----不能Mask但里面的内容每一行可以单独作为一个环境变量存储并Mask使用的时候再进行拼接看看操作步骤 将SSH_PRIVATE_KEY每一行拆分成一个变量进行存储有多少行就要存多少变量为了偷懒此处只列了3行实际上我这个SSH_PRIVATE_KEY除去头尾有26行…… 修改.gitlab-ci.yml并加入一些测试
before_script:- command -v ssh-agent /dev/null || ( apt-get update -y apt-get install openssh-client -y )- eval $(ssh-agent -s)# 拼接SSH_PRIVATE_KEY- |SSH_PRIVATE_KEY$-----BEGIN RSA PRIVATE KEY-----\nSSH_PRIVATE_KEY$SSH_PRIVATE_KEY$SSH_PRIVATE_KEY1$\nSSH_PRIVATE_KEY$SSH_PRIVATE_KEY$SSH_PRIVATE_KEY2$\nSSH_PRIVATE_KEY$SSH_PRIVATE_KEY$SSH_PRIVATE_KEY3$\nSSH_PRIVATE_KEY$SSH_PRIVATE_KEY$-----END RSA PRIVATE KEY-----# --- test begin ---- echo $SSH_PRIVATE_KEY - echo $SSH_PRIVATE_KEY output.txt- cat output.txt# --- test end ---- echo $SSH_PRIVATE_KEY | tr -d \r | ssh-add -- mkdir -p ~/.ssh- chmod 700 ~/.ssh- echo $SSH_KNOWN_HOSTS ~/.ssh/known_hosts- chmod 644 ~/.ssh/known_hosts运行测试 方案行是行实际操作起来要存26个变量然后还要拼起来实在是太土了能不能减少行数存一行。
合并存储
Mask不支持空格只支持:.~那我们尝试把SSH_PRIVATE_KEY除了头尾的部分合并成一行把换行符替换成支持的符号如.然后再与头尾进行拼接。操作步骤如下 合并SSH_PRIVATE_KEY
# 输入示例
echo -----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsWchpjSe6HW8dS/DdmokMqET2eCvD8ysOeju3Ur3cbXtZF1
*****
pbPfj6ifaMGc1wbPSvh8P5bcWTJZvZcP87D/HRmSFz6xcT014
-----END RSA PRIVATE KEY----- | tr -d \r | tr \n .#输出示例
-----BEGIN RSA PRIVATE KEY-----.MIIEogIBAAKCAQEAsWchpjSe6HW8dS/DdmokMqET2eCvD8ysOeju3Ur3cbXtZF1.LMb2Rq68/FPXsteLr4Y1ECKoy/YhFpyDw1h3cLm2WBUtRjt/Tq0ASbQCWAVkDsmx.uy28WofwfEKktzy3FmDSCXbvcOQgjChAmMbALWyH****.-----END RSA PRIVATE KEY-----.将除头尾部分存入环境变量并Mask 修改.gitlab-ci.yml
before_script:- command -v ssh-agent /dev/null || ( apt-get update -y apt-get install openssh-client -y )- eval $(ssh-agent -s)# 拼接SSH_PRIVATE_KEY- SSH_PRIVATE_KEY$-----BEGIN RSA PRIVATE KEY-----\n$SSH_PRIVATE_KEY$\n-----END RSA PRIVATE KEY-----# --- test begin ---- echo $SSH_PRIVATE_KEY - echo $SSH_PRIVATE_KEY output.txt- cat output.txt- echo $SSH_PRIVATE_KEY | tr -d \r | tr . \n # --- test end ---- echo $SSH_PRIVATE_KEY | tr -d \r | tr . \n | ssh-add -- mkdir -p ~/.ssh- chmod 700 ~/.ssh- echo $SSH_KNOWN_HOSTS ~/.ssh/known_hosts- chmod 644 ~/.ssh/known_hosts运行测试 和“编码存储”的方案一样跑的通但依旧可以通过对应的方式打印出SSH_PRIVATE_KEY。
到这里可以隐约猜到Mask变量的原理是简单做了一个是否包含字符串的判断。如果与环境变量的值匹配就显示[MASKED]如果不匹配就直接将变量显示出来。这也是为什么目前只允许值是单行且没有太多特殊符号的环境变量才可以MASK的原因。
打马赛克
为了验证上一步留下来的猜想我设计了一个实验 恢复环境变量中的SSH_PRIVATE_KEY为原始内容并且不做Mask当然也无法Mask 新建一个环境变量值为SSH_PRIVATE_KEY的一部分内容这里设置的是SSH_PRIVATE_KEY内容的第一行然后设置为Mask 恢复.gitlab-ci.yml文件需要注意的是这里面没有任何关于MOSAIC环境变量的使用
before_script:- command -v ssh-agent /dev/null || ( apt-get update -y apt-get install openssh-client -y )- eval $(ssh-agent -s)- echo $SSH_PRIVATE_KEY - echo $SSH_PRIVATE_KEY | tr -d \r| ssh-add -- mkdir -p ~/.ssh- chmod 700 ~/.ssh- echo $SSH_KNOWN_HOSTS ~/.ssh/known_hosts- chmod 644 ~/.ssh/known_hosts运行测试 正如猜想一样即便没有使用MOSAIC环境变量但它依然作为判断是否包含字符串而被执行了。
利用这个特性我们可以通过设置几个马赛克变量给SSH_PRIVATE_KEY的部分内容打码就可以一定程度上防止SSH_PRIVATE_KEY的泄露。 结论 作为一般场景下使用上面的四种方式任意选一个都可以实现基本的安全防护正所谓防君子不防小人。如果要进一步提高安全性还是如官方所说上专业的密钥管理工具如Vault或者期待下极狐GitLab在管理密钥这块功能的完善。