Linuxのケーパビリティを使用する


導入


能力セットとセットを構成するビットに関する議論でした.また、スレッドとプロセスのケーパビリティセットをどのように検証できるかを見ました.このポストでは、システムによって管理されたプロセスに対するケーパビリティのアプリケーションを見ていきます.

システム


Systemdは、最新のLinuxディストリビューションでのデフォルトのシステムとサービスマネージャです.ブート( PID 1 )の最初のプロセスとして実行すると、起動時にユーザ空間サービスの操作を管理します.initシステムとして、systemdプロセスは、有効なユーザーID 0で実行されます.
(base) boye@hp7940m1:~$ ps -fp 1
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 Aug16 ?        00:00:41 /sbin/init splash
(base) boye@hp7940m1:~$ 

SystemMDで管理されているプロセスのケーパビリティセットと、デフォルトの動作を変更する設定の設定を調べるには、便利な小さなPythonスクリプトを使用します.このスクリプトはgithub . このリポジトリには、デモンストレーションのために使用する他のファイルもあります.READMEmdファイルには、これらのファイルの説明とインストール手順があります.
CapHand表示スクリプトは/usr/include/linux/capabilityをスクロールします.hファイル名とその値の間のマッピングを作成する.また、/proc/pid/statusファイルのPIDに設定されているケーパビリティの16進数表現を読み込み、マッピングを使用して、ケーパビリティセットの人間に優しい表現を出力します.
(capabilities_show) (base) boye@hp7940m1:~/Documents/dev/capabilities_show$ cap_display --pid 1
Name:   systemd
Tgid:   1
Pid:    1
PPid:   0
Uid:    0       0       0       0
Gid:    0       0       0       0

CapInh:  0000000000000000        None
CapPrm:  0000003fffffffff        cap_audit_read,cap_block_suspend,cap_wake_alarm,cap_syslog,cap_mac_admin,cap_mac_override,cap_setfcap,cap_audit_control,cap_audit_write,cap_lease,cap_mknod,cap_sys_tty_config,cap_sys_time,cap_sys_resource,cap_sys_nice,cap_sys_boot,cap_sys_admin,cap_sys_pacct,cap_sys_ptrace,cap_sys_chroot,cap_sys_rawio,cap_sys_module,cap_ipc_owner,cap_ipc_lock,cap_net_raw,cap_net_admin,cap_net_broadcast,cap_net_bind_service,cap_linux_immutable,cap_setpcap,cap_setuid,cap_setgid,cap_kill,cap_fsetid,cap_fowner,cap_dac_read_search,cap_dac_override,cap_chown
CapEff:  0000003fffffffff        cap_audit_read,cap_block_suspend,cap_wake_alarm,cap_syslog,cap_mac_admin,cap_mac_override,cap_setfcap,cap_audit_control,cap_audit_write,cap_lease,cap_mknod,cap_sys_tty_config,cap_sys_time,cap_sys_resource,cap_sys_nice,cap_sys_boot,cap_sys_admin,cap_sys_pacct,cap_sys_ptrace,cap_sys_chroot,cap_sys_rawio,cap_sys_module,cap_ipc_owner,cap_ipc_lock,cap_net_raw,cap_net_admin,cap_net_broadcast,cap_net_bind_service,cap_linux_immutable,cap_setpcap,cap_setuid,cap_setgid,cap_kill,cap_fsetid,cap_fowner,cap_dac_read_search,cap_dac_override,cap_chown
CapBnd:  0000003fffffffff        cap_audit_read,cap_block_suspend,cap_wake_alarm,cap_syslog,cap_mac_admin,cap_mac_override,cap_setfcap,cap_audit_control,cap_audit_write,cap_lease,cap_mknod,cap_sys_tty_config,cap_sys_time,cap_sys_resource,cap_sys_nice,cap_sys_boot,cap_sys_admin,cap_sys_pacct,cap_sys_ptrace,cap_sys_chroot,cap_sys_rawio,cap_sys_module,cap_ipc_owner,cap_ipc_lock,cap_net_raw,cap_net_admin,cap_net_broadcast,cap_net_bind_service,cap_linux_immutable,cap_setpcap,cap_setuid,cap_setgid,cap_kill,cap_fsetid,cap_fowner,cap_dac_read_search,cap_dac_override,cap_chown
CapAmb:  0000000000000000        None
(capabilities_show) (base) boye@hp7940m1:~/Documents/dev/capabilities_show$ 

スクリプトを使っているPID 1の試験です.ここでは、UIDとGID = 0を見ることができます、そして、効果的で、許されて、制限された能力はプロセスにセットします.すべてのビットを設定します.これはeuid = 0のプロセスに対して期待される.
Systemdによって管理されたサービスのために設定された能力に影響を及ぼすことができるSystemd Unitファイルの3つの設定オプションを見ています.これらはユーザー、環境変数、capabilityBoundingSetオプションです.

システム管理のデフォルト動作


現在の時刻を示すダミーサービスユニットの観点から、systemdによって管理されるプロセスの動作を探ります.このサービスは、ポストシリーズで見つけることができますrepository . コードは、この例の1つから適応されますbook .
実行可能ファイルを実行し、以下のようにTCPポート番号を指定することで、最先端のサービスを実行します
(base) boye@hp7940m1:~/go/bin$ ./DayTimeServer 1021
Fatal Error: listen tcp :1021: bind: permission denied
(base) boye@hp7940m1:~/go/bin$ 

特権のないユーザが1024の下でポート番号を使用できないので、上記の失敗で驚きません.TCPポート1029でサービスを開始する.
(base) boye@hp7940m1:~/go/bin$ ./DayTimeServer 1029

(base) boye@hp7940m1:~/go/bin$ nc localhost 1029
2021-08-17 21:29:47.570860654 +1200 NZST m=+50.203298522
(base) boye@hp7940m1:~/go/bin$  

我々は、サーバーをプローブするためにNCユーティリティを使用して日付と時刻を取得します.

特権のない港
我々は現在、以下の単位ファイル構成を使用してシステム管理されたサービスとしてサーバーを実行します.
(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 3000

[Install]
WantedBy=multi-user.target

プロセスがTCPポート3000で動いているのを見ることができます.

Systemdのようなケーパビリティセットは、有効な機能セットビットをすべて有効にしている.

特権ポート
私たちは、同じ特権ポート1021で同じサービスを実行しようとします
(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 1021

[Install]
WantedBy=multi-user.target


我々は、それが正常に実行され、プロセスIDの検査は、すべての有効な機能ビットが設定されていることを示しています.
要約すると、システムによって管理されるプロセスは、デフォルトで有効になっているすべての権限で実行されます.

ユーザオプションを持つシステム単位のファイル


我々は現在、同じバイナリサービスを実行しますが、我々は非特権ユーザーにユーザーを設定されます.以下はシステムサービス単位ファイルです.
(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_user.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 3001
User=boye

[Install]
WantedBy=multi-user.target


上記の出力から、このプロセスに有効な機能ビットが設定されていないことがわかる.

EnvirentCapabilityオプションを持つシステム単位のファイル


今上司はちょうど昼間のサービスアプリケーションのビジネスで私たちの最大の競合他社がちょうどバーを調達したことを知らされた.彼らはサービスを特権ポートで実行できるようにします.サービスユニットファイルのアンビエント機能オプションを使用して、この機能をサービスに追加できます.
(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_user_net_bind.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 105
User=boye
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
上の単位ファイルでは、TCPポート105でサービスを実行しようとしています.そして、アンビエントケーパビリティセットでCapchy NetHand BindDirサービスビットを設定します.この機能は、非特権のユーザに1024以下のネットワークポートにバインドする権限を与えます.


上記の出力から、プロセスが通常のユーザによって所有されていても、EnvirentCapacityオプションを使用することでプロセスが特権ポート番号にバインドすることができます.プロセスIDのためのCapHand表示出力は、有効な能力セットのCapchy NetThand BindDirサービスビットが有効になったことを示します.
アンビエントケーパビリティセットは、親プロセス(systemd、pid 1)から特権をサービスプロセスに転送するために使用される.

CapabilityBoundingSetオプションを持つシステム単位のファイル


我々がこのポストで探索する最終的なオプションは特にプロセスのためにユーザーを変更したくない状況のために有用です、しかし、我々はちょうどプロセスが必要な特権に制限されることを望みます.サービス単位ファイルのcapabilityBoundingSetオプションは、親プロセスから子プロセスへ転送されることができる制限セットとして機能します.
私たちは効果的に制限された能力セットのすべてのビットを無効にするサービス単位ファイルを使用することによって、効果を見ます.
(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_limited.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 3002
CapabilityBoundingSet=

[Install]
WantedBy=multi-user.target


CapHandディスプレイ出力から、特権ユーザーとして実行されているプロセスにもかかわらず、有効なパーミッションセットがないことがわかります.特権ポートを使用しようとすると、以下のように失敗します.
(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_limited_privilege_port_attempt.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 108
CapabilityBoundingSet=

[Install]
WantedBy=multi-user.target

Systemdで起動して管理されたすべてのプロセスに対するすべての権限を与えるデフォルトの動作を変更するには、3つのオプションがありました.単位ファイルのcapabilityBoundingSetオプションは、rootとして実行されている子プロセスに渡すことができる機能を減少させるために使用できます.そして、アンビエンケイケーションズオプションは特権のないユーザーに属する子プロセスに特定の特権を与えるのに便利です.
次のポストはDockerユースケースを調査します.