Write by lyc at 2020-8-31
iptables动作总结之一
iptables动作总结之二

1.ACCEPT, DROP 基础动作

  • ACCEPTDROP 都属于基础动作,REJECT 则属于扩展动作。
  • 使用扩展动作也需要借助扩展模块,但是,扩展动作可以直接使用,不用像使用”扩展匹配条件”那样指定特定的模块。

2.REJECT 扩展动作

  • REJECTDROP 不同的是,会返回给客户端提示,而 DROP 是直接丢弃数据包,表现为 hang 住卡在那里
  • REJECT 动作的常用选项为 --reject-with,可以设置提示信息,当对方被拒绝时,会提示对方为什么被拒绝:
    • icmp-net-unreachable
    • icmp-host-unreachable
    • icmp-port-unreachable 默认值
    • icmp-proto-unreachable
    • icmp-net-prohibited
    • icmp-host-pro-hibited
    • icmp-admin-prohibited
1
$ iptables -A INPUT -s 192.168.99.208/32 -j REJECT --reject-with icmp-host-unreachable

3.SNAT, DNAT 扩展动作

  • 源地址转换:Source Network Address Translation,缩写为SNAT。
  • 目标地址转换:Destinationnetwork address translation,缩写为DNAT。
  • 整个过程被称为SNAT还是DNAT,取决于整个过程的前半段使用了SNAT还是DNAT。

iptables NAT:开启内核路由转发

使用 NAT功能首先要开启linux 内核转发

1
2
3
4
5
6
7
# 临时配置
$ echo 1 > /proc/sys/net/ipv4/ip_forward
$ cat /proc/sys/net/ipv4/ip_forward

# 永久生效
$ echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
$ sysctl -p

例1:SNAT 让ucloud没有公网IP的服务器C上网

服务器编号 服务器角色 公网IP 内网IP
A 公司办公笔记本 220.249.166.153
B iptables网关服务器(防火墙) 106.75.14.210 10.19.174.244
C ucloud内网服务器 10.19.171.140
  • 服务器C没有公网IP,是无法访问外网服务器,即无法ping通服务器A
  • B是ucloud内网区域,正常是需要把服务器C的默认网关指向服务器B,这里仅做对公司网络服务器A的打通,故不该默认路由,只在C上加一条去往公司网络的主机路由,下一条为服务器B的内网地址。
1
2
# 服务器C:配置去往服务器A的主机路由,下一条为服务器B的内网地址
$ route add -net 220.249.166.153 netmask 255.255.255.255 gw 10.19.174.244 dev eth0
1
2
3
4
5
6
# 服务器B:SNAT配置,来自服务器C的数据包,在nat表的POSTROUTING链出去时,源地址改写为服务器B自己的内网地址
$ iptables -t nat -I POSTROUTING -s 10.19.171.140 -j SNAT --to-source 10.19.174.244
$ iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 1 packets, 74 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT all -- * * 10.19.171.140 0.0.0.0/0 to:10.19.174.244
1
2
3
4
5
6
7
8
9
10
# 服务器C:ping测试可以连通服务器A
$ ping 220.249.166.153
PING 220.249.166.153 (220.249.166.153) 56(84) bytes of data.
64 bytes from 220.249.166.153: icmp_seq=1 ttl=50 time=40.9 ms
64 bytes from 220.249.166.153: icmp_seq=2 ttl=50 time=39.6 ms
64 bytes from 220.249.166.153: icmp_seq=3 ttl=50 time=39.5 ms
^C
--- 220.249.166.153 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 39.526/40.051/40.973/0.673 ms

例2:iptables实现内网ssh映射

Iptables实现公网IP DNAT/SNAT

(1)先理解云主机的NAT的过程

Write by lyc at 2020-9-18

1
2
客户端      175.42.20.30
云主机1 117.50.4.90-10.19.138.40
  • 首先要知道Ucloud云主机的EIP和云主机的eth0间有一层NAT转发,云主机是虚拟机,网卡上并没有绑定EIP
  • 所以数据包送达EIP时,会被DNAT转发到后端所绑定的云主机eth0上
1
客户端发数据包给EIP:源IP:175.42.20.30,目的IP:117.50.4.90

客户端发起请求,数据包送达云主机EIP,云DNAT进行转发,会修改数据包的目的地址改为云主机eth0的IP,数据包转发给eth0

1
EIP DNAT转发数据包给云主机eth0:源IP:175.42.20.30,目的IP:10.19.138.40

云主机接收到数据包,处理完后修改数据包的源、目的IP,回包给EIP

1
云主机eth0回包给EIP:源IP:10.19.138.40,目的IP:175.42.20.30

EIP收到回包的数据包,发现目的地址是公网的客户端,修改源IP地址为自己公网的EIP后,把数据包回包给客户端

1
EIP回包给客户端:源IP:117.50.4.90,目的IP:175.42.20.30

(2)iptables实现内网ssh映射

1
2
3
客户端      175.42.20.30
云主机1 117.50.4.90-10.19.138.40
云主机2 10.19.100.150

想要实现的效果,访问云主机1的2222端口,就可以访问到没有公网IP的云主机2上的10.19.100.150:22端口

iptables NAT:开启内核路由转发

使用 NAT功能首先要开启linux 内核转发

1
2
3
4
5
6
7
# 临时配置
echo 1 > /proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

# 永久生效
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

方式一:云主机1 配置DNAT

方式一是原理

1
2
$ iptables -t nat -I PREROUTING -p tcp -m tcp -s 175.42.20.0/26 -d 10.19.138.40 --dport 2222 -j DNAT --to-destination 10.19.100.150:22
$ iptables -t nat -I POSTROUTING -d 10.19.100.150 -j SNAT --to-source 10.19.138.40

-s 175.42.20.0/26 限制客户端的IP,因为是ssh,所以要限制访问的源。

数据包在iptables的流向NAT-PREROUTING -> FILTER-FORWARD -> NAT-POSTROUTING

分析数据包:

1
2
客户端发出数据包:源175.42.20.30,目的117.50.4.90
数据包到达云主机1之前:源175.42.20.30,目的10.19.138.40 (云EIP NAT改写)
  1. 数据包到达云主机1的eth0前,被 PREROUTING 链接收,匹配源和目的地址匹配,把目的地址改成云主机2的eth0 IP
1
数据包经过云主机1的PREROUTING:源175.42.20.30,目的10.19.100.150
  1. FILTER-FORWARD 接收ACCEPT默认规则放行
  2. NAT-POSTROUTING 接收,匹配目的地址是去云主机2的10.19.100.150,动作SANT处理修改了数据包源地址为 10.19.138.40(云主机1)的IP地址,转发数据包给云主机2
1
数据包经过云主机1的POSTROUTING:源10.19.138.40(主机1),目的10.19.100.150(主机2)
  1. 云主机2收到数据包,目的地址是自己的,处理数据包后,调换源和目的地址,此刻目的地址是云主机1的10.19.138.40,回包发送给云主机1
1
回包发往云主机1:源10.19.100.150(主机2),目的10.19.138.40(主机1)
  1. 云主机1收到回包,那么云主机1怎么回给客户端?
  2. 因为云主机1的iptables 内部维护了一张经过NAT改写的表,发现这个数据包是先前被SNAT过的,此刻就会把数据包的目的地址,还原成SANT之前的客户端真实IP地址,因此
1
2
3
4
云主机1先修改源和目的地址:源10.19.138.40(主机1),目的:??
查找NAT记录表,还原SNAT的记录
云主机1回包给EIP:源10.19.138.40(主机1),目的175.42.20.30(客户端)
把数据包发给EIP
  1. EIP最后修改数据包的源地址为自己的公网IP,回包给客户端
1
EIP回包客户端:源117.50.4.90(云主机1EIP),目的175.42.20.30(客户端)

方式二:云主机1 配置DNAT(-j MASQUERADE)

  • 方式二POSTROUTING时省略了SANT,利用MASQUERADE来实现SNAT,MASQUERADE会随机挑选云主机1任意一张网卡的IP地址做SNAT
  • 因为是有单网卡eth0,所以随机也就是只挑选eth0做SNAT而已
  • 这种方式就是省事,适用于单网卡。
1
2
iptables -t nat -I PREROUTING -p tcp -m tcp -s 175.42.20.0/26 -d 10.19.138.40 --dport 2222 -j DNAT --to-destination 10.19.100.150:22
iptables -t nat -I POSTROUTING -j MASQUERADE

同理:iptables NAT转发URedis、UDB

1
2
3
4
5
6
### ssh
iptables -t nat -I PREROUTING -p tcp -m tcp -s 175.42.20.0/26 -d 10.19.138.40 --dport 2222 -j DNAT --to-destination 10.19.100.150:22
iptables -t nat -I POSTROUTING -d 10.19.100.150 -j SNAT --to-source 10.19.138.40
### URedis
iptables -t nat -I PREROUTING -p tcp -m tcp -s 175.42.20.0/26 -d 10.19.138.40 --dport 3333 -j DNAT --to-destination 10.19.22.172:6379
iptables -t nat -I POSTROUTING -d 10.19.22.172 -j SNAT --to-source 10.19.138.40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 1 packets, 40 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- * * 175.42.20.0/26 10.19.138.40 tcp dpt:3333 to:10.19.22.172:6379
0 0 DNAT tcp -- * * 175.42.20.0/26 10.19.138.40 tcp dpt:2222 to:10.19.100.150:22

Chain INPUT (policy ACCEPT 1 packets, 40 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
0 0 SNAT all -- * * 0.0.0.0/0 10.19.22.172 to:10.19.138.40
0 0 SNAT all -- * * 0.0.0.0/0 10.19.100.150 to:10.19.138.40

4.MASQUERADE 扩展动作

MASQUERADE 会动态的将源地址转换为可用的IP地址,其实与SNAT实现的功能完全一致,都是修改源地址,只不过SNAT需要指明将报文的源地址改为哪个IP,而MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址

可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效。

1
2
$ iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
$ iptables -t nat -A POSTROUTING -j MASQUERADE

5.REDIRECT 扩展动作

使用REDIRECT动作可以在本机上进行端口映射

比如,将本机的80端口映射到本机的8080端口上

iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080

经过上述规则映射后,当别的机器访问本机的80端口时,报文会被重定向到本机的8080端口上。

REDIRECT规则只能定义在PREROUTING链或者OUTPUT链中。