iptables 鏈 DOCKER-USER 似乎不起作用
我使用 ipset 在我的伺服器上阻止來自許多國家的 IP 範圍(幾乎整個世界,除了法國和法語國家)。
我在 ipset 中有兩個規則集:badbadworld1 和 badbadworld2
我的主機正在執行 docker:一個 Nginx docker 和其他用於不同服務的 docker。
# docker -v Docker version 20.10.17, build 100c701
我想將我的 ipsets 添加到 netfilter(在我的主機上),以便僅從我選擇的國家/地區訪問 Nginx(以及其背後的其他服務)。
當我將 DROP 規則添加到 DOCKER-USER 鏈時,我沒有看到任何數據包被丟棄。
當我將相同的規則添加到 DOCKER 鏈時,我看到丟棄的數據包。
我都是這種情況,我可以使用來自被封鎖國家的線上代理進行測試。
我可以將 DROP 規則添加到兩個鏈中,從文件 DOCKER-USER 在 DOCKER 之前進行評估,所以在這種情況下,數據包必須由 DOCKER-USER 而不是 DOCKER 鏈丟棄,對嗎?
我對此進行了測試:
iptables -I DOCKER-USER -m set --match-set badbadworld2 src -j DROP iptables -I DOCKER-USER -m set --match-set badbadworld1 src -j DROP iptables -I DOCKER -m set --match-set badbadworld2 src -j DROP iptables -I DOCKER -m set --match-set badbadworld1 src -j DROP
幾分鐘後,這是我的 iptables -v -n -L :
[...] Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1596 253K DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0 1188 162K ACCEPT all -- * br-a4cbc882767a 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 56 3324 DOCKER all -- * br-a4cbc882767a 0.0.0.0/0 0.0.0.0/0 352 87455 ACCEPT all -- br-a4cbc882767a !br-a4cbc882767a 0.0.0.0/0 0.0.0.0/0 43 2580 ACCEPT all -- br-a4cbc882767a br-a4cbc882767a 0.0.0.0/0 0.0.0.0/0 0 0 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited 0 0 DROP all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0 [...] Chain DOCKER (2 references) pkts bytes target prot opt in out source destination 10 584 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set badbadworld1 src 1 40 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set badbadworld2 src 2 120 ACCEPT tcp -- !br-a4cbc882767a br-a4cbc882767a 0.0.0.0/0 172.18.0.6 tcp dpt:443 0 0 ACCEPT tcp -- !br-a4cbc882767a br-a4cbc882767a 0.0.0.0/0 172.18.0.6 tcp dpt:80 [...] Chain DOCKER-USER (1 references) pkts bytes target prot opt in out source destination 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set badbadworld1 src 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set badbadworld2 src 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 [...]
您可以看到,對於相同的規則,在 DOCKER 鏈中丟棄了 11 個數據包,在 DOCKER-USER 中丟棄了 0 個數據包。
注意:我首先測試了只添加到 DOCKER-USER 鏈,但我很驚訝沒有看到任何丟棄的數據包(可以肯定的是,我已經嘗試連接來自被封鎖國家的線上代理,並且我可以連接),向兩條鏈添加規則是沒有用的,但這只是為了證明問題。
謝謝 !
在跳轉到 DOCKER-USER 鏈之前已經接受或丟棄的所有數據包。
數據包檢查從鏈中的第一個規則按順序進行,直到某些規則匹配。如果匹配規則的目標是最終的,例如 ACCEPT、DROP、REJECT,則數據包將被接受或丟棄,並且不會進一步檢查下一個規則。在 DOCKER-USER 鏈之前,您有幾個與所有數據包匹配的 ACCEPT 和 DROP。這就是 -j DOCKER-USER 規則的計數器為零的原因。
0 0 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
與 ACCEPT、DROP、REJECT 目標匹配的規則是最終規則- 它停止進一步檢查。
在您的情況下,所有數據包都被 FORWARD 鏈中先前匹配的ACCEPT 和 DROP 規則“吃掉”,並且永遠不會到達您的 DOCKER-USER 鏈。
如果 FORWARD 中的所有規則都是自動生成的,並且您無法更改它們的順序,則可能是 docker 的錯誤或文件錯誤。
否則,您應該更改 FORWARD 規則順序,以便在 ACCEPT ESTABLISHED 規則(#2 規則)之前跳轉到 DOCKER-USER,或者在 ESTABLISHED 之前將您的 DROP 規則直接插入 FORWARD。
如果 DROP 遵循 ESTABLISHED 規則,則 DROP 不會立即對已建立的連接起作用,直到它們顯式關閉或超時。
此外,您應該查看規則的輸入/輸出介面,因為您擁有哪些介面以及要丟棄數據包的介面並不明顯。