我想让这种情况成为可能(为了便于理解,简化了一些与问题无关的方面)
假设我们有一个只有两个文件的简单 gitlab 存储库。
index.html
- 存储静态网页gitlab-ci.yml
- 存储此存储库的管道
我们有 Debian 11 服务器(由于具有 root 权限,因此我可以做任何我想做的事情)
邮件目标是创建一个 gitlab 管道,自动 ssh 登录到此服务器并执行更新(cds 到正确的文件夹并拉大师)主合并后因此每一个变化都会发生。
我发现许多来源都涉及生成 ssh 密钥并将私钥存储到 gitlab 变量中(并从管道访问它)的步骤。
管道看起来总是这样的:
stages:
- deploy
deploy:
image: ubuntu:latest
stage: deploy
only:
- main
before_script:
- apt-get -yq update
- apt-get -yqq install ssh
- install -m 600 -D /dev/null ~/.ssh/id_rsa
- echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_rsa
- ssh-keyscan -H $SSH_HOST > ~/.ssh/known_hosts
script:
- ssh $SSH_USER@$SSH_HOST "cd $WORK_DIR && git checkout $MAIN_BRANCH && git pull && exit"
after_script:
- rm -rf ~/.ssh
这让我想到第一个问题,是否有更好的解决方案可以绕过私钥?我担心的是安全问题。我知道有人入侵 gitlab 并窃取所有私有变量的风险很低,但我想寻求任何更安全的解决方案。如果有帮助的话,甚至可以通过 Docker 容器执行此操作(但在我看来,在服务器端,执行 git 命令和 docker 命令之间只有区别,这在这方面并没有真正的帮助)
如果第一个问题的答案是不我想问另一个问题-保护这个 ssh 密钥对的最佳方法是什么?是否可以只为仅允许访问一个文件夹(存储此存储库内容的位置)且仅允许执行某些命令的用户生成 ssh 密钥(例如 scanrio,登录后他会自动重定向到该文件夹,并且只允许执行而不允许执行git pull
其他任何命令?因此,任何人使用该私钥所能造成的最大损害就是提取存储库的最新版本?
答案1
我面临的问题是开发人员能够修改 .gitlab-ci.yml 并运行管道,因此他们也可以执行 echo $SSH_PRIVATE_KEY 并使用该密钥。
如果您只想确保用户可以执行 git pull,您可以在主机的 sshd 中配置它,选中 ForceCommand 选项。但最好允许该用户仅使用 sftp,并从 gitlab-ci scp 工件,而不是在远程服务器上拉取 Git:
Match user your-ssh-user
ForceCommand internal-sftp
如果 Gitlab 的某个人能够审查这个问题并将其添加到文档中就好了,因为在我看来这是一个真正相关的问题。
您可以启动一个在 ssh-agent 中加载了 SSH 密钥的运行器(这些密钥无法被泄露),这个功能将会很有趣。