我有一个带有开放端口的远程服务器。该服务器连接到 VPN 网络。我的本地计算机也连接到该 VPN 网络。这样,两台计算机就可以通信了。
我想做的是:我想在我的本地计算机上托管一个 http (websocket) 服务器,并通过访问我的服务器的 IP 地址从 Internet 上访问它。
我已经尝试过这些iptables
命令,但它们似乎不起作用:
iptables -t nat -A PREROUTING -p tcp --dport $SERVER_PORT -j DNAT --to-destination $LOCAL_MACHINE_VPN_ADDRESS:$SERVER_PORT
iptables -t nat -A POSTROUTING -p tcp -d $LOCAL_MACHINE_VPN_ADDRESS --dport $SERVER_PORT -j SNAT --to-source $SERVER_LOCAL_NETWORK_ADDRESS
我的例子中的确切值是:
SERVER_PORT=6767
LOCAL_MACHINE_VPN_ADDRESS=10.0.1.255
SERVER_LOCAL_NETWORK_ADDRESS=193.108.113.52
我从界面下的命令SERVER_LOCAL_NETWORK_ADDRESS
中读取。它有这个字符串:。ip addr
eth0
inet 193.108.113.52/24 scope global eth0
我有点迷失在这里。我是否需要以某种方式显式设置eth0
和wg0
接口?
我确定的一件事是我的 VPN 配置:我已经nginx
在这台服务器上运行,代理到我的本地计算机,并且工作正常。
答案1
我从eth0 接口下的命令
SERVER_LOCAL_NETWORK_ADDRESS
读取。ip addr
它有这个字符串:inet 193.108.113.52/24 scope global eth0
。
由于您打算在 VPN 内路由数据包,并且没有在 LOCAL_MACHINE 上进行特殊的路由调整以允许从通常的 Internet 访问之外的其他地方(例如:家庭路由器)接收公共 IP 地址,也没有对 WireGuard 进行特殊的调整设置允许这样做, POSTROUTINGiptablesSERVER 上的命令应将地址设置为其本地 WireGuard 隧道地址,而不是其公共地址:上述信息不需要且无法工作。
相反,只需使用-j MASQUERADE
(因为我不知道远程服务器的 WireGuard 地址,可能是 10.0.1.1 之类的地址,否则我也可以建议更改地址-j SNAT
)。所以iptables
下面的最后一个命令:
iptables -t nat -A POSTROUTING -p tcp -d $LOCAL_MACHINE_VPN_ADDRESS --dport $SERVER_PORT -j SNAT --to-source $SERVER_LOCAL_NETWORK_ADDRESS
应替换为:
iptables -t nat -A POSTROUTING -p tcp -d $LOCAL_MACHINE_VPN_ADDRESS --dport $SERVER_PORT -j MASQUERADE
笔记:
在所有情况下,执行 SNAT 或 MASQUERADE 将阻止 Websocket 服务查看 Internet 客户端的实际 IP 地址:该地址始终是远程服务器上的地址。
要让 websocket 服务看到 Internet 客户端的实际公共地址,需要实际的路由,涉及基于策略的路由因为 LOCAL_MACHINE 现在必须是多宿主的,而不是使用 NAT。这需要了解远程服务器和本地服务器的完整网络配置,包括未提供的 WireGuard 配置,以了解要更改的内容。
提醒一句,iptables(或者nftables或者网络过滤器) 不路由。它可以改变与路由相关的地址或其他属性,如果这种改变是在路由堆栈看到它们之前完成的(例如:PREROUTING),那么这可以间接改变路由决策。实际路由是使用ip route
、 完成的,对于基于策略的路由,还可以使用ip rule
、 或使用网络配置工具执行与这些命令相同的操作。