(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Docker/Linux】CAP_NET_RAWを無効にしてコンテナを起動する

スポンサーリンク

はじめに

「CAP_NET_RAW」というケーパビリティがありますが、セキュリティを考慮してコンテナ起動時に削除することができます。
このケーパビリティは「RAWソケットとPACKETソケットの使用を許可」を司っていいて、任意のパケットの送受信を行うために必要な権限となっています。

本記事ではCAP_NET_RAWが必要なpingコマンドを例に実際にコンテナを起動して挙動を確認しました。

環境情報
  • Docker Version:19.03.5

Pingコマンドが打てない

Ubuntiイメージを起動してapt-get install iputils-pingを行えばpingコマンドを押下でき

# docker run -it ubuntu

実際に利用できます。

# ping yahoo.co.jp
PING yahoo.co.jp (182.22.59.229) 56(84) bytes of data.
64 bytes from 182.22.59.229 (182.22.59.229): icmp_seq=1 ttl=37 time=61.8 ms
64 bytes from 182.22.59.229 (182.22.59.229): icmp_seq=2 ttl=37 time=77.2 ms
...

ところが以下のようにコンテナを起動すると

$ docker run -it --cap-drop net_raw ubuntu 

パーミッションエラーでpingが打てません。

# ping
bash: /usr/bin/ping: Operation not permitted

もちろんファイルとしての権限は付与されています。

# ls -l /usr/bin/ping
-rwxr-xr-x 1 root root 72776 ... /usr/bin/ping

straceで詳細を確認する

結論としては冒頭で述べた「CAP_NET_RAW」がpingコマンドに必要だからです。

# getcap /bin/ping
/bin/ping = cap_net_raw+ep

よって例えばarpingのようなping相当のツールを落としてきても以下のように利用できません。

# arping yahoo.co.jp
arping: libnet_init(LIBNET_LINK, <null>): libnet_open_link(): UID/EUID 0 or capability CAP_NET_RAW required

straceコマンドで中身を確認すると分かりますが

# strace arping yahoo.co.jp
execve("/usr/sbin/arping", ["arping", "yahoo.co.jp"], 0x7ffc73334738 /* 8 vars */) = 0
...
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) = -1 EPERM (Operation not permitted)
close(-1)                               = -1 EBADF (Bad file descriptor)
write(2, "arping: libnet_init(LIBNET_LINK,"..., 108arping: libnet_init(LIBNET_LINK, <null>): libnet_open_link(): UID/EUID 0 or capability CAP_NET
_RAW required
) = 108
getuid()                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

生パケットを打とうとしていることが分かります。
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

終わりに

CAP_NET_RAWを持つプロセスは任意の内容のパケットを送信できるので、明確な必要がない場合は権限を削除してコンテナを起動することがベストプラクティスとなっています。コンテナであれば挙動が簡単に確認できるので、本記事を参考に手元でも試してみる事おススメします。

以上、ご参考になれば幸いです。