容器访问控制

2020-08-29  本文已影响0人  欧耶90

容器的访问控制主要是通过iptables防火墙软件实现的

  1. 容器访问外部网络
    容器的默认网关为docker0网桥的docker0接口,docker0接口也是宿主机的本地网络接口,如果容器需要访问到外部网络则需要宿主机进行辅助转发。
    在宿主机上面需要打开以下设置:
    sysctl -w net.ipv4.ip_forward=1    # 开启转发功能
    
    Docker服务启动时会默认开启--ip-forward=true,自动配置宿主机系统的转发规则。
    假如容器内部的ip地址是172.17.0.2,本地网络地址是10.0.2.2.容器要能够访问外部网络,源地址不能使172.17.0.2,需要进行源地址映射(SNAT),修改为本地系统的IP地址10.0.2.2.
    映射是通过iptables的源地址伪装操作实现的,查看主机nat表上POSTROUTING链的规则,该链负责数据包离开主机前,改写起源地址:
    ➜  ~ iptables -t nat -nvL POSTROUTING
    Chain POSTROUTING (policy ACCEPT 260 packets, 22174 bytes)
     pkts bytes target     prot opt in     out     source               destination         
     48  3648 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
      0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:6379
      0     0 MASQUERADE  tcp  --  *      *       172.17.0.3           172.17.0.3           tcp dpt:80
    

上述规则将所有源地址是172.17.0.0/16网络,且不是从docker0接口发出的流量(即从容器中出来的流量),动态伪装为从系统网卡发出。MASQUERADE行动与传统SNAT行动相比,好处是能动态地从网卡获取地址。

  1. 容器之间的访问
    容器之间访问需要两方面的支持:
    • 网络拓扑是否已经连通,默认情况下,所有容器都会连接到docker0网桥上,这表示网络拓扑是互通的;
    • 本地防火墙iptables规则是否允许访问通过
      当启动Docker服务时,默认会添加一条允许转发策略到iptables的FORWARD链上,通过配置--icc=true|false实现,为了安全考虑,可以在Docker配置文件中指定DOCKER_OPTS=--icc=false来默认禁止容器间的访问,同时可以指定--iptables=false参数,不会修改宿主机上面iptables的规则。
    iptables -nL
    

如果--iptables=true,表示Docker可以自主添加iptables规则,启动容器时使用--link=CONTAINER_NAME:ALIAS选项,Docker会在iptables中为两个互连容器分别添加一条ACCEPT规则,运行相互访问开放的端口。

  1. 外部网络访问容器
    容器运行外部网络访问,可以在docker run的时候通过-p或-P参数来启用。其实是在本地的iptables的nat表中添加规则,将访问外部ip的包进行目的地址DNAT,将目标地址修改为容器的ip地址。
    以一个开放的6379端口的redis容器为例,使用-p,本地的6379端口映射到容器的6379端口:
➜  ~ iptables -t nat -nvL 
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 5 packets, 332 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 5 packets, 332 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:6379

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:6379 to:172.17.0.2:6379

可以看到,nat表中设计两条链:PREROUTING链负责包到达网络接口时,改写目的地址,将所有流量转发到DOCKER链,而DOCKER链将所有不是从docker0进来的包(意外着不是本地主机产生),同时目标端口为6379的修改为目标地址是172.17.0.2,目标端口修改为6379

上一篇 下一篇

猜你喜欢

热点阅读