项目实战1——基于iptables的SNAT+DNAT与Docker容器发布的项目

Posted REPCHAOCHAO

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目实战1——基于iptables的SNAT+DNAT与Docker容器发布的项目相关的知识,希望对你有一定的参考价值。

目录

项目简介 

项目详细代码如下 

一、拓扑结构图如下

二、实现SNAT并配置好服务器的IP

三、配置好客户机内网的IP

四、安装好Docker,并启动nginx和MySQL的Docker容器

五、配置DNAT策略

六、测试DNAT是否实现成功



项目简介 

  • 项目名称:基于iptables的SNAT+DNAT与Docker容器发布的项目
  • 项目环境:CentOS8,Docker,mysql(5.7.35),nginx,iptables等
  • 项目描述:通过模拟企业的环境,发布内网服务器,让内网服务器实现网络链接;同时采取Docker容器构建自己的web和MySQL应用
  • 项目步骤
    1. 规划整个项目的拓扑结构和IP地址
    2. 安装好3台服务器系统,根据拓扑图的规划配置IP地址,并安装好Docker软件
    3. 在网关服务器上实现SNAT让内网的服务器实现上网功能,同时配置内网服务器的ip、网关和dns
    4. 在内网服务器上启动nginx和MySQL的Docker容器,测试容器是否能正常访问
    5. 在网关服务器上完成配置DNAT策略,并开启路由功能
    6. 进行测试,检验项目效果。使用curl或chrome测试web服务是否成功,使用SQLyog的测试MySQL容器是否成功。
  • 项目心得
    1. 明白了项目拓扑图的重要性,依次才能完成好各项步骤
    2. 进一步加强了对iptables和Docker容器的理解与掌握
    3. 对于多台服务器的功能实现有了一定的经验
    4. 增强了自身的网络troubleshooting能力
    5. 提升了自己shell编程能力,更懂得了shell编程时严谨的重要性
  • 遇到的问题
    1. 网关服务器外的两台客户机连不上XSHELL同时不能ping通外网地址,是由于网关服务器的防火墙功能未关闭
    2. 在Windows添加路由时,CMD始终是别不了route add命令,是由于未使用管理用方式打开CMD
    3. 由于不够细致,有时较长的iptables的命令出现漏掉选项等情况,导致命令无法执行,需要进一步提升严谨性

  • 项目详细代码如下 

  • 一、拓扑结构图如下


  • 二、实现SNAT并配置好服务器的IP

    主机:root@server

    客户机1:root@web-mysql

    客户机2:root@web-mysql-2

  • 1.配置好网关服务器的SNAT策略:
    [root@server /]# cd /lianxi
    [root@server lianxi]# mkdir 0813
    [root@server lianxi]# ls
    0813
    [root@server 0813]# vim snat.sh
    snat.sh
    [root@server 0813]# cat snat.sh 
    #!/bin/bash
    
    #open route function
    echo 1 >/proc/sys/net/ipv4/ip_forward
    
    #clear iptables rules
    iptables -F
    iptables -t nat -F
    iptables -P INPUT ACCEPT
    
    #start snat
    #iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens33 -j SNAT --tosource 192.168.2.200
    iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens33 -j MASQUERADE
    [root@server 0813]# vim snat.sh 
    [root@server 0813]# cat snat.sh 
    #!/bin/bash
    
    #stop firewalld service
    service firewalld stop 
    
    # selinux policy
    setenforce 0
    
    #open route function
    echo 1 >/proc/sys/net/ipv4/ip_forward
    
    #clear iptables rules
    iptables -F
    iptables -t nat -F
    iptables -P INPUT ACCEPT
    
    #start snat
    
    #iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens33 -j SNAT --tosource 192.168.2.200
    iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens33 -j MASQUERADE
    [root@server 0813]# bash snat.sh 
    Redirecting to /bin/systemctl stop firewalld.service
    [root@server 0813]# iptables -L -t nat -n # 查看iptables的规则
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination         
    
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination         
    
    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination         
    MASQUERADE  all  --  192.168.50.0/24      0.0.0.0/0           
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination         
    [root@server 0813]# 
    

    注意:

    此时需要在windows里添加一条路由,从而方便我们ssh到内网的服务器里

    命令:route add 192.168.20.0/24 192.168.50.200


三、配置好客户机内网的IP

# 配置root@web-mysql的IP
[root@web-mysql network-scripts]# cd /etc/sysconfig/network-scripts/
[root@web-mysql network-scripts]# ls
ifcfg-ens33
[root@web-mysql network-scripts]# vim ifcfg-ens33 
[root@web-mysql network-scripts]# cat ifcfg-ens33 
BOOTPROTO="none"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.50.100
PREFIX=24
GATEWAY=192.168.2.200
DNS1=114.114.114.114
DNS2=192.168.50.200

[root@web-mysql network-scripts]# ifup ens33
[root@web-mysql network-scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:0d:bc:42 brd ff:ff:ff:ff:ff:ff
    inet 192.168.50.100/24 brd 192.168.50.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe0d:bc42/64 scope link 
       valid_lft forever preferred_lft forever
[root@web-mysql network-scripts]# ^C

# 同理配置root@web-mysql的IP
[root@web-mysql-2 ~]# cd /etc/sysconfig/network-scripts/
[root@web-mysql-2 network-scripts]# ls
ifcfg-ens33
[root@web-mysql-2 network-scripts]# cat ifcfg-ens33 
BOOTPROTO="none"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=192.168.50.101
PREFIX=24
GATEWAY=192.168.50.200
DNS1=114.114.114.114
DNS2=192.168.50.200
[root@web-mysql-2 network-scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:bf:ff:dc brd ff:ff:ff:ff:ff:ff
    inet 192.168.50.101/24 brd 192.168.50.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:febf:ffdc/64 scope link 
       valid_lft forever preferred_lft forever
[root@web-mysql-2 network-scripts]# 

四、安装好Docker,并启动nginxMySQLDocker容器

客户机一:
[root@web-mysql ~]# yum remove docker \\
>                   docker-client \\
>                   docker-client-latest \\
>                   docker-common \\
>                   docker-latest \\
>                   docker-latest-logrotate \\
>                   docker-logrotate \\
>                   docker-engine
未找到匹配的参数: docker
未找到匹配的参数: docker-client
未找到匹配的参数: docker-client-latest
未找到匹配的参数: docker-common
未找到匹配的参数: docker-latest
未找到匹配的参数: docker-latest-logrotate
未找到匹配的参数: docker-logrotate
未找到匹配的参数: docker-engine
没有软件包需要移除。
依赖关系解决。
无需任何处理。
完毕!
[root@web-mysql ~]# yum install -y yum-utils
[root@web-mysql ~]# yum-config-manager \\
>     --add-repo \\
>     http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
添加仓库自:http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@web-mysql ~]# yum install docker-ce docker-ce-cli containerd.io
……
完毕!
[root@web-mysql ~]# 
[root@web-mysql ~]# systemctl start docker
[root@web-mysql ~]# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
[root@web-mysql ~]# docker pull mysql:5.7.35
[root@web-mysql ~]# docker pull nginx
[root@web-mysql ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    dd34e67e3371   25 hours ago   133MB
mysql        5.7.35    6c20ffa54f86   26 hours ago   448MB
[root@web-mysql ~]# docker run -d --name chao-nginx-1 -p 80:80 nginx #创建nginx镜像为基础的容器,实现web功能
d98d2891a17bd60d8736728aa2f748030665080804d838e6104e486e959eaff3
[root@web-mysql ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
d98d2891a17b   nginx     "/docker-entrypoint.…"   7 seconds ago   Up 5 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   chao-nginx-1
[root@web-mysql ~]# ss -anplut|grep 80 #查看端口情况(法一)
tcp     LISTEN   0        128              0.0.0.0:80            0.0.0.0:*       users:(("docker-proxy",pid=5583,fd=4))                                         
tcp     LISTEN   0        128                 [::]:80               [::]:*       users:(("docker-proxy",pid=5587,fd=4))                                         
[root@web-mysql ~]# yum install net-tools -y
[root@web-mysql ~]# netstat -anplut|grep 80  #查看端口情况(法二)
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      5583/docker-proxy   
tcp6       0      0 :::80                   :::*                    LISTEN      5587/docker-proxy 
[root@web-mysql ~]# curl 192.168.50.100:80 #查看容器是否创建成功
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@web-mysql ~]# docker exec -it chao-nginx-1 /bin/bash
root@d98d2891a17b:/# cd /usr/share/nginx/html/
root@d98d2891a17b:/usr/share/nginx/html# ls
50x.html  index.html
root@d98d2891a17b:/usr/share/nginx/html# echo "Welcome To ChaoChao's world!" >index.html  #更改index.html文件
root@d98d2891a17b:/usr/share/nginx/html# 
客户机2同理。现展示客户机2实现mysql容器:
[root@web-mysql-2 ~]# docker pull mysql:5.7.35
5.7.35: Pulling from library/mysql
Digest: sha256:7cf2e7d7ff876f93c8601406a5aa17484e6623875e64e7acc71432ad8e0a3d7e
Status: Image is up to date for mysql:5.7.35
docker.io/library/mysql:5.7.35
[root@web-mysql-2 ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        5.7.35    6c20ffa54f86   26 hours ago   448MB
[root@web-mysql-2 ~]# docker run -d --name chao-mysql -e MYSQL_ROOT_PASSWORD='chao123456' -p 3306:3306 mysql:5.7.35 
a0d5fa963fba9b8a3bd1789d34ead90a7abbef2b93bf91b157758f131364e9b0
[root@web-mysql-2 ~]# mysql -uroot -pchao123456 -h 192.168.50.101
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 2
Server version: 5.7.35 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策略:
[root@server 0813]# vim dnat.sh
[root@server 0813]# cat dnat.sh 
#!/bin/bash

#stop firewalld service
service firewalld stop

# selinux policy
setenforce 0

#open route function
echo 1 >/proc/sys/net/ipv4/ip_forward

#clear iptables rules
iptables -F
iptables -t nat -F
iptables -P INPUT ACCEPT

#start snat

#iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens33 -j SNAT --tosource 192.168.2.200
iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o ens33 -j MASQUERADE

#DNAT policy -->web
iptables -t nat -A PREROUTING -d 192.168.2.200 -p tcp --dport 80 -j DNAT --to-destination 192.168.50.100:80

#DNAT policy -->mysql
iptables -t nat -A PREROUTING -d 192.168.2.200 -p tcp --dport 3306 -j DNAT --to-destination 192.168.50.101:3306

[root@server 0813]# 
[root@server 0813]# bash dnat.sh 
Redirecting to /bin/systemctl stop firewalld.service
[root@server 0813]# iptables -t nat -L -n #查看是否实现DNAT
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            192.168.2.200        tcp dpt:80 to:192.168.50.100:80
DNAT       tcp  --  0.0.0.0/0            192.168.2.200        tcp dpt:3306 to:192.168.50.101:3306

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  192.168.50.0/24      0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
[root@server 0813]# 

六、测试DNAT是否实现成功

对于客户机一的web功能:

测试方法一:在另一台客户机上访问客户机一的地址

[root@docker ~]# curl 192.168.50.100
Welcome To ChaoChao's world!
[root@docker ~]# 

测试方法二:在浏览器上访问客户机一的地址

 

对于客户机二的mysql功能:

以上是关于项目实战1——基于iptables的SNAT+DNAT与Docker容器发布的项目的主要内容,如果未能解决你的问题,请参考以下文章

dnat,snat

iptables基础实战练习

iptables SNAT和MASQUERATE

iptables中 SNAT与DNAT的原理与应用

Linux防火墙iptables之SNAT与DNAT

iptables中实现内外网相互访问 SNAT与DNAT的原理与应用