iptables网络防火墙和SNAT原理实战

Posted struggle-1216

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iptables网络防火墙和SNAT原理实战相关的知识,希望对你有一定的参考价值。

网络防火墙

iptables/netfilter网络防火墙:

(1) 充当网关
(2) 使用filter表的FORWARD链

注意的问题:

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

实战演练:

环境准备:

A主机:192.168.37.6(NAT模式,做内网)

B主机:192.168.37.7(NAT模式),172.16.0.7(桥接模式)B主机作为防火墙

C主机:172.16.0.17(桥接模式,做外网)

技术图片

 (1)在A主机修改IP地址

[root@centos7network-scripts]#cat ifcfg-ens33
DEVICE=ens33
BOOTPROTO=static
IPADDR=192.168.37.6
PREFIX=24
GATEWAY=192.168.37.7
ONBOOT=yes

(2)修改B主机的NAT模式IP地址配置文件

[root@centos7network-scripts]#cat ifcfg-ens33
DEVICE=ens33
BOOTPROTO=none
IPADDR=192.168.37.7
PREFIX=24
ONBOOT=yes
GATEWAY=192.168.34.2
DNS1=114.114.114.114

    修改B主机桥接模式IP地址配置文件

[root@centos7network-scripts]#cat ifcfg-ens37
DEVICE=ens37
BOOTPROTO=none
IPADDR=172.16.0.7
PREFIX=24
ONBOOT=yes
DNS1=114.114.114.114

(3)在C主机修改IP地址

[root@centos777network-scripts]#cat ifcfg-ens37
DEVICE=ens37
BOOTPROTO=dhcp
IPADDR=172.16.0.17
PREFIX=24
GATEWAY=172.16.0.7
ONBOOT=yes

 (4)在B主机修改路由规则,将A主机和C主机跨网段ping通

[root@centos7~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@centos7~]#sysctl -p  使配置文件生效
net.ipv4.ip_forward = 1

 技术图片

 (5)在B主机设置(防火墙)设置FORWARD请求与响应防火墙策略,实现A主机ping通C主机策略

[root@centos7~]#iptables -A FORWARD -j REJECT  在B主机(防火墙)设置一个FORWARD拒绝策略
[root@centos7~]#iptales -vnL --line-numbers
[root@centos7~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 85 packets, 6520 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 63 packets, 5876 bytes)
num   pkts bytes target     prot opt in     out     source               destination 
[root@centos7~]#iptables -I FORWARD 1 -s 192.168.37.6 -p icmp --icmp-type 8 -j ACCEPT  设置A主机请求允许的策略
[root@centos7~]#iptables -I FORWARD 1 -d 192.168.37.6 -p icmp --icmp-type 0 -j ACCEPT  设置A主机响应允许的策略

(6)也可以删除内网的响应允许IP,添加一个state模块,进行状态跟踪,ping通出去,回来就成为老的状态,也可以成功,此方法也可以

[root@centos7~]#iptables -D FORWARD 2
[root@centos7~]#iptables -I FORWARD 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@centos7~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 49 packets, 3608 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        5   420 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
2        3   252 ACCEPT     icmp --  *      *       192.168.37.6         0.0.0.0/0            icmptype 8
3        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

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

实现内网访问外网httpd服务

(1)在C主机安装httpd服务 

[root@centos777~]#yum install httpd
[root@centos777~]#systemctl start  httpd
[root@centos777~]#echo internet server > /var/www/html/index.html

(2)在B主机设置防火墙策略,允许内网访问外网的httpd服务,但外网不能访问内网的服务

[root@centos7~]#iptables -I FORWARD 2 -s 192.168.37.0/24 -p tcp --dport 80  -j ACCEPT

(3)此时在A主机就可以访问C主机(外网)httpd服务

[root@centos7network-scripts]#curl 172.16.0.17
internet server

(4)C主机也可以对外网的httpd进行加密httpd服务

[root@centos777~]#yum install mod_ssl  -y
[root@centos777~]#systemctl restart httpd

(5)在B主机设置一个加密443和httpd端口80的防火墙规则

[root@centos7~]#iptables -I FORWARD 2 -s 192.168.37.0/24 -p tcp -m multiport --dport 80,443  -j ACCEPT

(6)此时在A主机就可以进行加密访问外网httpd服务

[root@centos7network-scripts]#curl -k https://172.16.0.17   加上-k不需要进行证书检测
internet server

(7)也可以在B主机实现外网访问内网的httpd服务

[root@centos7~]#iptables -I FORWARD 2 -d 192.168.37.6 -p tcp -m multiport --dport 80,443  -j ACCEPT
[root@centos7~]#iptables -vnL
Chain INPUT (policy ACCEPT 20 packets, 1528 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   34  4644 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.37.6         multiport dports 80,443
    4   240 ACCEPT     tcp  --  *      *       192.168.37.0/24      0.0.0.0/0            multiport dports 80,443
    4   336 ACCEPT     icmp --  *      *       192.168.37.6         0.0.0.0/0            icmptype 8
   84  4889 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

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

(8)在C主机访问A主机的HTTPD服务

[root@centos777~]#curl 192.168.37.6
lan server

链管理:

-N:new, 自定义一条新的规则链
-X:delete,删除自定义的空的规则链
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
ACCEPT:接受
DROP:丢弃
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除

实战演示:创建自定义链,进行模块化(实现内网访问内网)

(1)以上实验的基础上,将B主机创建一个新链,方便管理模块化

[root@centos7~]#iptables -N TOINTERNET  创建一个新模块链
[root@centos7~]#iptables -A TOINTERNET -s 192.168.37.0/24 -p tcp -m multiport --dports 80,443,22 -j ACCEPT  将内网访问外网的规则添加到新链上
[root@centos7~]#iptables -A TOINTERNET -s 192.168.37.0/24 -p icmp --icmp-type 8  -j ACCEPT
[root@centos7~]#iptables -I FORWARD 2 -j TOINTERNET  将新自定义的链加入到FORWARD链中

(2)此时就可以从内网访问外网,创建的自定义链规则,方便管理,条理清晰

[root@centos7html]#curl -k https://172.16.0.17
internet server
[root@centos7html]#curl 172.16.0.17
internet server
[root@centos7html]#ssh 172.16.0.17
The authenticity of host ‘172.16.0.17 (172.16.0.17)‘ can‘t be established.
ECDSA key fingerprint is SHA256:nl4GdONb/BsSo/TpR+UHsM/gFo4+tLpD40NhCklkf7M.
ECDSA key fingerprint is MD5:55:a8:61:99:c3:52:fd:25:80:95:21:88:2b:98:1b:87.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘172.16.0.17‘ (ECDSA) to the list of known hosts.
Last login: Fri Dec  6 12:15:40 2019 from lpj-pc
[root@centos777~]#

(3)删除自定义链

[root@centos7~]#iptables -vnL
Chain INPUT (policy ACCEPT 77 packets, 5948 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  143 24925 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    3   180 TOINTERNET  all  --  *      *       0.0.0.0/0            0.0.0.0/0              删除第二条链表
  316 19254 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

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

Chain TOINTERNET (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    3   180 ACCEPT     tcp  --  *      *       192.168.37.0/24      0.0.0.0/0            multiport dports 80,443,22
    0     0 ACCEPT     icmp --  *      *       192.168.37.0/24      0.0.0.0/0            icmptype 8
[root@centos7~]#iptables -D FORWARD 2   删除第二条新建的链表
[root@centos7~]#iptables -F TOINTERNET  先清空链表内容
[root@centos7~]#iptables -X TOINTERNET  删除空链表

NAT

NAT概念

NAT(Network Address Translation)是一种地址转换技术,可以将IPv4报文头中的地址转换为另一个地址。通常情况下,利用NAT技术将IPv4报文头中的私网地址转换为公网地址,可以实现位于私网的多个用户使用少量的公网地址同时访问Internet。因此,NAT技术常用来解决随着Internet规模的日益扩大而带来的IPv4公网地址短缺的问题。

NAT原理

NAT的基本工作原理是,当私有网主机和公共网主机通信的IP包经过NAT网关时,将IP包中的源IP或目的IP在私有IP和NAT的公共IP之间进行转换。

如下图所示,NAT网关有2个网络端口,其中公共网络端口的IP地址是统一分配的公共 IP,为202.20.65.5;私有网络端口的IP地址是保留地址为192.168.1.1。私有网中的主机192.168.1.2向公共网中的主机202.20.65.4发送了1个IP包(Dst=202.20.65.4,Src=192.168.1.2)。

技术图片

当IP包经过NAT网关时,NAT Gateway会将IP包的源IP转换为NAT Gateway的公共IP并转发到公共网,此时IP包(Dst=202.20.65.4,Src=202.20.65.5)中已经不含任何私有网IP的信息。由于IP包的源IP已经被转换成NAT Gateway的公共IP,Web Server发出的响应IP包(Dst= 202.20.65.5,Src=202.20.65.4)将被发送到NAT Gateway。

这时,NAT Gateway会将IP包的目的IP转换成私有网中主机的IP,然后将IP包(Des=192.168.1.2,Src=202.20.65.4)转发到私有网。对于通信双方而言,这种地址的转换过程是完全透明的。转换示意图如下。

技术图片

 如果内网主机发出的请求包未经过NAT,那么当Web Server收到请求包,回复的响应包中的目的地址就是私有网络IP地址,在Internet上无法正确送达,导致连接失败。

NAT: network address translation

PREROUTING,INPUT,OUTPUT,POSTROUTING
请求报文:修改源/目标IP,由定义如何修改
响应报文:修改源/目标IP,根据跟踪机制自动实现

SNAT:source NAT POSTROUTING, INPUT

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

DNAT:destination NAT PREROUTING , OUTPUT

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

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

注意:局域网内的IP地址要规范,尽量配置公有地址,如果不配置规范地址,和访问的外网地址一致时,就会冲突,无法连接到外网。 

nat表的target:

SNAT:固定IP
--to-source [ipaddr[-ipaddr]][:port[-port]]
--random

MASQUERADE:动态IP,如拨号网络

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

实战演练:SNAT 

 A主机:192.168.37.6(NAT模式,作为内网)

B主机:192.168.37.7,172.16.0.7(NAT和桥接模式,作为防火墙)

C主机:172.16.0.17 (桥接模式,作为外网)

(1)在C主机将网关删掉,暂时不配置172.16.0.7网关,此时A主机去访问C主机,无法返回信息,就无法上网

[root@centos777network-scripts]#cat ifcfg-ens37
DEVICE=ens37
BOOTPROTO=dhcp
PREFIX=24
IPADDR=172.16.0.17
ONBOOT=yes
DNS1=114.114.114.114

(2)在B主机进行设置SNAT防火墙策略。

[root@centos7network-scripts]#iptables -t nat -A POSTROUTING -s 192.168.37.0/24 -j SNAT --to-source 172.16.0.7   将192.168.37.0出去的IP网段都替换成172.16.0.7的源地址
[root@centos7network-scripts]#iptables -vnL -t nat
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         
    0     0 SNAT       all  --  *      *       192.168.37.0/24      0.0.0.0/0            to:172.16.0.7

(3)此时在A主机就可以访问C主机

[root@centos7~]#ping 172.16.0.17
PING 172.16.0.17 (172.16.0.17) 56(84) bytes of data.
64 bytes from 172.16.0.17: icmp_seq=1 ttl=63 time=2.23 ms
64 bytes from 172.16.0.17: icmp_seq=2 ttl=63 time=0.688 ms
64 bytes from 172.16.0.17: icmp_seq=3 ttl=63 time=0.919 ms

(4)此时在C主机查看,以为是172.16.0.7地址在访问,实则是内网的192.168.37.7在连接

[root@centos777~]#tcpdump -i ens37 -nn host 172.16.0.7
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens37, link-type EN10MB (Ethernet), capture size 262144 bytes
17:17:17.505943 IP 172.16.0.7 > 172.16.0.17: ICMP echo request, id 12095, seq 13, length 64
17:17:17.506055 IP 172.16.0.17 > 172.16.0.7: ICMP echo reply, id 12095, seq 13, length 64
17:17:18.502328 IP 172.16.0.7 > 172.16.0.17: ICMP echo request, id 12095, seq 14, length 64
17:17:18.502438 IP 172.16.0.17 > 172.16.0.7: ICMP echo reply, id 12095, seq 14, length 64
17:17:19.519997 IP 172.16.0.7 > 172.16.0.17: ICMP echo request, id 12095, seq 15, length 64

 MASQUERADE:动态IP,如拨号网络,也可以实现替换源地址功能

  直接在B主机重新设置一个防火墙策略,就可以在A主机访问C主机

[root@centos7network-scripts]#iptables -F -t nat
[root@centos7network-scripts]#iptables -t nat -A POSTROUTING -s 192.168.37.0/24 -j MASQUERADE

DNAT

--to-destination [ipaddr[-ipaddr]][:port[-port]]
?iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]

实战演练:公网地址访问内网地址

(1)在B主机设置防火墙策略,将外网的IP地址映射为企业内网的IP地址及端口(即目标地址和80端口映射成192.168.37.6IP地址和8080端口)

[root@centos7network-scripts]#iptables -t nat -A PREROUTING -d 172.16.0.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.37.6:8080(端口号也可以默认为80端口)

(2)修改A主机的httpd端口,并重启httpd服务

[root@centos7~]#vim /etc/httpd/conf/httpd.conf
Listen 8080
[root@centos7~]#systemctl restart httpd

(3)C主机进行访问A主机

[root@centos777~]#curl 172.16.0.7
lan server

(4)在A主机查看log日志,此时由于改的是目标地址,未改本地源地址(172.16.0.17),因此日志中查看到的就是外网地址访问信息

技术图片

端口重定向(转发)

REDIRECT:
NAT表

可用于:PREROUTING OUTPUT 自定义链
通过改变目标IP和端口,将接受的包转发至不同端口
--to-ports port[-port]

实战演练:将企业服务器端口转发

(1)在A主机设置防火墙策略,将本地目标IP地址映射为8080端口,即将80端口转发为8080端口

[root@centos7~]#iptables -t nat -A  PREROUTING -d 192.168.37.6 -p tcp --dport 80 -j REDIRECT  --to-ports 8080

(2)在B主机将目标IP地址、端口映射为192.168.37.6和80端口

[root@centos7network-scripts]#iptables -t nat -A PREROUTING -d 172.16.0.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.37.6:80

(3)最后C主机还是可以访问A主机的httpd服务,虽然访问的是映射的172.16.0.7的IP地址,实则访问的是内网地址

[root@centos777~]#curl 172.16.0.7
lan server

(4)此时A主机监控的httpd服务端口号就是本机将80端口转发成的8080端口

技术图片

 

 

 

 

 

  

 

 

 

  

 

 

 

 

 

  

 

  

 

 

 

以上是关于iptables网络防火墙和SNAT原理实战的主要内容,如果未能解决你的问题,请参考以下文章

iptables中实现内外网相互访问 SNAT与DNAT的原理与应用

iptables实现网络防火墙功能,SNAT以及DNAT功能

网络SNAT与DNAT防火墙之iptables

iptables实现网络防火墙——SNAT与DNAT

firewall之iptables ,SNAT,DNAT

Linux防火墙iptables之SNAT与DNAT