![SSH 端口被 iptables 阻止 - 但仍可以从任何地址登录到 SSH 端口](https://linux22.com/image/755471/SSH%20%E7%AB%AF%E5%8F%A3%E8%A2%AB%20iptables%20%E9%98%BB%E6%AD%A2%20-%20%E4%BD%86%E4%BB%8D%E5%8F%AF%E4%BB%A5%E4%BB%8E%E4%BB%BB%E4%BD%95%E5%9C%B0%E5%9D%80%E7%99%BB%E5%BD%95%E5%88%B0%20SSH%20%E7%AB%AF%E5%8F%A3.png)
在一些具有相同防火墙规则的服务器上,我遇到了这种情况,因此我怀疑我的 iptables 配置中缺少某些内容,但不确定哪里出了问题。一些 CentOS 服务器和我的 Ubuntu 服务器上都出现了这种情况。我使用 iptables 多年,并认为自己知道自己在做什么……但显然并非如此。
我在非标准端口 (2022) 上运行 SSH。我有防火墙规则允许我的个人 IP 访问,然后阻止包括 2022 在内的特定端口,然后是拒绝所有规则。在过去 3 周左右的时间里,我的日志显示来自不在我的接受列表中的外部 IP 的 SSH 登录尝试失败。我的笔记本电脑上有 VPN 服务,因此我可以尝试从各个国家/地区、IP 等登录,防火墙不再像以前那样阻止我。我将手机用作热点,这样我就可以确保我拥有应该被阻止的随机 IP,但我仍然可以登录 ssh。我从随机 IP 使用 nmap,它显示端口 2022 为 OPEN。
我不确定到底发生了什么,防火墙曾经正确地阻止了不允许的 IP 地址上的 SSH,而且我认为在出现这种情况之前我没有做过任何更改,也没有使用类似 fail2ban 的东西让事情变得复杂。我甚至还检查了 rootkit,但什么也没发现。我在 Google 上搜索了很多次,但搜索结果太嘈杂,没有太多相关的回复,所以我放弃了,决定在这里发布问题,希望得到更好的指导。
该服务器运行的是 ubuntu 14.04.6 LTS
我允许的 IP 在 209.xxx 和 216.xxx 范围内 以下是我的 iptables 规则 (iptables -L -n):
ACCEPT all -- 127.0.0.1 0.0.0.0/0
ACCEPT all -- 209.xxx.xxx.1 0.0.0.0/0
ACCEPT all -- 209.xxx.xxx.2 0.0.0.0/0
ACCEPT all -- 209.xxx.xxx.3 0.0.0.0/0
ACCEPT all -- 209.xxx.xxx.4 0.0.0.0/0
ACCEPT all -- 209.xxx.xxx.5 0.0.0.0/0
ACCEPT all -- 209.xxx.xxx.6 0.0.0.0/0
ACCEPT all -- 216.xxx.xxx.1 0.0.0.0/0
ACCEPT all -- 216.xxx.xxx.2 0.0.0.0/0
ACCEPT all -- 74.xxx.xxx.2 0.0.0.0/0
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x00
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x17/0x02 limit: avg 1/sec burst 2
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x3F
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:110
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:143
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:465
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:993
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:995
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:2022
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
--------------------------------
典型的服务器日志显示类似以下故障:
Jul 26 05:29:38 SERVERNAME sshd[3536]: Invalid user postgres from 159.89.231.172
Jul 26 05:29:39 SERVERNAME sshd[3536]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=159.89.231.172
Jul 26 05:29:40 SERVERNAME sshd[3534]: Failed password for mysql from 159.89.231.172 port 56352 ssh2
Jul 26 05:29:40 SERVERNAME sshd[3534]: Received disconnect from 159.89.231.172: 11: Normal Shutdown, Thank you for playing [preauth]
Jul 26 05:29:40 SERVERNAME sshd[3538]: reverse mapping checking getaddrinfo for usa1.getlark.com [159.89.231.172] failed - POSSIBLE BREAK-IN ATTEMPT!
这是我创建的用于实现规则的带有注释的脚本:
APPEND="sudo /sbin/iptables -A INPUT"
INSERT="sudo /sbin/iptables -I INPUT"
OUTPUT="sudo /sbin/iptables -A OUTPUT"
# drop old rules and start from scratch
sudo /sbin/iptables -F
sudo /sbin/iptables -X
# allow local host
$INSERT -s 127.0.0.1 -j ACCEPT
# Allow full access to our approved IPs first:
$APPEND -s 209.xxx.xxx.1 -j ACCEPT
$APPEND -s 209.xxx.xxx.2 -j ACCEPT
$APPEND -s 209.xxx.xxx.3 -j ACCEPT
$APPEND -s 209.xxx.xxx.4 -j ACCEPT
$APPEND -s 209.xxx.xxx.5 -j ACCEPT
$APPEND -s 209.xxx.xxx.6 -j ACCEPT
$APPEND -s 216.xxx.xxx.1 -j ACCEPT
$APPEND -s 216.xxx.xxx.2 -j ACCEPT
$APPEND -s 74.xxx.xxx.2 -j ACCEPT
# drop Null packets
$APPEND -p tcp --tcp-flags ALL NONE -j DROP
# block syn flood attack
$APPEND -p tcp --syn -m limit --limit 1/s --limit-burst 2 -j RETURN
# block recon/Xmas Packets
$APPEND -p tcp --tcp-flags ALL ALL -j DROP
# don’t lock me out if I screwed up:
$APPEND -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow/Block our legit services
$APPEND -p tcp --dport 80 -j ACCEPT
$APPEND -p tcp --dport 110 -j DROP
$APPEND -p tcp --dport 143 -j DROP
$APPEND -p tcp --dport 443 -j ACCEPT
$APPEND -p tcp --dport 465 -j DROP
$APPEND -p tcp --dport 993 -j DROP
$APPEND -p tcp --dport 995 -j DROP
$APPEND -p tcp --dport 2022 -j DROP
# LAst Rule - Block everything else
$APPEND -j REJECT --reject-with icmp-host-prohibited
答案1
由于我的菜鸟名声,我需要在这里询问澄清。
您能否编辑您的问题以包含 INPUT 链默认策略?我问这个问题是因为这一行:
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x17/0x02 limit: avg 1/sec burst 2
我不是专家,但我从未见过它在顶层使用。不过可能只有我才这么认为。iptables 手册页中关于 RETURN 的说法是:
RETURN 表示停止遍历此链并从上一个(调用)链中的下一个规则恢复。如果到达内置链的末尾或匹配了目标为 RETURN 的内置链中的规则,则链策略指定的目标将决定数据包的命运。
我有预感您的问题可能与此功能有关。
答案2
根据提供的数据,我很难给出直接的答案,但我的方法是:
- 将 iptables 精简为仅两个规则:允许单个 IP 地址范围(您正在连接的 IP 地址范围),并拒绝其他所有 IP 地址。注意不要将自己锁定在服务器之外!拥有控制台访问权限或备份计划可能会救你一命。如果你足够自信,这里有一个如何继续的示例。谨慎行事!:
您可以发出类似以下命令:
sudo iptables-save > /tmp/original-rules.txt
sudo iptables -F
sudo iptables -X
sudo iptables -A INPUT -s 209.xxx.xxx.1 -j ACCEPT
sudo iptables -A INPUT -j DROP
上述命令序列将保存您现有的规则,对所有链进行基本清理,向 INPUT 链添加单个 IP 地址或地址范围,并向 INPUT 链添加删除“任何”规则。
恢复原始规则可以通过以下方式实现:
sudo iptables-restore < /tmp/original-rules.txt
- 测试两条规则的设置:
2a. 如果有效,你就知道问题出在原始规则上。慢慢地继续添加规则并测试它们,直到你满意为止。你也可以使用日志记录了解哪条规则被匹配。
2b. 如果您的服务器在只有两条规则的情况下仍可访问,而除了您允许的 IP 地址之外,其他任何 IP 地址都无法访问您的服务器,那么您就知道这不是规则问题,而是 iptables 本身出了问题。可能是它没有正确加载,或者 iptables 的先前状态正在内存中运行。
答案3
原始海报接受了我之前的回答,但这里有更深入的解释:
我进行了一些诊断和调试。这是我首先做的事情:
- 安装 Ubuntu 14.04 作为 VMware 虚拟机
- 修改 /etc/ssh/sshd_config 如下:
Port 2022
- 重启机器
- 记下虚拟机 IP 地址,即 192.168.241.171
接下来,我取出您的防火墙脚本并删除了 xxx 条目。我将修改后的脚本称为“原始”脚本。
我进行了几次重启/脚本修改/脚本运行/Putty 连接循环。以下是场景和结果:
- 没有修改“原来的”脚本:Putty 连接到 192.168.241.171 端口 2022 是成功的
- 删除
$APPEND -p tcp --syn -m limit --limit 1/s --limit-burst 2 -j RETURN
了“原来的”脚本:Putty 连接到 192.168.241.171 端口 2022 是受阻 - 在此之前添加了
#allow local host"
:/sbin/iptables -P INPUT DROP`到“原来的”脚本:Putty 连接到 192.168.241.171 端口 2022 是受阻 - 在此之前已添加
#allow local host"
:/sbin/iptables -P INPUT ACCEPT`到“原来的”脚本:Putty 连接到 192.168.241.171 端口 2022 是成功的
我想我知道发生了什么。用户忘记将 INPUT 链默认策略设置为 DROP。一些使用 RETURN 语句阻止 syn 泛洪的示例期望将默认 INPUT 链策略设置为 DROP,而用户在没有设置策略的情况下改编了此类示例。我进一步推测防火墙脚本从未完全发挥作用,并且一直保护 sshd 免受外部用户的攻击的是非标准端口 2022(但现在坏人也在敲 2022)。
PS. 如果要更改默认策略,则应在下班后进行,以消除对人们的直接影响,然后再进行测试并适应新问题(如果有)。