1. 程式人生 > 其它 >解決docker容器開啟埠對映後,會自動在防火牆上開啟埠的問題

解決docker容器開啟埠對映後,會自動在防火牆上開啟埠的問題

在docker中執行第三方服務時,通常需要繫結服務埠到本地主機。但使用 -p 引數進行的埠對映,會自動在iptables中建立規則,繞過firewalld,這對於埠級的黑白名單控制管理是很不利的,所以我們需要對iptables進行手動修改。

這裡以從名為centos.19.09.05的image建立一個容器為例:

首先,如果系統是CentOS7的話,需要關閉自帶firewalld防火牆,並切換為iptables.

假設需要將新容器的27017埠對映到主機的27017埠,一般情況下我們使用命令

docker run -idt -p 27017:27017 centos.19.09.05 /bin/bash

在容器中27017埠服務執行起來後,我們在外網使用埠掃描工具,發現本地主機的27017埠已經打開了,而我們還未在防火牆上進行開放操作;此時檢查iptabes規則:

iptables --list

發現在Chain DOCKER下多出了一條

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             172.17.0.2           tcp dpt:27017

其中172.17.0.2為該容器在docker網橋中的IP,可見該規則允許任意來源的地址訪問27017埠,所以我們需要刪除該規則,並替換成安全性更高的規則。

#刪除DOCKER鏈中的1號規則;如果待刪除規則不位於第一行,則將數字改為對應行號
iptables -D DOCKER 1

#此容器只接受來自地址123.345.456.567的連線請求
iptables -A DOCKER -s 123.345.456.567 -d 172.17.0.2 -p tcp --sport 27017 -j ACCEPT

再次進行埠掃描,發現27017埠已經關閉,只有IP為123.234.345.456的主機能夠連線。


還有一種更簡單的方式。因為docker繞過防火牆的原理是修改了iptables,那不讓它修改即可,此方法無需切換預設防火牆。

按照https://blog.csdn.net/qadzhangc/article/details/96140703所述設定即可,經試驗不可省略步驟,否則可能造成容器無法連線外網。

vim /etc/default/docker

#修改檔案,此處設定等同於在建立容器時手動指定iptables=false引數
DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -iptables=false"
vim /etc/docker/daemon.json
{
"iptables": false
}
#此處對更改設定之前建立的容器也有效,編輯後需重啟docker服務

對ufw的設定主要是為容器建立起轉發,如果容器內的服務不需要訪問外網,不做也可以。

firewalld的操作與ufw有些不同

#ubuntu(ufw)操作為
vim /etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"

#對應centos(firewalld)上操作為:
firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD_direct 0 -i eth0 -j ACCEPT  #eth0為宿主機網絡卡名
firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD_direct 0 -o eth0 -j ACCEPT
firewall-cmd --reload
ubuntu(ufw):
vim /etc/ufw/before.rules

在`*filter`前面新增下面內容
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
COMMIT

centos(firewalld):
firewall-cmd --zone=public --add-masquerade #預設docker0在public zone裡
firewall-cmd --reload