SUID/SGID/Sticky bit - 特殊権限ビットを理解する
SUID/SGID/Sticky bit とは?
特殊権限ビット(SUID・SGID・Sticky bit)は、通常の rwx 権限に加えて設定できる 3 種類の特殊フラグ。passwd のような root 権限が必要なコマンドを一般ユーザーが実行できる仕組みや、共有ディレクトリで他のユーザーのファイルを削除させない仕組みはこれで実現されている。
| ビット | 数値 | 設定対象 | 主な用途 |
|---|---|---|---|
| SUID | 4 | 実行ファイル | 所有者の権限(UID)で実行させる |
| SGID | 2 | 実行ファイル・ディレクトリ | グループ権限の継承 |
| Sticky bit | 1 | ディレクトリ | 自分のファイルだけ削除可能にする |
SUID(Set User ID)とは?
SUID が設定された実行ファイルは、実行したユーザーの権限ではなく、ファイル所有者の権限で動作する。
/usr/bin/passwd が典型例。一般ユーザーが自分のパスワードを変更できるのは、passwd に SUID が設定されており root 権限で動作するためだ。
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 59976 Mar 22 2024 /usr/bin/passwd
所有者の x 位置が s になっているのが SUID の印。
SUID を設定・解除する
# SUID を設定(シンボリック記法) $ chmod u+s /path/to/file # SUID を設定(数値記法: 4XXX の形) $ chmod 4755 /path/to/file # SUID を解除 $ chmod u-s /path/to/file
SUID はセキュリティリスクを伴う。不必要なファイルへの設定は避け、定期的に棚卸しを行う。
# システム全体の SUID ファイルを検索 $ find / -perm -4000 -type f 2>/dev/null
SGID(Set Group ID)とは?
SGID の動作は設定対象によって異なる。実行ファイルに設定した場合は所有グループの権限で動作し、ディレクトリに設定した場合は配下のファイルがそのグループを継承する。
実行ファイルへの SGID
$ ls -l /usr/bin/write
-rwxr-sr-x 1 root tty 14952 Mar 30 2023 /usr/bin/write
グループの x 位置が s になっているのが SGID の印。
ディレクトリへの SGID
チーム共有ディレクトリで特に有効。SGID を付けると、新規ファイルがディレクトリのグループを継承する。
# 共有ディレクトリに SGID を設定 $ chmod g+s /shared/project # 確認 $ ls -ld /shared/project
drwxrwsr-x 2 user devteam 4096 Jun 1 12:00 /shared/project
このディレクトリ内に作成したファイルは、作成者のプライマリグループではなく devteam グループになる。
$ touch /shared/project/newfile.txt $ ls -l /shared/project/newfile.txt
-rw-r--r-- 1 alice devteam 0 Jun 1 12:00 /shared/project/newfile.txt
SGID の設定コマンド
# シンボリック記法 $ chmod g+s /path/to/dir # 数値記法(2XXX の形) $ chmod 2775 /path/to/dir
Sticky bit とは?
Sticky bit はディレクトリに設定し、そのディレクトリ内のファイルを所有者以外が削除・改名できなくする。world-writable な共有ディレクトリで他ユーザーのファイルを保護するために使う。
/tmp が典型例。誰でも書き込めるが、自分のファイルしか削除できない。
$ ls -ld /tmp
drwxrwxrwt 17 root root 4096 Jun 1 12:00 /tmp
その他ユーザー(others)の x 位置が t になっているのが Sticky bit の印。
Sticky bit を設定・解除する
# Sticky bit を設定(シンボリック記法) $ chmod +t /shared/dir # Sticky bit を設定(数値記法: 1XXX の形) $ chmod 1777 /shared/dir # Sticky bit を解除 $ chmod -t /shared/dir
動作確認:
$ mkdir /tmp/testdir && chmod 1777 /tmp/testdir $ ls -ld /tmp/testdir
drwxrwxrwt 2 user group 40 Jun 1 12:00 /tmp/testdir
数値記法でまとめて設定する
特殊ビットと通常権限を組み合わせる場合、4 桁の数値で指定する。先頭の桁が特殊ビット(SUID=4、SGID=2、Sticky=1 の合計)。
| 設定 | 数値 | コマンド例 |
|---|---|---|
| SUID のみ | 4755 | chmod 4755 file |
| SGID のみ | 2755 | chmod 2755 dir |
| Sticky bit のみ | 1777 | chmod 1777 dir |
| SUID + SGID | 6755 | chmod 6755 file |
# SUID 付き(owner=rwx, group=rx, others=rx) $ chmod 4755 myprogram # SGID 付き共有ディレクトリ(owner=rwx, group=rwx, others=rx) $ chmod 2775 shared_dir
ls -l での表示の読み方
特殊ビットは ls -l の出力で確認できる。x が置き換わる位置に注目する。
-rwsr-xr-x → SUID あり(owner の x が s) -rwxr-sr-x → SGID あり(group の x が s) drwxrwxrwt → Sticky bit あり(others の x が t) -rwSr--r-- → SUID あり・owner に実行権限なし(大文字 S) -rwxr-Sr-- → SGID あり・group に実行権限なし(大文字 S) drwxrwxrwT → Sticky bit あり・others に実行権限なし(大文字 T)
小文字 s / t → 特殊ビットと実行権限の両方が設定されている
大文字 S / T → 特殊ビットはあるが実行権限がない(多くの場合は設定ミス)
find コマンドで特殊ビットが設定されたファイルを一覧できる。
# SUID が設定されたファイルを検索 $ find / -perm -4000 -type f 2>/dev/null # SGID が設定されたファイル・ディレクトリを検索 $ find / -perm -2000 2>/dev/null # Sticky bit が設定されたディレクトリを検索 $ find / -perm -1000 -type d 2>/dev/null
セキュリティ上の注意点
特殊権限ビットは利便性と引き換えにセキュリティリスクをはらむ。
SUID/SGID の設定は最小限に
不要な SUID/SGID ファイルは権限昇格攻撃に利用される。シェルスクリプトへの SUID 設定は Linux では効力を持たないが、意図しない誤解を招くため設定しないこと。
SUID ファイルの定期監査
# SUID/SGID ファイルを一覧してベースラインを記録する $ find / -perm /6000 -type f 2>/dev/null > /tmp/suid_baseline.txt
定期的に実行して差分を確認することで、不正に追加された SUID ファイルを検出できる。