允许传入 SSH 连接的 IPTables 规则

Ste*_*ven 13 iptables

这个脚本的目的是只允许通过 VPN 的流量,除了 localhost<->localhost 和传入的 SSH 流量。但是当我通过 SSH 运行脚本时,我断开连接并被迫重新启动虚拟机。我的脚本有什么问题?

#!/bin/bash
iptables -F

#Allow over VPN
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT

#Localhost
iptables -A INPUT -s 127.0.0.1/8 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1/8 -j ACCEPT

#VPN
iptables -A INPUT -s 123.123.123.123 -j ACCEPT
iptables -A OUTPUT -d 123.123.123.123 -j ACCEPT

#SSH
iptables -A INPUT -p tcp --dport ssh -j ACCEPT

#Default Deny
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
Run Code Online (Sandbox Code Playgroud)

gol*_*cks 13

您的#SSH规则暗示 ssh 是一种通信方式,但事实并非如此。数据被差遣背部。

由于您无法提前知道客户端的端口号,因此处理此问题的正常方法是允许被视为“已建立”或与已建立连接“相关”的连接。为此,您需要:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

在你的DROP规则之前(最好在顶部,因为规则是按顺序处理的,这两个将适用于大多数数据包)。

还有如何建立TCP连接开始建立的解释在这里; 本质上,服务器回复您的#SSH INPUT规则允许的数据包的事实使它如此。

  • @SkyDan **[这是一个参考](http://www.iptables.info/en/connection-state.html#TCPCONNECTIONS)**。注意上图,当服务器在收到打开的syn 后向客户端发送syn/ack 时,连接*已建立*,这意味着iptables 将让该回复数据包通过:“一旦它看到一个数据包(SYN),它认为连接是新的。一旦它看到返回数据包(SYN/ACK),它就会认为连接是 ESTABLISHED。” -&gt; 再次:iptables *看到*服务器想要发送的返回数据包,将连接设置为已建立,并让回复通过。 (2认同)
  • @SkyDan 事实上,该逻辑不仅适用于 tcp - 我错了`-p tcp` 在这个意义上产生任何差异,并查看该页面上对 UDP 的后续解释(它是相同的)。关键是服务器在不知道 iptables 是否允许的情况下进行回复,并且*当 iptables 从本地系统上的服务器收到该回复时*,它现在已经看到了双向流量(即使客户端还没有) ,认为连接已建立,并让回复出去。这里的“技术性”取决于防火墙是*在两方的中间*。 (2认同)

hel*_*ylo 11

输出链负责输出任何数据包。

您的脚本只允许出站数据包到隧道接口、本地主机和位于 123.123.123.123 的远程主机。

如果您以一种需要 SSH 守护程序将数据包发送到上述目的地以外的目的地的方式连接到服务器,则将不允许流量出去。

要允许从 SSH 守护程序到 SSH 客户端的出站数据包,您需要添加以下规则:

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

如果您仅从一个位置进行连接,您可能还想将目标 IP 标准添加到上述规则中。此规则需要出现在输出链的最终“删除任何其他”规则之前。