zl程序教程

您现在的位置是:首页 >  其他

当前栏目

LInux iptables实现NAT原理

2023-02-18 16:34:36 时间
NAT: network address translation,网络地址转换。

NAT的类型:

  • SNAT:Source Network Address Translation,请求报文替换了源地址

  • DNAT:Destinationnetwork address translation,外网用户访问局域网内的站点时,网关收到请求报文并将请求报文内的目标地址和端口更换为局域网内的地址和端口

  • PNAT(PNAT):Network Address Port Translation,端口重定向,

SNAT:
实现用一个公网ip能让一个局域网里面的设备都能通过这个公网ip访问到互联网。

特点:
网络内部的主机可以借助SNAT隐藏自己的IP地址,同时还能够共享合法的公网IP,让局域网内的多台主机共享公网IP访问互联网。

实现:
私网主机访问公网服务时,报文经过路由器,路由器将报文中的私网IP与端口号进行修改和映射,将其映射为公网IP与端口号

iptables实现命令格式:
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP

#MASQUERADE:基于nat表的target,适用于动态的公网IP,如:拨号网络
DNAT:
实现互联网访问到局域网里面的指定主机或者服务。外网设备访问的时候是访问对应的公网ip,公网ip通过DNAT技术,将公网的端口映射到指定内网主机的对应服务上面。

原理:
报文中的目标IP为公网IP,当路由器收到报文后,将报文的目标地址改为对应的私网地址

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

#destination不写端口默认保持一样
PNAT:
REDIRECT 转发:用户访问本机的某个端口时,转发到另外一个端口

例如:
外网用户要访问内网的http服务请求的端口是80,而内网的httpd服务工作在非标准的端口8080上,
此时内网的http服务器就需要将发送给本机80端口的数据报文重新重定向至本机的8080端口,这就叫做PNAT 也叫端口重定向

格式:
iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080

#访问172.16.100.10的80端口的时候,在172.16.100.10这台设备上,通过iptables将端口重定向到8080

#因为防火墙工作在内核空间,所以没有端口监听这个说法,端口监听是应用层程序干的事。

image
环境配置:

#10.0.0.7
[root@Client ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens160 
TYPE=Ethernet
BOOTPROTO=none
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.7
PREFIX=24
GATEWAY=10.0.0.8
#10.0.0.17
[root@CentOS8 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens160 
TYPE=Ethernet
BOOTPROTO=none
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.17
PREFIX=24
GATEWAY=10.0.0.8

#防火墙
[root@CentOS8 ~]# cd /etc/sysconfig/network-scripts/
[root@CentOS8 network-scripts]# ls
ifcfg-eth0  ifcfg-eth1
[root@CentOS8 network-scripts]# cat ifcfg-eth0 
TYPE=Ethernet
BOOTPROTO=none
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.8
PREFIX=24


[root@CentOS8 network-scripts]# cat ifcfg-eth1
TYPE=Ethernet
DEVICE=eth1
NAME=eth1
ONBOOT=yes
BOOTPROTO=none
IPADDR=192.168.10.8
NETMASK=255.255.255.0
#192.168.10.6
[root@CentOS8 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 
TYPE=Ethernet
BOOTPROTO=none
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.10.6
PREFIX=24

SNAT的实现:内网能访问外网,外网进不去内网

测试:没配置SNAT之前,内网能发送数据到外网,但是万网不能回复内网主机数据,因为没有路由

#SNAT实现:
[root@CentOS8 ~]# iptables -t nat  -A POSTROUTING -s 10.0.0.0/24  ! -d 10.0.0.0/24 -j MASQUERADE
“-t nat”表示操作nat表,不同的表有不同的功能,filter表的功能是过滤,nat表的功能就是地址转换

“-A POSTROUTING”表示将SNAT规则添加到POSTROUTING链的末尾,

#POSTROUTING链是iptables中报文发出的最后一个”关卡”,我们应该在报文马上发出之前,修改报文的源地址,否则就再也没有机会修改报文的源地址了

-s 10.0.0.0/24:标识报文来自于这个网段

-d:标识报文去往这个网段

“-j SNAT”表示使用SNAT动作,对匹配到的报文进行处理

#MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址

#拨号网上时,每次分配的IP地址往往不同,不会长期分给我们一个固定的IP地址


#通过在192.168.10.6抓包可以看到数据包是从192.168.10.8出来的
[root@CentOS8 ~]# tcpdump  -i eth0 -nn icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
03:09:14.622787 IP 192.168.10.8 > 192.168.10.6: ICMP echo request, id 2040, seq 1, length 64
03:09:14.622825 IP 192.168.10.6 > 192.168.10.8: ICMP echo reply, id 2040, seq 1, length 64
03:09:15.625139 IP 192.168.10.8 > 192.168.10.6: ICMP echo request, id 2040, seq 2, length 64
03:09:15.625168 IP 192.168.10.6 > 192.168.10.8: ICMP echo reply, id 2040, seq 2, length 64
03:09:16.626645 IP 192.168.10.8 > 192.168.10.6: ICMP echo request, id 2040, seq 3, length 64

DNAT的实现:外网能访问到内往

iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --todestination InterSeverIP[:PORT] #端口不写默认一样的

ExtIP:访问的公网地址,必须为一个具体的地址

DNAT:转发给内网的某个地址

[root@CentOS8 ~]# iptables -t nat -A PREROUTING -d 192.168.10.8 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.7

#外网能访问到10.0.0.7的80端口对应的应用程序。

[root@CentOS8 ~]# curl 192.168.10.8
this is LAN1


[root@Client ~]# tail -f  /var/log/httpd/access_log
192.168.10.6 - - [30/Aug/2022:06:22:40 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"

#DNAT是能看到客户端的真是地址的。

PNAT的实现

访问本机80端口的时候,转发到本机的8080这个端口 
[root@Client conf]# iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 80 -j REDIRECT --to-ports 8080

测试:
[root@CentOS8 ~]# curl 192.168.10.8
this is LAN1