root権限
root権限
The vulnerability, which is a signal handler race condition in OpenSSH’s server (sshd), allows unauthenticated remote code execution (RCE) as root on glibc-based Linux systems; that presents a significant security risk. This race condition affects sshd in its default configuration.
Linuxの権限
Windows や Macと同じくLinuxの権限もシステム管理権限と一般権限に分かれます。
通常の操作は一般権限であれば十分であり、特定の操作のみシステム権限が求められます。
この強いシステム管理権限を持ったユーザーを root ユーザー(スーパーユーザー)とよび、ユーザーID=0が割り振られています。
$ id root
uid=0(root) gid=0(root) groups=0(root)
一般ユーザーの ubuntu
と比較してみましょう
$ echo $USER # ログインユーザー
ubuntu
$ id $USER
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),119(netdev),120(lxd),999(docker)
出力から ubuntu
ユーザーは、以下の機能を使えるグループに属している事がわかります。
- 27(sudo)
- 999(docker)
su/sudo コマンドで強い権限で操作
サーバーを停止したり、HTTP通信用の80番ポートでウェブサーバーを起動するなど、サーバー全体に影響をあたえるような操作を行う場合、システム管理者権限が必要です。
このような場合に sudo
コマンドや su
コマンドを使います。
別ユーザー権限でコマンド実行するsudo
sudo
コマンドを利用すると、別ユーザーの権限でコマンドを実行できます。特に、root ユーザー権限でコマンド実行したい時に利用されます。
man
には “execute a command as another user” とあります。
Ubuntuでは systemd
というプログラムでプロセス管理されています。
一般ユーザー権限で、この systemd 経由で WebサーバーのApache(nginxの仲間)の再起動を試みると、権限不足のエラーが発生します。
$ systemctl restart apache2
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'apache2.service'.
Authenticating as: Ubuntu (ubuntu)
Password:
sudo
を接頭すると、root ユーザーとして実行されるため、再起動が成功します。
$ sudo systemctl restart apache2
$
一般には sudo
コマンド実行時には、ユーザーのパスワードが必要ですが、EC2 Ubuntuの場合は、ubuntu
ユーザーはパスワード無しに sudo
をよびだせる設定になっています。
$ sudo grep ubuntu /etc/sudoers
ubuntu ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot, /sbin/shutdown
別ユーザーに変わる su
コマンド単位で別ユーザーの権限で実行するかわりに、別ユーザーにかわって、コマンドをまとめて実行したい場合に su
コマンドを使います。
man
には “ run a command with substitute user and group ID” とあります。
$ su - # root ユーザーになる。`-` をつけることで、ログインシェルとしてログイン(=`~/.profile` などの初期化ファイルを読み込む)
Password:
$ su - sato # sato ユーザーになる
Password:
su
実行時には、切り替わる先のユーザーのパスワード入力が必要です。
EC2 Ubuntuの場合は、root
パスワードは初期設定されていないため、一度rootユーザーになってパスワードを設定する、あるいは、次のようにして sudo
経由で su
を呼び出すと、root
パスワードは不要です。
$ sudo su -
root@ip-172-31-34-13:~#
root@ip-172-31-34-13:~# echo $USER
root
Apache プロセスの場合
80番ポートで起動しているApache のプロセスを確認します
$ sudo lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 2529 root 4u IPv6 23786 0t0 TCP *:http (LISTEN)
apache2 2531 www-data 4u IPv6 23786 0t0 TCP *:http (LISTEN)
apache2 2532 www-data 4u IPv6 23786 0t0 TCP *:http (LISTEN)
apache2 2533 www-data 4u IPv6 23786 0t0 TCP *:http (LISTEN)
apache2 2534 www-data 4u IPv6 23786 0t0 TCP *:http (LISTEN)
apache2 2535 www-data 4u IPv6 23786 0t0 TCP *:http (LISTEN)
1~1024のポートを利用するネットワーク・サーバーの起動にはシステム管理者権限が必要です。
rootユーザーが80番ポートでApacheを起動し(PID=2529)、そこからの fork()
で、80番ポート番号のサーバーの起動、及び、 setuid
で実行ユーザーを root から www-data
に変更しています。
対応する pstree
結果も共有します。
├─apache2(2529)─┬─apache2(2531)
│ ├─apache2(2532)
│ ├─apache2(2533)
│ ├─apache2(2534)
│ └─apache2(2535)
Python の http
ライブラリを用い、-p
オプションでポートを指定して起動してみましょう。
一般ユーザーで80番ポートのプロセスを起動しようとすると、エラーが発生します
$ echo $USER
ubuntu
$ python3 -m http.server 80
Traceback (most recent call last):
File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/usr/lib/python3.10/http/server.py", line 1307, in <module>
test(
File "/usr/lib/python3.10/http/server.py", line 1258, in test
with ServerClass(addr, HandlerClass) as httpd:
File "/usr/lib/python3.10/socketserver.py", line 452, in __init__
self.server_bind()
File "/usr/lib/python3.10/http/server.py", line 1301, in server_bind
return super().server_bind()
File "/usr/lib/python3.10/http/server.py", line 137, in server_bind
socketserver.TCPServer.server_bind(self)
File "/usr/lib/python3.10/socketserver.py", line 466, in server_bind
self.socket.bind(self.server_address)
PermissionError: [Errno 13] Permission denied
sudo
でシステム管理者権限で起動したり、1024より大きなポート番号で起動する必要があります。
$ sudo python3 -m http.server 80
Serving HTTP on :: port 80 (http://[::]:80/) ...
$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
オプション:sudo の利用制限
Amazon EC2のAmazon LinuxやUbuntuでは、初期ユーザーは自由度高く sudo
を呼び出せて、ルート権限で色々操作できます。
実運用では、どのユーザーに sudo
を許可するか、どのコマンドを sudo
で実行できるか、といったことを詰める必要も出てきます。
発展:コンテナの実行ユーザー
Dockerコンテナではデフォルトでrootユーザーで実行されています。
このようなコンテナは、ホストから見ると、コンテナプロセスがrootで動作することになり、ホスト側にエスケープされた場合にホストのroot権限が取得されてしまうことになります。
そのため、UIDマッピングやRootlessモードの使用が推奨されます。
詳細は森田 浩平著『基礎から学ぶコンテナセキュリティ』の「4.3セキュアなコンテナイメージを作る」や「5.5コンテナ実行ユーザーの変更と権限昇格の防止」を参照ください。