Amazon-Ec2

限制對特定 Docker 容器的 AWS EC2 元數據的訪問

  • June 4, 2019

我在 AWS EC2 實例上執行 docker,我想阻止某些容器訪問 EC2 實例元數據(IP 地址為 169.254.169.254)。我想我可以通過以特定使用者(例如 userx)身份執行這些容器來做到這一點,在以下 ip 表規則存在的情況下:

$ iptables -A OUTPUT -m owner --uid-owner userx -d 169.254.169.254 -j DROP

當容器與主機網路一起執行時,這會按預期阻止連接:

$ docker run -it --rm --network host -u $(id -u userx):$(id -g userx) appropriate/curl  http://169.254.169.254/latest/meta-data/
...blocks..

但遺憾的是,當容器在其自己的網路中執行時允許連接

$ docker run -it --rm -u $(id -u userx):$(id -g userx) appropriate/curl  http://169.254.169.254/latest/meta-data/
...show metadata...

我怎樣才能使這項工作?或者,是否有其他技術可以在阻止實例元數據的同時為特定容器提供完整的網路訪問權限?

您的問題是OUTPUT沒有擷取從容器中出來的數據包。FORWARD做。

這是為什麼?

每個 Docker 容器都在自己的網路命名空間中執行。每個網路命名空間都有自己的路由表和 iptables 規則,其行為就像是一台單獨的物理機器一樣。

在 iptables 中:

  • INPUT匹配到本地程序的數據包
  • FORWARD匹配從一個網路介面傳入並從另一個網路介面傳出(被路由通過)的數據包。
  • OUTPUT匹配來自本地程序的數據包

關鍵是“本地程序”是指“這個網路命名空間中的一個程序”,而不是“這個機器中的一個程序”。

我們來分析一下是怎麼回事:

  • 數據包由 Docker 容器的網路命名空間中的程序生成。
  • 它們通過OUTPUT容器的網路命名空間 iptables 中的 iptables 鏈。(這是空的!)
  • 他們被路由出veth介面。
  • veth它們從介面到達主機的網路命名空間。
  • 主機網路命名空間查閱路由表並決定他們需要離開例如eth0.
  • 它們通過主機網路命名空間中的 iptablesFORWARD鏈。
  • 他們出去eth0

因此,解決方案是將您的規則放入FORWARD鏈中。

問題是-m ownerFORWARD. 根據man iptables-extensions

此匹配僅在 OUTPUT 和 POSTROUTING 鏈中有效。轉發的數據包沒有任何與之關聯的套接字。

您可以對容器的 IP 地址進行硬編碼,也可以將要過濾的容器放在特殊的網路中,並匹配整個範圍。與此類似的東西應該​​可以工作:

   # single container
   iptables -A FORWARD -s 172.17.0.4 -d 169.254.169.254 -j DROP

   # or entire network
   iptables -A FORWARD -s 172.17.0.0/16 -d 169.254.169.254 -j DROP

此外,owner無論哪種方式,使用都可能不是一個好主意,因為 docker 容器內的程序可以通過例如 setuid 二進製文件(如 sudo)更改其 uid,如果映像中有的話。

引用自:https://serverfault.com/questions/969051