在检查其他问题的系统日志时,我注意到我实时收到大量 SSH 尝试。具体来说我有关于每天 10'000 次尝试!
$ grep Disconnected /var/log/auth.log | wc -l #since March 6
46149
这让我大开眼界,因为我位于 NAT 后面,并且通常有 0 次登录尝试。从日志中我得到了关于发生了什么的清晰提示:登录尝试全部来自localhost
!
Mar 10 11:27:38 devbox sshd[11409]: Disconnected from invalid user mn 127.0.0.1 port 45822 [preauth]
Mar 10 11:27:46 devbox sshd[11426]: Disconnected from authenticating user root 127.0.0.1 port 45824 [preauth]
我能想到的唯一有意义的事情是,这些连接源自我为跳转主机建立的反向 SSH 隧道,以便能够从家里登录到我的工作计算机。事实上,当做sudo systemctl stop reverse-tunnel
所有活动时立即停止!所以我的设置有些可疑。到目前为止,我假设我的设置要求客户端能够使用对该主机有效的证书登录到跳转主机,以允许启动连接,但这显然是错误的!
设置
客户端.ssh/config
Host jump
HostName jumphost.somedomain.com
User ubuntu
IdentityFile ~/.ssh/jump
# local -> jump -> jump:30001 --> work
# reverse tunnel: work -> jump:22 sets up jump:30001 -> work
Host work
ProxyJump jump
User my-user
IdentityFile ~/.ssh/work
HostName jumphost.somedomain.com
Port 30001
上面看起来不错,因为它只涵盖了“客户端”位,告诉我的本地计算机如何连接。
反向隧道服务
这是设置为始终运行的 systemd 服务,并且实际上允许从跳转主机到我的工作计算机的入站连接。这是主要嫌疑人。
# The SSH tunnel is configured mostly through options specified in the default ssh config file (such as private key)
# It needs to be copied to /etc/systemd/system/ to be picked up and then run
# sudo systemctl daemon-reload
# sudo systemctl enable tunnel
# sudo systemctl start tunnel
# Original implementation: https://askubuntu.com/a/1316825/165026
[Unit]
Description=Maintain Reverse SSH Tunnel
After=network.target
[Service]
User=my-user
ExecStart=/usr/bin/autossh -o ServerAliveInterval=30 -o "ServerAliveCountMax 3" -M 44444 -o ExitOnForwardFailure=yes -gnNT -R 30001:localhost:22 jump
RestartSec=15
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target
我怀疑这就是罪魁祸首:-R 30001:localhost:22 jump
答案1
这是服务器配置,愚蠢的
显然,端口 30001 似乎在面向公众的网络接口上向公众完全开放。为了验证这一点,我尝试使用登录ssh -p 30001 clearly-wrong@jump
,事实上,这个易于 grepable 的用户名出现在日志中:
Mar 10 14:35:46 ACME sshd[22697]: Failed password for invalid user pt from 127.0.0.1 port 45854 ssh2
Mar 10 14:36:08 ACME sshd[22705]: Failed password for invalid user cluster from 127.0.0.1 port 45856 ssh2
Mar 10 14:36:37 ACME sshd[22736]: Failed password for invalid user clearly-wrong from 127.0.0.1 port 45858 ssh2
更简单的方法是使用 netcat:
$ nc jumphost.somedomain.com 30001
SSH-2.0-OpenSSH_8.4p1 Ubuntu-6ubuntu2.1
这表明问题更容易。
因此,如果我成功地向公众关闭了这个端口,我就已经堵住了安全漏洞。让我们来netstat
找出它监听哪些端口:
$ sudo netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1984729/sshd: /usr/
tcp 0 0 0.0.0.0:30001 0.0.0.0:* LISTEN 2950075/sshd: ubunt
所以它显然正在监听所有接口。
那么让我们看一下这个在我的工作计算机上执行的代码-R 30001:localhost:22 jump
:这表示“打开一个反向隧道,从本地主机上的端口 30001 到端口 22”。这里似乎缺少的是指定哪个 IP 应侦听端口 30001。如果缺少,则可能意味着所有接口。我们localhost
也将其限制到那里!所以我使用连接
ssh -nNT -R 127.0.0.1:30001:localhost:22 jump
应该这样处理吧?
$ sudo netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1984729/sshd: /usr/
tcp 0 0 0.0.0.0:30001 0.0.0.0:* LISTEN 2950287/sshd: ubunt
不,事实证明它什么也没做?好的,那么多读一点事实证明,sshd
配置GatewayPorts
与它有关(显然忘记了我很久以前就这样做了),所以我尝试将其注释掉,然后重新加载 ssh 配置,瞧:
$ sudo service ssh reload
$ sudo netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1984729/sshd: /usr/
tcp 0 0 127.0.0.1:30001 0.0.0.0:* LISTEN 2950497/sshd: ubunt
事实上,这解决了问题:
$ nc -v jumphost.somedomain.com 30001
nc: connect to jumphost.somedomain.com (191.212.201.145) port 30001 (tcp) failed: Connection refused
ProxyJump
为了让ssh 昵称发挥作用,我现在需要做的唯一调整是将公共主机名work
调整为.HostName
localhost
问题:我需要为其他服务启用 GatewayPorts ...
虽然这使得连接到 SSH 变得容易,但有时我需要在跳转主机上公开在工作计算机上运行的端口。通常,如果在工作计算机上运行某些 PHP 服务器并且需要在家中对其进行调试。事实证明,启用和禁用之间有一个中间选项:clientspecified
!你可以阅读更多相关信息请点击这里。