与iptables转发端口到其他客户端,但承认原始发件人IP

时间:2013-02-14 15:11:12

标签: iptables

我在专用的ubuntu服务器上有一个防火墙(基于iptables)。 我有几个局域网客户端。

在我的一个LAN客户端,我正在运行软件,我可以根据IP限制访问。 对我来说,重要的是我可以通过使用WAN IP来限制它,而不是LAN IP。

我已配置防火墙,以便将一个/一个端口转发到工作正常的LAN客户端(在stackoverflow上找到解决方案)。到目前为止没有任何问题。

然而,在局域网客户端,我没有看到外部发送者的IP,但是 - 我认为由于转发 - 客户端看到该数据包来自我的局域网服务器。

问题是:如何将我的服务器上的端口转发到具有不同端口的另一个LAN IP,但是以便LAN客户端识别该数据包的外部IP。

让我们说清楚:

服务器LAN IP:192.168.1.10 服务器端口:8080

应转发至: 客户端局域网IP:192.168.1.20 客户端LAN端口:8000

使用iptables我有:

iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8080 -d 192.168.1.10 -j DNAT --to 192.168.1.20:8000

iptables -A FORWARD -p tcp -d 192.168.1.20 --dport 8000 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

iptables -t nat -A POSTROUTING -p tcp --dport 8000 -d 192.168.1.20 -j SNAT --to 192.168.1.10

正如所写的有效,但当f.i.有人在IP 88.77.66.55发送数据包然后我的LAN客户端(192.168.1.20)看到该数据包来自我的LAN服务器(192.168.1.10),不幸的是不是来自88.77.66.55。

我能解决这个问题吗??

3 个答案:

答案 0 :(得分:5)

您的最后一条规则与MASQUERADE规则相同。

例如:

iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE

使用MASQUERADE或SNAT,您将在通过第一台服务器时修改源IP地址。第二个服务器看到数据包并将其响应发送回该IP,然后将其发送回客户端。

但是,服务器将请求视为来自192.168.1.10 - 因为它就是来自的地方。

客户>网关> iptables-router>服务器(见.10)> iptables-router>网关>客户端

如果删除MASQUERADE / SNAT,服务器会看到真实的IP,但是当它发送回复时,数据包将进入默认网关(默认路由),这可能是您的路由器或数据中心的网关。客户端从它不知道的IP地址获得响应,并且不知道如何处理它,所以它看起来不起作用。或者,网关/ rputer看到没有关联连接的SYNACK并丢弃该数据包。

客户>网关> iptables-router>服务器>网关(DROP)或>客户端(DROP)

如果您希望服务器获取客户端的真实IP,可以使用以下两种常用方法:

  1. 将服务器的网关(默认路由)设置为iptables机器的IP地址(即:运行这些iptables规则的机器)。在这种情况下,服务器将所有外部流量(即:对来自互联网的随机IP地址的响应)发送到正在等待回复的iptables机器的MAC地址。 iptables会将它发送回客户端。使用iptables机器作为路由器,网络服务器机器 iptables机器后面。
  2. 客户>网关> iptables-router>服务器(真实IP)> iptables-router>网关>客户端

    1. 使用像nginx这样的HTTP代理,它的工作方式与现在工作方式相同,客户端只能看到内部.10地址。但是,因为它是一个代理,它可以发送一个HTTP标头,如X-Original-IP-Address:123.456.789.012,其中包含客户端的真实IP地址。
    2. 客户>网关> iptables-router>服务器(看到X-Original-IP头)> iptables-router>网关>客户端

      最诚挚的问候, 尼尔

答案 1 :(得分:2)

让我们来定义:     
{source address} - 包发送者(某个远程地址)     
{接口地址} - 数据包接收器(防火墙外部地址)     
{本地地址} - 分组端点接收器本地网络地址     
{本地网关} - 防火墙本地地址     
{proto block} - IP协议限制(即-p tcp -m tcp --dport xxxx)
1.如果您希望客户端查看数据包源的IP地址 - 请执行以下操作:

IPTABLES -t nat -A PREROUTING -s {source address} -d {interface address} {proto block} -j DNAT --to-destination {local address}
IPTABLES -A FORWARD -d {local address} -j ACCEPT

别忘了制作:

echo "1" > /proc/sys/net/ipv4/ip_forward

它将启用数据包转发 在这种情况下,您的终点将看到原始IP地址,但是,它会尝试响应默认网关,如果此地址不在本地网络范围内,请添加:

route add {source address} gw {local gateway}

这将告诉您的端点通过{local gateway}发送{source address}的数据包(或回复) 2.您不希望端点看到原始IP地址,也不希望修改路由表,然后添加

IPTABLES -t nat -A POSTROUTING -s {source address} -j MASQUERADE

在这种情况下,LAN客户端将只看到{本地网关}地址。

在任何情况下,请不要忘记通过以下方式伪装从本地网络到远程地址的所有数据包:

IPTABLES -t nat -A POSTROUTING !-d 192.168.0.0/16 -j MASQUERADE
  1. 您希望保留源地址和目标地址以供进一步处理。在这种情况下,您的{本地网关}将只是数据包路由的一部分,{本地地址}必须只是下一跳 - 使用策略路由。
  2. 首先,将您自己的路径表标记为/etc/iproute2/rt_tables

    ,标记低于252

    然后 - 您可以将{source address}的规则直接添加到规则集或标记来自{source address}的数据包 - 两种方法都会查找您的自定义路由表以查找该数据包:

    ip rule add from {source address} table custom_table
    

    iptables -t mangle -A PREROUTING -s {source address} -j MARK --set-mark 1
    ip rule add fwmark 1 table custom_table
    

    然后,为这些数据包创建{local address}下一跳网关:

    ip route add default via {local address} table custom_table
    

    当然,POSTROUTING链将在数据包退出之前应用,您可以根据需要调整源地址。

答案 2 :(得分:0)

删除最后一条规则(不要做SNAT)。 或者限制SNAT只允许通过添加-o eth0条件伪装您的LAN客户端(假设eth0是外部接口):

iptables -t nat -A POSTROUTING -p tcp -o eth0 --dport 8000 -d 192.168.1.20 -j SNAT --to 192.168.1.10