Linux系统缺省并没有打开IP转发功能,要确认IP转发功能的状态,可以查看/proc文件系统,使用下面命令:
cat /proc/sys/net/ipv4/ip_forward如果上述文件中的值为0,说明禁止进行IP转发;如果是1,则说明IP转发功能已经打开。
要想打开IP转发功能,可以直接修改上述文件:
echo 1 > /proc/sys/net/ipv4/ip_forward把文件的内容由0修改为1。禁用IP转发则把1改为0。
上面的命令并没有保存对IP转发配置的更改,下次系统启动时仍会使用原来的值,要想永久修改IP转发,需要修改/etc/sysctl.conf文件,修改下面一行的值:
net.ipv4.ip_forward = 1修改后可以重启系统来使修改生效,也可以执行下面的命令来使修改生效:
sysctl -p /etc/sysctl.conf进行了上面的配置后,IP转发功能就永久使能了
有时候我们会在一个已有网络(10.10.10.0/24)内组建一个实验网络(192.168.1.0/24),网络结构如上图所示。
假设我们不能控制(修改)A网络内除D主机以外的系统配置,但可以完全控制网络B内的主机。
此时Server D实际上要承担一个路由的角色(它有两张网卡分别在两个网络A,B内)
所以先打开其上的内核路由转发功能,修改/etc/sysctl.conf中的如下配置
net.ipv4.ip_forward = 1保存后应用查看
1 2 # sysctl -p net.ipv4.ip_forward = 1另外需要保证Server D上的路由表配置正确,这里我们假设D上10.10.10.103所在的接口为eth0, 而192.168.1.1所在的接口为eth1
最后将网络B内的主机的默认网关都设置为Server D的192.168.1.1地址,到此准备工作已经完成。下面可以采用不同的方法来使得网络B和网络A中的主机实现不同程度的互联。
SNAT
如果想让B网络内的所有主机单向访问A网络内的资源可以在Server D上做一个NAT(SNAT):
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE这种方法就是最常用的NAT,内部网络B中的主机可以主动发起请求访问的外网A中的资源,实现内外网主机通信,但是外网A内的主机无法主动与内网主机建立连接。内网B中的主机没有A网内的独立IP。
如果只想让某台B网中的主机访问A网,则可以限定来源IP,具体可以参考iptables手册:
iptables -t nat -A POSTROUTING -s 192.168.100.100 -o eth0 -j MASQUERADESNAT + DNAT + ARP代理 = 浮动IP
如果我们想为网络B内的Server E分配一个IP如10.10.10.104(A网络的地址),使得网络A内的主机可以直接访问主机E
此时我们可以在Server D上先做一个SNAT:
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.100(E在B网内的地址) -j SNAT --to-source 10.10.10.104这样网络A网络收到Server E发出的包时,看到的IP就是10.10.10.104,其响应也会回发给这个地址
然后我们在Server D(网关)上做一个DNAT:
iptables -t nat -A PREROUTING -i eth0 -d 10.10.10.104 -j DNAT --to-destination 192.168.1.100这样Server D收到目的IP为10.10.10.104的包时就会修改目的IP为网络B内的Server E的IP(192.168.1.100),自然的按照Server D上的路由规则这个包会从接口eth1出去,经过交换机B,到达Server E。
现在还存在一个问题,我们不能修改网络A内的主机配置,怎么做才能让IP为10.10.10.104的包发到Server D来(因为主机D自己的IP是10.10.10.103)。如果我们自Server D上再插入一张网卡,让后将其地址设为10.10.10.104就可以,不过我们没有必要这么做。我们在主机D的eth0接口上加入一个次级地址即可
ip addr add 10.10.10.104/24 dev eth0这样网络A内的主机在使用ARP协议查询10.10.10.104所对应的MAC地址时,Server D就能做出响应,发送一个虚拟的MAC地址,于是发往10.10.10.104的包就会到达主机D,在进行上述的DNAT步骤,两边就可以互通了。
服务端口映射 SNAT + DNAT
浮动IP的方案需要占用一个网络A的IP,且会完全暴露主机E,有时可以通过端口映射向外部网络A暴露网络B内的服务,如将Server D上的2222端口与Server E上的22端口建立映射,这样网络A内的主机访问10.10.10.103:2222实际就是访问网络B内的主机192.168.100:22。