Nginx反向代理下GitLab SSH操作失败,如何配置解决?
问题描述
已将Nginx作为多服务器反向代理,其中一台虚拟机部署GitLab CE。反向代理通过子域名gitlab.mydomain.com转发HTTP/HTTPS请求至GitLab服务器(192.168.10.118:10987),HTTP请求运行正常,但GitLab SSH操作(克隆、拉取、推送)失败。原因是域名解析指向Nginx服务器,SSH请求默认连接到Nginx服务器的22端口,而非GitLab的SSH服务端口。
当前GitLab子域名的Nginx配置如下:
server { server_name gitlab.mydomain.com; location / { proxy_pass http://192.168.10.118:10987; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen 443 ssl; ssl_certificate /etc/letsencrypt/live/gitlab.mydomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/gitlab.mydomain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { if ($host = gitlab.mydomain.com) { return 301 https://$host$request_uri; } listen 80; server_name gitlab.mydomain.com; return 404; }
解决方案
以下两种方案均可解决SSH流量无法到达GitLab的问题,可根据实际场景选择:
方案一:iptables端口转发(直接复用22端口)
该方案将Nginx服务器22端口的SSH流量直接转发到GitLab服务器的SSH端口,用户无需修改克隆命令或客户端配置。
- 确认GitLab SSH端口:GitLab默认使用22端口,可通过
ssh -p 22 git@192.168.10.118测试是否能直接连接GitLab的SSH服务。 - 调整Nginx服务器的SSH端口(避免冲突):
编辑/etc/ssh/sshd_config,修改Port为其他端口(如2222),重启SSH服务:systemctl restart sshd,并确保防火墙允许新端口的SSH访问。 - 添加iptables转发规则:
# 将访问gitlab.mydomain.com的22端口流量转发到GitLab服务器 iptables -t nat -A PREROUTING -p tcp --dport 22 -d gitlab.mydomain.com -j DNAT --to-destination 192.168.10.118:22 # 配置源地址转换,确保GitLab能正常返回流量 iptables -t nat -A POSTROUTING -p tcp --dport 22 -d 192.168.10.118 -j SNAT --to-source [Nginx服务器内网IP] - 保存iptables规则:
Debian/Ubuntu系统执行iptables-save > /etc/iptables/rules.v4;RHEL/CentOS系统执行service iptables save。 - 验证:执行
git clone git@gitlab.mydomain.com:username/project.git测试是否正常。
方案二:Nginx Stream模块转发SSH流量(使用自定义端口)
该方案通过Nginx的Stream模块监听自定义端口,转发SSH流量到GitLab,适合无法修改系统SSH端口的场景。
步骤1:确认Nginx已启用Stream模块
执行nginx -V | grep -- '--with-stream',若输出包含该参数则已启用;否则需重新编译Nginx或安装带Stream模块的包(如Debian/Ubuntu的nginx-extras)。
步骤2:修改Nginx主配置
编辑Nginx主配置文件(如/etc/nginx/nginx.conf),添加stream块:
stream { server { listen 2222; # 自定义SSH转发端口 proxy_pass 192.168.10.118:22; # GitLab服务器的SSH端口 proxy_timeout 5m; proxy_connect_timeout 1s; } }
重启Nginx:systemctl restart nginx
步骤3:调整GitLab配置(生成正确的SSH克隆链接)
编辑GitLab配置文件/etc/gitlab/gitlab.rb:
gitlab_rails['gitlab_shell_ssh_port'] = 2222
重新配置GitLab:gitlab-ctl reconfigure
步骤4:客户端配置(二选一)
- 方式1:克隆时指定端口:
git clone ssh://git@gitlab.mydomain.com:2222/username/project.git - 方式2:通过SSH配置自动识别端口:
编辑用户的~/.ssh/config文件,添加如下内容:
保存后,即可直接使用Host gitlab.mydomain.com Port 2222 User gitgit clone git@gitlab.mydomain.com:username/project.git操作。
额外注意事项
- 确保GitLab服务器的防火墙允许Nginx服务器访问其22端口
- 确保Nginx服务器的防火墙允许外部访问对应的SSH转发端口(方案一的22,方案二的2222)
内容的提问来源于stack exchange,提问作者nexus-10orbits
相关产品推荐
相关产品推荐

