iptables网络防火墙、SNAT、DNAT原理及端口重定向实战

网络防火墙

iptables/netfilter网络防火墙:

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

注意的问题:

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

实现内网ping通外网,外网无法ping通内网

第一种实现方法:

环境准备:

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 #指定防火墙左侧的IP地址
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=16
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=16
GATEWAY=172.16.0.7  # 指定防火墙右侧的IP地址
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主机策略,但是C主机无法ping通A主机

[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.0/24 -p icmp --icmp-type 8 -j ACCEPT    # 设置A主机请求允许的策略
[root@centos7 ~]# iptables -I FORWARD 1 -d 192.168.37.0/24 -p icmp --icmp-type 0 -j ACCEPT # 设置A主机响应允许的策略

第二种实现方法:

也可以删除内网的响应允许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

实现外网访问内网HTTP服务

也可以在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链中


[root@centos7 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 14 packets, 960 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         
    0     0 TOINTERNET  all  --  *      *       0.0.0.0/0            0.0.0.0/0    # 将链名加入到规则中        
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

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

Chain TOINTERNET (1 references)  # 自定义的链
 pkts bytes target     prot opt in     out     source               destination         
    0     0 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

(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地址要规范,尽量配置公有地址,如果不配置规范地址,和访问的外网地址一致时,就会冲突,无法连接到外网;

SNAT:请求报文替换源地址。

DNAT:请求报文替换目标地址。

nat表的target:

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

MASQUERADE:动态IP,如拨号网络

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

实战演练:SNAT

实现原理:在防火墙上设置SNAT表和POSTROUTING链上,将源地址(也就是内网的IP地址)替换为防火墙访问的公网地址,此方法设置的是固定的IP地址,最终通过内网的IP地址访问外网的地址。

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主机,无法返回信息,就无法上网,其他配置与前面的IP地址配置不变。

[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防火墙策略,因为我们可能是本机的地址出去到公网或者是本地局域网的地址出去到公网,我们都可以在POSTROUTING链上将所有的IP地址汇总转发到公网上。

[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.6在访问C主机信息。

[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主机外网重新设置一个防火墙策略,设置不固定的IP地址,就可以在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]

实战演练:外部用户访问防火墙公网地址转发到内网地址

实现原理:使用DNAT表,以及PREROUTING链,当外部用户访问防火墙公网的IP地址,防火墙的公网IP地址转发到后端内网的IP地址和端口上,表面上用户访问的是防火墙的公网IP地址和端口,实际访问的是后端内网的IP地址和端口。

如果用户访问内网的http服务,经过postrouting,此时已经经过了input output,以及postrouting三个链,在经过input链时,就会访问防火墙的http服务,此时防火墙内部无http服务,就无法再继续往下传递到下一个链,此postrouting无法实现IP地址转发,因此只能在prerouting链进行转发IP地址。

(1)在B主机设置防火墙策略,将防火墙外网的IP地址映射为企业内网的IP地址及端口即目标地址和80端口映射成企业内部的(192.168.37.6)IP地址和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]

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

实现原理:将公司内网的端口重定向到指定的端口,比如8080端口,重定向到80端口,然后在防火墙上定义转发规则,将防火墙公网的IP地址和端口映射到内网的IP地址和重定向的端口号80。

(1)在A主机设置防火墙策略,将本地目标的80端口映射为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(172.16.0.7)地址和端口(80),映射为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服务端口号就是本机的8080端口,用户访问的80端口全部转发至8080端口上。

 

 

 

 

 

  

 

 

 

  

 

 

 

 

 

  

 

  

 

 

 

posted @ 2019-12-06 20:45  一叶知秋~~  阅读(4704)  评论(0编辑  收藏  举报