Gitlab CI/Docker:ssh-add 不断要求输入密码
Posted
技术标签:
【中文标题】Gitlab CI/Docker:ssh-add 不断要求输入密码【英文标题】:Gitlab CI/Docker: ssh-add keeps asking for passphrase 【发布时间】:2019-07-24 06:19:22 【问题描述】:我目前正在尝试做的是从 Gitlab CI/CD Docker 容器触发远程机器上的脚本。作业配置如下:
stages:
- deploy
image: maven:3.3.9
server-deploy:
stage: deploy
allow_failure: false
script:
## Install ssh agent
- apt update && apt install openssh-client -y
- eval $(ssh-agent -s)
## Create SSH key file
- "echo \"-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACByjJBGT21Arna/pirWVXQqGAr/aszqQ5HzvrA2MzVDZAAAAJiGKEEKhihB
CgAAAAtzc2gtZWQyNTUxOQAAACByjJBGT21Arna/pirWVXQqGAr/aszqQ5HzvrA2MzVDZA
AAAEAKbObQgJGXbrKQt4wdCy3YQfpVBqkT5RNEt2IYU5pv3HKMkEZPbUCudr+mKtZVdCoY
Cv9qzOpDkfO+sDYzNUNkAAAAFHN2ZW5AREVTS1RPUC0xTjVKUjRSAQ==
-----END OPENSSH PRIVATE KEY-----\" > deploy-key"
## Fix permissions on key file and .ssh folder
- chmod 700 deploy-key; mkdir -p ~/.ssh; chmod 700 ~/.ssh
## Import SSH key
- ssh-add -k deploy-key
## Make sure that ssh will trust the new host, instead of asking
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
## Run script on the remote server
- ssh -t user@255.255.255.255 "./deploy-master"
(SSH 密钥只是一个临时密钥,专门为 SO 问题生成) 现在,作业在到达“ssh-add -k deploy-key”命令时失败,要求输入密码,如下所示:
$ ssh-add -k deploy-key
Enter passphrase for deploy-key: ERROR: Job failed: exit code 1
SSH 密钥显然没有附加密码,我可以通过在我自己的 Linux 机器上运行完全相同的命令来验证这一点,它们可以正常工作。
所以我的问题是:如何防止 ssh-add 要求输入密码?而且我也很好奇为什么这只发生在 Gitlab CI Docker 容器上而不是我自己的 PC 上。
提前致谢!
【问题讨论】:
【参考方案1】:好的,我搞定了。事实证明,ssh-add 对文件格式非常挑剔,尤其是换行符。 .gitlab-ci.yml 中的换行符不会直接传输到命令中,因此密钥最终是一大行。
我是这样解决的:
- echo -----BEGIN OPENSSH PRIVATE KEY----- >> deploy-key
- echo b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW >> deploy-key
- echo QyNTUxOQAAACByjJBGT21Arna/pirWVXQqGAr/aszqQ5HzvrA2MzVDZAAAAJiGKEEKhihB >> deploy-key
- echo CgAAAAtzc2gtZWQyNTUxOQAAACByjJBGT21Arna/pirWVXQqGAr/aszqQ5HzvrA2MzVDZA >> deploy-key
- echo AAAEAKbObQgJGXbrKQt4wdCy3YQfpVBqkT5RNEt2IYU5pv3HKMkEZPbUCudr+mKtZVdCoY >> deploy-key
- echo Cv9qzOpDkfO+sDYzNUNkAAAAFHN2ZW5AREVTS1RPUC0xTjVKUjRSAQ== >> deploy-key
- echo -----END OPENSSH PRIVATE KEY----- >> deploy-key
这样文件中的换行符会自动创建,现在 ssh-add 会选择格式。
【讨论】:
将您的密钥存储在CI variable
docs.gitlab.com/ee/ci/variables中会更好、更容易处理、更安全
@SaschaFrinken 肯定会更安全,但是在这个学校项目期间,我们不允许访问项目设置,因此无法添加秘密变量。
使用 yaml 块可能会更容易。【参考方案2】:
在 yaml 中使用块可能会起作用。
stages:
- deploy
image: maven:3.3.9
server-deploy:
stage: deploy
allow_failure: false
script:
## Install ssh agent
- apt update && apt install openssh-client -y
- eval $(ssh-agent -s)
## Create SSH key file
- |
echo '-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACByjJBGT21Arna/pirWVXQqGAr/aszqQ5HzvrA2MzVDZAAAAJiGKEEKhihB
CgAAAAtzc2gtZWQyNTUxOQAAACByjJBGT21Arna/pirWVXQqGAr/aszqQ5HzvrA2MzVDZA
AAAEAKbObQgJGXbrKQt4wdCy3YQfpVBqkT5RNEt2IYU5pv3HKMkEZPbUCudr+mKtZVdCoY
Cv9qzOpDkfO+sDYzNUNkAAAAFHN2ZW5AREVTS1RPUC0xTjVKUjRSAQ==
-----END OPENSSH PRIVATE KEY-----' > deploy-key
## Fix permissions on key file and .ssh folder
- chmod 700 deploy-key; mkdir -p ~/.ssh; chmod 700 ~/.ssh
## Import SSH key
- ssh-add -k deploy-key
## Make sure that ssh will trust the new host, instead of asking
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
## Run script on the remote server
- ssh -t user@255.255.255.255 "./deploy-master"
【讨论】:
【参考方案3】:ssh-add 在 ssh-agent 中使用加密的 ssh-key
此解决方案在变量 SSH_PRIVATE_KEY 中有一个 ed25519 加密的 ssh 密钥,在变量 SSH_PASSPHRASE 中有用于解密它的密码。
image: ubuntu:trusty
before_script:
##
## Install ssh-agent if not already installed, it is required by Docker.
## (change apt-get to yum if you use an RPM-based image)
##
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
##
## Run ssh-agent (inside the build environment)
##
- eval $(ssh-agent -s)
##
## Create the SSH directory and give it the right permissions
##
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
## Create a shell script that will echo the environment variable SSH_PASSPHRASE
- echo 'echo $SSH_PASSPHRASE' > ~/.ssh/tmp && chmod 700 ~/.ssh/tmp
##
## Why would you encrypt your private keys? Can I echo the value to stdout?
- echo $SSH_PRIVATE_KEY
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
## We're using tr to fix line endings which makes ed25519 keys work
## without extra base64 encoding.
## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
##
## If ssh-add needs a passphrase, it will read the passphrase from the current
## terminal if it was run from a terminal. If ssh-add does not have a terminal
## associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the
## program specified by SSH_ASKPASS and open an X11 window to read the
## passphrase. This is particularly useful when calling ssh-add from a
## .xsession or related script. Setting DISPLAY=None drops the use of X11.
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | DISPLAY=None SSH_ASKPASS=~/.ssh/tmp ssh-add -
##
## Use ssh-keyscan to scan the keys of your private server. Replace gitlab.com
## with your own domain name. You can copy and repeat that command if you have
## more than one server to connect to.
##
- ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
##
## Alternatively, assuming you created the SSH_SERVER_HOSTKEYS variable
## previously, uncomment the following two lines instead.
##
#- echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
#- chmod 644 ~/.ssh/known_hosts
【讨论】:
以上是关于Gitlab CI/Docker:ssh-add 不断要求输入密码的主要内容,如果未能解决你的问题,请参考以下文章
gitlab-ci docker-in-docker 访问不安全的注册表
Gitlab+Gitlab-CI+Docker实现持续集成(CI)与持续部署(CD)
在 GitLab-ci Docker build 中执行外部 bash 脚本
Gitlab CI - Docker 推送到 AWS ECR