有一个内联网和由 CentOS 驱动的网关,为内联网设备提供连接。
网关的 iptables 规则集中的典型端口转发如下所示(提供 TCP 版本):
$IPTABLES -A PREROUTING -t nat -i $EXTERNAL_IF -p tcp -d $EXTERNAL_IP \
--dport $EXTERNALPORT -j DNAT --to $INTERNAL_IP:$INTERNAL_PORT
$IPTABLES -A FORWARD -i $EXTERNAL_IF -p tcp -d $INTERNAL_IP \
--dport $INTERNAL_PORT -j ACCEPT
在这样的配置下,$EXTERNAL_IP:$EXTERNAL_PORT 无法从内网访问。
有没有办法将所有内部(源自内联网)流量直接重定向到 $EXTERNAL_IP:$EXTERNAL_PORT 到 $INTERNAL_IP:$INTERNAL_PORT ?
添加规则,例如
$IPTABLES -A PREROUTING -t nat -s $INTRANET -p tcp -d $EXTERNAL_IP \
--dport $EXTERNALPORT -j DNAT --to $INTERNAL_IP:$INTERNAL_PORT
$IPTABLES -A FORWARD -s $INTRANET -p tcp -d $INTERNAL_IP \
--dport $INTERNAL_PORT -j ACCEPT
其中 $INTRANET 是内部网地址的 CIDR,不起作用。
因此,我需要保留内联网设备的源地址(目标应该知道连接的确切来源)。
目前,都是使用hosts文件中IP的静态覆盖,不太方便。
答案1
当然不行。
让我们来看一下一个数据包离开 YOUR_PC,前往一个外部 IP 地址为 HTTP_EXT、内部 IP 地址为 HTTP_LAN 的网站。首先让我们考虑原来的iptables 规则。
数据包离开 YOUR_PC 前往 HTT_EXT,到达 CentOS 路由器;
CentOS 路由器拦截它,将源地址重写为自己地址,并将数据包发送到 HTTP_LAN 而不是 HTTP_EXT;
HTTP_LAN 收到数据包,发现它来自 CentOS,于是对其进行回复;
CentOS 收到回复数据包,记得它是经过 DNATted 的对话的一部分,将回复地址重写为 HTTP_EXT 而不是 HTTP_LAN,然后将其发送到 YOUR_PC。
YOUR_PC 看到来自 HTTP_EXT 的回复数据包,它已写入该数据包。一切正常。
但现在,考虑一下如果你可以做你想做的事:
数据包离开 YOUR_PC 前往 HTT_EXT,到达 CentOS 路由器;
CentOS 路由器拦截它,不是将源地址重写为自己的地址,并将数据包发送到HTTP_LAN而不是HTTP_EXT;
HTTP_LAN 收到数据包,发现它来自 YOUR_PC,则进行回复,无需经过 CentOS;
YOUR_PC 收到来自 HTTP_LAN 的数据包,同时它已写入 HTTP_EXT。出于明显的安全原因,它将丢弃回复数据包。
因此在这种情况下,这是行不通的就像你说的。换句话说:这个 INTRANET 地址转换有效当且仅当您同时执行 DNAT 和 SNAT。