网络SNAT与DNAT防火墙之iptables

iptables/netfilter

利用filter表的FORWARD链,可以充当网络防火墙:

注意的问题:

(1) 请求-响应报文均会经由FORWARD链,要注意规则的方向性
(2) 如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行

NAT的实现分为下面类型:

SNAT:source NAT ,支持POSTROUTING, INPUT,让本地网络中的主机通过某一特定地址访问
外部网络,实现地址伪装,请求报文:修改源IP

DNAT:destination NAT 支持PREROUTING , OUTPUT,把本地网络中的主机上的某服务开放给外
部网络访问(发布服务和端口映射),但隐藏真实IP,请求报文:修改目标IP

PNAT: port nat,端口和IP都进行修改

环境准备:

web1服务器:172.31.0.17
web2服务器:172.31.0.27
模拟外网:192.168.0.100  # 仅主机模式
防火墙服务器:172.31.0.37  # 添加一个网卡仅主机模式192.168.0.106

两台web安装软件:

# 安装并启动
[root@localhost ~]# yum install httpd -y ; echo 172.31.0.17 > /var/www/html/index.html;systemctl start httpd

[root@localhost ~]# yum install httpd -y ; echo 172.31.0.27 > /var/www/html/index.html;systemctl start httpd

# 两台web的网关必须指向防火墙服务器的eth0网卡
[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.0.37     0.0.0.0         UG    100    0        0 eth0
172.31.0.0      0.0.0.0         255.255.0.0     U     100    0        0 eth0

配置防火墙服务器

# 172.31.0.37
# 开启路由转发功能
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

tcpdump抓包分析问题

# 172.31.0.27
[root@localhost ~]# tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:48:08.680084 IP 192.168.0.100 > 172.31.0.27: ICMP echo request, id 2237, seq 1, length 64
21:48:08.680693 IP 172.31.0.27 > 192.168.0.100: ICMP echo reply, id 2237, seq 1, length 64
21:48:09.721779 IP 192.168.0.100 > 172.31.0.27: ICMP echo request, id 2237, seq 2, length 64
21:48:09.721947 IP 172.31.0.27 > 192.168.0.100: ICMP echo reply, id 2237, seq 2, length 64

模拟外网的配置:

# 192.168.0.100
路由要指向防火墙服务器的eth1网卡
[root@sz-kx-centos8 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.106   0.0.0.0         UG    100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0

添加这个规则,外面进不来,里面出得去

[root@localhost ~]# iptables -A FORWARD ! -s 172.31.0.0/16 -d 172.31.0.0/16 -m state --state NEW -j REJECT

范例:允许外网访问172.31.0.17:80

[root@localhost ~]# iptables -I FORWARD ! -s 172.31.0.0/16 -d 172.31.0.17 -m state --state NEW -p tcp --dport 80 -j ACCEPT

客户端测试:

[root@sz-kx-centos8 ~]# curl 172.31.0.17
172.31.0.17
[root@sz-kx-centos8 ~]# curl 172.31.0.27
curl: (7) Failed to connect to 172.31.0.27 port 80: Connection refused

范例:利用state模块实现允许内网可以访问外网所有资源

[root@localhost ~]# iptables -I FORWARD 2 -s 172.31.0.0/16 -m state --state NEW -j ACCEPT

SNAT

SNAT:基于nat表的target,适用于固定的公网IP

SNAT选项:

--to-source [ipaddr[-ipaddr]][:port[-port]]

MASQUERADE:基于nat表的target,适用于动态的公网IP,如:拨号网络

MASQUERADE选项:

--to-ports port[-port]
--random

配置防火墙服务器

# 172.31.0.37
# 开启路由转发功能
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

范例:针对专线静态公共IP

[root@localhost ~]# iptables -t nat -A POSTROUTING -s 172.31.0.0/16 -j SNAT --to-source 192.168.0.106

范例:针对拨号网络和专线静态公共IP

[root@localhost ~]# iptables -t nat -A POSTROUTING -s 172.31.0.0/16 -j MASQUERADE

DNAT

DNAT:nat表的target,适用于端口映射,即可重定向到本机,也可以支持重定向至不同主机的不同端
口,但不支持多目标,即不支持负载均衡功能

DNAT选项:

--to-destination [ipaddr[-ipaddr]][:port[-port]]

DNAT 格式:

iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --todestination
InterSeverIP[:PORT]

配置防火墙服务器

# 172.31.0.37
# 开启路由转发功能
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

实验:

# 删除外网的默认网关
[09:29:14 root@sz-kx-centos8 ~]# ip route
default via 192.168.0.106 dev eth0 proto static metric 100 
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.100 metric 100 
[09:44:55 root@sz-kx-centos8 ~]# ip route del default via 192.168.0.106 dev eth0 proto static metric 100

# 添加iptables规则
[root@localhost ~]# iptables -t nat -A PREROUTING -d 192.168.0.106 -p tcp --dport 80 -j DNAT --to-destination 172.31.0.17

# 模拟外网服务器测试curl 防火墙的eth1网卡
[09:47:31 root@sz-kx-centos8 ~]# curl 192.168.0.106
172.31.0.17

# web1服务器查看日志
[root@localhost ~]# tail -f /var/log/httpd/access_log 

192.168.0.100 - - [09/May/2021:09:51:27 +0800] "GET / HTTP/1.1" 200 12 "-" "curl/7.61.1"

# 当服务器80端口改为8080时
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
Listen 8080
[root@localhost ~]# systemctl restart httpd

# 模拟外网服务器测试curl 防火墙的eth1网卡报错了
[09:51:28 root@sz-kx-centos8 ~]# curl 192.168.0.106
curl: (7) Failed to connect to 192.168.0.106 port 80: Connection refused

# 添加如下iptables规则
[root@localhost ~]# iptables -t nat -I PREROUTING 1 -d 192.168.0.106 -p tcp --dport 80 -j DNAT --to-destination 172.31.0.17:8080

# 再次访问
[09:50:40 root@sz-kx-centos8 ~]# curl 192.168.0.106
172.31.0.17

防火墙服务器不监听ip端口,是使用内核处理80端口请求

当端口发生变化,在不改防火墙端口情况下操作如下:

REDIRECT 转发

REDIRECT,是NAT表的target,通过改变目标IP和端口,将接受的包转发至同一个主机的不同端口,可用于PREROUTING OUTPUT链

REDIRECT选项:

--to-ports port[-port]

注意: 无需开启 ip_forward

[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
Listen 9000
[root@localhost ~]# systemctl restart httpd

# 客户端访问报错
[10:04:25 root@sz-kx-centos8 ~]# curl 192.168.0.106
curl: (7) Failed to connect to 192.168.0.106 port 80: Connection refused

# 在web1添加一条转发iptables规则REDIRECT 转发
[root@localhost ~]# iptables -t nat -A PREROUTING  -d 172.31.0.17 -p tcp --dport 8080 -j REDIRECT --to-ports 9000

客户端再次测试:
[10:07:27 root@sz-kx-centos8 ~]# curl 192.168.0.106
172.31.0.17

综合案例

环境准备:

总共四台服务器
私网服务器:192.168.0.100/24     # 仅主机模式
防火墙服务器1:172.31.0.17/16    # 仅主机模式 192.168.0.102/24
防火墙服务器2:172.31.0.27/16    # 仅主机模式 10.0.0.27/24
另一个私网服务器:10.0.0.37/24   # 自定义仅主机模式vmnet10

安装软件

两台私网服务器安装
[root@localhost ~]# yum -y install httpd ;echo 192.168.0.100 > /var/www/html/index.html;systemctl start httpd

[root@localhost ~]# yum -y install httpd ;echo 10.0.0.37 > /var/www/html/index.html;systemctl start httpd

配置两台防火墙服务器开启路由转发

[root@localhost ~]# vim /etc/sysctl.conf 
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

两台不同的私网服务器网关指向相同网段的ip地址作为网关

没有添加iptables规则时,两台私网服务器都是不能访问对方网址

[root@localhost ~]# curl 10.0.0.37
curl: (7) Failed connect to 10.0.0.37:80; No route to host
[root@localhost ~]# curl 192.168.0.100
curl: (7) Failed connect to 192.168.0.100:80; No route to host

添加iptables规则实现双方可以访问对方的的所有端口网址

# 192.168.0.102
[root@localhost ~]# iptables -t nat -A POSTROUTING  -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j MASQUERADE

# 10.0.0.27
[root@localhost ~]# iptables -t nat -A POSTROUTING  -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

客户端测试

# 192.168.0.100
[root@localhost ~]# curl 10.0.0.37
10.0.0.37

# 10.0.0.37
[root@localhost ~]# curl 192.168.0.100
192.168.0.100

升级版:

添加iptables规则实现双方可以访问对方的80端口

# 192.168.0.102
[root@localhost ~]# iptables -t nat -A POSTROUTING  -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j MASQUERADE
[root@localhost ~]# iptables -t nat -A PREROUTING -d 172.31.0.17 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100:80

# 10.0.0.27
[root@localhost ~]# iptables -t nat -A POSTROUTING  -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE
[root@localhost ~]# iptables -t nat -A PREROUTING -d 172.31.0.27 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.37:80

客户端访问

[root@localhost ~]# curl 172.31.0.27
10.0.0.37

[root@localhost ~]# curl 172.31.0.17
192.168.0.100

web查看日志可以看到是公网地址172.31.0.27

# 192.168.0.100
[root@localhost ~]# tail -f /var/log/httpd/access_log


172.31.0.27 - - [09/May/2021:03:51:02 -0400] "GET / HTTP/1.1" 200 14 "-" "curl/7.29.0"

使用tcpdump抓包发现公网返回的不是真正的ip地址

# 192.168.0.100
[root@localhost ~]# ping 10.0.0.37
PING 10.0.0.37 (10.0.0.37) 56(84) bytes of data.
64 bytes from 10.0.0.37: icmp_seq=1 ttl=127 time=0.951 ms
64 bytes from 10.0.0.37: icmp_seq=2 ttl=127 time=0.908 ms

[root@localhost ~]# tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
03:29:09.149404 IP 192.168.0.1 > 192.168.0.100: ICMP echo request, id 17595, seq 1, length 64
03:29:09.149437 IP 192.168.0.100 > 192.168.0.1: ICMP echo reply, id 17595, seq 1, length 64
03:29:10.151662 IP 192.168.0.1 > 192.168.0.100: ICMP echo request, id 17595, seq 2, length 64
posted @ 2021-05-09 17:17  空白的旋律  阅读(282)  评论(0编辑  收藏  举报