Linuxの権限システム - 特別権限

# Linuxの特別権限

Linuxでは、一般的な`rwx`権限の他に、3つの特別な権限が存在します。それらはSUID、SGID、そしてStickyです。これらの特別な権限は`rwx`権限体系とは独立しています。

## 特別権限について

- **SUID**: 二進数の実行可能ファイルに適用され、ユーザーはこのプログラムの所有者の権限を継承します。
- **SGID**: 二進数の実行可能ファイルに適用され、ユーザーはこのプログラムの所有グループの権限を継承します。ディレクトリに適用されると、このディレクトリ内で新しく作成されたファイルの所有グループがこのディレクトリから自動的に継承されます。
- **Sticky**: ディレクトリに適用され、このディレクトリ内のファイルを所有者自身とrootのみが削除できるようにします。

```shell
| 権限  | 文字表示 | 八進数表示 | 備考                                                                         |
|-------|--------|-----------|----------------------------------------------------------------------------|
| SUID  | `s`    | `4`       | 元々の所有者に実行可能権限がなく、SUID権限が加わった場合、表示が`S`になります       |
| SGID  | `s`    | `2`       | 元々の所有グループに実行可能権限がなく、SGID権限が加わった場合、表示が`S`になります |
| STICKY | `t`    | `1`       | otherに実行可能権限がなく、STICKY権限が加わった場合、表示が`T`になります          |
```

### SUIDの特別な権限

- **前提**: プロセスは所有者と所有グループを持っています。ファイルも所有者と所有グループを持っています。
- **実行可能プログラムファイルのSUID権限機能**:
  - 実行可能プログラムファイルがプロセスとして起動するかどうかは、発動者がプログラムファイルに対して実行権限を持っているかに依存します。
  - プロセスとして起動した後、そのプロセスの所有者は元のプログラムファイルの所有者です。
  - SUIDは二進数の実行可能プログラムにのみ有効です。
  - ディレクトリにSUIDを設定することは意味がありません。

#### SUID権限の設定:

```shell
chmod u+s FILE...
chmod 4xxx FILE
chmod u-s FILE...
```

#### 例:

```shell
[jose@rocky8 ~]$ ll /etc/shadow
----------. 1 root root 1475 Jun 26 14:02 /etc/shadow
#一般ユーザーは/etc/shadowファイルを開くことができません。権限がありません。このファイルにはユーザーのパスワードが格納されています。
[jose@rocky8 ~]$ cat /etc/shadow
cat: /etc/shadow: Permission denied
#しかし、passwdコマンドを使用してパスワードを変更することができます。つまり、普通のユーザーはpasswdコマンドを通じて/etc/shadowファイルを変更することができます。
[jose@rocky8 ~]$ passwd
Changing password for user jose.
Current password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
```

#### 例:

```shell
[root@rocky8 0626]# chmod u+s /usr/bin/cat

#権限を持っています。
[jose@rocky8 ~]$ cat /etc/shadow
root:$6$10pvyo2c4EI8tYh1$PT2yiAT6nrxs9rtjhQFWfDuHyFaV5HARXzn9YZ6wpJKveHccoIefnFO
JNdnVHx2xpApl5Qoljt7iIlmHxWuy//::0:99999:7:::
bin:*:18700:0:99999:7:::
daemon:*:18700:0:99999:7:::
adm:*:18700:0:99999:7:::
lp:*:18700:0:99999:7:::
sync:*:18700:0:99999:7:::
```

### SGIDの特別な権限

- **二進数の実行可能ファイル上のSGID権限機能**:
  - 任意の実行可能プログラムファイルがプロセスとして起動するかどうかは、発動者がプログラム
ファイルに対して実行権限を持っているかに依存します。
  - プロセスとして起動した後、そのプロセスの所有グループは元のプログラムファイルの所有グループです。

#### SGID権限の設定:

```shell
chmod g+s FILE...
chmod 2xxx FILE
chmod g-s FILE...
```

#### 目录上のSGID権限機能:

- 通常の場合、ユーザがファイルを作成すると、そのファイルの所有グループはそのユーザのメイングループです。しかし、あるディレクトリにSGIDが設定されていると、そのディレクトリに書き込み権限を持つユーザがそのディレクトリ内で作成したファイルの所有グループがそのディレクトリの所有グループに自動的になります。これは、共同作業ディレクトリを作成する際によく使用されます。

#### SGID権限の設定:

```shell
chmod g+s DIR...
chmod 2xxx DIR
chmod g-s DIR...
```

#### 例:

```shell
[jose@rocky8 ~]$ ll -d dir1/
drwxrwxr-x. 2 jose jose 42 Jun 26 14:19 dir1/
[jose@rocky8 ~]$ ll dir1/
total 0
-rw-rw-r--. 1 jose jose 0 Jun 26 14:19 jose-1.txt
-rw-r-----. 1 root root 0 Jun 26 14:19 root-1.txt
#権限を追加
[jose@rocky8 ~]$ chmod g+s dir1/
#ファイルを作成
[jose@rocky8 ~]$ touch dir1/jose-2.txt
[root@rocky8 ~]# touch /home/jose/dir1/root-2.txt
[jose@rocky8 ~]$ ll dir1/ -d
drwxrwsr-x. 2 jose jose 78 Jun 26 14:20 dir1/
[jose@rocky8 ~]$ ll dir1/
total 0
-rw-rw-r--. 1 jose jose 0 Jun 26 14:19 jose-1.txt
-rw-rw-r--. 1 jose jose 0 Jun 26 14:20 jose-2.txt
-rw-r-----. 1 root root 0 Jun 26 14:19 root-1.txt
-rw-r-----. 1 root jose 0 Jun 26 14:20 root-2.txt #新規ファイルの所属グループがディレクトリの所属グループになりました
```

### Stickyビットの特別な権限

- 書き込み権限を持つディレクトリでは、通常、ユーザはそのディレクトリ内の任意のファイルを削除することができます。それがユーザがそのファイルに対する権限を持っているかどうかに関わりません。
- ディレクトリにStickyビットを設定すると、ファイルの所有者かrootのみがそのファイルを削除できるようになります。
- Stickyはファイルに設定しても意味がありません。

#### Sticky権限の設定:

```shell
chmod o+t DIR...
chmod 1xxx DIR
chmod o-t DIR...
```

#### 例:

```shell
[root@rocky8 /]# mkdir dir1
[root@rocky8 /]# chmod a=rwx /dir1/
[root@rocky8 /]# touch /dir1/root-1.txt
[root@rocky8 /]# su - jerry -c "touch /dir1/jerry-1.txt"
[jose@rocky8 ~]$ touch /dir1/jose-1.txt
[root@rocky8 /]# ll /dir1/ -d
drwxrwxrwx. 2 root root 61 Jun 26 14:29 /dir1/
[root@rocky8 /]# ll /dir1/
total 0
-rw-r--r--. 1 jerry steve 0 Jun 26 14:29 jerry-1.txt
-rw-rw-r--. 1 jose jose 0 Jun 26 14:29 jose-1.txt
-rw-r-----. 1 root root 0 Jun 26 14:29 root-1.txt
#普通ユーザーは他のユーザーのファイルを削除できます
[jose@rocky8 ~]$ rm -f /dir1/root-1.txt
[jose@rocky8 ~]$ rm -f /dir1/jerry-1.txt
[jose@rocky8 ~]$ ll /dir1/
total 0
-rw-rw-r--. 1 jose jose 0 Jun 26 14:29 jose-1.txt
#権限を追加
[root@rocky8 /]# chmod o+t /dir1/
[root@rocky8 /]# ll -d /dir1/
drwxrwxrwt. 2 root root 24 Jun 26 14:31 /dir1/
#再度ファイルを作成
[root@rocky8 /]# touch /dir1/root-2.txt
[root@rocky8 /]# su - jerry -c "touch /dir1/jerry-2.txt"
[root@rocky8 /]# ll /dir1/
total 0
-rw-r--r--. 1 jerry steve 0 Jun 26 14:33 jerry-2.txt
-rw-rw-r--. 1 jose jose 0 Jun 26 14:29 jose-1.txt
-rw-r-----. 1 root root 0 Jun 26 14:33 root-2.txt
#これで他のユーザーのファイルを削除できなくなりました
[jose@rocky8 ~]$ rm -f /dir1/root-2.txt
rm: cannot remove '/dir1/root-2.txt': Operation not permitted
[jose@rocky8 ~]$ rm -f /dir1/jerry-2.txt
rm: cannot remove '/dir1/jerry-2.txt': Operation not permitted
```

#### 例:ディレクトリのSticky権限を確認

```shell
[root@rocky8 /]# ll -d /dir1/
drwxrwxrwt. 2 root root 61 Jun 26 14:33 /dir1/
[root@rocky8 /]# file /dir1/
/dir1/: sticky, directory
```

### 特別な権限の数値表現

```shell
| 文字表示       | 二進数表示 | 八進数表示 | 備考                |
|----------------|-----------|-----------|------------------|
| `---------`    | `000`     | `0`       | 特別な権限なし        |
| `--------t`    | `001`     | `1`       | Sticky           |
| `-----s---`    | `010`     | `2`       | SGID             |
| `-----s--t`    | `011`     | `3`       | SGID, Sticky     |
| `--s------`    | `100`     | `4`       | SUID             |
| `--s-----t`    | `101`     | `5`       | SUID, Sticky     |
| `--s---s---`   | `110`     | `6`       | SUID, SGID       |
| `--s--s--t`    | `111`     | `7`       | SUID, SGID, Sticky|
```

#### 例:

```shell
chmod 4777 /tmp/a.txt
```

### 権限ビット映射

- **SUID**: user、所有者の実行権限ビットに占有されます。
  - `s`: 所有者がx権限を持つ
  - `S`: 所有者がx権限を持たない
- **SGID**: group、所有グループの実行権限ビットに占有されます。
  - `s`: グループがx権限を持つ
  - `S`: グループがx権限を持たない
- **Sticky**: other、オーザーの実行権限ビットに占有されます。
  - `t`: オーザーがx権限を持つ
  - `T`: オーザーがx権限を持たない

### ファイルの特別属性を設定

```shell
chattr [-pRVf] [-+=aAcCdDeijPsStTuF] [-v version] files...
#よく使われるオプション
-p project #ファイルのプロジェクト番号を設定
-R         #再帰的に実行
-V         #処理の進行状況を表示し、chattr のバージョンを出力
-f         #エラーメッセージを出力しない
-v version #バージョンを設定
#操作子
+attribute #属性を追加
-attribute #属性を削除
=attribute #指定した属性のみを設定
#よく使われる属性
a #ファイル: 追加のみ可能、削除・変更・名前の変更不可。ディレクトリ: 新規作成、変更は可能だが、ファイルの削除は不可。
A #atimeの更新を行わない
c #ファイルは圧縮されて保存される
i #ファイル: 削除・変更・名前の変更不可。ディレクトリ: ファイルの閲覧、変更は可能だが、新規作成や削除は不可。
s #ファイルを完全に削除し、元のデータブロックを0で埋める
u #誤って削除された場合に備えて、そのファイルが格納されていたブロックが新しいデータで上書きされないようにする
```

### ファイルの特別属性を表示

```shell
lsattr [-RVadlpv] [files...]
```

#### +i 誤削除防止

ここでは、Linuxファイルシステムの特殊な属性について説明しています。特に、`chattr`コマンドを使用してファイルに設定できる`+i`属性と`+a`属性に焦点を当てています。

- `+i`属性（不変属性）:

  この属性が設定されたファイルは、削除、変更、名前の変更ができなくなります。また、新しい内容を追加することもできません。しかし、そのファイルの内容を読むことやそのファイルを別の場所にコピーすることは可能です。

  ```shell
  [root@rocky8 ~]# echo "abcd">a.txt
  [root@rocky8 ~]# chattr +i a.txt
  [root@rocky8 ~]# rm -f a.txt
  rm: cannot remove 'a.txt': Operation not permitted
  [root@rocky8 ~]# lsattr a.txt
  ----i--------e-- a.txt
  ```

#### +a 属性は一般にログファイルに使用されます。
- `+a`属性（追加専用属性）:

  この属性が設定されたファイルには、新しい内容を追加（例：リダイレクトによる追記）することができますが、既存の内容を変更したり、ファイル自体を削除したりすることはできません。この属性は、ログファイル等、追記のみが許されるファイルに便利です。

  ```shell
  [root@rocky8 ~]# echo "abcd">b.txt
  [root@rocky8 ~]# chattr +a b.txt
  [root@rocky8 ~]# ll b.txt
  -rw-r-----. 1 root root 5 Jun 26 14:49 b.txt
  [root@rocky8 ~]# lsattr b.txt
  -----a-------------- b.txt
  ```

これらの属性により、システム上の重要なファイルが誤って変更されることを防いだり、ログなどのデータの追記専用ファイルとして保護することができます。

`a`属性により、`b.txt`に対する追記操作のみが許可されます。これは、特にログファイルなど、情報の追加は許可するが、既存の内容の変更や削除は禁止したい場合に有効です。

### まとめ

これらの例を通して、Linuxのファイルシステムの拡張属性がいかに強力であるかがわかります。これにより、システム管理者は、重要なファイルの不正な変更や削除を防ぐことができ、システムのセキュリティを大幅に強化することができます。

ファイルの属性を制御することは、システムの適切な運用と保護のために非常に役立つ機能です。しかし、この強力な機能を適切に使用するためには、それを管理する管理者の責任と知識が求められます。適切な時に適切な方法でこれらの属性を利用することが、システムの健全な運営を保証します。