如何用iptables实现NAT

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用iptables实现NAT相关的知识,希望对你有一定的参考价值。

如前所述,在使用iptables的NAT功能时,我们必须在每一条规则中使用"-t nat"显示的指明使用nat表。然后使用以下的选项:  1. 对规则的操作  加入(append) 一个新规则到一个链 (-A)的最后。  在链内某个位置插入(insert) 一个新规则(-I),通常是插在最前面。  在链内某个位置替换(replace) 一条规则 (-R)。  在链内某个位置删除(delete) 一条规则 (-D)。  删除(delete) 链内第一条规则 (-D)。  2. 指定源地址和目的地址  通过--source/--src/-s来指定源地址(这里的/表示或者的意思,下同),通过--destination/--dst/-s来指定目的地址。可以使用以下四中方法来指定ip地址:  a. 使用完整的域名,如“ www.linuxaid.com.cn”;  b. 使用ip地址,如“192.168.1.1”;  c. 用x.x.x.x/x.x.x.x指定一个网络地址,如“192.168.1.0/255.255.255.0”;  d. 用x.x.x.x/x指定一个网络地址,如“192.168.1.0/24”这里的24表明了子网掩码的有效位数,这是 UNIX环境中通常使用的表示方法。  缺省的子网掩码数是32,也就是说指定192.168.1.1等效于192.168.1.1/32。  3. 指定网络接口  可以使用--in-interface/-i或--out-interface/-o来指定网络接口。从NAT的原理可以看出,对于PREROUTING链,我们只能用-i指定进来的网络接口;而对于POSTROUTING和OUTPUT我们只能用-o指定出去的网络接口。  4. 指定协议及端口  可以通过--protocol/-p选项来指定协议,如果是udp和tcp协议,还可--source-port/--sport和 --destination-port/--dport来指明端口。 参考技术A 使用实例

1. 源NAT(SNAT)

比如,更改所有来自192.168.1.0/24的数据包的源ip地址为1.2.3.4:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 1.2.3.4

这里需要注意的是,系统在路由及过虑等处理直到数据包要被送出时才进行SNAT。

有一种SNAT的特殊情况是ip欺骗,也就是所谓的Masquerading,通常建议在使用拨号上网的时候使用,或者说在合法ip地址不固定的情况下使用。比如

# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

可以看出,这时候我们没有必要显式的指定源ip地址等信息。

2. 目的SNAT(DNAT)

比如,更改所有来自192.168.1.0/24的数据包的目的ip地址为1.2.3.4:

iptables -t nat -A PREROUTING -s 192.168.1.0/24 -i eth1 -j DNAT --to 1.2.3.4

这里需要注意的是,系统是先进行DNAT,然后才进行路由及过虑等操作。

有一种DNAT的特殊情况是重定向,也就是所谓的Redirection,这时候就相当于将符合条件的数据包的目的ip地址改为数据包进入系统时的网络接口的ip地址。通常是在与squid配置形成透明代理时使用,假设squid的监听端口是3128,我们可以通过以下语句来将来自192.168.1.0/24,目的端口为80的数据包重定向到squid监听
端口:

iptables -t nat -A PREROUTING -i eth1 -p tcp -s 192.168.1.0/24 --dport 80
-j REDIRECT --to-port 3128

六、综合例子

1. 使用拨号带动局域网上网

小型企业、网吧等多使用拨号网络上网,通常可能使用代理,但是考虑到成本、对协议的支持等因素,建议使用ip欺骗方式带动区域网上网。

成功升级内核后安装iptables,然后执行以下脚本:

#载入相关模块
modprobe ip_tables
modprobe ip_nat_ftp

#进行ip伪装
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

2. ip映射

假设有一家ISP提供园区Internet接入服务,为了方便管理,该ISP分配给园区用户的IP地址都是伪IP,但是部分用户要求建立自己的WWW服务器对外发布信息。我们可以再防火墙的外部网卡上绑定多个合法IP地址,然后通过ip映射使发给其中某一个IP地址的包转发至内部某一用户的WWW服务器上,然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。

我们假设以下情景:

该ISP分配给A单位www服务器的ip为:
伪ip:192.168.1.100
真实ip:202.110.123.100

该ISP分配给B单位www服务器的ip为:
伪ip:192.168.1.200
真实ip:202.110.123.200

linux防火墙的ip地址分别为:
内网接口eth1:192.168.1.1
外网接口eth0:202.110.123.1

然后我们将分配给A、B单位的真实ip绑定到防火墙的外网接口,以root权限执行以下命令:

ifconfig eth0 add 202.110.123.100 netmask 255.255.255.0
ifconfig eth0 add 202.110.123.200 netmask 255.255.255.0

成功升级内核后安装iptables,然后执行以下脚本:

#载入相关模块
modprobe ip_tables
modprobe ip_nat_ftp

首先,对防火墙接收到的目的ip为202.110.123.100和202.110.123.200的所有数据包进行目的NAT(DNAT):

iptables -A PREROUTING -i eth0 -d 202.110.123.100 -j DNAT --to 192.168.1.100
iptables -A PREROUTING -i eth0 -d 202.110.123.200 -j DNAT --to 192.168.1.200

其次,对防火墙接收到的源ip地址为192.168.1.100和192.168.1.200的数据包进行源NAT(SNAT):

iptables -A POSTROUTING -o eth0 -s 192.168.1.100 -j SNAT --to 202.110.123.100
iptables -A POSTROUTING -o eth0 -s 192.168.1.200 -j SNAT --to 202.110.123.200

这样,所有目的ip为202.110.123.100和202.110.123.200的数据包都将分别被转发给192.168.1.100和192.168.1.200;而所有来自192.168.1.100和192.168.1.200的数据包都将分别被伪装成由202.110.123.100和202.110.123.200,从而也就实现了ip映射。

iptables之NAT

iptables之NAT

==============================================================================

概述:





NAT:

1)Firewall

源地址转换(SNAT):POSTROUTING

  主要用于实现让内网客户端访问外部主机地址时使用,要定义在POSTROUTING链或INPUT链

  • 静态转换:外网地址是固定的;

  • 动态转换:外网地址不固定

目标地址转换(DNAT):PREROUTING

PAT:Port Address Translati:端口映射(了解即可)

SNAT实验测试如下:

  实验环境是基于上一篇网络防火墙的环境,这里不再过多赘述:


  1.实验操作之前,内网主机的可以访问外网主机,也可以ping通,如下:

技术分享 

  通过外网的日志查看和请求ping报文清除的知道源地址是内网主机,内网主机没有做任何的转换

技术分享

   2.接下来我们要把内网地址转换成网关主机的外网地址,已达到伪装,隐藏之源地址的目的。

   1)定义规则源地址转换为网关主机的外网地址10.1.252.161,允许内网的所有主机访问外网的所有服务

[[email protected] ~]# iptables -vnL  # 定义规则前查看
Chain INPUT (policy ACCEPT 16 packets, 1130 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 12 packets, 1008 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 6 packets, 1160 bytes)
 pkts bytes target     prot opt in     out     source               destination         

 定义规则,指明源内网地址,因为访问的是外网的所有服务所以地址和端口不用指定,指明源地址转化为网关
 主机的外网地址
[[email protected] ~]# iptables -t nat -A POSTROUTING -s 192.168.22.0/24 -j SNAT --to-source 10.1.252.161

[[email protected] ~]# iptables -t nat -vnL  指明nat表查看定义的规则
Chain PREROUTING (policy ACCEPT 59 packets, 6309 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 21 packets, 3188 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1 packets, 156 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 1 packets, 156 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    1    84 SNAT       all  --  *      *       192.168.22.0/24      0.0.0.0/0            to:10.1.252.161

  接下来,内网主机再次访问外网的web服务和ping操作,外网抓包和访问日志已经伪装成网关主机的外网地址,如下:

技术分享

   为了验证是在哪个环节发生的地址转换,我们在网关主机的内网网卡和外网网卡分别抓包,如下:

技术分享


DNAT目标地址转换实验如下:

   实验前环境准备:

   1.因为DNAT为目标地址转换,即让内网中的服务器在外网中可以被访问到,所以,为了增加实验的说服力,我这里在内网的同一块网卡上再添加一个ip地址,让每一个ip地址对应一个服务,如下:

技术分享 

   2.如上,地址已经添加成功,假设22地址对应的是web服务,23的地址对应的是ssh服务(这里可以想象成两个主机,但实际上是一个主机,为了演示效果);为了不影响实验效果这里我先把上例中定义的SNAT规则清空,如下:

[[email protected] ~]# iptables -t nat -F
[[email protected] ~]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination


实验如下:

   假设内网地址192.168.22.2上提供了web服务,我们希望外网用户把对网关主机外网网卡请求的web服务的80端口全都转化到内网的192.168.22.2上,设置如下:

分析:这里一定是在nat表的PREROUTING链上定义,指明目标IP为网关主机的外网地址10.1.252.161
,指明协议为tcp协议(如果不指明的话所有的服务会统统转到一台内网主机之上),指明目标端口
为网关主机外网地址的80端口(实际上根本没有,因为网关主机跟本就没有提供服务),指明转换的
目标地址为提供服务的内网主机地址192.168.22.2,这里没指明端口,默认就是网关主机的端口80,也
可以不相同,也就是端口映射;

[[email protected] ~]# iptables -t nat -A PREROUTING -d 10.1.252.161 -p tcp --dport 80 -j DNAT --to-destination 192.168.22.2
[[email protected] ~]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 3 packets, 675 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            10.1.252.161         tcp dpt:80 to:192.168.22.2

Chain INPUT (policy ACCEPT 3 packets, 675 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

 查看网关主机确认是没有开通web服务的80端口

[[email protected] ~]# ss -tnl
State       Recv-Q Send-Q                                      Local Address:Port                                                     Peer Address:Port              
LISTEN      0      25                                                      *:514                                                                 *:*                  
LISTEN      0      128                                                     *:22                                                                  *:*                  
LISTEN      0      128                                             127.0.0.1:631                                                                 *:*                  
LISTEN      0      100                                             127.0.0.1:25                                                                  *:*                  
LISTEN      0      128                                             127.0.0.1:6010                                                                *:*                  
LISTEN      0      25                                                     :::514                                                                :::*                  
LISTEN      0      128                                                    :::22                                                                 :::*                  
LISTEN      0      128                                                   ::1:631                                                                :::*                  
LISTEN      0      100                                                   ::1:25                                                                 :::*                  
LISTEN      0      128                                                   ::1:6010                                                               :::*

 使用外网主机请求网关主机的web服务,如下:

技术分享

 

  如上,我们只是把web服务转发到了一个内网服务上,是有选择行的。如果我们现在用外网去ping网关主机的外网地址,是不通的,要想通定义如下:

[[email protected] ~]# iptables -t nat -F # 清空服务

把上例中指定的协议和端口去掉即可,即外网用户的所有任意服务访问,全都转到内网主机为192.168.22.2的主机
[[email protected] ~]# iptables -t nat -A PREROUTING -d 10.1.252.161  -j DNAT --to-destination 192.168.22.2
[[email protected] ~]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DNAT       all  --  *      *       0.0.0.0/0            10.1.252.161         to:192.168.22.2

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

  外网主机去ping网关主机的10.1.252.161,在内网主机上抓包如下:

技术分享

















































以上是关于如何用iptables实现NAT的主要内容,如果未能解决你的问题,请参考以下文章

iptables 及 docker 容器网络分析

Linux下如何用iptables限制某段IP访问服务器

关于iptables--基础知识

如何用rsync进行fu服务器之间的超快速同步数据?

脑筋急转弯:如何用两个栈实现一个队列 && 如何用两个队列实现一个栈

脑筋急转弯:如何用两个栈实现一个队列 && 如何用两个队列实现一个栈