"The Linux Command Line" 輪読会「9 -- Permissions」レジュメ

この記事は、現在会社で行われている輪読会における、筆者の発表担当箇所の要旨をまとめたものです。
輪読会の対象書籍は下記の通りです。

[William Shotts (2019) "The Linux Command Line"]( https://linuxcommand.org/tlcl.php)

本記事では、上記書籍の中の **"Part I Chapter 9 -- Permissions"** を筆者がまとめた要旨と筆者の感想を記述します。

## 9 -- Permissions

### Owners, Group Members, and Everybody Else

- Unixシステムはマルチユーザシステム
- 例えば`file /etc/shadow`と入力すると、「権限がない」と怒られる
  - これは自分のユーザに読み込み権限がないため
- `id`と入力すると、自分のuser ID (uid)やgroup ID (gid)を見ることができる
- ユーザアカウントは`/etc/passwd`に定義されている
- グループは`/etc/group`に定義されている
- モダンなLinuxは慣習的に、ユニークでメンバー1人のグループをユーザ名と同じ名前で作成する。
  - こうすることで、特定の権限の付与が簡単になる

### Reading, Writing, and Executing

- ファイルやディレクトリへのアクセス権限は3種類
  - read
  - write
  - execution
- `ls -l`コマンドで、アクセス権限が分かる。
  - `-rw-rw-r--`のような10文字でファイル属性（*file attributes*）が出てくる。

最初の1文字はファイルタイプ（*file type*）

|属性|ファイルタイプ|
|:--|:--|
|`-`|普通のファイル|
|`d`|ディレクトリ|
|`l`|シンボリックリンク。<br />ファイル属性は常に`rwxrwxrwx`になる。<br />実際の属性はそれが指す実態に従う。|
|`c`|キャラクタ型のスペシャルファイル<br />（*character special file*）。<br />データをバイトストリームとして<br />扱うデバイス。<br />e.g. ターミナルや`/dev/null`。|
|`b`|ブロック型のスペシャルファイル<br />（*block special file*）。<br />データをブロックとして扱うデバイス。<br />e.g. HDDやDVD。|

残りの9文字はファイルモード（*file mode*）

- ファイルオーナー(*file owner*)、グループオーナー(*group owner*)、その他誰でも(*world*)の別にread, write, executeを表す

|オーナー|グループ|その他|
|:-:|:-:|:-:|
|`rwx`|`rwx`|`rwx`|

|属性|ファイル|ディレクトリ|
|---|---|---|
|`r`|開いて読める|`x`がセットされていれば中身を表示できる|
|`w`|書き込んだり切り取ったりできる<br />削除したりリネームしたりできるかはディレクトリの属性による|`x`がセットされていれば、中にファイルを作成したり削除したりリネームしたりできる|
|`x`|プログラムとして実行できる。<br />スクリプトファイルを実行するには`r`もセットされている必要がある|ディレクトリの中に進入できる<br />e.g. `cd directory`|

### `chmod` -- Change File mode

- ファイルモードや権限を変えるには、`chmod`を使う
- ファイルオーナーかスーパーユーザーのみが使用できる
- 先ほどの`rwx`のシンボルか、8進数が使える

|8進数|2進数|モード|
|---|---|---|
|0|000|`---`|
|1|001|`--x`|
|2|010|`-w-`|
|3|011|`-wx`|
|4|100|`r--`|
|5|101|`r-x`|
|6|110|`rw-`|
|7|111|`rwx`|

- e.g. `chmod 600 foo.txt`とすると、<br />`foo.txt`は`-rw-------`になる
- `chmod`は「誰に適用するか」を`u`, `g`, `o`, `a`というシンボルで表すことができる

|シンボル|意味|
|---|---|
|`u`|ファイルオーナー(**u**ser)|
|`g`|グループオーナー(**g**roup owner)|
|`o`|その他(**o**thers)|
|`a`|上記全て(**a**ll)|

- 省略すると、`a`（全て）が指定されたとみなされる
- `+`は権限の追加を表す
- `-`は権限の剥奪を表す
- `=`はその権限が適用され、それ以外は剥奪されることを表す

|例|意味|
|---|---|
|`u+x`|ファイルオーナーに実行権限を付与|
|`u-x`|ファイルオーナーから実行権限を剥奪|
|`+x`|全員に実行権限を付与（=`a+x`）|
|`o-rw`|オーナー・グループオーナー以外から読み書き権限を剥奪|
|`go=rw`|ファイルオーナー以外を読み書き権限に設定|
|`u+x,go=rx`|ファイルオーナーに実行権限を付与、それ以外は読み込み・実行権限に設定|

### `umask` -- Set Default Permissions

- `umask`コマンドはデフォルトのパーミッションを設定するコマンド
- デフォルト値はたいてい`0002`もしくは`0022`
- オリジナルのファイルモード（`--- rw- rw- rw-`）からマスクしてデフォルトのパーミッションを決める
- 最初の`0`は今は置いておく（後で説明する）と、後の3桁がそれぞれファイルオーナー・グループオーナー・その他に対応する

|オリジナル|`--- rw- rw- rw-`|
|---|---|
|マスク(`0022`)|`000 000 010 010`|
|結果|`--- rw- r-- r--`|

- 大抵の場合、デフォルトのマスクから変えることはないよ
- 高いセキュリティが求められる状況では変えたいことがあるかも

### Some Special Permissions

- 最初の1桁目はあまり使わない権限の設定に使う
- setuid bit (`4000`)
  - 実行ファイルに適用することで、実際に実行した人ではなくプログラムのオーナー（大抵はスーパーユーザー）のユーザIDで実行される
- setgid bit (`2000`)
  - setuidと似ているが、グループIDに対して作用する
- sticky bit (`1000`)
  - 実行ファイルを「交換不可能」とする。ファイルに対しては無視される。ディレクトリに対して適用されると、中のファイルを削除できるのはファイルのオーナー、ディレクトリのオーナー、スーパーユーザーに限定される。

- e.g. 実行ファイル`program`に対してsetuidを付与する場合: `chmod u+s`→`-rwsr-xr-x`
- ディレクトリ`dir`にsetgidを付与する場合: `chmod g+s`→`drwxrwsr-x`
- ディレクトリ`dir`にsticky bitを付与する場合`chmod +t dir`→`drwxrwxrwt`

### Changing Identities

- ユーザを変更したい場合、3つの方法がある

1. ログアウトして別のユーザでログインする
2. `su`コマンドを使う
3. `sudo`コマンドを使う

#### `su` -- Run a Shell with Substitute User and Group IDs

- `su`は他のユーザとしてシェルを開始するコマンド
- ユーザを省略するとスーパーユーザーとみなされる
- `-l`もしくは`-`を付けると指定されたユーザのログインシェルを開く
- スーパーユーザーのパスワードが要求される
- `-c 'コマンド'`でコマンドを実行できる

#### `sudo` -- Execute a Command as Another User

- `sudo`は`su`と似ているが、いくつか重要な機能が追加されている
- `/etc/sudoers`という設定ファイルで使えるユーザとコマンドを設定できる
- `sudo`は使用に際してスーパーユーザーのパスワードを要求せず、ユーザ自身のパスワードを使用する
- `-l`で付与される権限の一覧を確認できる

## Ubuntu and `sudo`

- Windowsでは一般ユーザに管理者権限を付与するやり方が取られる→危ない
- Unixでは慣習的に、管理者ユーザと一般ユーザを分けるやり方を取っていた
- しかし、`su`で`root`になって作業することが常習化した→危ない
- Ubuntuは`root`へのログインを無効にし、代わりに`sudo`でスーパーユーザーに昇格できるようにした

### `chown` -- Change File Owner and Group

- `chown`コマンドはファイルやディレクトリのオーナーやグループオーナーを変更するコマンド
- `chown [オーナー][:[グループ]] ファイル`で指定する

### `chgrp` -- Change Group Ownership

- 古いUnixでは`chown`コマンドではグループオーナーを変えられなかったので、`chgrp`コマンドを使ったよ

## Changing Your Password

- `passwd`コマンドでパスワードを変更できる
- このコマンドは「強力な」パスワードを設定するように強制してくる
  - 短かったり以前のパスワードと似ていたり安易に推測可能なパスワードは拒否される
- スーパーユーザー権限があれば、引数にユーザ名を指定することで他のユーザのパスワードを設定できる

### Summing Up

- Linuxが基にしているUnixの権限システムは、大昔のUnix初期に考えられたものだよ
- モダンなシステムにはちょっと粒度に欠けるところもあるよ

### Furser Readling

- Wikipediaの[マルウェアの記事（英語版）](https://en.wikipedia.org/wiki/Malware)は良い記事だよ
- ユーザやグループを作ったり管理したりするコマンドがあるよ
  - `adduser`
  - `useradd`
  - `groupadd`

## 感想とか

- 今回はファイルのアクセス権やユーザー、管理者権限まわりの話で、比較的普段から目にするものであり親しみやすかった。
- 「`umask`でデフォルトのパーミッションを変えられる」や、「`su`と`sudo`の違いとその歴史的経緯」といった自分が知らなかった話も色々出てきたので勉強になった。
    - "Ubuntu and `sudo`"のコラムでは特にUbuntuで`su`の代わりに`sudo`が使われるようになった歴史的経緯が明快に説明されていると同時に、さりげなくWindowsがボロクソに言われていて笑った。
- ユーザーやグループを追加するコマンド`useradd`や`adduser`、`groupadd`が最後に「こんなコマンドもあるよ」という紹介の数行で済まされていたのが惜しかった。特に自分のような読者は「`useradd`と`adduser`って何が違うの？」となってしまった。
- Linuxコマンド全般に言えることであるが、コマンドは声に出して発音するときに何と読めばいいのか分からないことが多い。
    - 勉強会終了後、「[sudoコマンドの発音は？](https://news.mynavi.jp/techplus/article/20190731-867815/#:~:text=%E3%81%93%E3%82%8C%E3%81%AB%E3%82%88%E3%82%8C%E3%81%B0%E3%80%81sudo,%E3%81%A8%E3%82%82%E8%AA%AC%E6%98%8E%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82)」という記事を教えていただいた。
    - この記事によれば「スードゥー」もしくは「スードー」が正しい読み方らしい。~~須藤さんじゃなかったんですね~~