什么是SNAT?
SNAT用于局域网访问互联网,局域网的主机A想访问互联网上的主机C,首先要将数据包发送到防火墙所在的主机B,B收到后修改数据包的源地址为B机的公网IP,然后再发送到互联网。
C机收到后将回应包经互联网发送给B,B收到回应包之后修改回应包的目的地址为A,然后将数据包转发给A。
至此就是SNAT的完整过程,在这个过程中,修改了请求报文的源地址,叫做SNAT(source NAT POSTROUTING),用于局域网访问互联网。
而DNAT(destination NAT POSTROUTING),修改了请求报文的目标地址,用于互联网访问局域网。

什么是DNAT?
Destination Network Address Translation
应用场景:在Internet中发布位于企业局域网内的服务器
原理
目的地址转换
修改数据包的目标IP地址
基于iptables的SNAT+DNAT+docker服务器集群搭建介绍
项目名称:基于iptables的SNAT+DNAT+docker服务器集群搭建
项目环境:CentOS 8.3,docker 20.10.8,Mysql 8.0
项目描述:模拟企业环境,构建并发布内网服务器,并让内网服务器可以上网,使用docker快速部署并搭建自己的web和MySQL应用
项目步骤:
- 规划整个项目的拓扑网络结构和IP地址
- 初始化3台服务器的系统,并根据拓扑图的规划配置ip地址,并初始化docker软件
- 实现SNAT方法让内网的服务器可以安全上网
- 在网关服务器上基于DNAT策略修改并更新IP配置文件,同时开启路由功能
- 在内网服务器上使用docker快速启动Nginx和MySQL容器
- 测试整个发布的效果
项目心得:
对SNAT和DNAT的认识更加深刻
对docker容器的概念与应用有了更深的理解,能够很好地使用docker进行应用的快速部署
对集群的概念有了更深的认识,认识到集群的优势就是能够更加合理地分配资源
一、机器配置
如下图做机器配置:
其中Web-server,Mysql-server和Linux网关服务器分别为三台系统为CentOS的虚拟机
具体修改IP地址,添加网卡的操作可以参考笔者之前的博文:
注意,初始配置完成之后集群的状态应当是:
Web-server、Mysql-server不能联网,也就是ping不通www.baidu.com的状态
而Linux网关服务器可以联网
二、SNAT实现
各机器全部配置好之后,在网关服务器上运行snat.sh脚本如下:
#!/bin/bash
#临时开启路由功能
echo 1 >/proc/sys/net/ipv4/ip_forward
#临时关闭selinux
setenforce 0
#临时关闭firewalld
service firewalld stop
#清除filter表和nat表里的防火墙规则
iptables -F
iptables -t nat -F
iptables -P INPUT ACCEPT
#snat策略,将进入的LAN口网段(192.168.170.0)包装成出去的WAN口网段(192.168.2.15)
iptables -t nat -A POSTROUTING -s 192.168.170.0/24 -o ens33 -j SNAT --to-source 192.168.2.15
运行之后web和mysql-server即可ping通,能够联网
再查看一下策略
iptables -t nat -L -n
三、启动容器
3.1 在web-server上启动docker的nginx容器
docker run -d --name sc-nginx-2 -p 80:80 nginx
测试
[root@web ~]# netstat -anplut|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3411/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 3415/docker-proxy
成功
3.2 在mysql-server上启动docker的mysql容器
docker run -d --name mysql1 -e MYSQL_ROOT_PASSWORD='123456' -p 3306:3306 mysql
测试
[root@web ~]# mysql -uroot -p123456 -h 192.168.170.2
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.26 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
成功
四、DNAT实现
然后在主机上运行dnat.sh脚本如下:
#!/bin/bash
#临时开启路由功能
echo 1 >/proc/sys/net/ipv4/ip_forward
#临时关闭selinux
setenforce 0
#临时关闭firewalld
service firewalld stop
#dnat to web
iptables -t nat -A PREROUTING -d 192.168.2.15 -p tcp --dport 80 -j DNAT --to-destination 192.168.170.1:80
#dnat to mysql
iptables -t nat -A PREROUTING -d 192.168.2.15 -p tcp --dport 3306 -j DNAT --to-destination 192.168.170.2:3306
查看一下策略
iptables -t nat -L -n
最终nat表如下:
[root@server ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 192.168.2.15 tcp dpt:80 to:192.168.170.1:80
DNAT tcp -- 0.0.0.0/0 192.168.2.15 tcp dpt:3306 to:192.168.170.2:3306
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 192.168.170.0/24 0.0.0.0/0 to:192.168.2.15
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
最后的验证
五、验证web-server
在web-server中进入nginx容器做如下修改(不修改也可以,但是只能看到nginx默认页面)
[root@web ~]# docker exec -it web1 /bin/bash
root@4240c605729f:/# cd /usr/share/nginx/html/
root@4240c605729f:/usr/share/nginx/html# ls
50x.html index.html
root@4240c605729f:/usr/share/nginx/html# echo "welcome to liwenbin's home!" >index.html
在win10浏览器地址栏中输入192.168.2.15,得到效果图如下:
六、验证mysql-server
另开一台虚拟机,使用之前验证mysql-server容器是否启动的命令测试即可