实战经验:Linux Source NAT在Ping场景下的应用

实战经验:Linux Source NAT在Ping场景下的应用

作者:BlogUpdater |  时间:2017-06-28 |  浏览:1383 |  评论已关闭 条评论

有时候,有这样的一种需求:
需要修改IP数据包中的源地址,比如,从某一个主机发送Ping包到另一个主机,需要修改源地址为另一个源(通常,发出Ping请求的主机有多个网卡地址)。
为了解决这一需求,Linux下的netfilter组件中有个Source NAT的功能,可以修改IP数据包中的源地址。
此功能实际上是通过iptables在POSTROUTING链中添加一条规则,此规则在数据包被最终发送出去之前被应用。下面是一个实例:

主机A网络配置:
eth0: 192.168.10.10
eth1: 172.18.10.10

主机B:
eth0: 192.168.10.1

1) 第一张场景
从A发送Ping请求到B:
# ping 192.168.10.1
通过WireShark抓包可以知道,Ping包中的源地址为192.168.10.10(默认Ping请求从eth0出来),目的地址是192.168.10.1。

2) 第二种场景
从A发送Ping请求到B,并使用-I选项:
# ping 192.168.10.1 -I 172.18.10.10
在此场景下,这里指定了-I选项,表明指定源地址为172.18.10.10。
所以,Ping请求包中的源地址变为172.18.10.10,目的地址不变,依然为192.168.10.1。

问题来了:怎样在第二种场景中(在指定-I选项的情况下)将源地址修改为192.168.10.10?

解决方法:添加Source NAT规则。具体步骤如下:

添加规则:
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to 192.168.10.10

添加完上述规则后,再次执行ping 192.168.10.1 -I 172.18.10.10,可以通过抓包发现Ping请求中的源地址已经由172.18.10.10修改为192.168.10.10。

备注:
如果想删除上面添加的Source NAT规则,可以执行如下指令删除:

删除规则:
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to 192.168.10.10

查看规则:
# iptables -nvL -t nat

参考资料:
以下内容来自netfilter官网帮助文档,也记录在这里留作参考:

1) Source NAT
You want to do Source NAT; change the source address of connections to something different. This is done in the POSTROUTING chain, just before it is finally sent out; this is an important detail, since it means that anything else on the Linux box itself (routing, packet filtering) will see the packet unchanged. It also means that the `-o’ (outgoing interface) option can be used.
Source NAT is specified using `-j SNAT’, and the `–to-source’ option specifies an IP address, a range of IP addresses, and an optional port or range of ports (for UDP and TCP protocols only).

## Change source addresses to 1.2.3.4.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

## Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6

## Change source addresses to 1.2.3.4, ports 1-1023
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

Masquerading
There is a specialized case of Source NAT called masquerading: it should only be used for dynamically-assigned IP addresses, such as standard dialups (for static IP addresses, use SNAT above).
You don’t need to put in the source address explicitly with masquerading: it will use the source address of the interface the packet is going out from. But more importantly, if the link goes down, the connections (which are now lost anyway) are forgotten, meaning fewer glitches when connection comes back up with a new IP address.

## Masquerade everything out ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

2) Destination NAT
This is done in the PREROUTING chain, just as the packet comes in; this means that anything else on the Linux box itself (routing, packet filtering) will see the packet going to its `real’ destination. It also means that the `-i’ (incoming interface) option can be used.
Destination NAT is specified using `-j DNAT’, and the `–to-destination’ option specifies an IP address, a range of IP addresses, and an optional port or range of ports (for UDP and TCP protocols only).

## Change destination addresses to 5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8

## Change destination addresses to 5.6.7.8, 5.6.7.9 or 5.6.7.10.
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10

## Change destination addresses of web traffic to 5.6.7.8, port 8080.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 5.6.7.8:8080

Redirection
There is a specialized case of Destination NAT called redirection: it is a simple convenience which is exactly equivalent to doing DNAT to the address of the incoming interface.

## Send incoming port-80 web traffic to our squid (transparent) proxy
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128

Note that squid needs to be configured to know it’s a transparent proxy!

标签:

相关推荐

评论已关闭。