Linux save iptables on Docker Host Environment - 在安裝了 Docker 的環境處理 iptables 的儲存 === ###### tags: `blog` > iptables 是在 Linux 系統上實用的防火牆、NAT、封包管理系統,但如果需要在複雜的環境當中使用 iptables ,並且將 iptables 的規則保存的話,就需要使用一些技巧 ## Context 以往在 Linux 當中,我們可以透過 iptables 來當作防火牆使用,只要透過 iptables 中預設的 filter tables,即可做到封包的過濾功能。 但 iptables 的資料是於執行時新增規則,如果想要將規則存檔,並於開機時自動載入的話,我們就需要透過 `iptables-save` 與 `iptables-restore` 這兩個指令來完成。 根據 `Debian Wiki`[^debian-wiki-iptables] 中提到的方法,可以使用 `iptables > /etc/iptables.up.rules` 的方式將 iptables 的 rule 匯出至檔案,再透過 `iptables < /etc/iptable.up.rules` 指令將規則檔案還原。 文中也提到,可以在 `/etc/network/if-pre-up.d/` 路徑中,放置 bash 檔案,這樣就會在網卡啟動前,呼叫 `iptables-restore` 指令,載入 iptables 的規則。 ## Problem 問題來了,傳統作法中,所使用的 iptables-save 指令,會將目前所有的規則匯出,但是如果主機環境中有安裝 Docker 的話, Docker 會建立許多橋接器 (Bridge) ,並透過 iptables 的 filter 、 nat 這兩張表,建立 container 的網路與連線關係。 而 Docker 的環境不清楚他會在何時啟動,並更改 iptables 的狀況下,如果冒然執行 `iptables-restore` 指令,勢必會破壞原先 docker 所建立的規則。 ## Solution 如果無法透過 `iptables-restore` 指令直接匯入規則檔的話,還可以透過另一個方式:使用 iptables 指令動態新增規則。 不過這邊要注意的是,要注意目前 iptables 中的規則是否已經存在,免得重複新增規則。 使用 iptables 的 check 指令可以根據回傳值得之規則是否存在 > iptables [-t ++table++] -C ++chain++ ++rule-specification++' 一樣將 bash 檔案寫在 `/etc/network/if-pre-up.d/` 中, 透過 if 判斷欲新增的規則是否已經存在於 iptables 中, 如果沒有找到的話,再使用 `iptables` 指令動態增加新的規則。 以下是 bash 的範例,透過 function 的方式判斷規則存不存在,不存在則新增規則 ```bash #!/bin/sh # check iptables rule specification is exist, # if not add it check_and_add_iptables() { RULE_SPEC=$@ iptables -C $RULE_SPEC > /dev/null 2>&1 EXIST=$? if [ $EXIST -ne 0 ]; then iptables -A $@ fi } check_and_add_iptables INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT check_and_add_iptables INPUT -p tcp --dport 22 -j DROP ``` ## Conclusion `iptables` 是一個很好用的防火牆軟體,不過在一些複雜的環境當中,無法單純使用 restore 指令套用規則,就得使用動態增加的方式,使用動態增加的方式又得顧慮到該指令重複執行會造成的影響,所以還需要透過一些 test 的方式判斷目前的環境 (Context) 是否可以新增規則。 ## References [^debian-wiki-iptables]: <https://wiki.debian.org/iptables>
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up