更新 1

更新 1

这是我的 iptables 命令:

sudo iptables -F
sudo iptables -A INPUT -p tcp -s 109.123.74.85 --dport 27000 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 188.170.80.4 --dport 27000 -j ACCEPT
sudo iptables -A INPUT -p tcp  --dport 27000 -j REJECT
sudo iptables -L

这给了我以下 iptables 规则:

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  109.123.74.85        anywhere             tcp dpt:27000
ACCEPT     tcp  --  188.170.80.4         anywhere             tcp dpt:27000
REJECT     tcp  --  anywhere             anywhere             tcp dpt:27000 reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (0 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION (0 references)
target     prot opt source               destination      

我有一个简单的 HTTP 服务器来测试它:

python3 -m http.server 27000

当我从 VPN 客户端(ip 109.123.74.85)请求它时:curl myServerIP:27000/1.txt它没有响应。

但是,当我关闭客户端上的 VPN 并curl myServerIP:27000/1.txt使用客户端 IP 188.170.80.4 发出请求时,它可以正常工作。

另外,有趣的是,当我使用端口 8881 而不是 27000 时,它对于 VPN 和非 VPN 客户端都能很好地运行。

那么如何配置 iptables 来为使用 VPN 的特定 IP 地址客户端打开端口 27000,而对其他所有 IP 地址客户端进行阻止?

更新 1

为了澄清响应类型:当我从 VPN 客户端发出请求时,我收到操作超时:

curl myServerIP:27000/1.txt
curl: (7) Failed to connect to myServerIP port 27000: Operation timed out

更新 2

当我描述端口 8881 运行正常时,我的意思是在这种情况下我使用了以下 iptables:

sudo iptables -A INPUT -p tcp -s 109.123.74.85 --dport 8881 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 188.170.80.4 --dport 8881 -j ACCEPT
sudo iptables -A INPUT -p tcp  --dport 8881 -j REJECT

更新 3

这是我检查客户端 IP 地址的方法:curl ifconfig.me

更新 4

该死,我意识到我遇到了同样的问题,VPN 客户端请求 27000 端口,即使服务器上的 iptables 为空。所以我想我应该写信给 vpn 提供商支持,弄清楚发生了什么。虽然请求端口 8881 工作正常。

更新 5(最终版)

所以我更换了 VPN 提供商,一切都按预期运行

答案1

我猜你不是 iptables 专家,所以我会尽量快速帮助你,但你应该阅读iptables 教程(这是一份很棒的文档)以了解详细信息。

将示例规则集保存到某个文件中,然后使用命令加载它iptables-apply <path-to-file>。默认情况下,此命令需要用户确认。如果超过等待超时时间而未得到用户确认,则规则集将回滚。

此外,您应该阅读 Linux 发行版的文档以使更改永久生效,否则系统重启后结果将丢失。使用 iptables-persistent 包或类似包是个好主意。

针对您的情况制定的规则的一般框架:

# Generated by iptables-save v1.6.2 on Thu May 16 16:17:54 2019
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:HTTP_IN - [0:0]

# allow already established and related connections
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# you can use multiple port numbers, separated with comma
# use the HTTP_IN chain for incoming packets to tcp/27000 port
-A INPUT -p tcp -m tcp -m multiport --dports 27000 -j HTTP_IN

# allow local connections
-A INPUT -i lo -j ACCEPT

# allow the icmp packets. it can be improved.
-A INPUT -p icmp -j ACCEPT

# this is the whitelist of ip addresses
-A HTTP_IN -s 109.123.74.85/32 -j ACCEPT
-A HTTP_IN -s 188.170.80.4/32 -j ACCEPT

# this rule should be last in the HTTP_IN chain
-A HTTP_IN -j REJECT --reject-with icmp-port-unreachable

COMMIT

为了更好地将新的 IP 地址添加到白名单,您可以编辑当前规则集文件并使用iptables-restore或加载它iptables-apply。您也可以使用iptables -I HTTP_IN --src <allowed-ip> -j ACCEPT命令。

与您的问题相关的一些细节。

当我从 VPN 客户端(ip 109.123.74.85)请求它时:curl myServerIP:27000/1.txt它没有响应。

not response和之间是有区别的connection reset。第一种情况下,您没有任何回复;第二种情况下,您会收到特殊数据包(带有 RST 标志的 TCP 或某些 ICMP 消息)。如果您没有回复,则问题出在其他地方 - 使用tcpdump进行故障排除。如果您有ICMP port unreachable回复 - 检查您的客户端的 IP 地址,很可能它与您的预期不同。您还可以检查规则计数器(最好使用iptables-save -c命令列出带有计数器的完整规则集)。

另外,有趣的是,当我使用端口 8881 而不是 27000 时,它对于 VPN 和非 VPN 客户端都能很好地运行。

这是预期的行为,因为在这种情况下数据包没有通过您的ACCEPT/REJECT规则并且被 INPUT 策略接受。

解决两台主机之间的连接问题最有效的方法是tcpdump在两端使用。此外,Linux在处理tcpdump之前netfilter(读作iptables)捕获传入数据包,但在防火墙之后捕获传出数据包。如果您在一端看到传出数据包,但在另一端看不到它们是传入的,那么它们在中间某处被丢弃或丢失了。您可以使用traceroute/tcp数据udp包来检测问题主机。

相关内容