DockerがDockerで機能しないのはなぜですか?

How Containers Workのコンテナ機能ページを編集したとき、Dockerで機能しない理由を説明する必要がありましたstraceこれstraceは私のラップトップのDockerコンテナーで実行たときに何が起こったかです:



$ docker run  -it ubuntu:18.04 /bin/bash
$ # ... install strace ...
root@e27f594da870:/# strace ls
strace: ptrace(PTRACE_TRACEME, ...): Operation not permitted


straceシステムコールを介して機能するptraceため、許可なく機能しptraceません。しかし、修正は簡単で、私のラップトップでは次のようにしました。



docker run --cap-add=SYS_PTRACE  -it ubuntu:18.04 /bin/bash


しかし、問題を解決するのではなく、なぜこの状況が一般的に発生するのかを理解することは私にとって興味深いことでした。では、なぜそれが機能せstraceず、--cap-add=SYS_PTRACEすべて修正ないのですか?



仮説1:コンテナープロセスには独自の特権がない CAP_SYS_PTRACE



問題はを通じて一貫して解決されているため、--cap-add=SYS_PTRACEDockerコンテナープロセスには本来、独自の特権がないように見えますCAP_SYS_PTRACEが、2つの理由により、ここでは何かが追加されません。



理由1:実験として、通常のユーザーとしてログインしているstraceため、任意のプロセスを簡単に起動できましたが、現在のプロセスに特権があるかどうかを確認してCAP_SYS_PTRACEも何も見つかりませんでした。



$ getpcaps $$
Capabilities for `11589': =


理由2:man capabilities特権CAP_SYS_PTRACE次のように読み取ります。



CAP_SYS_PTRACE
       * Trace arbitrary processes using ptrace(2);


要点CAP_SYS_PTRACEは、rootと同様に、ユーザーの任意のプロセスを制御できるということです。以下のためにptrace、ユーザーの通常のプロセス、この権限は必要ありません。



また、私は1つの以上のチェックを行わ:私はを通じてドッカーコンテナを開始しましたdocker run --cap-add=SYS_PTRACE -it ubuntu:18.04 /bin/bash権限を取り消した後、CAP_SYS_PTRACE-とstraceさえ特権なしで正常に動作し続けました。なぜ?!



仮説2:カスタム名前空間ですか?



私の次の(そして十分に根拠のない)仮説は、「うーん、おそらくプロセスは別のユーザー名前空間にあり、strace機能しない...という理由で?」それはあまり一貫性のない一連のステートメントのように見えますが、私はまだ問題をこちら側から見てみました。



それで、プロセスは別のカスタム名前空間にありますか?これはコンテナ内でどのように見えるかです:



root@e27f594da870:/# ls /proc/$$/ns/user -l
... /proc/1/ns/user -> 'user:[4026531837]'


そして、これはホスト上での外観です。



bork@kiwi:~$ ls /proc/$$/ns/user -l
... /proc/12177/ns/user -> 'user:[4026531837]'


コンテナー内のルートは、ホストのルートと同じユーザーです。これは、共通のユーザー名空間識別子(4026531837)を持っているため、その側で干渉するstrace理由があるはずがないためです。ご覧のとおり、仮説はまあまあであることが判明しましたが、コンテナー内のユーザーとホスト上のユーザーが同じであることにまだ気づいておらず、このアプローチは興味深いものに思えました。



仮説3:システムコールがptraceルールによってブロックされているseccomp-bpf



Dockerには、コンテナプロセッサによる多数のシステムコールの起動を制限するルールがあることはすでに知っていました。またseccomp-bpf、定義によってブロックされているコールのリストに、そのルールがあることがわかりましたptrace(実際、呼び出しリストは例外シートであり、ptrace単に



その中に含まれませんが、結果は変わりません。)これでstrace完全にブロックされたptraceものを呼び出すことが機能しないことが明らかであるため、Docker コンテナーが機能しない理由が明らかになりました。



この仮説をテストして、straceすべてのseccompルールを無効にした場合にDockerコンテナーを使用できるかどうかを確認してみましょう



$ docker run --security-opt seccomp=unconfined -it ubuntu:18.04  /bin/bash
$ strace ls
execve("/bin/ls", ["ls"], 0x7ffc69a65580 /* 8 vars */) = 0
... it works fine ...


いいね!すべてが機能し、その秘密が明らかになります!それだけです...



なぜ--cap-add=SYS_PTRACE問題が解決するのですか?



なぜそれ--cap-add=SYS_PTRACEが通話で発生する問題を解決するのかについてはまだ説明していませんメインページでdocker runは、引数が次のように機能する方法が説明されています--cap-add



--cap-add=[]
   Add Linux capabilities


これは、seccompルールとは何の関係もありません!どうしたの?



Dockerのソースコードを見てみましょう。



ドキュメントがまだ役に立たない場合は、ソースに突入するだけで残ります。

Goには1つの優れた機能があります。Goリポジトリでの依存関係の自動販売のおかげで、リポジトリgrep全体を調べて、興味のあるコードを見つけることができます。それで、私はそれをgithub.com/moby/moby複製して、フォームの表現を探すためにスキャンしましたrg CAP_SYS_PTRACE



私の意見では、これはここで起こることです:コンテナー内のseccompの実装のcontrib / seccomp / seccomp_default.goセクションには、seccompルールを通じて、特権を持つプロセスがこの特権に従ってシステムコールを使用する権限を持っているかどうかをチェックする多くのコードがあります。



		case "CAP_SYS_PTRACE":
			s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{
				Names: []string{
					"kcmp",
					"process_vm_readv",
					"process_vm_writev",
					"ptrace",
				},
				Action: specs.ActAllow,
				Args:   []specs.LinuxSeccompArg{},
			})




mobyにはまだコードがあり、profiles / seccomp / seccomp.goseccompプロファイルでは、定義により、同様の操作を実行するため、おそらく答えが見つかりました!



Docker --cap-addは言われている以上の能力があります



結局のところ、それ--cap-addはメインページに表示されているとおりではなく、のように見えるはず--cap-add-and-also-whitelist-some-extra-system-calls-if-requiredです。そして、本当のようです:あなたは精神の権限がある場合CAP_SYS_PTRACEは、システムコールを使用することができます、process_vm_readvしかし、コールがSeccompプロファイルをブロックされているが、あなたは認証がシステムコールを使用するようにすることを、多くの助けではないprocess_vm_readvptraceを通じてCAP_SYS_PTRACE合理的なルックス。



straceDockerの最新バージョンで動作することが判明



カーネルバージョン4.8以降では、このコミットのおかげ、Docker 19.03はついにシステムコールを許可しましたptraceそれはちょうど私のDockerラップトップでまだバージョン18.09.7があり、このコミットが明らかに欠落しています。



それで全部です!



この問題に対処することは興味深いことがわかりました。これは、コンテナーの移動する「充填」の重要な相互作用の良い例だと思います。



この投稿が気に入った場合は、私の雑誌How Containers Workも気に入っていただけると思います。これは、Linuxカーネルの24ページのコンテナー処理機能について説明しています。そこには、特権seccomp-bpfが表示されます。



All Articles