前回からだいぶ間隔が空いてしまいました。前回の最後に案内したudzuraさんのCRIUに関する記事はもう少し時間がかかるようですので,
今回から数回は,
setuid
一般的にはUNIX系のOSでは,
一般ユーザは,ping
コマンドは特権が必要で,setuid
されており,
cmd
$ ls -l $(which ping)
-rwsr-xr-x 1 root root 64424 Jun 28 20:05 /bin/ping
↑(このsがsetuidされている印)
ケーパビリティ
先に紹介したping
コマンドは,setuid
されており,
逆に言うとRawソケットを使うのに必要な権限のみが必要なのに,ping
コマンドに渡していることになります。これはセキュリティ上の観点から望ましいことではありません。
Linuxにはこのような場合に使える,
例えば,CAP_
というケーパビリティがあればRawソケットを使用できます。Linuxカーネルでは,/usr/
で定義されています。
$ grep "#define CAP_" /usr/include/linux/capability.h #define CAP_CHOWN 0 #define CAP_DAC_OVERRIDE 1 #define CAP_DAC_READ_SEARCH 2 #define CAP_FOWNER 3 #define CAP_FSETID 4 #define CAP_KILL 5 :(略)
ケーパビリティの実装は結構古くて,capabilities(7)
に載っています。
プロセスのケーパビリティ
プロセス
- Permitted
- EffectiveとInheritableで持つことを許されるケーパビリティセット
- Inheritable
execve(2)
した際に継承できるケーパビリティセット- Effective
- 実際にカーネルがスレッドの実行権限を判定するのに使うケーパビリティセット
- Ambient
- 特権のない
(setuid/ setgidされていない) プログラムを execve(2)
した際に子プロセスに継承されるケーパビリティセット(Linux 4. 3以降で使用可能)
さらに,
実際にカーネルがプロセスが持つ権限をチェックする時は,
そして,
capset(2)
:システムコールでケーパビリティを設定するexecve(2)
:システムコールの前後でケーパビリティが変化するprctl(2)
:システムコールでAmbientケーパビリティやバウンディングセットを設定する
execve(2)
システムコールはプログラムを実行するためのシステムコールです。このシステムコールとケーパビリティの関係については次回で説明します。
実行中のプロセスが持つケーパビリティを確認する
では実際にプロセスでケーパビリティがどのように設定されているかを見てみましょう。
プロセス/proc/<PID>/status
ファイルで確認できます。例えばPIDが1であるinit
のPermittedCapPrm
),CapEff
),CapBnd
)
$ grep Cap /proc/1/status CapInh: 0000000000000000 CapPrm: 0000003fffffffff CapEff: 0000003fffffffff CapBnd: 0000003fffffffff CapAmb: 0000000000000000
特定のケーパビリティだけが設定されている,ntpd
は次のようになっています。
$ grep Cap /proc/$(pgrep ntpd)/status CapInh: 0000000000000000 CapPrm: 0000000002000400 CapEff: 0000000002000400 CapBnd: 0000003fffffffff CapAmb: 0000000000000000
上記の例のように status
ファイルでケーパビリティを確認できます。しかし,
もう少しわかりやすくプロセスのケーパビリティセットを確認したい場合はlibcap
に含まれるgetpcaps
コマンドが使えますlibcap2-bin
パッケージに含まれています)。
$ getpcaps $(pgrep ntpd) Capabilities for `21935': = cap_net_bind_service,cap_sys_time+ep
ポート番号1024番未満を使うには特権が必要です。しかし,ntpd
は一般ユーザであるntp
ユーザ権限で動作しており,ntpd
で使うポートである123番ポートは使えないはずです。しかし,cap_
を持っているので123番ポートを使えます。
また,cap_
を持っていますので,
つまりntpd
は必要最低限のケーパビリティのみを持った状態で実行されているということです。不要な特権を持たずにデーモンが実行されていますので,