《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》

一、背景

目前我们的系统部署在客户专网环境,由于业务特殊性,安全等级非常高,对于专网的主机客户要求我们启用防火墙并配置安全访问策略。业务系统使用的基础组件有Mysql、redis、mongodb等数据库,且都是使用docker来部署的,现在需要对容器配置安全策略。

环境信息如下:
在这里插入图片描述
需求如下:192.168.1.48这台使用docker部署了mysql、redis、mongodb服务,另外有三台主机分别是192.168.1.11、192.168.1.12、192.168.1.13分别部署了平台系统的java应用,现在需要对192.168.1.48上部署的mysql、redis、mongodb配置ip访问白名单,即只允许192.168.1.11、192.168.1.12、192.168.1.13这三台主机能够访问mysql、redis、mongodb这三个服务。

如下图所示:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第1张图片


二、解决方案

Docker启动后,默认任何外部source IP都被允许转发,从而能够从该source IP连接到宿主机上的任何Docker容器实例。如果只允许一个指定的IP访问容器实例,可以插入路由规则到DOCKER-USER链中,从而能够在DOCKER链之前被加载。


2.1、临时生效

在Docker的规则之前添加iptables策略

步骤如下:

[root@host-48 ~]# iptables -L DOCKER-USER -n
Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
[root@host-48 ~]# iptables -I DOCKER-USER -m iprange -i ens33 ! --src-range 192.168.1.11-192.168.1.13 -j DROP
[root@host-48 ~]# iptables -L DOCKER-USER -n
Chain DOCKER-USER (1 references)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0            source IP range ! 192.168.1.11-192.168.1.13
RETURN     all  --  0.0.0.0/0            0.0.0.0/0   

192.168.1.11主机测试如下:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第2张图片
192.168.1.12主机测试如下:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第3张图片
192.168.1.13主机测试如下:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第4张图片
192.168.1.21主机测试如下:
在这里插入图片描述
说明:经测试192.168.1.11、192.168.1.12、192.168.1.13主机可以访问192.168.1.48主机上的mysql、redis、mongodb服务,其它主机则无法访问。

总结:
1、只允许192.168.1.8 IP访问docker容器

iptables -I DOCKER-USER -i ens33 ! -s 192.168.1.8 -j DROP

2、只允许192.168.1.0/24子网内的IP访问docker容器

iptables -I DOCKER-USER -i ens33 ! -s 192.168.1.0/24 -j DROP

3、重启docker服务DOCKER-USER链配置规则不会失效。
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第5张图片
4、重启服务器后DOCKER-USER链配置的规则会失效。
在这里插入图片描述


2.2、永久生效

2.2.1、方法一(未安装iptables-services)

步骤如下:

[root@host-48 ~]# iptables -I DOCKER-USER -m iprange -i ens33 ! --src-range 192.168.1.11-192.168.1.13 -j DROP
[root@host-48 ~]# iptables -L DOCKER-USER -n 
Chain DOCKER-USER (1 references)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0            source IP range ! 192.168.1.11-192.168.1.13
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
[root@host-48 ~]# iptables-save > /etc/sysconfig/iptables

1、重启docker服务在DOCKER-USER链上手动配置的规则未失效,如下图所示:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第6张图片
2、手动保存iptables配置文件后,重启服务器服务后,在DOCKER-USER链上手动配置的规则已经失效,如下图所示:
在这里插入图片描述
3、在系统重启后手动加载此配置文件

[root@host-48 ~]# iptables-restore < /etc/sysconfig/iptables

如下图所示:
在这里插入图片描述


2.2.2、方法二(安装iptables-services)

步骤如下:

#1、安装iptables软件
[root@host-48 ~]# yum install iptables -y && yum install iptables-services -y
[root@host-48 ~]# systemctl start iptables.service && systemctl enable iptables.service
[root@host-48 ~]# systemctl stop firewalld.service && systemctl mask firewalld.service

#2、在DOCKER-USER链上配置规则
[root@host-48 ~]# iptables -I DOCKER-USER -m iprange -i ens33 ! --src-range 192.168.1.11-192.168.1.13 -j DROP
[root@host-48 ~]# iptables -L DOCKER-USER -n 
Chain DOCKER-USER (1 references)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0            source IP range ! 192.168.1.11-192.168.1.13
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

#3、将我们配置好的规则保存到备份配置文件中
[root@host-48 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  确定  ]

1、重启docker服务在DOCKER-USER链上手动配置的规则未失效,如下图所示:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第7张图片
2、手动保存iptables配置文件后,重启iptables服务后,在DOCKER-USER链上手动配置的规则未失效,如下图所示:
《Linux运维总结:基于Centos系统使用iptables为docker容器配置防火墙策略》_第8张图片
3、手动保存iptables配置文件后,重启服务器后,在DOCKER-USER链上手动配置的规则未失效,如下图所示:
在这里插入图片描述
4、如果安装了iptables软件,则必须设置开机自启,即使保存了iptables的配置文件,重启服务器后之前在DOCKER-USER链上配置的规则也会失效,测试如下:

[root@host-48 ~]# systemctl list-unit-files | grep iptables
iptables.service                              disabled
[root@host-48 ~]# systemctl start iptables
[root@host-48 ~]# systemctl status  iptables
● iptables.service - IPv4 firewall with iptables
   Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
   Active: active (exited) since 三 2021-11-10 14:08:39 CST; 4s ago
  Process: 11342 ExecStart=/usr/libexec/iptables/iptables.init start (code=exited, status=0/SUCCESS)
 Main PID: 11342 (code=exited, status=0/SUCCESS)

1110 14:08:38 host-48 systemd[1]: Starting IPv4 firewall with iptables...
1110 14:08:39 host-48 iptables.init[11342]: iptables: Applying firewall rules: [  确定  ]
1110 14:08:39 host-48 systemd[1]: Started IPv4 firewall with iptables.
[root@host-48 ~]# iptables -I DOCKER-USER -m iprange -i ens33 ! --src-range 192.168.1.11-192.168.1.13 -j DROP
[root@host-48 ~]# iptables -L DOCKER-USER -n 
Chain DOCKER-USER (1 references)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0            source IP range ! 192.168.1.11-192.168.1.13
DROP       all  --  0.0.0.0/0            0.0.0.0/0            source IP range ! 192.168.1.11-192.168.1.13
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
[root@host-48 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  确定  ]
[root@host-48 ~]# 
[root@host-48 ~]# 
[root@host-48 ~]# 
[root@host-48 ~]# reboot

测试结果如下图所示:
在这里插入图片描述
原因分析:服务器重启后,iptables服务先启动,启动后会去加载备份的配置文件,但是此时,docker服务还未启动,DOCKER规则链还未创建,所以虽然iptables有加载我们备份的配置,但他没法加载DOCKER规则链上的内容,从而导致我们写的DOCKER规则链上的规则没有成功加载,而docker启动后,DOCKER规则链就存在了,这时不管是手动让iptables加载配置文件还是直接重启iptables让他自己再读一遍配置,我们备份的DOCKER规则就都能成功加载了。

[root@host-48 ~]# grep iptables  /var/log/messages
Nov 10 14:23:54 host-48 systemd: Starting IPv4 firewall with iptables...
Nov 10 14:23:56 host-48 iptables.init: iptables: Applying firewall rules: [  确定  ]
Nov 10 14:23:56 host-48 systemd: Started IPv4 firewall with iptables.

[root@host-48 ~]# grep dockerd /var/log/messages
Nov 10 14:23:58 host-48 dockerd: time="2021-11-10T14:23:58.350259038+08:00" level=info msg="Daemon has completed initialization"
Nov 10 14:23:58 host-48 dockerd: time="2021-11-10T14:23:58.391864224+08:00" level=info msg="API listen on /var/run/docker.sock"

总结:整理不易,如果对你有帮助,可否点赞关注一下?

更多详细内容请参考:Linux运维实战总结

你可能感兴趣的:(《Linux运维实战总结》,运维,容器,linux)