Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
rootful・rootless・privilegedコンテナの違い/rootful_root...
Search
moz_sec_
December 28, 2024
Technology
0
900
rootful・rootless・privilegedコンテナの違い/rootful_rootless_privileged_container_difference
2024/12/28に開催されたOWASP KansaiのLTの資料です。
https://owasp-kansai.doorkeeper.jp/events/179740
moz_sec_
December 28, 2024
Tweet
Share
More Decks by moz_sec_
See All by moz_sec_
学ぶ・つながる・挑戦する ~ 大学から始めるセキュリティの学び~/security_learning
moz_sec_
0
58
Lima+containerd+nerdctlで作るコンテナ環境/lima_containerd_nerdctl
moz_sec_
0
170
セキュリティ人材になるために/becoming a security personnel
moz_sec_
0
240
IPA試験 合格体験記/qualification-story
moz_sec_
0
120
Other Decks in Technology
See All in Technology
累計5000万DLサービスの裏側 – LINEマンガのKotlinで挑む大規模 Server-side ETLの最適化
ldf_tech
0
190
AIで急増した生産「量」の荒波をCodeRabbitで乗りこなそう
moongift
PRO
0
520
CLIPでマルチモーダル画像検索 →とても良い
wm3
2
800
Raycast AI APIを使ってちょっと便利なAI拡張機能を作ってみた
kawamataryo
1
250
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
0
430
仕様駆動開発を実現する上流工程におけるAIエージェント活用
sergicalsix
11
5.9k
20251102 WordCamp Kansai 2025
chiilog
1
550
Playwrightで始めるUI自動テスト入門
devops_vtj
0
150
The Twin Mandate of Observability
charity
1
340
激動の時代を爆速リチーミングで乗り越えろ
sansantech
PRO
1
260
Databricks Free Editionで始めるMLflow
taka_aki
0
790
GTC 2025 : 가속되고 있는 미래
inureyes
PRO
0
150
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Product Roadmaps are Hard
iamctodd
PRO
55
11k
Java REST API Framework Comparison - PWX 2021
mraible
34
8.9k
Side Projects
sachag
455
43k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Bash Introduction
62gerente
615
210k
KATA
mclloyd
PRO
32
15k
Stop Working from a Prison Cell
hatefulcrawdad
272
21k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.7k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
54k
The Pragmatic Product Professional
lauravandoore
36
7k
Visualization
eitanlees
150
16k
Transcript
rootful・rootless・privileged コンテナの違い Kobayashi Shun (@moz_sec)
3 巷で話題のルートレスコンテナ
4 ⼀⽬でわかる違い • ホスト側で作られるプロセスのユーザが異なる rootless コンテナ rootrul コンテナ 作成 コンテナ内
ホストから 作成 コンテナ内 ホストから
5 ⼀⽬でわかる違い • ホスト側で作られるプロセスのユーザが異なる rootless コンテナ rootrul コンテナ rootユーザ(UID: 0)
作成 コンテナ内 ホストから testユーザ(UID: 1000) 作成 コンテナ内 ホストから コンテナから⾒ると同じ
6 以上です
7 • user_namespace(7) による分離の有無 • rootlessコンテナはこれを使うことで、⼀般ユーザでのコンテ ナ作成を実現する 技術的な違い
8 • リソースを隔離する技術 • Linuxカーネルv6.8.0時点では8種類 1. Cgroup: cgroup ルートディレクトリ(v.4.6~) 2.
IPC: IPCオブジェクト, POSIXメッセージキュー (v.2.6.19~) 3. Network: ネットワークデバイス・スタック, ポート など(v2.6.26~) 4. Mount: mountポイント (v2.4.19~) 5. PID: プロセスID (v2.6.24~) 6. Time: 時間 (v.5.6~) 7. User: UID, GID(Linux v2.6.19~) 8. UTS: ホスト名, ドメイン名 (v2.6.19~) Namespace rootlessコンテナとroo0ulコンテナの違いはこれ
9 • プロセスがどのNamespaceに属するかは /proc/<PID>/ns/* で確認できる Namespace
10 Namespace • ホストのPID1とコンテナのNamespaceをdiffで⽐較する roo#ulコンテナ rootlessコンテナ cgroup, ipc, mnt, net,
pid, uts Namespace が分離されているのは共通 rootlessコンテナではuser Namespaceも 分離されている
11 • user Namespaceを使うことで、実現する • 新しいUser Namespaceを作成してそのNamespaceに⼊ると、そ のuser Namespaceにおいてはrootとなり、コンテナ⽣成に必要 な権限のほとんどを取得できる
• user Namespace内のrootと元のroot(実root)は若⼲異なる rootlessコンテナの仕組み
12 • コンテナのUIDとホストのUIDを紐づけることができる • /proc/PID/uid_map に書き込まれる (Namespace内の最初のID) (Namespace外の最初のID) (範囲) •
newuidmap(1) が使われる • 同じuser Namespaceのプロセスには継承される • /etc/subuid で各ユーザが指定できるUIDは決められている uid_mapping roo#ulコンテナ rootlessコンテナ コンテナでは UID: 0 ↔ ホスト上では UID: 1000 コンテナのUID: 1~ ↔ホスト上ではUID: 100000~
13 • コンテナランタイムの脆弱性によりコンテナブレイクアウト されても、ホスト側での権限はユーザ権限 • 実際にruncの脆弱性を調べてみると21件 • CVE-2019-5736ではruncバイナリを上書きできるが、rootlessコ ンテナだと上書きできない rootlessコンテナの利点
<>$7&SVOD TFBSDISFTVMTUT IUUQTDWFNJUSFPSHDHJCJODWFLFZDHJ LFZXPSESVOD <>6/*5#SFBLJOHPVUPG%PDLFSWJBSVO$ r &YQMBJOJOH$7& IUUQTVOJUQBMPBMUPOFUXPSLTDPNCSFBLJOHEPDLFSWJBSVODFYQMBJOJOHDWF dockerd Container Runtime Linux High Level Low Level gRPC JSON設定ファイル と サブコマンド Container 過去に“Lima+containerd+nerdctlで作るコンテナ環境”で紹介
14 • 複数の⾮rootユーザがコンテナを作成できる rootfulコンテナの場合、root権限を持つか、ユーザをdockerグ ループに追加する必要がある • ⾮rootユーザは⾃⾝が起動したコンテナの /proc/PID/root にア クセスできる
/proc/PID/root は mount Namespaceでの / を指す • ネストされたコンテナを分離可能にする rootlessコンテナの利点 rootlessコンテナの場合、⼀般ユーザ rootfulコンテナの場合、rootになるためアクセスできない
15 • ホスト上ではユーザ権限でプロセスが動くため、いくつか制 約はある [5] • ホストの1024番未満のポート番号にバインドできない 例) コンテナは80番ポートで待ち受けできるが、ホストで80番 で待ち受けてポートフォーワードすることは不可
• デフォルト設定では、pingコマンドが使えない • cgroup v2 + systemd のときのみcgroupをサポート • slirp4netnsを使うとネットワークパフォーマンスが低下 rootlessコンテナの制限 <>(JU)VCDPOUBJOFSTQPENBO SPPUMFTTNE IUUQTHJUIVCDPNDPOUBJOFSTQPENBOCMPCNBJOSPPUMFTTNE
16 • デフォルトでDockerはrootful、Podmanはrootless • ただ、Docker v19.03 以降であれば、以下のコマンドを叩くだ けでrootlessコンテナとして作成できる $ dockerd-rootless-setuptool.sh
install • 条件(Ubuntu24.04でデフォルトで満たす) newuidmap(1), newgidmap(1) がインストール済み /etc/subuid, /etc/subgidに65536個以上のUID/GIDが含まれる Dockerでもrootlessコンテナは作れる <>%PDLFS%PDT3PPUMFTTNPEF IUUQTEPDTEPDLFSDPNFOHJOFTFDVSJUZSPPUMFTT
17 • 現在rootlessコンテナはサポートされていない • ただ、User Namespacesをサポートする動きはあり、 Kubernetes v1.30でβ機能としてリリース • 近いうちにstableになるかもしれない
Kubernetesでは <>TQFBDLFS EFDL࣍ͷίϯςφηΩϡϦςΟͷ࣌6TFS/BNFTQBDF8JUIB1PE IUUQTTQFBLFSEFDLDPNQGODMPVEOBUJWFEBZTVTFSOBNFTQBDFXJUIBQPE 今年のCNDWで紹介されています
21 ここまでが roo#ulコンテナとrootlessコンテナのお話
22 そういえば、dockerのオプションに --privilegedっていうのもあったはず 何が違うの︖
23 • --privileged オプションで作れる • コンテナに対するさまざまな制約を全て削ぎ落とす • LinuxカーネルのcapabiliWesを全て付与 • デフォルトのseccompプロファイルを無効化
• デフォルトのAppArmorプロファイルを無効化 • 全てのデバイスへのアクセスを許可 • /sys/ (=sysfs)を読み書き可能にする • Docker in Dockerを実⾏するなどのユースケースのために存在 特権コンテナ(privilegedコンテナ) <>%PDLFSEPDTQSJWJMFHFEDPOUBJOFS IUUQTEPDTEPDLFSDPNSFGFSFODFDMJEPDLFSDPOUBJOFSSVOQSJWJMFHFE
24 • --privileged オプションで作れる • コンテナに対するさまざまな制約を全て削ぎ落とす • LinuxカーネルのcapabiliWesを全て付与 • デフォルトのseccompプロファイルを無効化
• デフォルトのAppArmorプロファイルを無効化 • 全てのデバイスへのアクセスを許可 • /sys/ (=sysfs)を読み書き可能にする • Docker in Dockerを実⾏するなどのユースケースのために存在 特権コンテナ(privilegedコンテナ) <>%PDLFSEPDTQSJWJMFHFEDPOUBJOFS IUUQTEPDTEPDLFSDPNSFGFSFODFDMJEPDLFSDPOUBJOFSSVOQSJWJMFHFE
25 capabili3es? seccomp? AppArmor? これら全てLinuxカーネルの機能
26 • プロセスに対して特権を細分化して割り当てる機能 = CAP_SYS_ADMIN: rootユーザが持っている権限 を細分化 • Dockerではデフォルトで割り当てるcapabilityを制限[7] capabilities
<>%PDLFSEPDTMJOVYLFSOFMDBQBCJMJUJFT IUUQTEPDTEPDLFSDPNFOHJOFTFDVSJUZMJOVYLFSOFMDBQBCJMJUJFT <>(JU)VCNPCZPDJDBQTEFGBVMUTHP IUUQTHJUIVCDPNNPCZNPCZCMPCNBTUFSPDJDBQTEFGBVMUTHP 1024番未満のポートを使⽤可能 Rawソケットを使⽤可能 → pingが使える
27 • --cap-addや--cap-dropでできる[9] • --privilegedにしたい時は、ほとんどの場合、--cap-addで capabili;esを付与すれば解決できる • capabili[esはgetpcaps(1)で確認可能 capabilities <>%PDLFSEPDTSVOUJNFQSJWJMFHFBOEMJOVYDBQBCJMJUJFT
IUUQTEPDTEPDLFSDPNFOHJOFDPOUBJOFSTSVOSVOUJNFQSJWJMFHFBOEMJOVYDBQBCJMJUJFT 最初に作ったコンテナで確認 p.24で作ったprivilegedコンテナで確認
28 • システムコールを制限する機能 • /boot/configでCONFIG_SECCOMP=yならば有効 Ubuntu 24.04では、デフォルトで有効 • 300以上あるシステムコールの中からDockerではデフォルトで 約44個のシステムコールを無効化[10]
seccomp <>%PDLFSEPDTTFDDPNQ IUUQTEPDTEPDLFSDPNFOHJOFTFDVSJUZTFDDPNQQBTTBQSPpMFGPSBDPOUBJOFS
29 seccomp <>(JU)VCNPCZNPCZ QSPGJMFTTFDDPNQEFGBVMUKTPO IUUQTHJUIVCDPNNPCZNPCZCMPCNBTUFSQSPGJMFTTFDDPNQEFGBVMUKTPO • デフォルトのseccompプロファイルを⼀部抜粋[11] • --security-opt で変更可能
最初に全てのシステムコールを拒否 ホワイトリスト形式で許可していく 権限の条件
30 • 強制アクセス制御(MAC: Mandatory Access Control)を実現 • 所有者がアクセス制御を設定する任意アクセス制御 (DAC: Discretionary
Access Control)の逆 • ファイルパスごとに許可・拒否を⾏う コンテナ内でrootであっても、アクセス拒否などができる • aa-status(1)で確認可能 AppArmor <>%PDLFSEPDTQBTTBQSPGJMFGPSBDPOUBJOFS IUUQTEPDTEPDLFSDPNFOHJOFTFDVSJUZTFDDPNQQBTTBQSPGJMFGPSBDPOUBJOFS
31 AppArmor <>(JU)VCNPCZNPCZ UFNQMBUFHP IUUQTHJUIVCDPNNPCZNPCZCMPCNBTUFSQSPpMFTBQQBSNPSUFNQMBUFHP /proc の拒否 /sys の拒否 •
デフォルトのAppArmorプロファイルを⼀部抜粋[12] • --security-opt で変更可能 mount の拒否 runc のシグナル拒否
32 • コンテナに対するさまざまな制約を全て削ぎ落とす • Linuxカーネルのcapabilitiesを全て付与 → ホストのrootと同じ権限 • デフォルトのseccompプロファイルを無効化 →
システムコールに制限なし • デフォルトのAppArmorプロファイルを無効化 → 強制アクセス制御が無効 • 全てのデバイスへのアクセスを許可 • /sys/ (=sysfs)を読み書き可能にする 特権コンテナ(privilegedコンテナ) 再掲
33 • Dockerのドキュメントでもできるだけ使わないことを推奨 • コンテナブレイクアウトが容易 Container Security Bookのbreakout-to-hostで紹介されている • 特権コンテナを使う際は、ベストプラクティスに従うこと
[12] コンテナ内でrootユーザを使わない ユーザが権限昇格コマンドを実⾏するのを防ぐ(--security-opt no-new-privilegesを使う) 特権コンテナ(privilegedコンテナ) <>4OZL$POUBJOFSJTSVOOJOHJOQSJWJMFHFENPEF IUUQTMFBSOTOZLJPMFTTPODPOUBJOFSSVOTJOQSJWJMFHFENPEF
35 1. 特権コンテナ (--privileged) + コンテナ内でroot 容易にホストにアクセス可 2. 特権コンテナ (--privileged)
+ コンテナ内で追加したユーザ コンテナ内でrootになると容易にホストにアクセス可 3. rootful + コンテナ内でroot コンテナランタイムの脆弱性が⾒つかるなどするとまずい 4. rootful + コンテナ内で追加したユーザ コンテナ内でrootになったのちに、コンテナブレイクアウト 多層防御(弱い順)
36 5. rootless + コンテナ内でroot コンテナブレイクアウトしたのちに、ホスト上で特権昇格 6. rootless + コンテナ内で追加したユーザ
コンテナ内でrootになったのちに、コンテナブレイクアウトし てさらにホスト上で特権昇格 多層防御(弱い順)
37 • むやみに --privileged は使わない 使うなら、最低限コンテナ内でroot以外のユーザを使⽤し、 --security-opt no-new-privileges でrootになるのを防ぐ •
デフォルトだとDockerではrootful, Podmanではrootless • コンテナを実現するための技術はなかなか奥が深い • rootlessコンテナの場合、コンテナブレイクアウトできても、 ホスト側ではユーザ権限 • Kubernetesでは、KEP-127: Support User Namespaces に期待 まとめ