ケイパビリティ
ケイパビリティ (POSIX 1003.1e, capabilities(7)) はスーパーユーザー権限の細かい制御を提供することで、root ユーザーの使用を減らすことができます。ソフトウェアの開発者は、システムバイナリの強力な setuid 属性を、より最低限のケイパビリティのセットに置き換えることが推奨されています。多数のパッケージがケイパビリティを利用しており、例えば CAP_NET_RAW
は fping バイナリで使われています。これによって (setuid と同じように) 通常ユーザーで fping
を実行することができ、それと同時に、fping
に脆弱性があった場合のセキュリティ上の影響を緩和することができます。
実装
Linux ではケイパビリティは拡張属性 (xattr(7)) の security 名前空間を使って実装されています。拡張属性は Ext2、Ext3、Ext4、Btrfs、JFS、XFS、そして Reiserfs など全ての主要な Linux ファイルシステムでサポートされています。以下の例では getcap
を使って fping のケイパビリティを出力し、さらに getfattr
を使ってエンコードされた同じデータを出力しています:
$ getcap /usr/bin/fping
/usr/bin/fping cap_net_raw=ep
$ getfattr --dump --match="^security\\." /usr/bin/fping
# file: usr/bin/fping security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=
一部のプログラムは拡張属性を自動的にコピーしますが、他のプログラムでは特別なフラグが必要です。両方のクラスの例については、拡張属性# 拡張属性を保持するを参照してください。
Arch では、ケイパビリティは パッケージインストールスクリプト によって設定されます。例としては fping.install が挙げられます。
管理とメンテナンス
パッケージが過度に強力なケイパビリティを持っている場合はバグと考えられます。なので、ここに記載するのではなくバグとして報告してください。Arch は MAC/RBAC システムをサポートしていないため、root アクセスと本質的に等価なケイパビリティ (CAP_SYS_ADMIN
) や root アクセスを容易にするケイパビリティ (CAP_DAC_OVERRIDE
) はバグではありません。
ケイパビリティを利用できる他のプログラム
以下のパッケージには setuid 属性が設定されたファイルがありませんが、実行するには root 権限を必要とします。ケイパビリティを有効にすることで、権限昇格を行わなくても通常ユーザーでプログラムを使うことが可能になります。
ケイパビリティの後ろにある +ep
は、ケイパビリティセットの effective と permitted を示しています。詳細は capabilities(7) § File capabilities を参照してください。
プログラム | コマンド(root で実行) |
---|---|
Beep | setcap cap_dac_override,cap_sys_tty_config+ep /usr/bin/beep
|
chvt(1) | setcap cap_dac_read_search,cap_sys_tty_config+ep /usr/bin/chvt
|
iftop(8) | setcap cap_net_raw+ep /usr/bin/iftop
|
mii-tool(8) | setcap cap_net_admin+ep /usr/bin/mii-tool
|
mtr(8) | setcap cap_net_raw+ep /usr/bin/mtr-packet
|
nethogs(8) | setcap cap_net_admin,cap_net_raw+ep /usr/bin/nethogs
|
wavemon(1) | setcap cap_net_admin+ep /usr/bin/wavemon
|
便利なコマンド
setuid-root ファイルを検索:
$ find /usr/bin /usr/lib -perm /4000 -user root
setgid-root ファイルを検索:
$ find /usr/bin /usr/lib -perm /2000 -group root
ケイパビリティを一時的に付与してプログラムを実行する
capsh(1) を使用すると、バイナリの拡張属性を変更せずに、特定のケイパビリティを持つプログラムを実行することが可能です。以下の例では、CAP_SYS_PTRACE
ケイパビリティを使用して GDB を使用してプロセスにアタッチする方法を示しています:
$ sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_sys_ptrace+eip" --keep=1 --user="$USER" --addamb="cap_sys_ptrace" --shell=/usr/bin/gdb -- -p <pid>
上記の sudo
に渡される -E
は、現在のユーザーのログイン環境、たとえば PATH
変数などを子プロセスに引き継ぐために使用されます。
以下は、netcat を使用して低いポート、今回は 123 にバインドする例です:
$ sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_net_bind_service+eip" --keep=1 --user="$USER" --addamb="cap_net_bind_service" --shell=/usr/bin/nc -- -lvtn 123 Listening on 0.0.0.0 123
上記の例はどちらも実際には説明目的のものであり、ほとんどのシステムでは、他のユーザーが所有するプロセスにデバッガーをアタッチするか、root ユーザーとしてポート 1024 未満を開くことが可能です。それでも、capsh
を使用することはある程度のセキュリティメリットを提供します。なぜなら、capsh --user
は指定されたユーザーとして、通常のカーネルケイパビリティ(つまり、制限)を持って実行されるためです。
systemd
AmbientCapabilities
と CapabilityBoundingSet
を使用することで、systemd ユニットにケイパビリティを割り当てることが可能です。これは、バイナリにケイパビリティを設定するよりも安全です。詳細は systemd.exec(5) を参照してください。