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
920
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
62
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
Rubyist入門: The Way to The Timeless Way of Programming
snoozer05
PRO
3
170
これからアウトプットする人たちへ - アウトプットを支える技術 / that support output
soudai
PRO
16
5.2k
エンタープライズ企業における開発効率化のためのコンテキスト設計とその活用
sergicalsix
1
320
旧から新へ: 大規模ウェブクローラの Perl から Go への移行 / YAPC::Fukuoka 2025
motemen
1
650
【AWS reInvent 2025 関西組 事前勉強会】re:Inventの“感動と興奮”を思い出してモチベ爆上げしたいです
ttelltte
0
130
「データ無い! 腹立つ! 推論する!」から 「データ無い! 腹立つ! データを作る」へ チームでデータを作り、育てられるようにするまで / How can we create, use, and maintain data ourselves?
moznion
6
3.4k
us-east-1 の障害が 起きると なぜ ソワソワするのか
miu_crescent
PRO
2
780
こんな時代だからこそ! 想定しておきたいアクセスキー漏洩後のムーブ
takuyay0ne
4
530
Data & AIの未来とLakeHouse
ishikawa_satoru
0
720
re:Invent完全攻略ガイド
junjikoide
1
260
QAセントラル組織が運営する自動テストプラットフォームの課題と現状
lycorptech_jp
PRO
0
350
AI時代に必要なデータプラットフォームの要件とは by @Kazaneya_PR / 20251107
kazaneya
PRO
4
960
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
Unsuck your backbone
ammeep
671
58k
Bash Introduction
62gerente
615
210k
Thoughts on Productivity
jonyablonski
73
4.9k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
Making Projects Easy
brettharned
120
6.4k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.8k
Producing Creativity
orderedlist
PRO
348
40k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
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 に期待 まとめ