Sudo
は内部的にどのように機能しますか? su
とは異なり、rootパスワードがなくてもrootになることができるのはなぜですか?プロセスにはどのシスコールなどが関係していますか? Linuxの大きなセキュリティホールではありませんか(たとえば、通常のSudo
と同じように、パッチを頻繁に適用したSudo
をコンパイルできなかったが、非特権ユーザーのパスワードを要求しなかったのはなぜですか? )?
login and su internals を読みました。私も読みました Sudoはどのように使用される予定ですか? ですが、タイトルにもかかわらず、主にsu
とSudo
の違いを扱います。
実行ファイルSudo
を見てみると、
$ which Sudo
/usr/bin/Sudo
$ ls -la /usr/bin/Sudo
---s--x--x 2 root root 208808 Jun 3 2011 /usr/bin/Sudo
許可ビット---s--x--x
が付いていることに気づくでしょう。これらは次のように分類できます。
-|--s|--x|--x
- - first dash denotes if a directory or a file ("d" = dir, "-" = file)
--s - only the setuid bit is enabled for user who owns file
--x - only the group execute bit is enabled
--x - only the other execute bit is enabled
したがって、プログラムでsetuidビットが有効(SUIDとも呼ばれる)になっている場合、誰かがこのプログラムを実行すると、ファイルを所有するユーザーの資格情報(別名)で実行されることを意味します。この場合はrootです。
ユーザーsamlとして次のコマンドを実行すると、
$ whoami
saml
$ Sudo su -
[Sudo] password for saml:
Sudo
の実行が実際にはrootとして実行されていることがわかります。
$ ps -eaf|grep Sudo
root 20399 2353 0 05:07 pts/13 00:00:00 Sudo su -
SUIDの仕組みに興味がある場合は、man setuid
をご覧ください。これは、私が説明できるよりもよく説明されているmanページからの抜粋です。
setuid()は、呼び出しプロセスの実効ユーザーIDを設定します。呼び出し元の実効UIDがrootの場合、実際のUIDと保存されたset-user-IDも設定されます。 Linuxでは、setuid()は_POSIX_SAVED_IDS機能を備えたPOSIXバージョンのように実装されています。これにより、set-user-ID(root以外)プログラムは、すべてのユーザー特権を削除し、いくつかの非特権作業を行ってから、元の有効なユーザーIDを安全な方法で再利用できます。
ユーザーがrootであるか、プログラムがset-user-ID-rootである場合は、特別な注意が必要です。 setuid()関数は、呼び出し元の実効ユーザーIDをチェックし、それがスーパーユーザーである場合、すべてのプロセス関連のユーザーIDはuidに設定されます。これが発生した後、プログラムがroot権限を取り戻すことはできません。
ここでの重要な概念は、プログラムには実際のユーザーID(UID)と有効なユーザーID(EUID)があるということです。このビットが有効な場合、Setuidは実効ユーザーID(EUID)を設定しています。
したがって、カーネルの観点からは、この例ではsaml
がまだ元の所有者(UID)であることがわかっていますが、EUIDは実行可能ファイルの所有者であるユーザーに設定されています。
また、Sudoコマンドのアクセス許可を分解する場合、2番目のビットグループはグループアクセス許可用であったことにも触れておきます。グループビットには、setuidに似たセットグループID(別名setgid、SGID)もあります。これは、所有者の資格情報ではなくグループの資格情報を使用してプロセスを実行することを除いて、SUIDと同じことを行います。
実際のSudo
バイナリは setuid root であり、この方法で設定されたファイルを存在させることはできません。
setuidおよびsetgid(それぞれ「実行時にユーザーIDを設定する」および「実行時にグループIDを設定する」の略)[1]は、ユーザーが実行可能ファイルの所有者またはグループの権限で実行可能ファイルを実行できるようにするUnixアクセス権フラグです。ディレクトリの動作を変更します。
誰も触れていないように見えるsyscallに関する部分に答えるために、重要なsyscallの1つはsetresuid()またはsetresgid()のいずれかです。他にもあると思いますが、これら2つはsetuid/Sudoにかなり特有のようです。