コンテンツにスキップ

Unix socket とファイルディスクリプタ

Unix ドメインソケットの所有者・グループ・アクセス権と、高権限プロセスが開いたファイルディスクリプタは、ファイルのパスとは異なる権限境界になる。ソケットの発見手順はネットワークと IPCにまとめた。

ターミナルウィンドウ
ss -lxnp
find /run /var/run -maxdepth 3 -type s -ls 2>/dev/null
ls -l /run/<app>/<name>.sock
  • socket の group と mode により、別ユーザーだけが管理 API へ接続できる。
  • daemon が高権限で開いた file descriptor を渡す。または privileged action を受け付ける。
ターミナルウィンドウ
id
stat /run/<app>/<name>.sock
lsof -U | grep <app>
  • 目的: 接続できるユーザー、daemon の実行ユーザー、socket とプロセスの対応を確認する。
  • 前提条件: ソケットへの接続で処理が始まる場合がある。先に実装やプロトコルを読む。
  • 出力の解釈: srw-rw---- root group なら、グループへの所属が接続権限を決める。SCM_RIGHTS では、パス権限では読めないファイルのディスクリプタを渡せる。
  • 失敗した場合の切り分け: group の不一致、socket path の間違い、daemon の停止、abstract namespace socket。
  • 代替: socat - UNIX-CONNECT:<sock> は、接続自体が状態変更になり得る。実装を読んでから使う。
  • 状態変更: stat は読み取り。接続はアプリ次第で状態変更になる。

/proc/<PID>/fd は、パスの権限とは異なる経路で開かれたファイルを調べる手掛かりになる。同一ユーザーか高権限でないと読めないことがあり、読めないこと自体も権限境界の情報になる。プロセスの調べ方はプロセスと systemdを参照する。

低権限ユーザーから ss と ps で、root daemon と /run/<app>/<name>.sock を対応付ける。daemon がログ中の検知語で lockdown に入り、socket と SCM_RIGHTS で設定ファイルの FD を渡す実装では、パス権限では読めない root のファイルを受け取れる。

ログに検知語
↓
root daemon の lockdown
↓
Unix socket / SCM_RIGHTS
↓
秘密ファイルの FD
↓
高権限ファイルの読み取り

接続前に、group membership と実装を確認する。プロトコルを読まずにソケットへ入力を送らない。