最近工作中正好用到Linux NAT配置,总结一下这方面的经验,方便以后随时用到。
一、相关概念:
1.典型应用环境:
SNAT: 局域网主机共享单个公网IP地址接入Internet。
DNAT:在Internet中发布位于企业局域网内的服务器。
2.原理
SNAT: 源地址转换,修改数据包的源IP地址。
DNAT: 目标地址转换,修改数据包的目标IP地址。
3.前提条件
SNAT: 局域网各主机正确设置IP地址/子网掩码,局域网各主机正确设置默认网关。
DNAT: 局域网的Web服务器正确设置了IP地址/子网掩码,局域网的Web服务器正确设置了默认网关。
4.推荐实现步骤
4.1 SNAT
一、开启网关主机的路由转发功能。
二、添加使用SNAT策略的防火墙规则
规则示例:iptables -t nat -A POSTROUTING -s 192.168.3.0/24 -o eth0 -j SNAT --to-source 120.196.122.115
注:
POSTROUTING: 在路由选择之后再进行处理。
192.168.3.0/24: 来自特定局域网段的数据包。
eth0: 需要从接口eth0外出的数据包。
120.196.122.145: 网关主机外网接口的IP。
网关使用动态公网IP地址的情况,只需 将“-j SNAT --to-source 120.196.122.145”的形式改为“-j MASQUERADE”即可,如果是通过ADSL拨号方式连接Internet,则外网接口名称通常为ppp0、ppp1等。
MASQUERADE策略应用示例:iptables -t nat -A POSTROUTING -s 192.168.3.0/24 -o ppp0 -j MASQUERADE
4.2 DNAT
一、确认已经开启网关的路由转发功能。
二、添加使用DNAT策略的防火墙规则。
规则示例:iptables -t nat -A PREROUTING -i eth0 -d 120.196.122.145 -p tcp --dport 80 -j DNAT --to-destination 192.168.3.10
注:
PREROUTING: 在路由选择之前进行处理。
eth0: 从外网接口eth0进入的数据包。
120.196.122.145: 访问网关的公网IP地址的数据包。
80: 访问标准Web服务端口的数据包。
192.168.3.10: 内网中Web服务器的实际IP地址。
通过DNAT策略同时修改目标端口号,只需要在“--to-destination”后的目标IP地址后面增加“: 端口号”即可,即:-j DNAT --to-destination 目标IP:目标端口
通过DNAT策略修改目标端口号的应用示例:
从Internet中访问网关主机(120.196.122.145)的8888端口时,实际由运行在局域网主机(192.168.3.10)的8080端口应用程序提供服务。
iptables -t nat -A PREROUTING -i eth0 -d 120.196.122.145 -p tcp --dport 8888 -j DNAT --to-destination 192.168.3.10:8080
二、应用实例
网络拓扑:
配置Shell脚本如下:
#!/bin/bash
# This is Linux iptables NAT scripts
# write: liweizhong
# e-mail: lwz_benet@163.com
# date: 2012-08-28 version: 1.0
# Parameter variable
IP_FORWARD=`cat /proc/sys/net/ipv4/ip_forward`
SELINUX=`grep "SELINUX" /etc/sysconfig/selinux |sed -n 2p |cut -c 9-20`
IP_ETH0=`/sbin/ifconfig eth0 | sed -n "2p" |awk '{print $2}'| awk -F ":" '{print $2}'`
IP_ETH1=`/sbin/ifconfig eth0 | sed -n "2p" |awk '{print $2}'| awk -F ":" '{print $2}'`
SOURCE_NETWORK=`/sbin/ifconfig eth1 | sed -n "2p" |awk '{print $2}'| awk -F ":" '{print $2}'|awk -F "." '{print $1"."$2"."$3}'`
#WEB_IP=192.168.xx.xx
#TOMCAT_IP=192.168.xx.xx
#OTHER_IP=192.168.x.xx
# disabled selinux
if [ $SELINUX != disabled ]
then
sed -i "6s/enforcing/disabled/g" /etc/sysconfig/selinux
fi
# open route forward
if [ $IP_FORWARD -eq 0 ]
then
echo "1" > /proc/sys/net/ipv4/ip_forward
sysctl -p
fi
# iptables clean
iptables -F
iptables -t nat -F
# iptables filter ( Policy rule )
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -I INPUT -p udp --sport 53 -j ACCEPT
iptables -I INPUT -p tcp --sport 53 -j ACCEPT
#iptables -A INPUT -p tcp --dport 5901 -j ACCEPT
#iptables -A INPUT -p udp --dport 18080:18089 -j ACCEPT
#iptables -A INPUT -p tcp --dport 18080:18089 -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
iptables -A INPUT -i eth0 -j DROP
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
# iptables SNAT ( Internet sharing )
iptables -t nat -A POSTROUTING -o eth0 -s $SOURCE_NETWORK.0/24 -j SNAT --to $IP_ETH0
# iptables DNAT ( Optional )
#iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to $WEB_IP
#iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to $TOMCAT_IP
#iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1818 -j DNAT --to $OTHER_IP