UIDとsudoによる権限の委譲
実行主体が変わる箇所と、主体・コマンド・引数による許可の範囲を確かめます。
説明
Linuxのプロセスは利用者を表す資格情報を持ちます。実UIDは呼出し元の識別、実効UIDは多くの権限判定に関わり、set-user-ID付きの実行ファイルでは両者が異なる場合があります。sudoも、設定された規則に従って別の主体でコマンドを実行する仕組みです。
ayaとレポート専用の利用者reporterを使います。reporterとして動くプログラムのUIDを調べ、元のシェルへ戻った後の値を確認します。続いてsudoの許可一覧に合わせてコマンドを実行し、実行主体や引数を変えた場合の認可結果を比べます。
1呼び出した利用者のUID
ayaのシェルでidを実行し、UID・主グループ・補助グループを表示します。
id利用者とグループを表示UIDは1000、主グループは1000、追加でops=2000に所属しています。UIDは利用者名と対応する数値です。処理の権限を調べる際は、ログインした名前だけでなく、そのプロセスが持つ資格情報を確認します。
2set-user-IDの付いた実行ファイル
report-readerはreporter所有の小さな読取り用プログラムです。statで実行ファイルの種類・モード・所有者を表示します。
stat -c表示形式を指定 '%A %U %G'モード・所有者・グループ /usr/local/bin/report-reader対象の実行ファイル所有者の実行位置がsになり、set-user-IDが設定されています。所有者reporterのUIDは2001です。ここでは通常の実行可能バイナリで、nosuidやno_new_privs、トレースなどの抑制条件がないものとします。Linuxではスクリプトにset-user-IDビットを付けるだけでは同じ動作になりません。
3実行中の資格情報
report-readerの--identityは、この教材のプログラムが実UID・実効UID・保存UID・ファイルシステムUIDを表示する機能です。
/usr/local/bin/report-readerset-user-ID付きのプログラム --identity各UIDを表示実UID1000は呼出し元、実効UID2001は実行時の主体です。この条件では保存UIDとファイルシステムUIDも2001になります。Linuxのファイルアクセスではfsuidなどが使われ、通常は実効UIDに追随します。UIDの種類を一つの値として扱わないようにします。
4委譲された主体でファイルを読む
report.txtはreporter所有でmode400です。report-readerは指定されたレポートを読んで内容を出力します。
/usr/local/bin/report-reader委譲された主体で処理 /srv/report.txt読むレポートtotal=42が読めます。通常のayaには所有者向けrが適用されませんが、このプログラムのファイルアクセスはreporterとして行われます。委譲先プログラムの引数検査や処理内容も、利用者にできる操作の範囲を決めます。
5元のシェルの主体
プログラムが終わった後、元のシェルで実効UIDを表示します。
id -u元のシェル側の実効UID1000のままです。子として起動したプログラムの資格情報が変わっても、呼び出したシェルのUIDが同じように書き換わるわけではありません。
6sudoの実行対象と引数の範囲
今度はsudoの許可一覧を読みます。ayaに許可された実行主体とコマンドを確認します。
sudo -l委譲された操作の一覧reporterとして/usr/bin/cat /srv/report.txtを実行する規則です。括弧内は実行主体で、常にrootとは限りません。この例は引数まで指定した規則であり、任意のcatや任意のファイルを読む許可ではありません。
7許可された主体と引数で実行
一覧の通り、reporterとしてレポートを読みます。認証済みの状態から始めます。
sudo -u reporter実行主体を指定 /usr/bin/cat許可されたプログラム /srv/report.txt許可された引数total=42が表示されます。sudoは規則に従って実行主体を設定し、指定コマンドを起動します。ファイルに対する通常の権限判定も、その実行主体の資格情報で行われます。
8実行主体だけを変えた場合
同じコマンドをrootとして要求します。reporterとしての許可がrootにも広がるかを確認します。
sudo -u root許可外の実行主体 /usr/bin/cat /srv/report.txtコマンドと引数は同じrootとしての実行は拒否されます。認証済みであっても、選んだ実行主体が許可規則に合う必要があります。実行する利用者、対象主体、コマンド、引数をそれぞれ照合します。
9引数だけを変えた場合
主体をreporterへ戻し、読むファイルだけprivate.txtへ変更します。
sudo -u reporter許可された主体 /usr/bin/cat同じプログラム /srv/private.txt許可外の引数引数が規則と違うため拒否されます。この例の拒否はファイルを開く前のsudoの認可によるもので、private.txtの所有者やモードを判定した結果とは異なります。
まとめ
呼出し元の実UIDと、実行中の実効UIDなどの資格情報は異なる場合があります。
子プログラムの資格情報変更は、元のシェルの主体をそのまま変更する操作ではありません。
sudoの許可は実行主体・コマンド・引数を含めて確認し、認証済みであることだけで判断しません。
操作履歴と解説を振り返れます。
Linux シェル / aya@lab
iduid=1000(aya) gid=1000(aya) groups=1000(aya),2000(ops)
stat -c '%A %U %G' /usr/local/bin/report-reader-rwsr-xr-x reporter reporter
/usr/local/bin/report-reader --identityreal UID: 1000 effective UID: 2001 saved UID: 2001 filesystem UID: 2001
/usr/local/bin/report-reader /srv/report.txttotal=42
id -u1000
sudo -lUser aya may run the following commands on lab:
(reporter) /usr/bin/cat /srv/report.txtsudo -u reporter /usr/bin/cat /srv/report.txttotal=42
sudo -u root /usr/bin/cat /srv/report.txtSorry, user aya is not allowed to execute '/usr/bin/cat /srv/report.txt' as root on lab.
sudo -u reporter /usr/bin/cat /srv/private.txtSorry, user aya is not allowed to execute '/usr/bin/cat /srv/private.txt' as reporter on lab.
演習完了