File Permissions and ACLs
Linux ファイル権限と ACL - 包括的ガイド
目次
- はじめに
- 標準 Unix パーミッション
- 2.1 rwx の基本
- 2.2 8進数表記
- 2.3 ディレクトリに対するパーミッションの意味
- 権限変更コマンド
- 3.1 chmod - パーミッション変更
- 3.2 chown - 所有者変更
- 3.3 chgrp - グループ変更
- umask
- 特殊パーミッション
- 5.1 SUID (Set User ID)
- 5.2 SGID (Set Group ID)
- 5.3 Sticky Bit
- ACL (Access Control Lists)
- 6.1 getfacl - ACL の表示
- 6.2 setfacl - ACL の設定
- 6.3 デフォルト ACL
- 6.4 ACL の継承
- SELinux コンテキストの基礎
- ファイル属性 (lsattr / chattr)
- パーミッション比較表
- 実践的セキュリティシナリオ
- トラブルシューティング
- ベストプラクティス
- 参考文献
1. はじめに
Linux のファイルパーミッションシステムは、DAC(任意アクセス制御)の中核をなす仕組みである。標準の Unix パーミッション、ACL、SELinux コンテキスト、そしてファイル属性を組み合わせることで、多層的なアクセス制御を実現できる。
本記事では、これらの仕組みを基礎から実践まで体系的に解説する。
2. 標準 Unix パーミッション
2.1 rwx の基本
Linux のすべてのファイルとディレクトリは、3つのエンティティに対してパーミッションが設定される。
-rwxr-xr-- 1 sysadmin developers 4096 Apr 10 12:00 script.sh
│├─┤├─┤├─┤
│ │ │ │
│ │ │ └── Others (その他) : r-- (読み取りのみ)
│ │ └───── Group (グループ) : r-x (読み取り+実行)
│ └───────── Owner (所有者) : rwx (全権限)
└─────────── ファイルタイプ : - (通常ファイル)
ファイルタイプ識別子:
| 文字 | 種類 | 例 |
|---|---|---|
- | 通常ファイル | テキスト、バイナリ等 |
d | ディレクトリ | フォルダ |
l | シンボリックリンク | ショートカット |
c | キャラクタデバイス | /dev/tty |
b | ブロックデバイス | /dev/sda |
p | 名前付きパイプ (FIFO) | IPC 用 |
s | ソケット | /var/run/*.sock |
パーミッションの意味(ファイル vs ディレクトリ):
| パーミッション | ファイルでの意味 | ディレクトリでの意味 |
|---|---|---|
r (read) | ファイル内容の読み取り | ディレクトリ内の一覧表示 |
w (write) | ファイル内容の変更 | ファイルの作成・削除・名前変更 |
x (execute) | ファイルの実行 | ディレクトリへの移動(cd) |
2.2 8進数表記
r = 4
w = 2
x = 1
組み合わせ表:
| 8進数 | 記号 | 意味 |
|---|---|---|
| 0 | --- | 権限なし |
| 1 | --x | 実行のみ |
| 2 | -w- | 書き込みのみ |
| 3 | -wx | 書き込み + 実行 |
| 4 | r-- | 読み取りのみ |
| 5 | r-x | 読み取り + 実行 |
| 6 | rw- | 読み取り + 書き込み |
| 7 | rwx | 全権限 |
一般的な権限パターン:
| 8進数 | 記号 | 用途 |
|---|---|---|
| 755 | rwxr-xr-x | 実行ファイル、スクリプト |
| 644 | rw-r--r-- | 設定ファイル、HTMLファイル |
| 600 | rw------- | 秘密鍵、パスワードファイル |
| 700 | rwx------ | ホームディレクトリ、秘密ディレクトリ |
| 750 | rwxr-x--- | グループ共有プログラム |
| 775 | rwxrwxr-x | グループ共有ディレクトリ |
| 660 | rw-rw---- | グループ共有ファイル |
| 440 | r--r----- | /etc/sudoers |
| 400 | r-------- | SSH 秘密鍵 |
2.3 ディレクトリに対するパーミッションの意味
# ディレクトリの各パーミッションの効果を検証
$ mkdir /tmp/test_perms && cd /tmp/test_perms
# r のみ(一覧は見えるが、cd やファイルアクセスは不可)
$ chmod 444 /tmp/test_perms
$ ls /tmp/test_perms
file1.txt file2.txt
$ cat /tmp/test_perms/file1.txt
cat: /tmp/test_perms/file1.txt: Permission denied
$ cd /tmp/test_perms
bash: cd: /tmp/test_perms: Permission denied
# x のみ(cd は可能だが、一覧表示は不可。パスを知っていればアクセス可能)
$ chmod 111 /tmp/test_perms
$ cd /tmp/test_perms # OK
$ ls /tmp/test_perms
ls: cannot open directory '/tmp/test_perms': Permission denied
$ cat /tmp/test_perms/file1.txt # ファイル名を知っていればOK
Hello World
# r+x(通常の読み取り用ディレクトリ)
$ chmod 555 /tmp/test_perms
$ ls /tmp/test_perms # OK
$ cat /tmp/test_perms/file1.txt # OK
$ touch /tmp/test_perms/new.txt
touch: cannot touch '/tmp/test_perms/new.txt': Permission denied
3. 権限変更コマンド
3.1 chmod - パーミッション変更
シンボリックモード:
# 基本構文: chmod [who][operator][permission] file
# who: u(user), g(group), o(others), a(all)
# operator: +(add), -(remove), =(set exactly)
# perm: r, w, x, X, s, t
# 所有者に実行権限を追加
$ chmod u+x script.sh
$ ls -l script.sh
-rwxr--r-- 1 sysadmin developers 256 Apr 10 12:00 script.sh
# グループに書き込み権限を追加
$ chmod g+w config.yaml
$ ls -l config.yaml
-rw-rw-r-- 1 sysadmin developers 1024 Apr 10 12:00 config.yaml
# その他から全権限を削除
$ chmod o-rwx secret.key
$ ls -l secret.key
-rw-r----- 1 sysadmin developers 3243 Apr 10 12:00 secret.key
# 所有者に rwx、グループに rx、その他に権限なし(= で正確に設定)
$ chmod u=rwx,g=rx,o= deploy.sh
$ ls -l deploy.sh
-rwxr-x--- 1 sysadmin developers 512 Apr 10 12:00 deploy.sh
# 全員に実行権限を追加
$ chmod a+x public_script.sh
# 再帰的にディレクトリ配下を変更
$ chmod -R 750 /opt/myapp/
# X(大文字): ディレクトリにのみ実行権限を設定(ファイルは除外)
$ chmod -R u=rwX,g=rX,o= /var/www/html/
# → ディレクトリ: rwxr-x---
# → ファイル: rw-r-----
8進数モード:
# 644: rw-r--r--
$ chmod 644 index.html
# 755: rwxr-xr-x
$ chmod 755 /usr/local/bin/myapp
# 600: rw-------
$ chmod 600 ~/.ssh/id_rsa
# 700: rwx------
$ chmod 700 ~/.ssh
# 再帰的に設定
$ find /var/www -type f -exec chmod 644 {} \;
$ find /var/www -type d -exec chmod 755 {} \;
# --reference: 別ファイルと同じパーミッションにする
$ chmod --reference=template.conf new.conf
3.2 chown - 所有者変更
# 所有者を変更
$ sudo chown webuser index.html
$ ls -l index.html
-rw-r--r-- 1 webuser developers 4096 Apr 10 12:00 index.html
# 所有者とグループを同時に変更
$ sudo chown webuser:www-data index.html
$ ls -l index.html
-rw-r--r-- 1 webuser www-data 4096 Apr 10 12:00 index.html
# グループのみ変更(:グループ名)
$ sudo chown :www-data index.html
# 再帰的に変更
$ sudo chown -R webuser:www-data /var/www/html/
# シンボリックリンク自体の所有者を変更(-h)
$ sudo chown -h webuser symlink_file
# --reference: 別ファイルと同じ所有者にする
$ sudo chown --reference=existing_file new_file
# 実行例
$ ls -la /var/www/html/
total 16
drwxr-xr-x 3 webuser www-data 4096 Apr 10 12:00 .
drwxr-xr-x 3 root root 4096 Apr 10 12:00 ..
-rw-r--r-- 1 webuser www-data 612 Apr 10 12:00 index.html
drwxr-xr-x 2 webuser www-data 4096 Apr 10 12:00 css
3.3 chgrp - グループ変更
# グループを変更
$ sudo chgrp developers /opt/project/
$ ls -ld /opt/project/
drwxrwxr-x 5 root developers 4096 Apr 10 12:00 /opt/project/
# 再帰的に変更
$ sudo chgrp -R developers /opt/project/
# 実質的に chown :developers と同等
$ sudo chown :developers /opt/project/
4. umask
umask は、新規作成ファイル/ディレクトリのデフォルトパーミッションを制御する。
umask の計算方法:
ファイルのデフォルト: 666 (rw-rw-rw-)
ディレクトリのデフォルト: 777 (rwxrwxrwx)
実際の権限 = デフォルト - umask(ビット単位の補数演算)
umask 値とその効果:
| umask | ファイル権限 | ディレクトリ権限 | 用途 |
|---|---|---|---|
| 022 | 644 (rw-r--r--) | 755 (rwxr-xr-x) | 一般的(デフォルト) |
| 077 | 600 (rw-------) | 700 (rwx------) | セキュア(プライベート) |
| 027 | 640 (rw-r-----) | 750 (rwxr-x---) | グループ共有 |
| 002 | 664 (rw-rw-r--) | 775 (rwxrwxr-x) | グループ書き込み許可 |
| 007 | 660 (rw-rw----) | 770 (rwxrwx---) | グループ協業 |
実例:
# 現在の umask を確認
$ umask
0022
# シンボリック表示
$ umask -S
u=rwx,g=rx,o=rx
# umask が 022 の場合
$ touch testfile
$ mkdir testdir
$ ls -la
-rw-r--r-- 1 sysadmin sysadmin 0 Apr 10 12:00 testfile
drwxr-xr-x 2 sysadmin sysadmin 4096 Apr 10 12:00 testdir
# umask を変更(現在のシェルセッションのみ)
$ umask 077
$ touch securefile
$ mkdir securedir
$ ls -la
-rw------- 1 sysadmin sysadmin 0 Apr 10 12:01 securefile
drwx------ 2 sysadmin sysadmin 4096 Apr 10 12:01 securedir
# 永続的に umask を設定
# /etc/profile または ~/.bashrc に追加
$ echo "umask 027" >> ~/.bashrc
# PAM で umask を設定(全ユーザー適用)
# /etc/pam.d/common-session (Debian) or /etc/pam.d/system-auth (RHEL)
# session optional pam_umask.so umask=027
5. 特殊パーミッション
5.1 SUID (Set User ID)
ファイル実行時に、実行者ではなくファイル所有者の権限で実行される。
# SUID の表示(所有者の x が s になる)
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Apr 10 12:00 /usr/bin/passwd
# SUID の設定
$ sudo chmod u+s /usr/local/bin/myapp
$ sudo chmod 4755 /usr/local/bin/myapp
# SUID ファイルの検索
$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/passwd
/usr/bin/su
/usr/bin/sudo
/usr/bin/chage
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/mount
/usr/bin/umount
/usr/bin/pkexec
/usr/sbin/unix_chkpwd
# SUID の動作確認
# passwd は一般ユーザーが実行しても /etc/shadow(root所有)を更新できる
$ whoami
sysadmin
$ passwd # /etc/shadow に書き込める(SUID により root 権限で実行)
SUID の注意点:
- SUID はスクリプトファイルでは機能しない(セキュリティ上の理由)
- SUID バイナリはセキュリティリスクの元になるため、定期的に監査する
- 不要な SUID は削除する
5.2 SGID (Set Group ID)
ファイルに対する SGID: 実行時にファイルのグループ権限で実行される。
ディレクトリに対する SGID: ディレクトリ内で作成された新規ファイル/ディレクトリは、親ディレクトリのグループを継承する。
# SGID の表示(グループの x が s になる)
$ ls -ld /opt/shared/
drwxrwsr-x 2 root developers 4096 Apr 10 12:00 /opt/shared/
# SGID の設定
$ sudo chmod g+s /opt/shared/
$ sudo chmod 2775 /opt/shared/
# SGID ディレクトリの動作確認
$ sudo mkdir /opt/project
$ sudo chown root:developers /opt/project
$ sudo chmod 2775 /opt/project
# SGID なしの場合
$ mkdir /tmp/no_sgid
$ touch /tmp/no_sgid/test
$ ls -l /tmp/no_sgid/test
-rw-r--r-- 1 sysadmin sysadmin 0 Apr 10 12:00 test
# SGID ありの場合(グループが developers を継承)
$ touch /opt/project/newfile
$ ls -l /opt/project/newfile
-rw-rw-r-- 1 sysadmin developers 0 Apr 10 12:00 newfile
$ mkdir /opt/project/subdir
$ ls -ld /opt/project/subdir
drwxrwsr-x 2 sysadmin developers 4096 Apr 10 12:00 subdir
# → SGID も継承される
# SGID ファイルの検索
$ find / -perm -2000 -type f 2>/dev/null
/usr/bin/write
/usr/bin/wall
/usr/sbin/postdrop
/usr/sbin/postqueue
5.3 Sticky Bit
ディレクトリに設定すると、ファイルの削除/名前変更は所有者と root のみ可能になる。
# Sticky Bit の表示(その他の x が t になる)
$ ls -ld /tmp
drwxrwxrwt 18 root root 4096 Apr 10 12:00 /tmp
# Sticky Bit の設定
$ sudo chmod +t /opt/shared/
$ sudo chmod 1777 /opt/shared/
# Sticky Bit の動作確認
$ ls -ld /tmp
drwxrwxrwt 18 root root 4096 Apr 10 12:00 /tmp
# ユーザーAが作成したファイル
$ sudo -u usera touch /tmp/userA_file
$ ls -l /tmp/userA_file
-rw-r--r-- 1 usera usera 0 Apr 10 12:00 /tmp/userA_file
# ユーザーBは削除できない(Sticky Bit により保護)
$ sudo -u userb rm /tmp/userA_file
rm: cannot remove '/tmp/userA_file': Operation not permitted
# ファイル所有者は削除可能
$ sudo -u usera rm /tmp/userA_file # OK
特殊パーミッション一覧:
| 名前 | 8進数 | 記号 | 対象 | 効果 |
|---|---|---|---|---|
| SUID | 4000 | s (所有者x) | ファイル | 所有者の権限で実行 |
| SGID | 2000 | s (グループx) | ファイル | グループの権限で実行 |
| SGID | 2000 | s (グループx) | ディレクトリ | グループ継承 |
| Sticky | 1000 | t (その他x) | ディレクトリ | 削除保護 |
大文字 S/T の意味:
# 小文字 s/t: 基となる x パーミッションが有効
-rwsr-xr-x # SUID + 実行権限あり
# 大文字 S/T: 基となる x パーミッションが無効(意味がない設定)
-rwSr-xr-x # SUID はあるが実行権限がない → 実質無効
drwxrwxrwT # Sticky Bit はあるがその他に x がない
6. ACL (Access Control Lists)
ACL は、標準の owner/group/others の枠を超えた細かなアクセス制御を提供する。
前提条件:
# ファイルシステムが ACL をサポートしているか確認
$ mount | grep "acl"
/dev/sda1 on / type ext4 (rw,relatime,acl)
# ACL パッケージのインストール(必要な場合)
$ sudo dnf install acl # RHEL/CentOS
$ sudo apt install acl # Debian/Ubuntu
6.1 getfacl - ACL の表示
# ACL の表示
$ getfacl /opt/project/report.txt
# file: opt/project/report.txt
# owner: sysadmin
# group: developers
user::rw-
user:auditor:r--
group::rw-
group:managers:r--
mask::rw-
other::---
# 複数ファイルの ACL を表示
$ getfacl -R /opt/project/
# ACL が設定されているファイルを確認
# ls -l で + マークが表示される
$ ls -l /opt/project/
-rw-rw----+ 1 sysadmin developers 4096 Apr 10 12:00 report.txt
-rw-rw-r-- 1 sysadmin developers 2048 Apr 10 12:00 readme.txt
# ↑ "+" は ACL が設定されていることを示す
6.2 setfacl - ACL の設定
# 特定ユーザーに読み取り権限を付与
$ setfacl -m u:auditor:r /opt/project/report.txt
# 特定グループに読み書き権限を付与
$ setfacl -m g:managers:rw /opt/project/report.txt
# 複数の ACL エントリを同時に設定
$ setfacl -m u:auditor:r,g:managers:rw,g:contractors:r /opt/project/report.txt
# ACL の削除(特定エントリ)
$ setfacl -x u:auditor /opt/project/report.txt
# ACL の全削除
$ setfacl -b /opt/project/report.txt
# 再帰的に ACL を設定
$ setfacl -R -m g:developers:rwx /opt/project/
# 確認
$ getfacl /opt/project/report.txt
# file: opt/project/report.txt
# owner: sysadmin
# group: developers
user::rw-
user:auditor:r--
group::rw-
group:managers:rw-
group:contractors:r--
mask::rw-
other::---
mask の役割:
mask は ACL エントリの有効な最大権限を制限する。
# mask の設定
$ setfacl -m m::r /opt/project/report.txt
# 確認(effective 列が実際の有効な権限を表示)
$ getfacl /opt/project/report.txt
# file: opt/project/report.txt
# owner: sysadmin
# group: developers
user::rw-
user:auditor:r--
group::rw- #effective:r--
group:managers:rw- #effective:r--
mask::r--
other::---
# → mask が r-- なので、group と ACL エントリは最大 r-- に制限される
# → owner と other は mask の影響を受けない
# chmod が mask に影響する
$ chmod 640 /opt/project/report.txt
# → グループの権限 (r--) が mask に反映される
$ getfacl /opt/project/report.txt
# ...
mask::r--
6.3 デフォルト ACL
デフォルト ACL は、ディレクトリ内で新規作成されるファイル/ディレクトリに自動適用される ACL。
# デフォルト ACL の設定
$ setfacl -d -m u::rwx /opt/project/
$ setfacl -d -m g::rwx /opt/project/
$ setfacl -d -m g:managers:rx /opt/project/
$ setfacl -d -m o::--- /opt/project/
# または一括で設定
$ setfacl -d -m u::rwx,g::rwx,g:managers:rx,o::--- /opt/project/
# デフォルト ACL の確認
$ getfacl /opt/project/
# file: opt/project
# owner: sysadmin
# group: developers
# flags: -s-
user::rwx
group::rwx
group:managers:r-x
other::---
default:user::rwx
default:group::rwx
default:group:managers:r-x
default:mask::rwx
default:other::---
# 動作確認: 新規ファイル作成
$ touch /opt/project/newfile.txt
$ getfacl /opt/project/newfile.txt
# file: opt/project/newfile.txt
# owner: sysadmin
# group: developers
user::rw-
group::rwx #effective:rw-
group:managers:r-x #effective:r--
mask::rw-
other::---
# 動作確認: 新規ディレクトリ作成
$ mkdir /opt/project/subdir
$ getfacl /opt/project/subdir/
# file: opt/project/subdir
# owner: sysadmin
# group: developers
user::rwx
group::rwx
group:managers:r-x
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:group:managers:r-x
default:mask::rwx
default:other::---
# → デフォルト ACL も継承される
# デフォルト ACL の削除
$ setfacl -k /opt/project/
6.4 ACL の継承
# 完全な共有ディレクトリ設定例
$ sudo mkdir -p /opt/teamproject
$ sudo chown root:developers /opt/teamproject
$ sudo chmod 2770 /opt/teamproject
# 基本的な ACL 設定
$ sudo setfacl -m g:developers:rwx /opt/teamproject
$ sudo setfacl -m g:managers:rx /opt/teamproject
$ sudo setfacl -m g:auditors:r /opt/teamproject
# デフォルト ACL 設定(新規作成物に継承される)
$ sudo setfacl -d -m g:developers:rwx /opt/teamproject
$ sudo setfacl -d -m g:managers:rx /opt/teamproject
$ sudo setfacl -d -m g:auditors:r /opt/teamproject
$ sudo setfacl -d -m o::--- /opt/teamproject
# ACL のバックアップと復元
$ getfacl -R /opt/teamproject > /tmp/teamproject_acl.bak
$ setfacl --restore=/tmp/teamproject_acl.bak
# ACL を別ディレクトリにコピー
$ getfacl /opt/teamproject | setfacl --set-file=- /opt/newproject
7. SELinux コンテキストの基礎
SELinux(Security-Enhanced Linux)は MAC(強制アクセス制御)を提供する。
SELinux コンテキストの表示
# ファイルの SELinux コンテキストを表示
$ ls -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
# ──────────── ──────── ──────────────────── ──
# user role type level
# プロセスの SELinux コンテキスト
$ ps -eZ | grep httpd
system_u:system_r:httpd_t:s0 1234 ? 00:00:05 httpd
# 現在のユーザーの SELinux コンテキスト
$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
SELinux コンテキストの構造:
user:role:type:level
| 要素 | 説明 | 例 |
|---|---|---|
| user | SELinux ユーザー | system_u, unconfined_u |
| role | SELinux ロール | object_r, system_r |
| type | タイプ(最も重要) | httpd_sys_content_t |
| level | MLS/MCS レベル | s0 |
コンテキストの変更
# chcon - 一時的なコンテキスト変更(再ラベル付けで元に戻る)
$ sudo chcon -t httpd_sys_content_t /var/www/html/custom.html
$ ls -Z /var/www/html/custom.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 custom.html
# 再帰的に変更
$ sudo chcon -R -t httpd_sys_content_t /var/www/html/newsite/
# 別ファイルのコンテキストを参照して設定
$ sudo chcon --reference=/var/www/html/index.html /var/www/html/new_page.html
# restorecon - ポリシーに基づいてデフォルトに復元(推奨)
$ sudo restorecon -v /var/www/html/custom.html
Relabeled /var/www/html/custom.html from unconfined_u:object_r:default_t:s0
to unconfined_u:object_r:httpd_sys_content_t:s0
# 再帰的に復元
$ sudo restorecon -Rv /var/www/html/
# semanage fcontext - 永続的なコンテキスト規則の追加
$ sudo semanage fcontext -a -t httpd_sys_content_t "/opt/mywebapp(/.*)?"
$ sudo restorecon -Rv /opt/mywebapp/
# 現在の SELinux モード確認
$ getenforce
Enforcing
# SELinux 関連のエラーを確認
$ sudo ausearch -m AVC -ts recent
$ sudo sealert -a /var/log/audit/audit.log
8. ファイル属性 (lsattr / chattr)
ファイル属性は、パーミッションとは別にファイルの動作を制御する仕組み。
lsattr - 属性の表示
$ lsattr /etc/resolv.conf
----i--------e----- /etc/resolv.conf
# i = immutable(変更不可)
# e = extent format(ext4のデフォルト)
$ lsattr -R /etc/ 2>/dev/null | grep -E "^-{4}i"
----i--------e----- /etc/resolv.conf
chattr - 属性の変更
# i (immutable): ファイルの変更・削除・名前変更・リンク作成を禁止
$ sudo chattr +i /etc/resolv.conf
$ echo "nameserver 8.8.8.8" >> /etc/resolv.conf
bash: /etc/resolv.conf: Operation not permitted
$ rm /etc/resolv.conf
rm: cannot remove '/etc/resolv.conf': Operation not permitted
# immutable を解除
$ sudo chattr -i /etc/resolv.conf
# a (append-only): 追記のみ可能(ログファイルに最適)
$ sudo chattr +a /var/log/secure_audit.log
$ echo "new entry" >> /var/log/secure_audit.log # OK
$ echo "overwrite" > /var/log/secure_audit.log # 失敗
bash: /var/log/secure_audit.log: Operation not permitted
# 追記属性を解除
$ sudo chattr -a /var/log/secure_audit.log
# A (no atime update): atime の更新を抑制(パフォーマンス向上)
$ sudo chattr +A /var/www/html/index.html
# s (secure delete): 削除時にブロックをゼロ埋め
$ sudo chattr +s /tmp/sensitive_data.txt
# S (synchronous): 書き込みを即座にディスクに反映
$ sudo chattr +S /var/lib/critical_db/data.mdb
主要な属性一覧:
| 属性 | 文字 | 説明 |
|---|---|---|
| Immutable | i | 一切の変更不可(root でも) |
| Append Only | a | 追記のみ可能 |
| No Atime | A | アクセス時刻を更新しない |
| Secure Delete | s | 削除時にゼロ埋め |
| Synchronous | S | 同期書き込み |
| No Dump | d | dump によるバックアップ対象外 |
| Undeletable | u | 削除しても復元可能(内容保持) |
| Compress | c | カーネルによる透過的圧縮 |
| Extent | e | ext4 のエクステント使用(自動設定) |
9. パーミッション比較表
アクセス制御メカニズムの比較
| 機能 | 標準パーミッション | ACL | SELinux | ファイル属性 |
|---|---|---|---|---|
| 制御の粒度 | owner/group/others | ユーザー/グループ単位 | タイプベース | ファイル単位 |
| 設定コマンド | chmod, chown | setfacl | chcon, semanage | chattr |
| 確認コマンド | ls -l | getfacl | ls -Z | lsattr |
| 継承 | なし | デフォルト ACL | ポリシールール | なし |
| root による回避 | 可能 | 可能 | 制限可能 | 一部制限可能(immutable) |
| 制御モデル | DAC | DAC(拡張) | MAC | 補助的 |
| パフォーマンス影響 | 最小 | 低 | 中 | 最小 |
| 複雑さ | 低 | 中 | 高 | 低 |
よく使うパーミッション設定の一覧
| ファイル/ディレクトリ | 推奨権限 | 所有者 | 理由 |
|---|---|---|---|
/etc/shadow | 000 or 640 | root:shadow | パスワードハッシュ保護 |
/etc/sudoers | 440 | root:root | sudo 設定保護 |
~/.ssh/ | 700 | ユーザー | SSH ディレクトリ |
~/.ssh/id_rsa | 600 | ユーザー | SSH 秘密鍵 |
~/.ssh/authorized_keys | 600 | ユーザー | SSH 公開鍵リスト |
/var/www/html/ | 755 | root:root | Webコンテンツ |
/var/www/html/*.html | 644 | root:root | 静的ファイル |
/tmp | 1777 | root:root | 共有一時ディレクトリ |
/var/log/ | 755 | root:root | ログディレクトリ |
| 設定ファイル | 640 | root:group | 機密設定 |
| cron ファイル | 600 | ユーザー | 個人 cron |
| SSL 証明書 | 644 | root:root | 公開証明書 |
| SSL 秘密鍵 | 600 | root:root | 秘密鍵 |
10. 実践的セキュリティシナリオ
シナリオ 1: Web アプリケーションのデプロイディレクトリ
# 要件:
# - webadmin がコンテンツを管理
# - www-data (Apache/Nginx) が読み取り
# - その他はアクセス不可
$ sudo mkdir -p /var/www/myapp
$ sudo chown -R webadmin:www-data /var/www/myapp
$ sudo chmod 2750 /var/www/myapp # SGID でグループ継承
# ディレクトリ配下の権限設定
$ sudo find /var/www/myapp -type d -exec chmod 2750 {} \;
$ sudo find /var/www/myapp -type f -exec chmod 640 {} \;
# CGI/スクリプトには実行権限
$ sudo chmod 750 /var/www/myapp/cgi-bin/*.cgi
# アップロードディレクトリ(Web サーバーが書き込み可能)
$ sudo mkdir /var/www/myapp/uploads
$ sudo chmod 2770 /var/www/myapp/uploads
# SELinux コンテキスト設定
$ sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/myapp(/.*)?"
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/myapp/uploads(/.*)?"
$ sudo restorecon -Rv /var/www/myapp/
シナリオ 2: チーム共有プロジェクトディレクトリ
# 要件:
# - developers グループが完全アクセス
# - managers グループが読み取りアクセス
# - auditors が特定ファイルのみ読み取り
# - 他チームはアクセス不可
$ sudo mkdir -p /opt/project/alpha
$ sudo chown root:developers /opt/project/alpha
$ sudo chmod 2770 /opt/project/alpha
# ACL の設定
$ sudo setfacl -m g:managers:rx /opt/project/alpha
$ sudo setfacl -m g:auditors:r /opt/project/alpha
# デフォルト ACL(新規作成物に継承)
$ sudo setfacl -d -m u::rwx /opt/project/alpha
$ sudo setfacl -d -m g::rwx /opt/project/alpha
$ sudo setfacl -d -m g:managers:rx /opt/project/alpha
$ sudo setfacl -d -m g:auditors:r /opt/project/alpha
$ sudo setfacl -d -m o::--- /opt/project/alpha
# 設定確認
$ getfacl /opt/project/alpha
# file: opt/project/alpha
# owner: root
# group: developers
# flags: -s-
user::rwx
group::rwx
group:managers:r-x
group:auditors:r--
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:group:managers:r-x
default:group:auditors:r--
default:mask::rwx
default:other::---
シナリオ 3: 重要設定ファイルの保護
# 重要な設定ファイルを immutable に設定
$ sudo chattr +i /etc/passwd
$ sudo chattr +i /etc/shadow
$ sudo chattr +i /etc/group
$ sudo chattr +i /etc/gshadow
$ sudo chattr +i /etc/sudoers
# ⚠️ 注意: ユーザー管理操作前に解除が必要
$ sudo chattr -i /etc/passwd /etc/shadow /etc/group /etc/gshadow
# 監査ログは append-only に設定
$ sudo chattr +a /var/log/auth.log
$ sudo chattr +a /var/log/secure
# 確認
$ lsattr /etc/passwd /etc/shadow /var/log/auth.log
----i--------e----- /etc/passwd
----i--------e----- /etc/shadow
-----a-------e----- /var/log/auth.log
シナリオ 4: 共有 /tmp の強化
# /tmp は別パーティションにマウント(推奨)
# /etc/fstab:
# tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev,size=2G 0 0
# Sticky Bit の確認
$ ls -ld /tmp
drwxrwxrwt 18 root root 4096 Apr 10 12:00 /tmp
# 古いファイルの定期削除
$ sudo systemd-tmpfiles --clean
# または
$ sudo find /tmp -type f -atime +7 -delete
11. トラブルシューティング
よくある問題と解決策
問題 1: Permission denied にもかかわらず権限があるように見える
# ACL の mask を確認
$ getfacl /opt/project/file.txt
# ...
group::rwx #effective:r--
mask::r--
# → mask が権限を制限している
# 解決: mask を修正
$ setfacl -m m::rwx /opt/project/file.txt
# SELinux が原因の場合
$ sudo ausearch -m AVC -ts recent | head -20
type=AVC msg=audit(...): avc: denied { read } for pid=1234
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:user_home_t:s0
# → httpd_t が user_home_t にアクセスできない
# 解決: 正しいコンテキストを設定
$ sudo restorecon -Rv /var/www/html/
問題 2: ファイルが削除できない
# immutable 属性を確認
$ lsattr problem_file
----i--------e----- problem_file
# 解決: immutable を解除
$ sudo chattr -i problem_file
# 親ディレクトリの権限を確認
$ ls -ld $(dirname problem_file)
# → 親ディレクトリに w+x が必要
問題 3: ACL が継承されない
# デフォルト ACL が設定されているか確認
$ getfacl /opt/project/ | grep default
# → 出力がなければデフォルト ACL が未設定
# 解決: デフォルト ACL を設定
$ setfacl -d -m g:developers:rwx /opt/project/
# ファイルシステムの ACL サポート確認
$ mount | grep "$(df /opt/project | tail -1 | awk '{print $1}')"
# → acl オプションが有効か確認
# fstab で有効化(必要な場合)
# /dev/sda1 /opt ext4 defaults,acl 0 2
$ sudo mount -o remount,acl /opt
問題 4: chmod が反映されない
# ファイルシステムのマウントオプション確認
$ mount | grep "/opt"
/dev/sda1 on /opt type ext4 (rw,nosuid,nodev)
# → nosuid がマウントされている場合、SUID/SGID は無効
# NFS の場合
$ mount | grep nfs
server:/export on /mnt/nfs type nfs4 (rw,nosuid,no_root_squash)
# → NFS の root_squash が影響する場合がある
パーミッション診断チェックリスト:
#!/bin/bash
# perm_check.sh <file_or_directory>
TARGET=$1
echo "=== ファイル情報 ==="
ls -la "$TARGET"
echo ""
echo "=== ACL ==="
getfacl "$TARGET" 2>/dev/null || echo "ACL 未対応"
echo ""
echo "=== ファイル属性 ==="
lsattr "$TARGET" 2>/dev/null || echo "属性取得不可"
echo ""
echo "=== SELinux コンテキスト ==="
ls -Z "$TARGET" 2>/dev/null || echo "SELinux 未対応"
echo ""
echo "=== マウントオプション ==="
df "$TARGET" | tail -1 | awk '{print $1}' | xargs -I{} mount | grep {}
echo ""
echo "=== 親ディレクトリ権限 ==="
ls -ld "$(dirname "$TARGET")"
12. ベストプラクティス
一般原則
- 最小権限の原則: 必要最小限の権限のみ付与する
- グループベースの管理: 個別ユーザーではなくグループで権限管理する
- SGID の活用: 共有ディレクトリには SGID を設定してグループ継承させる
- デフォルト ACL: 複雑な権限要件にはデフォルト ACL を使用する
- 定期的な監査: SUID/SGID ファイル、world-writable ファイルを定期チェック
- SELinux は Enforcing: 無効化せず、問題を正しく解決する
- immutable 属性: 重要な設定ファイルは chattr +i で保護する
セキュリティ監査スクリプト
#!/bin/bash
# security_audit.sh - ファイル権限の定期監査
echo "========================================="
echo " File Permission Security Audit"
echo " $(date)"
echo "========================================="
echo ""
echo "=== 1. SUID ファイル一覧 ==="
find / -perm -4000 -type f 2>/dev/null | sort
echo ""
echo "=== 2. SGID ファイル一覧 ==="
find / -perm -2000 -type f 2>/dev/null | sort
echo ""
echo "=== 3. World-writable ファイル(/tmp, /var/tmp 除外)==="
find / -perm -002 -type f ! -path "/tmp/*" ! -path "/var/tmp/*" \
! -path "/proc/*" ! -path "/sys/*" 2>/dev/null | sort
echo ""
echo "=== 4. World-writable ディレクトリ(Sticky Bit なし)==="
find / -perm -002 -type d ! -perm -1000 \
! -path "/proc/*" ! -path "/sys/*" 2>/dev/null | sort
echo ""
echo "=== 5. 所有者のないファイル ==="
find / -nouser -o -nogroup 2>/dev/null | head -20
echo ""
echo "=== 6. パスワード未設定アカウント ==="
sudo awk -F: '$2 == "" {print $1}' /etc/shadow
echo ""
echo "=== 7. 重要ファイルの権限チェック ==="
for f in /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/sudoers; do
perms=$(stat -c "%a %U:%G" "$f" 2>/dev/null)
echo " $f : $perms"
done
echo ""
echo "=== 8. SSH 設定の権限チェック ==="
for home in /home/*; do
user=$(basename "$home")
if [ -d "$home/.ssh" ]; then
echo " $user:"
stat -c " %n : %a" "$home/.ssh" "$home/.ssh/"* 2>/dev/null
fi
done
権限設定テンプレート(Ansible Playbook 例)
# file_permissions.yml
---
- name: Enforce file permissions
hosts: all
become: yes
tasks:
- name: Set critical file permissions
file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
loop:
- { path: '/etc/passwd', mode: '0644', owner: 'root', group: 'root' }
- { path: '/etc/shadow', mode: '0000', owner: 'root', group: 'root' }
- { path: '/etc/group', mode: '0644', owner: 'root', group: 'root' }
- { path: '/etc/gshadow', mode: '0000', owner: 'root', group: 'root' }
- { path: '/etc/sudoers', mode: '0440', owner: 'root', group: 'root' }
- name: Configure shared project directory
file:
path: /opt/project
state: directory
mode: '2770'
owner: root
group: developers
- name: Set ACL on shared project directory
acl:
path: /opt/project
entity: managers
etype: group
permissions: rx
state: present
- name: Set default ACL for inheritance
acl:
path: /opt/project
entity: developers
etype: group
permissions: rwx
default: yes
state: present
- name: Protect critical config files with immutable flag
command: "chattr +i {{ item }}"
loop:
- /etc/resolv.conf
- /etc/hosts
changed_when: false
13. 参考文献
- man chmod(1)
- man chown(1)
- man acl(5)
- man setfacl(1)
- man getfacl(1)
- man chattr(1)
- man lsattr(1)
- man umask(2)
- Red Hat - Managing File Permissions
- SELinux User's and Administrator's Guide
- POSIX Access Control Lists on Linux
文書情報
- 作成日: 2026-04-10
- 対象OS: RHEL 8/9, CentOS Stream 8/9, Ubuntu 22.04/24.04, Debian 12
- 生成: AI Generated Technical Article