セキュリティ管理タスク - SUID 探索/lsof/ulimit/sudo【LPIC-1 110.1】
この記事で達成できること
findで SUID / SGID が設定された危険なファイルを洗い出せるlsofでオープン中のファイル・ネットワークポートを特定できるfuserでファイルやファイルシステムを使用中のプロセスを確認・停止できるulimitでソフト/ハードリミットの違いを理解しリソースを制限できるsudo/sudoersをvisudoで安全に設定できるwho/w/lastでログイン状況を監査できる
LPIC-1 主題 110.1「セキュリティ管理業務を実施する」の中核。権限昇格の温床となる SUID ファイルの監査、リソース枯渇攻撃を防ぐ ulimit、最小権限を実現する sudo を体系的に押さえる。
なぜ SUID ファイルの監査が重要なのか
SUID が設定された実行ファイルは、実行者ではなくファイル所有者(多くは root)の権限で動く。脆弱性があれば権限昇格に直結するため、定期的な洗い出しが不可欠だ。
| ビット | 8 進数 | 意味 | 探索コマンド |
|---|---|---|---|
| SUID | 4000 |
所有者権限で実行(passwd 等) |
find / -perm -4000 |
| SGID | 2000 |
グループ権限で実行 / ディレクトリ継承 | find / -perm -2000 |
| Sticky | 1000 |
/tmp 等で他人のファイル削除を防止 |
find / -perm -1000 |
-perm の先頭の -(マイナス)は「指定したビットがすべて立っている」を意味する。-perm 4000(マイナスなし)は「パーミッションが完全一致」、-perm /4000 は「いずれかが立っている」となり挙動が異なる点に注意。
身に覚えのない SUID ファイル(特に /tmp や一般ユーザーのホーム配下)は権限昇格の侵入経路になり得る。基準値を find で取得し、差分を定期監査する運用が望ましい。
手順
Step 1: SUID / SGID ファイルを探索する
find / -perm -4000 -type f 2>/dev/null find / -perm -2000 -type f 2>/dev/null find / -perm -u=s -o -perm -g=s -type f 2>/dev/null
/usr/bin/passwd /usr/bin/sudo /usr/bin/su /usr/bin/mount /usr/bin/chsh
-perm -4000 は SUID、-perm -2000 は SGID を持つファイルを抽出する。シンボル表記 -perm -u=s(SUID)・-perm -g=s(SGID)でも同じ探索ができる。2>/dev/null で権限のないディレクトリのエラーを抑制する。
Step 2: lsof でオープンファイルとポートを調べる
lsof -i :22 lsof -p 1234 lsof -u alice
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 812 root 3u IPv4 18293 0t0 TCP *:ssh (LISTEN)
lsof -i :22 はポート 22 を使うプロセス、-p PID は特定プロセスが開くファイル、-u user はユーザーのオープンファイルを一覧する。-i TCP や -i @host のようにプロトコルやホストでも絞り込める。
Step 3: fuser で使用中プロセスを特定・停止する
fuser -v /var/log/syslog fuser -m /mnt/data fuser -k -m /mnt/data
USER PID ACCESS COMMAND /var/log/syslog: root 812 F.... rsyslogd
fuser -v file はファイルを開いているプロセスを ps 風に表示する。-m は引数をマウントされたファイルシステムとして扱い、そのファイルシステム上のファイルを使う全プロセスを対象にする。-k はそれらに SIGKILL を送る。アンマウント前に「device is busy」を解消する用途で使う。
fuser -k -m はファイルシステムを使う全プロセスを強制終了する。アンマウントしたい対象を誤ると無関係なプロセスまで巻き込む。実行前に必ず -k なしで対象を確認すること。
Step 4: ulimit でリソース制限を確認・設定する
ulimit -a ulimit -Sn ulimit -Hn ulimit -n 2048
open files (-n) 1024 max user processes (-u) 7860 ...
ulimit -a で全制限を一覧表示。-n はオープンできるファイル数、-u はユーザーのプロセス数。-S がソフトリミット(現在値)、-H がハードリミット(上限)。一般ユーザーはソフトをハード以下に変更できるが、ハードを引き上げられるのは root のみ。
恒久的に設定するには /etc/security/limits.conf を編集する。
# /etc/security/limits.conf # <domain> <type> <item> <value> alice soft nofile 4096 alice hard nofile 8192 @developers hard nproc 100
type に soft / hard、item に nofile(ファイル数)・nproc(プロセス数)等を指定。@グループ名 でグループ単位の制限も可能。
Step 5: visudo で sudo 権限を設定する
visudo
# /etc/sudoers alice ALL=(ALL:ALL) ALL %admin ALL=(ALL) ALL %developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
visudo は /etc/sudoers を文法チェック付きで編集する専用コマンド。%グループ名 でグループに権限を付与、NOPASSWD: でパスワード入力を省略できる。設定後は対象ユーザーで sudo -l で確認する。
sudo -l
User alice may run the following commands on host:
(ALL : ALL) ALL
/etc/sudoers を vi 等で直接編集すると、文法エラーがあっても保存できてしまい sudo 全体が機能停止する(自分も root になれなくなる)。必ず visudo を使うこと。visudo は保存時に文法を検証し、エラーがあれば再編集を促す。
su と su - の違い、ログイン監査
su と su - の差は 環境変数とカレントディレクトリの引き継ぎ にある。su user(オプションなし)は元ユーザーの環境変数の多くを保持したまま切り替えるが、su - user(ハイフン付き、su -l と同義)はログインシェルを起動し、対象ユーザーの PATH・HOME・初期化ファイルを完全に読み込む。root に切り替えて作業するときは su - が安全で、PATH 由来のコマンド誤実行を避けられる。
ログイン状況の監査には次のコマンドを使う。
| コマンド | 表示内容 | データソース |
|---|---|---|
who |
現在ログイン中のユーザー | /var/run/utmp |
w |
ログイン中ユーザー + 実行中プロセス・負荷 | /var/run/utmp |
last |
ログイン履歴(再起動含む) | /var/log/wtmp |
lastlog |
各ユーザーの最終ログイン日時 | /var/log/lastlog |
不審なログインの追跡は last と lastlog が基本。あわせて chage -l user でパスワード有効期限を確認すれば、放置アカウントの棚卸しができる。
chage -l alice
Last password change : May 01, 2026 Password expires : Jul 30, 2026 Account expires : never
ネットワーク側の確認では nmap でホストの開いているポートをスキャンできる(nmap localhost 等)。自組織以外への無断スキャンは不正アクセス行為に該当し得るため、許可された対象のみに使うこと。
よくあるミスと対処
sudoersを直接編集して破損:vi /etc/sudoersで誤った文法を保存すると sudo が完全に使えなくなる。必ずvisudoを使う。破損した場合はpkexecやレスキューモードで修復する。- ソフト/ハードリミットの混同: 一般ユーザーがハードリミットを超えて
ulimit -nを上げようとしてOperation not permittedになる。ハード引き上げは root +/etc/security/limits.conf。 - SUID の危険性を軽視: 自作スクリプトに安易に SUID を付けると権限昇格の穴になる。シェルスクリプトの SUID は多くの環境で無視されるが、依存コマンドの脆弱性は残る。
suとsu -の取り違え:suのみで root 化すると元ユーザーの環境が残り、PATH上の意図しないコマンドを root 実行してしまう恐れ。管理作業はsu -を使う。find -perm 4000と-perm -4000の混同: マイナスなしは「完全一致」のため、rwsr-xr-xのような実際の SUID ファイルがヒットしない。監査では先頭マイナス必須。
トラブルシューティング
症状: アンマウントしようとして「device is busy」
原因: そのファイルシステム上のファイルを開いているプロセスが残っている
確認:
fuser -vm /mnt/data lsof +D /mnt/data
対処: プロセスを特定して正常終了させる。やむを得ない場合のみ fuser -k -m /mnt/data で強制終了するが、対象を必ず事前確認する。
症状: アプリが「Too many open files」で落ちる
原因: オープンファイル数がソフトリミット(nofile)に達している
確認:
ulimit -Sn lsof -p PID | wc -l
対処: ulimit -n で当該シェルのソフトリミットを引き上げる。恒久対応は /etc/security/limits.conf に nofile を追記し、再ログインで反映する。
症状: sudo 実行時に毎回パスワードを求められて自動化できない
原因: 対象ユーザー/コマンドに NOPASSWD: が設定されていない
確認:
sudo -l
対処: visudo で特定コマンドに限定して NOPASSWD: を付与する。ALL への無条件 NOPASSWD はセキュリティ上避け、必要なコマンドのみに絞る。
作業完了チェックリスト
- [ ]
find / -perm -4000 -type fで SUID ファイルを洗い出した - [ ]
lsof -iでリッスン中のポートを確認した - [ ]
fuser -mで使用中プロセスを特定できることを確認した - [ ]
ulimit -aでソフト/ハードリミットの違いを把握した - [ ]
visudoで sudoers を安全に編集する手順を確認した - [ ]
who/w/lastでログイン監査ができることを確認した
まとめ
| 場面 | コマンド | 目的 |
|---|---|---|
| SUID/SGID 監査 | find / -perm -4000 -type f |
権限昇格リスクの洗い出し |
| ポート確認 | lsof -i :PORT |
リッスン中プロセスの特定 |
| 使用中プロセス | fuser -vm /mount |
アンマウント阻害要因の特定 |
| リソース制限 | ulimit -Sn / -Hn |
ソフト/ハードの確認・設定 |
| sudo 設定 | visudo |
文法検証付き sudoers 編集 |
| ログイン監査 | who / w / last |
ログイン状況・履歴の確認 |
セキュリティ管理は「権限の最小化」と「異常の可視化」が両輪。SUID 監査・sudo の最小権限・ulimit のリソース保護を押さえたら、暗号化やホスト堅牢化と組み合わせて防御を完成させる。