在 Gitlab CI 构建中,我无法通过私钥 ssh 进入 AWS EC2

Posted

技术标签:

【中文标题】在 Gitlab CI 构建中,我无法通过私钥 ssh 进入 AWS EC2【英文标题】:In Gitlab CI build, I can't ssh into AWS EC2 by private key 【发布时间】:2017-03-26 13:06:52 【问题描述】:

一开始,我尝试在 gitlab CI 构建后使用 ansible 进行部署,但结果显示“主机无法访问”。

经过反复试验,我发现问题是当通过私钥 ssh 进入我的 AWS EC2 实例进行部署时,ssh 权限被拒绝。

我的 .gitlab-ci.yml 配置是这样的:

.gitlab-ci.yml

image: ansible/ubuntu14.04-ansible:stable

stages:
  - deploy

deploy_web:
  stage: deploy
  script:
   - "echo Ansible"
   - "echo Environment: $ENV"
   - "echo TAG: $TAG"

   - "echo $VAULT_PASS > vault_pass.txt"
   - "mkdir sshkey"
   - "echo $SSH_KEY_APP > ./sshkey/app-key.pem"
   - "chmod 600 ./sshkey/app-key.pem"
   - "export SSH_KEY_DIR=`pwd`/sshkey"
   - "export ANSIBLE_HOST_KEY_CHECKING=False"
   - "ssh-keyscan foobar.io >> ~/.ssh/known_hosts"
   - "ssh -v -i ./sshkey/app-key.pem ubuntu@foobar.io" // for debugging

   - "ansible-playbook -i $ENV servers.yml --vault-password-file vault_pass.txt -vvvv --tags=$TAG"

当 gitlab CI 构建这个时,它基本上会给出这些 ssh 错误消息:

OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
Pseudo-terminal will not be allocated because stdin is not a terminal.
debug1: Connecting to foobar.io [12.34.56.78] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file ./sshkey/app-key.pem type -1
debug1: identity file ./sshkey/app-key.pem-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.7
debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.7 pat OpenSSH_6.6.1* compat 0x04000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5-etm@openssh.com none
debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ECDSA be:b1:53:76:aa:bf:65:ea:b4:1b:7a:8f:cc:7c:2a:79
debug1: Host 'foobar.io' is known and matches the ECDSA host key.
debug1: Found key in /root/.ssh/known_hosts:2
Warning: Permanently added the ECDSA host key for IP address '12.34.56.78' to the list of known hosts.
debug1: ssh_ecdsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Trying private key: ./sshkey/app-key.pem
debug1: key_parse_private2: missing begin marker
debug1: key_parse_private_pem: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: No more authentication methods to try.

Permission denied (publickey).

也尝试过使用绝对路径:

$ cat /builds/foobar/bar/sshkey/app-key.pem
-----BEGIN RSA PRIVATE KEY-----
 ...(the key)...
 -----END RSA PRIVATE KEY-----

$ ssh -v -i /builds/foobar/bar/sshkey/app-key.pem ubuntu@foobar.io
Permission denied (publickey).

这些是我尝试过的:

尝试为 gitlab CI runner 使用 shell 执行器 -> 失败 在本地 docker 容器中运行脚本 -> 成功 手动 ssh 进入运行器实例(不是通过 CI)并在 shell 中运行脚本 -> 成功 手动 ssh 进入运行器实例并在 docker 容器中运行脚本 -> 成功

作为一个结论 - 它只在 gitlab CI 运行时失败,所以我想知道是否有任何我没有注意到的额外配置来做这样的事情......

非常感谢任何可以提供帮助的人!

真正的问题是

在回显多行环境变量时,需要引号。 所以基本上key的每一行都以^M结尾,在gitlab的控制台中显示正确但实际上无法被ssh解析。

【问题讨论】:

【参考方案1】:

如果GilabCI运行失败,说明GitLab CI使用的用户和你在运行实例ssh时使用的用户不同。

参见例如“AWS SSH connection error: Permission denied (publickey)”

要检查的另一件事是/etc/ssh/sshd_config 中的PermitRootLoginAllowUsers

这个debug1: key_parse_private2: missing begin marker appears 如果您的用户访问受到限制,即使在密钥授权成功后也是如此。

在远程机器上手动 ssh 后检查:

tail -f -n 80 /var/log/auth.log

OP DarkBtf 加上in the comments:

在回显多行环境变量时,需要引号。 所以基本上key的每一行都以^M结尾,在gitlab的控制台中显示正确但实际上无法被ssh解析。

【讨论】:

使用gitlab CI docker executor时,用户为root。我没有将密钥放入 .ssh,所以我在 ssh 命令中将身份指定为“-i app-key.pem”。这样做有什么问题吗? @DarkBtf 唯一的问题是:“app-key.pem 在哪里”?您可以尝试使用绝对路径(并添加一个确保绝对路径可见的命令,例如cat /full/path/to/app-key.pem 我试过使用绝对路径(主帖已编辑),仍然被拒绝。 @DarkBtf 在同一个文件中有公钥吗?或/builds/foobar/bar/sshkey/app-key.pem(或app-key.pem.pub 我发现了真正的错误在哪里......真的很愚蠢......当回显多行环境变量时,需要引号

以上是关于在 Gitlab CI 构建中,我无法通过私钥 ssh 进入 AWS EC2的主要内容,如果未能解决你的问题,请参考以下文章

GitLab Runner CI 管道内的 SSH 连接无法验证主机密钥

Gitlab - 无法对 CI 和 CD 构建的远程服务器进行身份验证

无法在 Windows 服务器上使用 docker 为 gitlab-ci 运行构建

Docker 构建失败 - 带有 GKE 的 Gitlab CI。无法通过 tcp://localhost:2375 连接到 Docker 守护程序。 docker 守护进程是不是正在运行?

GitLab CI 构建仍在等待中

如何在 gitlab CI 构建中仅安装 ssh?