你知道Docker會讓Linux的UFW防火牆失效嗎?用ufw-docker解決此問題

在自架服務的時候,我很疑惑為何不用設定UFW規則就能從外部網路存取,後來發現Docker跟UFW是衝突的,Docker會無視UFW的設定逕行開放通訊埠。這篇文章記錄如何整合二者一起使用。

  • 作業系統:Arch Linux
  • Docker版本:20.10.21

1. 問題來源

Docker會繞過UFW自行建立iptables規則,因此導致UFW設定的規則失效,變成外部網路能直接存取Docker容器開放的通訊埠。

這會造成安全性問題,比方說用docker compose跑Nextcloud,會導致資料庫容器的通訊埠跟著暴露到公開網路,之後再用UFW封鎖是無效的。

若是編輯/etc/docker/daemon.json,把Docker自動調整iptables的功能關閉會使問題更複雜,Docker容器無法對外連線,要手動設定規則。

因此我們還是想辦法整合UFW和Docker吧,讓UFW負責管理整個網路和Docker的連線規則。

2. Docker配合UFW運作的解決方法

現代問題需要現代手段,使用chaifeng撰寫的ufw-docker指令稿能解決這問題。他的Github有詳細原理解釋,這邊直接講解法。

如果已經修改過/etc/docker/daemon.json停用iptables,請將該檔案直接刪除。

  1. 安裝此指令稿修改UFW設定檔,再重啟UFW與Docker服務。
1
2
3
4
5
6
7
8
9
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker

sudo chmod +x /usr/local/bin/ufw-docker

sudo ufw-docker install

sudo systemctl restart ufw

sudo systemctl restart docker
  1. 在採用chaifeng的指令稿後,來看實際例子學習新的UFW管理方式。

  2. 現在這裡有個容器,它將容器內部的8080 TCP通訊埠映射到實體機的8081 TCP通訊埠:

1
8f4q1aqia  searxng/searxng:latest         "/sbin/tini -- /usr/…"   2 hours ago    Up 2 hours             0.0.0.0:8081->8080/tcp, :::8081->8080/tcp                  searxng
  1. 因為上面的指令稿使用了ufw-user-forward規則,我們就得分別開啟「容器的8080 TCP通訊埠」和「實體機的8081 TCP通訊埠」:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看幫助
sudo ufw-docker help

# 開放容器通訊埠
sudo ufw-docker allow "容器名稱或UUID"  8080/tcp

# 開放實體機通訊埠
sudo ufw allow 8081/tcp

# 重新載入UFW
sudo ufw reload

# 重啟Docker服務
sudo systemctl restart docker
  1. 這樣子外部網路能存取此容器,該容器也能對外連線了,由UFW接管Docker的連線規則。

如果本網站文章對您有幫助,歡迎贊助我。