我有一台 Windows 机器和一台 Linux 机器。由于我不太熟悉 Windows 防火墙(也不确定操作系统的应用程序级防火墙安全性),所以我想从 Linux 机器而不是 Windows 机器打开应用程序端口到互联网。因此,它就像:互联网 -> Linux:7000 -> iptables(要阻止和转发的规则)-> 通过 ssh 的 Windows:7000。
我搜索了一下,也读了一些 stackexchange 帖子(比如这或者这),尝试了我认为应该有效的命令。但没有奏效。
# linux machine: 192.168.0.168:7000
# windows machine: 192.168.0.111:7000
# the linux's network interface is wlp2s0, and windows's is eth0
# ssh-ing, from the windows machine
ssh -L 7000:localhost:7000 [email protected]
# iptables
sudo iptables -t nat -I PREROUTING -p tcp -i wlp2s0 --dport 7000 -j DNAT --to-destination 192.168.0.111:7000
sudo iptables -A FORWARD -i wlp2s0 -o eth0 -p tcp -d 192.168.0.111 --dport 7000 -j ACCEPT
# curl to test
curl -I 220.xx.xx.xx:7000 # this should return curl: (52) Empty reply from server for succeed, but curl: (7) Failed to connect # the global ip is connected to the linux machine
那么,这些命令有什么问题?
答案1
我通过以下步骤解决了该问题。
# on the windows
$ ssh -R 7000:localhost:7000 user@[[linuxip]] # on windowspc
# on the linux
sudo iptables -t nat -A PREROUTING -p tcp -i wlp2s0 --dport 7000 -j DNAT --to-destination [[windowsip]]:7000
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
以上只是绕过连接。因此,以下是您想要允许特定 IP 的示例。
sudo iptables -t nat -A PREROUTING -p tcp -i wlp2s0 --dport 7000 -j DNAT --to-destination [[windowsip]]:7000
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
# filter
sudo iptables -I FORWARD -i wlp2s0 -p tcp -d [[windowsip]] --dport 7000 -j DROP
sudo iptables -I FORWARD -i wlp2s0 -p tcp -d [[windowsip]] --dport 7000 -s [[allowThisIp(s)]] -j ACCEPT
配置iptables以将ssh连接端口转发到服务器 - 智库101 - 一个基于Linux的问答分享平台
(我不完全相信这是最好的方法(主要是为了安全性、系统稳定性)。如果您知道更好或更合适的方法,请分享您的想法。)
答案2
不一定是这样的答案,因为您自己已经对其进行了分类,但希望一些评论来解释您所看到的行为可能会有所帮助。
SHH 反向隧道
在您的配置中,SSH 反向隧道是一个转移注意力的手段,实际上无关紧要,因为目标 IP 地址在到达监听 ssh 进程之前就被改变了。
您通常会在不同情况下使用 SSH 反向隧道,通常是为了绕过防火墙或地址转换。
IPtables 配置
您最初的配置将会按照下列方式改变入站数据包:
包 | 源 IP | 源端口 | 目标 IP | 目的端口 |
---|---|---|---|---|
原始数据包 | <外部 IP 地址 > | <端口_Y> | <linux_ip> | 7000 |
翻译包 | <外部 IP 地址 > | <端口_Y> | <windows_ip> | 7000 |
问题是返回的数据包看起来会像这样:
包 | 源 IP | 源端口 | 目标 IP | 目的端口 |
---|---|---|---|---|
返回包 | <windows_ip> | 7000 | <外部 IP 地址 > | <端口_Y> |
这些返回数据包将直接到达默认网关(如果未设置为默认网关,则绕过 Linux 机器),由于它与现有连接不匹配,因此将丢弃或更改该数据包。
修改 iptables 规则后,你将得到以下结果:
包 | 源 IP | 源端口 | 目标 IP | 目的端口 |
---|---|---|---|---|
原始数据包 | <外部 IP 地址 > | <端口_Y> | <linux_ip> | 7000 |
翻译包 | <linux_ip> | <端口 Z> | <windows_ip> | 7000 |
然后返回的数据包将会通过 Linux 机器传回,并且转换将会在相反方向上正确执行:
包 | 源 IP | 源端口 | 目标 IP | 目的端口 |
---|---|---|---|---|
原始退货包裹 | <windows_ip> | 7000 | <linux_ip> | <端口 Z> |
翻译后的返回数据包 | <linux_ip> | 7000 | <外部 IP 地址 > | <端口_Y> |
安全
如果不知道端口 7000 上的服务是什么,就很难对此发表评论,但考虑到您目前所掌握的信息,我认为在外围防火墙/路由器设备上实现同样的事情可能会更简单、更清晰,具体取决于该设备的功能。