使用iptables实现NAT

一、网络拓扑图

这里有一个图片
ubuntu版本为20.04
kali版本为2023.4

二、预配置

1.在mercury上stop并disable ufw服务

1
2
sudo systemctl stop ufw
sudo systemctl disable ufw

2.在mercury上安装软件包iptables-persistent,启动netfilter-persistent服务,这样就可以使用命令iptables了

1
2
sudo apt install iptables-persistent
sudo systemctl start iptables

三、仅开启linux内核的IP转发功能,不使用iptables进行NAT

1.在mercury上开启IP转发
(1)编辑文件/etc/sysctl.conf

1
sudo vim /etc/sysctl.conf

/etc/sysctl.conf 是一个配置文件,用于定义linux系统内核的各种参数。它允许你在系统启动时配置和调整内核参数,这些参数控制系统的行为,包括网络设置、内存管理、进程调度等

(2)取消注释或者在文件末尾添加如下行

1
net.ipv4.ip_forward = 1

这里有一个图片

(3)使配置生效

1
sudo sysctl -p

2.在venus上PING kali1(192.168.163.138)

1
ping 192.168.163.138

这里有一个图片
可以看到是PING不通的

3.在kali1上开启WireShark进行抓包并分析
(1)由下图可以看到,ICMP的request包的源IP为mercury而并非venus的IP,说明只进行了IP转发没有进行NAT
这里有一个图片

(2)而且由上图,kali1回复了ICMP的reply包,那为啥merury PING不通呢?
这是因为kali1上没有关于192.168.12.21的路由项,于是会将IP包发给默认网关192.168.163.2,所以mercury收不到ICMP reply包,也就是PING不通了

这里有一个图片

四、使用iptables实现NAT

1.在mercury上给iptables的nat表POSTROUTING链上增加一条规则

1
sudo iptables --table nat --append POSTROUTING --out-interface ens34 --jump MASQUERADE

这样,从内网要到外网的包的源IP地址就会被转换为venus的外网的接口ens34对应的IP 192.168.163.54

查看下nat表,看是否成功添加规则

1
sudo iptables --table nat --list

这里有一个图片

2.此时我们再PING下kali1

1
ping 192.168.163.138

由下图可以看到,此时能够PING通kali1
这里有一个图片

3.再次在kali1上用WireShark进行抓包
可以看到,ICMP request包的源IP已经变成了192.168.163.54,说明成功实现了NAT
这里有一个图片

4.那为什么kali1回复的ICMP reply包到达了venus后,能顺利返回mercury呢?
这里应该是跟iptables是有状态防火墙、NAT映射表、conntrack相关,但具体原因因为个人水平太低还无法阐述


使用iptables实现NAT
https://www.pasiphae.top/2022/07/12/使用iptables实现NAT/
作者
pasiphae
发布于
2022年7月12日
许可协议