解決docker容器開啟埠對映後,會自動在防火牆上開啟埠的問題
阿新 • • 發佈:2021-10-14
在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