SSH 端口被 iptables 阻止 - 但仍可以从任何地址登录到 SSH 端口

SSH 端口被 iptables 阻止 - 但仍可以从任何地址登录到 SSH 端口

在一些具有相同防火墙规则的服务器上,我遇到了这种情况,因此我怀疑我的 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

根据提供的数据,我很难给出直接的答案,但我的方法是:

  1. 将 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
  1. 测试两条规则的设置:

2a. 如果有效,你就知道问题出在原始规则上。慢慢地继续添加规则并测试它们,直到你满意为止。你也可以使用日志记录了解哪条规则被匹配。

2b. 如果您的服务器在只有两条规则的情况下仍可访问,而除了您允许的 IP 地址之外,其他任何 IP 地址都无法访问您的服务器,那么您就知道这不是规则问题,而是 iptables 本身出了问题。可能是它没有正确加载,或者 iptables 的先前状态正在内存中运行。

答案3

原始海报接受了我之前的回答,但这里有更深入的解释:

我进行了一些诊断和调试。这是我首先做的事情:

  1. 安装 Ubuntu 14.04 作为 VMware 虚拟机
  2. 修改 /etc/ssh/sshd_config 如下:Port 2022
  3. 重启机器
  4. 记下虚拟机 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. 如果要更改默认策略,则应在下班后进行,以消除对人们的直接影响,然后再进行测试并适应新问题(如果有)。

相关内容