特殊パーミッション (SUID、SGID、スティッキービット) の理解と適用
このステップでは、Linux の特殊パーミッションである SUID(Set User ID)、SGID(Set Group ID)、およびスティッキービットについて探求します。これらのパーミッションは、ファイルの実行とディレクトリの動作をより詳細に制御できます。
特殊パーミッションは、標準の 3 桁(所有者、グループ、その他)の前に配置される、8 進数のパーミッションモードに追加の数字で表されます。
- SUID(Set User ID):
- 8 進数値: 4
- ファイルへの影響: SUID が設定された実行可能ファイルが実行されると、それを実行したユーザーではなく、ファイルの所有者のパーミッションで実行されます。これは、
passwdコマンド(rootが所有する/etc/shadowファイルに書き込む必要がある)など、特定のタスクを実行するために高い権限を必要とするプログラムでよく使用されます。
ls -l出力での表示: 所有者のx(実行)パーミッションの代わりにsが表示されます。所有者に実行パーミッションがない場合は、大文字のSが表示されます。
- SGID(Set Group ID):
- 8 進数値: 2
- ファイルへの影響: SUID と同様ですが、実行可能ファイルはファイルのグループ所有者のパーミッションで実行されます。
- ディレクトリへの影響: SGID が有効になっているディレクトリ内で作成されたファイルとサブディレクトリは、それらを作成したユーザーのプライマリグループではなく、そのディレクトリのグループ所有権を継承します。これは、すべてのファイルが特定のグループに属する必要がある共有ディレクトリに非常に役立ちます。
ls -l出力での表示: グループのx(実行)パーミッションの代わりにsが表示されます。グループに実行パーミッションがない場合は、大文字のSが表示されます。
- スティッキービット:
- 8 進数値: 1
- ファイルへの影響: 影響なし。
- ディレクトリへの影響: ユーザーはディレクトリ内にファイルを作成できますが、所有しているファイルのみを削除または名前変更できます。これにより、ユーザーは共有ディレクトリ(例:
/tmp)内の他のユーザーのファイルを削除または移動できなくなります。
ls -l出力での表示: その他のx(実行)パーミッションの代わりにtが表示されます。その他に実行パーミッションがない場合は、大文字のTが表示されます。
これらの特殊パーミッションを実際に見てみましょう。
SUID の例
制限されたファイルを読み込もうとする簡単な C プログラムを作成します。
まず、rootだけが読み取れるファイルを作成します。
sudo touch ~/project/secret_data.txt
sudo chmod 600 ~/project/secret_data.txt
sudo chown root:root ~/project/secret_data.txt
パーミッションを確認します。
ls -l ~/project/secret_data.txt
出力:
-rw------- 1 root root 0 Jun 6 17:36 /home/labex/project/secret_data.txt
次に、このファイルを読み込もうとする C プログラムread_secret.cを作成します。
nano ~/project/read_secret.c
次のコードをread_secret.cに貼り付けます。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
FILE *fp;
char buffer[256];
printf("Attempting to read /home/labex/project/secret_data.txt...\n");
fp = fopen("/home/labex/project/secret_data.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
printf("Successfully read file.\n");
return 0;
}
nanoを保存して終了します(Ctrl+S、Ctrl+X)。
プログラムをコンパイルします。
gcc ~/project/read_secret.c -o ~/project/read_secret
次に、labexとして実行してみます。
~/project/read_secret
「Error opening file: Permission denied」というメッセージが表示されるはずです。これは、labexにはsecret_data.txtへの読み取りアクセス権がないためです。
次に、read_secretをrootが所有するようにし、SUID ビットを設定します。
sudo chown root:root ~/project/read_secret
sudo chmod u+s ~/project/read_secret
パーミッションを確認します。
ls -l ~/project/read_secret
出力:
-rwsr-xr-x 1 root root 17704 Jun 6 01:02 /home/labex/project/read_secret
所有者のパーミッションセットにsがあることに注目してください。次に、labexとしてプログラムをもう一度実行します。
~/project/read_secret
今回は、ファイルが正常に読み込まれます(空なので何も出力されませんが、「Successfully read file.」というメッセージは成功を示しています)。これは、SUID ビットによってプログラムがrootのパーミッションで実行されたためです。
SGID の例(ディレクトリに対して)
共有ディレクトリと新しいグループを作成しましょう。
sudo groupadd shared_group
sudo mkdir ~/project/shared_dir
sudo chown labex:shared_group ~/project/shared_dir
sudo chmod 770 ~/project/shared_dir
次に、shared_dirに SGID ビットを設定します。
sudo chmod g+s ~/project/shared_dir
パーミッションを確認します。
ls -ld ~/project/shared_dir
出力:
drwxrws--- 2 labex shared_group 6 Jun 6 01:02 /home/labex/project/shared_dir
グループのパーミッションセットにsがあることに注目してください。
次に、shared_dir内にファイルを作成します。
touch ~/project/shared_dir/new_file.txt
new_file.txtの所有権を確認します。
ls -l ~/project/shared_dir/new_file.txt
出力:
-rw-r--r-- 1 labex shared_group 0 Jun 6 01:02 /home/labex/project/shared_dir/new_file.txt
labexのプライマリグループはlabexですが、new_file.txtは SGID ビットのためにshared_dirからshared_groupのグループ所有権を継承しました。
スティッキービットの例
/tmpディレクトリは、スティッキービットが設定されたディレクトリの典型的な例です。同様のディレクトリを作成しましょう。
sudo mkdir ~/project/public_upload
sudo chmod 1777 ~/project/public_upload
1777の1は、スティッキービットの 8 進数値です。777は、所有者、グループ、およびその他に完全なパーミッションを付与します。
パーミッションを確認します。
ls -ld ~/project/public_upload
出力:
drwxrwxrwt 2 root root 6 Jun 6 01:02 /home/labex/project/public_upload
その他のパーミッションセットにtがあることに注目してください。
次に、別のユーザーがこのディレクトリにファイルを作成するシミュレーションを行います。labexユーザーしかいないため、labexとしてファイルを作成し、所有権をrootに変更した後(別のユーザーをシミュレート)、削除を試みます。
labexとしてファイルを作成します。
touch ~/project/public_upload/labex_file.txt
所有権をrootに変更します。
sudo chown root:root ~/project/public_upload/labex_file.txt
次に、labexとしてlabex_file.txtを削除しようとします。
rm ~/project/public_upload/labex_file.txt
書き込み保護されたファイルを削除するかどうかを尋ねるプロンプトが表示され、yで確認すると、「Operation not permitted」というエラーが表示されます。これは、スティッキービットにより、labexがpublic_uploadディレクトリへの書き込み権限を持っているにもかかわらず、ユーザーが所有していないファイルをそのディレクトリ内で削除できないためです。rootまたはlabex_file.txtの所有者(この場合はroot)のみがそれを削除できます。
クリーンアップするには、labex_file.txtを削除するためにsudoが必要です。
sudo rm ~/project/public_upload/labex_file.txt
クリーンアップ
作成したファイルとディレクトリ、およびユーザー/グループを削除します。
sudo rm -f ~/project/secret_data.txt ~/project/read_secret.c ~/project/read_secret
sudo rm -rf ~/project/shared_dir ~/project/public_upload
sudo groupdel shared_group