docker 究竟是如何繞過我的 nftables 的?

docker 究竟是如何繞過我的 nftables 的?

我的目標是阻止除 22、80、443 之外的所有非「lo」介面連接埠。

我有一個 nc 伺服器在連接埠 9123 上運行。然而 - 我在 docker 中啟動的任何服務似乎都沒有被阻止 - 其他 LAN 設備可以訪問 PI 上的 docker 伺服器。我不太明白這是怎麼發生的。在第 107 行,我的預設策略是 DROP,接下來的行在「lo」介面上新增了一個例外。這裡究竟發生了什麼事?我該如何實現所需的行為(即)阻止 LAN 裝置存取 pi 上除 22,80,443 之外的任何內容?謝謝

   root@raspberrypi:/home/pi/tmp # nft  list ruleset   | awk '{printf "%d\t%s\n", NR, $0}'
    1   table ip nat {
    2       chain DOCKER {
    3           iifname "docker0" counter packets 0 bytes 0 return
    4           iifname "docker_gwbridge" counter packets 0 bytes 0 return
    5           iifname "br-7a4b6e0a5c6f" counter packets 3840 bytes 115200 return
    6           iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 8920 counter packets 0 bytes 0 dnat to 172.20.0.2:8920
    7           iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 8096 counter packets 0 bytes 0 dnat to 172.20.0.2:8096
    8           iifname != "docker0" meta l4proto tcp tcp dport 8080 counter packets 0 bytes 0 dnat to 172.17.0.2:8080
    9           iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 445 counter packets 0 bytes 0 dnat to 172.20.0.3:445
    10          iifname != "docker0" meta l4proto tcp tcp dport 3389 counter packets 0 bytes 0 dnat to 172.17.0.2:3389
    11          iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 9125 counter packets 8306 bytes 531572 dnat to 172.20.0.5:80
    12          iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 9123 counter packets 0 bytes 0 dnat to 172.20.0.6:80
    13          iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 139 counter packets 0 bytes 0 dnat to 172.20.0.3:139
    14          iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 9124 counter packets 0 bytes 0 dnat to 172.20.0.7:80
    15          iifname != "br-7a4b6e0a5c6f" meta l4proto tcp tcp dport 32400 counter packets 0 bytes 0 dnat to 172.20.0.8:32400
    16      }
    17  
    18      chain POSTROUTING {
    19          type nat hook postrouting priority srcnat; policy accept;
    20          oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 958 bytes 399977 masquerade
    21          oifname != "docker_gwbridge" ip saddr 172.19.0.0/16 counter packets 0 bytes 0 masquerade
    22          oifname != "br-7a4b6e0a5c6f" ip saddr 172.20.0.0/16 counter packets 184 bytes 12810 masquerade
    23          oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade
    24          oifname != "br-7a4b6e0a5c6f" ip saddr 172.20.0.0/16 counter packets 8 bytes 502 masquerade
    25          oifname != "docker_gwbridge" ip saddr 172.19.0.0/16 counter packets 0 bytes 0 masquerade
    26          oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade
    27          oifname != "docker_gwbridge" ip saddr 172.19.0.0/16 counter packets 0 bytes 0 masquerade
    28          oifname != "br-7a4b6e0a5c6f" ip saddr 172.20.0.0/16 counter packets 8 bytes 502 masquerade
    29          oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 45 bytes 3148 masquerade
    30          oifname != "docker_gwbridge" ip saddr 172.19.0.0/16 counter packets 0 bytes 0 masquerade
    31          oifname != "br-7a4b6e0a5c6f" ip saddr 172.20.0.0/16 counter packets 36 bytes 2324 masquerade
    32          oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade
    33          oifname != "br-7a4b6e0a5c6f" ip saddr 172.20.0.0/16 counter packets 36 bytes 2324 masquerade
    34          oifname != "docker_gwbridge" ip saddr 172.19.0.0/16 counter packets 0 bytes 0 masquerade
    35          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8080 counter packets 0 bytes 0 masquerade
    36          ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 8920 counter packets 0 bytes 0 masquerade
    37          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3389 counter packets 0 bytes 0 masquerade
    38          ip saddr 172.20.0.4 ip daddr 172.20.0.4 tcp dport 32400 counter packets 0 bytes 0 masquerade
    39          ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 8096 counter packets 0 bytes 0 masquerade
    40          ip saddr 172.20.0.5 ip daddr 172.20.0.5 tcp dport 80 counter packets 0 bytes 0 masquerade
    41          ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 445 counter packets 0 bytes 0 masquerade
    42          ip saddr 172.20.0.7 ip daddr 172.20.0.7 tcp dport 80 counter packets 0 bytes 0 masquerade
    43          ip saddr 172.20.0.8 ip daddr 172.20.0.8 tcp dport 80 counter packets 0 bytes 0 masquerade
    44          ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 139 counter packets 0 bytes 0 masquerade
    45          ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 80 counter packets 0 bytes 0 masquerade
    46          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8080 counter packets 0 bytes 0 masquerade
    47          ip saddr 172.20.0.3 ip daddr 172.20.0.3 tcp dport 32400 counter packets 0 bytes 0 masquerade
    48          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3389 counter packets 0 bytes 0 masquerade
    49          ip saddr 172.20.0.5 ip daddr 172.20.0.5 tcp dport 80 counter packets 0 bytes 0 masquerade
    50          ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 80 counter packets 0 bytes 0 masquerade
    51          ip saddr 172.20.0.7 ip daddr 172.20.0.7 tcp dport 445 counter packets 0 bytes 0 masquerade
    52          ip saddr 172.20.0.8 ip daddr 172.20.0.8 tcp dport 8920 counter packets 0 bytes 0 masquerade
    53          ip saddr 172.20.0.7 ip daddr 172.20.0.7 tcp dport 139 counter packets 0 bytes 0 masquerade
    54          ip saddr 172.20.0.8 ip daddr 172.20.0.8 tcp dport 8096 counter packets 0 bytes 0 masquerade
    55          ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 445 counter packets 0 bytes 0 masquerade
    56          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8080 counter packets 0 bytes 0 masquerade
    57          ip saddr 172.20.0.3 ip daddr 172.20.0.3 tcp dport 80 counter packets 0 bytes 0 masquerade
    58          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3389 counter packets 0 bytes 0 masquerade
    59          ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 139 counter packets 0 bytes 0 masquerade
    60          ip saddr 172.20.0.4 ip daddr 172.20.0.4 tcp dport 32400 counter packets 0 bytes 0 masquerade
    61          ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 80 counter packets 0 bytes 0 masquerade
    62          ip saddr 172.20.0.8 ip daddr 172.20.0.8 tcp dport 80 counter packets 0 bytes 0 masquerade
    63          ip saddr 172.20.0.9 ip daddr 172.20.0.9 tcp dport 8920 counter packets 0 bytes 0 masquerade
    64          ip saddr 172.20.0.9 ip daddr 172.20.0.9 tcp dport 8096 counter packets 0 bytes 0 masquerade
    65          ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 80 counter packets 0 bytes 0 masquerade
    66          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8080 counter packets 0 bytes 0 masquerade
    67          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3389 counter packets 0 bytes 0 masquerade
    68          ip saddr 172.20.0.3 ip daddr 172.20.0.3 tcp dport 80 counter packets 0 bytes 0 masquerade
    69          ip saddr 172.20.0.4 ip daddr 172.20.0.4 tcp dport 80 counter packets 0 bytes 0 masquerade
    70          ip saddr 172.20.0.5 ip daddr 172.20.0.5 tcp dport 8920 counter packets 0 bytes 0 masquerade
    71          ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 445 counter packets 0 bytes 0 masquerade
    72          ip saddr 172.20.0.7 ip daddr 172.20.0.7 tcp dport 32400 counter packets 0 bytes 0 masquerade
    73          ip saddr 172.20.0.5 ip daddr 172.20.0.5 tcp dport 8096 counter packets 0 bytes 0 masquerade
    74          ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 139 counter packets 0 bytes 0 masquerade
    75          meta l4proto tcp ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 8920 counter packets 0 bytes 0 masquerade
    76          meta l4proto tcp ip saddr 172.20.0.2 ip daddr 172.20.0.2 tcp dport 8096 counter packets 0 bytes 0 masquerade
    77          meta l4proto tcp ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8080 counter packets 0 bytes 0 masquerade
    78          meta l4proto tcp ip saddr 172.20.0.3 ip daddr 172.20.0.3 tcp dport 445 counter packets 0 bytes 0 masquerade
    79          meta l4proto tcp ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3389 counter packets 0 bytes 0 masquerade
    80          meta l4proto tcp ip saddr 172.20.0.5 ip daddr 172.20.0.5 tcp dport 80 counter packets 0 bytes 0 masquerade
    81          meta l4proto tcp ip saddr 172.20.0.6 ip daddr 172.20.0.6 tcp dport 80 counter packets 0 bytes 0 masquerade
    82          meta l4proto tcp ip saddr 172.20.0.3 ip daddr 172.20.0.3 tcp dport 139 counter packets 0 bytes 0 masquerade
    83          meta l4proto tcp ip saddr 172.20.0.7 ip daddr 172.20.0.7 tcp dport 80 counter packets 0 bytes 0 masquerade
    84          meta l4proto tcp ip saddr 172.20.0.8 ip daddr 172.20.0.8 tcp dport 32400 counter packets 0 bytes 0 masquerade
    85      }
    86  
    87      chain PREROUTING {
    88          type nat hook prerouting priority dstnat; policy accept;
    89          fib daddr type local counter packets 86612 bytes 5842738 jump DOCKER
    90          fib daddr type local counter packets 59086 bytes 4082250 jump DOCKER
    91          fib daddr type local counter packets 58016 bytes 4020180 jump DOCKER
    92          fib daddr type local counter packets 58010 bytes 4019512 jump DOCKER
    93          fib daddr type local counter packets 21891 bytes 1551454 jump DOCKER
    94      }
    95  
    96      chain OUTPUT {
    97          type nat hook output priority -100; policy accept;
    98          ip daddr != 127.0.0.0/8 fib daddr type local counter packets 11 bytes 660 jump DOCKER
    99          ip daddr != 127.0.0.0/8 fib daddr type local counter packets 10 bytes 600 jump DOCKER
    100         ip daddr != 127.0.0.0/8 fib daddr type local counter packets 9 bytes 540 jump DOCKER
    101         ip daddr != 127.0.0.0/8 fib daddr type local counter packets 8 bytes 480 jump DOCKER
    102         ip daddr != 127.0.0.0/8 fib daddr type local counter packets 1 bytes 60 jump DOCKER
    103     }
    104 }
    105 table ip filter {
    106     chain INPUT {
    107         type filter hook input priority -450; policy drop;
    108         iifname "lo" counter packets 19231 bytes 156043045 accept
    109         ip daddr 127.0.0.0/8 counter packets 0 bytes 0 reject
    110         ct state established,related counter packets 67781 bytes 452733513 accept
    111         icmp type echo-request accept
    112         ct state new tcp dport 22 counter packets 119 bytes 7020 accept
    113         ct state new tcp dport 443 counter packets 324 bytes 19343 accept
    114         ct state new tcp dport 80 counter packets 17 bytes 916 accept
    115         ip protocol icmp counter packets 0 bytes 0 accept
    116         limit rate 5/minute counter packets 685 bytes 107167 log prefix "iptables denied: " level debug
    117         tcp dport 9125 drop
    118         counter packets 27066 bytes 4826608 drop
    119     }
    120 
    121     chain OUTPUT {
    122         type filter hook output priority filter - 1; policy drop;
    123         counter packets 133164 bytes 583633753 accept
    124     }
    125 }

答案1

正如人們在Netfilter 和通用網路中的封包流示意圖如下:

Netfilter 和通用網路中的封包流

nat 預路由鏈發生在路由決策之前。因此,當 Docker 使用 DNAT 將目的地從初始網路命名空間(即:主機)更改為其他網路命名空間(路由容器)時,流不再通過過濾器/輸入,而是使用過濾器/轉送: ip 過濾器INPUT 鏈不再被遍歷。選擇優先順序 -450 不會改變任何內容:這是同一鉤子中的優先順序。預路由總是發生在之前輸入(如圖)無論選擇什麼優先順序。在過濾器/輸入中使用 -450 只允許先遍歷鏈,然後再遍歷iptables' 預設優先級 0。

另外作為備註,選擇一條ip filter INPUT鏈條nftables如OP的範例所示(因為優先權-450只能使用nftables) 可能會與iptables-nft的過濾器/輸入鏈的處理發生衝突,應避免。

在少數情況下仍然可以使用 INPUT 規則:

  • 與 Docker 無關時:docker 不會重定向不適合其容器的流量
  • 當容器停止時(例如:應用程式崩潰且沒有自動重新啟動),Docker 會刪除相關規則:封包不再被路由/轉發
  • 當一個容器是另一個容器的客戶端時,可能取決於 Docker 的配置(關於docker-proxy由 Docker 全域參數控制的 NAT 髮夾),那麼在這種情況下,流量就不會被路由(因為它經過的是代理),從而到達輸入掛鉤。userland-proxydocker-proxydocker-proxy

我還在 UL SE Q/A 中回答如何使用nftables沿著 Docker,它自己使用iptablesbr_netfilter內核模組也會影響nftables即使nftables沒有足夠的工具來應對它:

nftables 白名單 docker

相關內容