首页 > 解决方案 > 带有 SSH ProxyJump 的 GitLab CI 运行器

问题描述

我的/etc/ssh/ssh_config文件中有以下设置:

Host serverA
  User idA
Host serverB
  User idB
  ProxyJump serverA

我还复制了公钥,所以如果我在本地运行ssh serverB,我serverB可以idB通过serverA.

现在,这是我的跑步者配置/etc/gitlab-runner/config.toml

[[runners]] 
name = "ssh-runner-1"                                                                
url = "http://my-cicd-server"                                    
token = "xxxxxxxxxxxxxxxx"                                                 
executor = "ssh"                                                               
[runners.custom_build_dir]                                                     
[runners.cache]                                                                
  [runners.cache.s3]                                                           
  [runners.cache.gcs]                                                          
  [runners.cache.azure]                                                        
[runners.ssh]                                                                  
  user = "idB"                                                    
  host = "serverB"                                                    
  identity_file = "/home/gitlab-runner/.ssh/id_ed25519"

当我在这个运行器上运行 CI/CD 作业时,我得到一个«连接被拒绝»错误:

ERROR: Preparation failed: ssh command Connect() error: ssh Dial() error: dial tcp xxx.xxx.xxx.xxx:22: connect: connection refused

我得出的结论是ProxyJump配置没有应用,并且由于带有运行器的机器无法直接连接到serverB,我被拒绝访问。如何配置运行器以应用代理跳转配置?

标签: sshgitlab-cigitlab-ci-runnergitlab-runner

解决方案


GitLab 运行器使用基于 Go 的 SSH 客户端。它不尊重您的系统 SSH 配置,并且与ssh您通常在操作系统发行版或类似软件包中安装的标准(通常是 OpenSSH)软件包具有相同的可配置性。

Go 客户端不支持ProxyJump配置。

您最好的选择可能是配置隧道连接,其中您的入口点不需要不受支持的 SSH 配置选项。

本地端口转发

一种方法可能是打开本地端口转发隧道,然后在 GitLab 配置中,将主机指定为转发端口,将端口指定localhost为转发端口。

例如:

  1. 打开隧道——本地2222端口通过ServerA通过ssh连接转发到ServerB上的22端口
ssh -L 2222:ServerB:22 -N ServerA
  1. 配置 runner 以使用隧道:
...
[runners.ssh]                                                                  
  host = "localhost"                                                    
  port = 2222
...

使用这种方法,您可能必须在服务器上编写一些自动化程序,以在隧道连接断开时恢复它。您如何执行此操作取决于您的操作系统和首选服务管理器。或者使用autossh 之类的工具

这基本上就是 ProxyJump 配置在后台的工作方式。

IP/端口转发系统

类似的方法是让您的跳转系统自动将连接转发到所需的目的地。这可能类似于软件防火墙规则(例如使用 iptables 路由规则)。这样,转发就透明地发生了。然后只需告诉跑步者以 ServerA 为目标,流量就会透明地转移到 ServerB。

这种方法更可靠,因为如果隧道掉线,您无需做任何事情来保持隧道的活力。但是,配置要复杂得多,并且需要 ServerB 的静态 IP。

例如,在 ServerA 上,假设 ServerB 的 IP 是10.10.10.10以下 iptables 配置可以使用:

iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 10.10.10.10:22
iptables -t nat -A POSTROUTING -j MASQUERADE

参考

然后 GitLab 运行器配置:

...
[runners.ssh]                                                                  
  host = "ServerA"                                                    
  port = 2222
...

最后,如果您需要,知道这也是 runnerdisable_strict_host_key_checking的一个未记录的配置选项也可能很有用。


推荐阅读