
网络 SNAT与DNAT
NAT简介
网络地址转换NAT(Network Address Translation)是将IP数据报文中的IP地址转换为另一个IP地址的过程。
随着internet的发展和网络应用的增多,IPV4地址枯竭已成为制约网络发展的瓶颈。尽管IPV6可以从根本上解决IPv4地址空间不足的问题,但目前众多网络设备和网络应用大多数是基于IPv4的,因此在IPv6广泛应用之前,一些过滤技术(如CIDR、私网地址等)的使用是解决这个问题最主要的技术手段。NAT主要用于实现内部网络(简称内网,使用私有的网络地址)访问外部网络(简称外网,使用公有IP地址)的功能。当内网的主机要访问外网时,通过NAT技术可以将其私网地址转换为公网地址,可以实现多个私网用户共用一个公网地址来访问外部网络。
优点 | 缺点 |
---|---|
节省IP地址空间 | 增加转发延迟 |
解决IP地址重叠问题 | 丧失端到端的寻址能力 |
增加网络连入internet的弹性 | 某些应用不支持NAT |
网络变更的时候减少IP重编址带来的麻烦 | 需要一定的内存空间支持动态存储NAT表项 |
对外隐藏内部地址,增加网络安全性 | 需要耗费一定NAT资源进行操作,需耗费一定内存资源进行存储NAT表项 |
静态NAT(SNAT)
Static NAT,静态NAT,用于将内部本地地址(私有IP)与内部全局地址(公有IP)进行一对一的映射。缺点是需要每一个内部IP地址需独占一个宝贵的公网地址。即,如果某个合法IP地址已经被NAT静态的IP地址转换定义,即使该地址当前没有被使用,也不能被用作其他的地址转换。而且这种方式是静态手工创建的NAT映射,可扩展性不高。
这种方法主要用在内网中存在需要对公网提供服务的服务器场景,类似的场景有Web服务器、邮件服务器、FTP服务器等。
Static NAT支持IP对IP的映射,以及端口对端口的映射。
我们可以看到在私网访问外网时,仅仅是对发送端的IP进行了修改,那MAC有没有修改呢?这里我们保留一个疑问,在接下来我们将通过ENSP来进行实践。
通过ENSP模拟IP对IP
我们需要实践的如下图所示:
PC1的IP是192.168.0.2/24
,AR1上的网关为192.168.0.1/24
。
Server1的IP为2.2.2.1/24
,AR1上的网关为2.2.2.2/24
下面是相关配置图。
我们知道SNAT是需要一对一的映射IP,所以我们只需要在PC1发往Server1数据包在AR1中的192.168.0.2
设置为2.2.2.3/24
之后再进行转发就可以进行与Server的通信了。命令如下:
system-view
# 查看当前AR1配置
dis current-configuration
# 重命名为Router
sysname Router
# 为0/0/0接口添加网关
interface GigabitEthernet0/0/0
ip address 192.168.0.1 255.255.255.0
# 为0/0/1接口添加网关
interface GigabitEthernet0/0/1
ip address 2.2.2.2 255.255.255.0
# 将PC1的IP映射为2.2.2.3
nat static global 2.2.2.3 inside 192.168.0.2 netmask 255.255.255.255
# 设置所有到该路由的流量下一站为2.2.2.1
ip route-static 0.0.0.0 0.0.0.0 2.2.2.1
运行测试。
ping 2.2.2.1
接下来我们分析GE0/0/1的包,发现它是从2.2.2.3
发过来的。
GE0/0/0不用说了把是从192.168.0.2
发到路由来的。
我们发现发送端的IP与MAC都变了,但MAC是哪个接口的MAC呢?
我们通过dis arp
查看IP所对应的MAC,发现MAC是2.2.2.2
的。
然后我们添加一个PC2,由于没有配置SNAT,没有对应的IP映射,所以导致私网无法请求服务器端,我们可以看到后面的抓0/0/1接口的包也是没有想关请求的。
SNAT Easy IP
Easy IP 特别适合小型局域网访问Internet的情况。这里的小型局域网主要指中小型网吧、小型办公室等环境,一般据有以下特点:内部主机较少、出接口通过拨号方式获得临时公网IP地址以供内部主机访问Internet。对于这种情况,可以使用Easy IP 方式使局域网用户都可以通过这个IP地址接入Internet。
对于只申请到少量IP地址甚至只有一个合法IP地址却经常有很多用户要求同时上网的情况,这种转换方式非常有用。这种地址转换方式真正意义上缓解了IPv4地址紧缺的问题。在各种网络中被广泛使用。
Linux下实现SNAT
我们知道内部地址要访问公网上的服务时,内部地址会主动发起连接,将内部地址转换成公有ip。网关这个地址转换称为 SNAT。但在Linux下我们应该如何模拟呢?我们可以通过下面的拓扑图进行实践。
# 添加br0
ip netns add ns1
ip l a br0 type bridge
ip l s br0 up
# 配置br0和veth0
ip l a veth0 type veth peer name br-veth0
ip l s veth0 netns ns1
ip l s br-veth0 master br0
ip l s br-veth0 up
# 配置ns1中的接口
ip netns exec ns1 ip a a 10.1.1.2/24 dev veth0
ip netns exec ns1 ip l s veth0 up
ip a a 10.1.1.1/24 dev br0
ip l s br0 up
ip netns exec ns1 ifconfig lo up
# 添加路由
ip netns exec ns1 route add -net 0.0.0.0 gw 10.1.1.1
# 修改内核转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 添加SNAT规则
# 假设让iptables防火墙承担NAT服务器功能。此时,如果希望内网10.1.1.0/24出去的数据包其源IP地址都转换外网接口的公网,则需要执行以下iptables命令。
iptables -t nat -A POSTROUTING -s 10.1.1.0/24 ! -o br0 -j MASQUERADE
# 测试运行
ip netns exec ns1 ping 114.114.114.114
DNAT
简单来说:从外到内的访问。
当内部需要对外提供服务时,外部发起主动连接,路由器或着防火墙的网关接收到这个连接,然后把连接转换到内部,此过程是由带公有ip的网关代替内部服务来接收外部的连接,然后在内部做地址转换,此转换称为 DNAT
docker run --name dnat -p 2022:22 --privileged=true -td centos:7 /sbin/init
docker exec -it dnat bash
yum -y install net-tools
# 安装ssh访问服务
yum -y install openssh-server
# 修改密码
passwd root
# 启动ssh与查看状态
systemctl restart sshd
netstat -an | grep 22
在主机上查看iptables的记录。
大致意思如下:当收到不是docker0网桥过来的包,放问2022端口的时候,将进行DNAT到我们刚刚创建的容器IP172.18.0.2:22
中。
iptables-save | grep 2022
接着我们通过刚刚的NS1进行测试是否可以进行连接。
ip netns exec ns1 ssh 10.1.1.1 -p 2022
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

