iptables之snat与dnat

dnat-目的网络地址转换

dnat是用来做目的网络地址转换的,就是重写包的目的IP地址。如果一个包被匹配了,那么和它属于同一个流的所有的包都会被自动转换,然后就可以被路由到正确的主机或网络。比如,你的Web服务器在LAN内部,而且没有可在Internet上使用的真实IP地址,那就可以使用这个dnat让防火墙把所有到它自己HTTP端口的包转发给LAN内部真正的Web服务器。目的地址也可以是一个范围,这样的话,DNAT会为每次请求随机分配一个机器,这样我们可以用这个dnat做负载平衡。

[root@linux ~]# iptables -t nat -A PREROUTING -i eth0 -p tcp\
--dst 122.225.97.111 --dport 80 -j DNAT --to-destination 192.168.1.130:80

上面的例子是把所有通过eth0这个网卡发往地址122.225.97.111的包都转发到局域网的中192.168.1.130这台机器上.它也可以配全--string功能更强大.

[root@linux ~]# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80\
-m string --string "img.51yip.com" --algo bm -j DNAT --to-destination 192.168.1.136:80

将匹配到img.51yip.com的请求转到局域网的192.168.1.136这台机器上.

snat-本地ip地址伪装成其他机器的ip地址

snat可以让本地ip地址伪装成其他机器的ip地址,或者是公网IP,假如我有三台机器,一台能上外网,另外二台却不可以。不能上网的机器可以伪装成可上网的那机器的IP

[root@linux ~]# iptables -t nat -I POSTROUTING 1 -j SNAT -s 192.168.10.0/24 --to-destination 192.168.1.108

192.168.10.0/24这个IP段是不可以上网的,108这台机器是可以上网的.

DNAT与SNAT的区别

DNAT(Destination Network Address Translation,目的地址转换) 通常被叫做目的映谢。而SNAT(Source Network Address Translation,源地址转换)通常被叫做源映谢。

这是我们在设置Linux网关或者防火墙时经常要用来的两种方式。

首先,我们要了解一下IP包的结构,如下图所示:

1587508-20190404232709080-1522487701

在任何一个IP数据包中,都会有Source IP Address与Destination IP Address这两个字段,数据包所经过的路由器也是根据这两个字段是判定数据包是由什么地方发过来的,它要将数据包发到什么地方去。而iptables的DNAT与SNAT就是根据这个原理,对Source IP Address与Destination IP Address进行修改。

然后,我们再看看数据包在iptables中要经过的链(chain):

netfilter_packet_flow

图中正菱形的区域是对数据包进行判定转发的地方。在这里,系统会根据IP数据包中的destination ip address中的IP地址对数据包进行分发。如果destination ip adress是本机地址,数据将会被转交给INPUT链。如果不是本机地址,则交给FORWARD链检测。

这也就是说,我们要做的DNAT要在进入这个菱形转发区域之前,也就是在PREROUTING链中做,比如我们要把访问202.103.96.112的访问转发到192.168.0.112上:

iptables -t nat -A PREROUTING -d 202.103.96.112 -j DNAT --to-destination 192.168.0.112

这个转换过程当中,其实就是将已经达到这台Linux网关(防火墙)上的数据包上的destination ip address从202.103.96.112修改为192.168.0.112然后交给系统路由进行转发。

而SNAT自然是要在数据包流出这台机器之前的最后一个链也就是POSTROUTING链来进行操作

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 58.20.51.66

这个语句就是告诉系统把即将要流出本机的数据的source ip address修改成为58.20.51.66。这样,数据包在达到目的机器以后,目的机器会将包返回到58.20.51.66也就是本机。如果不做这个操作,那么你的数据包在传递的过程中,reply的包肯定会丢失。

iptables设置

查看规则

参数说明

  • -L 列出所有规则
  • -n 数字显示地址和端口信息
  • -v 详细信息
  • -line-numbers 显示规则序号

示例

  • 列出所有的规则
iptables -L -n
  • 以数字形式查看filter表INPUT链的所有规则
iptables -nL INPUT
  • 查看filter表INPUT链的所有规则,并显示规则序号
iptables -L INPUT --line-numbers

添加规则

参数说明

  • -A 在链末尾追加一条规则
  • -I 在链开头或某序号前插入一条规则

示例

  • 在filter表INPUT链的末尾添加一条规则,允许TCP协议的数据包通过
iptables -A INPUT -p tcp -j ACCEPT 
  • 在filter表INPUT链的首行添加一条规则,允许UDP协议的数据包通过
iptables -I INPUT -p udp -j ACCEPT 
  • 在filter表INPUT链的第二行添加一条规则,允许icmp协议的数据包通过
iptables -I INPUT 2 -p icmp -j ACCEPT 

删除规则

参数说明

  • -D 删除某个序号的规则
  • -F 清空规则

示例

  • 清除预设表filter中的所有规则链的规则
iptables -F 
  • 清除预设表filter中使用者自定链中的规则
iptables -X 
  • 删除filter表INPUT链的第二条规则
iptables -D INPUT 2 

设置规则

  • 将filter表FORWARD链的默认策略设为丢弃
iptables -P FORWARD DROP 
  • 将filter表OUTPUT链的默认策略设为允许
iptables -P OUTPUT ACCEPT 
  • 设置ssh访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
  • 丢弃通过icmp协议访问本机的数据包
iptables -I INPUT -p icmp -j DROP 
  • 允许转发除了icmp协议之外的数据包
iptables -A FORWARD ! -p icmp -j ACCEPT 
  • 防止Xmas扫描
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP 
  • 防止TCP Null扫描
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP 
  • 拒绝TCP标记为SYN/ACK,但连接状态为NEW的数据包,防止ACK欺骗
iptables -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j DROP 
  • 禁止从其他主机ping本机,但允许本机ping其他主机
iptables -A INPUT -p icmp --icmp-type 8 -j DROP 
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -A INPUT -p icmp -j DROP
  • 查看可用的ICMP协议类型
iptables -p icmp -h 
  • 允许loopback!(不然会导致DNS无法正常关闭等问题)
iptables -A INPUT -i lo -p all -j ACCEPT (如果是INPUT DROP)
iptables -A OUTPUT -o lo -p all -j ACCEPT(如果是OUTPUT DROP)
  • 开放相关端口,对发给本机的TCP应答数据包予以放行,其他入站数据包都丢弃
iptables -P INPUT DROP
iptables -I INPUT -p tcp -m multiport --dport 80,20,21,53 -j ACCEPT
iptables -I INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
  • 减少不安全的端口连接
iptables -A OUTPUT -p tcp --sport 31337 -j DROP 
  • 减少不安全的端口连接
iptables -A OUTPUT -p tcp --dport 31337 -j DROP 
  • iptables操作
service iptables save //保存
systemctl restart iptables.service //重启
systemctl enable iptables.service //开机启动

其他用法

  • 允许本机开放25、80、110、143端口,以便提供电子邮件服务
iptables -A INPUT -p tcp -m multiport --dport 25,80,110,143 -j ACCEPT
  • 设置只允许某个ip的端口访问
iptables -A INPUT -s 192.168.10.1 -p tcp --dport 22 -j ACCEPT 
  • 允许转发192.168.10.1-192.168.10.100之间的TCP数据包
iptables -A FORWARD -p tcp -m iprange --src-range 192.168.10.1-192.168.10.100 -j ACCEPT 
  • 禁止其MAC地址访问本机的任何应用
iptables -A INPUT -m mac --mac-source 00:50:2e:cf:44:3f -j DROP 
  • 如果请求本机的端口11521,则将目的ip和端口设置为192.168.8.49:1521
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 11521 -j DNAT --to-destination 192.168.8.49:1521 
  • 如果目的ip为192.168.8.49,则将报文的来源ip设置为本机ip
$iptables -t nat -A POSTROUTING -p tcp -m tcp -d 192.168.8.49 -j SNAT --to-source 192.168.8.150

iptables可通过MASQUERADE及网卡进行snat,跟传统 SNAT 的好处是它能动态从网卡获取地址。-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

nat介绍