LinuxのパーミッションとWebサーバの挙動を確認してみた


#パーミッションとは
Linuxのディレクトリとファイルに設定する。
「誰に」「どのような操作」を許可するかを設定。


#誰に

| 誰に      　　　  |意味|
|:-----------------|------------------:|
| Owner（所有者）    |ファイル・ディレクトリの所有者
| Group（グループ） |ユーザーが属するグループ
| Other（その他）  |その他のユーザー


#どのような操作

###パーミッションの種類
パーミッションの種類には、「読み取り」「書き込み」「実行」の3種類の権限がある。

パーミッションの表記には、アルファベットと数値の表記がある。

| 種類       |　|　|
|:-----------|----------------|------------:|
| 読み取り　|　r　|　4　
| 書き込み　|　w　|　2　
| 実行　　　|　x　|　1　

　
ディレクトリとファイルのそれぞれのパーミッションの内容は以下。

###ディレクトリの場合
| 種類     |どのような操作               |使用可能なコマンド例|
|:----------------|-----------------------|------------------:|
| r|ディレクトリ内のリスト表示が可能。  |ls
| w|ディレクトリ内のディレクトリまたはファイルの新規作成・削除が可能。|mkdir, touch, rm
| x|カレントディレクトリとして移動可能。      |cd


###ファイルの場合
| 種類     |どのような操作                |使用可能なコマンド例|
|:----------------|-----------------------|------------------:|
| r|ファイルの読み取りが可能。  |less, more, cp
| w|ファイルの編集が可能。|vi
| x|ファイルの実行が可能。      |


#パーミッションの確認方法
###パーミッション早見表
|r x w|0-7|パーミッション|
|:-----|---|------------:|
|rwx|7|読み取り 書き込み 実行|
|rx-|6|読み取り 書き込み 　　|
|r-x|5|読み取り 実行 　　　　|
|r--|4|読み取り 　　　　 　　|
|-wx|3|書き込み 実行 　　　　|
|-w-|2|書き込み 　　　　 　　|
|--x|1|実行 　　　　 　　　　|
|---|0|
　

「**ls**」コマンドに「**-l**」オプションをつけて確認する。

```
$ ls -l /home/develop/public_html/
drwxrwxr-x 5 develop develop 71  3月  4 03:26 app
-rw-rw--r-- 1 develop develop 13  3月  4 03:24 index.html
lrwxrwxrwx 1 develop develop 41  3月  4 22:04 link.html -> /home/develop/public_html/app/sample.html
```
　

左の謎の暗号らしきものがパーミッションで、以下の並びで意味をもっている。
`[ファイルの種類][Ownerの権限][Groupの権限][Otherの権限]`

###drwxrwxr-x

|      |                ||意味|
|:----------------|------------|-----------|------------------:|
| 1文字目|d|ファイルの種類  |ディレクトリ
|2～4文字目|rwx|Ownerの権限|読み取り　書き込み　実行
| 5～7文字目|rwx|Groupの権限      |読み取り　書き込み　実行
| 8～10文字目|r-x|Otherの権限      |読み取り　　　　　　実行


###-rw-rw-r--

|      |                ||意味|
|:----------------|------------|-----------|------------------:|
| 1文字目|-|ファイルの種類  |ファイル
|2～4文字目|rw-|Ownerの権限|読み取り　書き込み
| 5～7文字目|rw-|Groupの権限      |読み取り　書き込み
| 8～10文字目|r--|Otherの権限      |読み取り　　　　　

###lrwxrwxrwx

|      |                ||意味|
|:----------------|------------|-----------|------------------:|
| 1文字目|l|ファイルの種類  |シンボリックリンク
|2～4文字目|rwx|Ownerの権限|読み取り　書き込み　実行
| 5～7文字目|rwx|Groupの権限      |読み取り　書き込み　実行
| 8～10文字目|rwx|Otherの権限      |読み取り　書き込み　実行


#パーミッションの設定方法
「**chmod**」コマンドで設定をする。

アルファベットで設定するシンボリックモードと、
数値で設定するオクタルモードの2種類の設定方法がある。


###シンボリックモード

`chmod [ユーザー][操作][権限] file`

以下の項目の組み合わせで設定

|ユーザー|意味|
|:-----|---|------------:|
|u|Ownerの権限|
|g|Groupの権限|
|o|Otherの権限|
|a|すべてのユーザーの権限|

|操作|意味|
|:-----|---|------------:|
|+|権限を付与|
|-|権限を削除|
|=|指定した権限にする|

|権限|意味|
|:-----|---|------------:|
|r|読み取り|
|w|書き込み|
|x|実行|


パーミッションが「rw-rw--r--」のindex.htmlのOtherの権限に「書き込み（w）」権限を付与する場合

```
$ ls -l /home/develop/public_html/
-rw-rw--r-- 1 develop develop 13  3月  4 03:24 index.html

chmod o+w /home/develop/public_html/index.html

$ ls -l /home/develop/public_html/
-rw-rw-rw- 1 develop develop 13  3月  4 03:24 index.html
```
　

カンマで区切りで複数の権限をまとめて設定することも可能

```
chmod u-x,go+w /home/develop/public_html/index.html
```

###オクタルモード
Owner・Group・Otherそれぞれの権限を数値で指定する。

`chmod [Owner][Group][Other] file`
　

早見表の数値で設定

|r x w|0-7|パーミッション|
|:-----|---|------------:|
|rwx|7|読み取り 書き込み 実行|
|rx-|6|読み取り 書き込み 　　|
|r-x|5|読み取り 実行 　　　　|
|r--|4|読み取り 　　　　 　　|
|-wx|3|書き込み 実行 　　　　|
|-w-|2|書き込み 　　　　 　　|
|--x|1|実行 　　　　 　　　　|
|---|0|



/home/develop/public_html/index.htmlに以下のパーミッションを設定する場合

Owner ・・・読み取り・書き込み
Group  ・・・読み取り・書き込み
Other  ・・・読み取り

```
chmod 664 /home/develop/public_html/index.html

$ ls -l /home/develop/public_html/
-rw-rw-r-- 1 develop develop 13  3月  4 03:24 index.html
```



#デフォルトのパーミッション

ファイルやディレクトリを作成すると、デフォルトでパーミッションが設定される。

デフォルトのパーミッションは「umask値」によって決まる。
「**umask**」コマンドで確認が可能。

```
# umask
0022

$ unmask
0002
```
rootと一般ユーザーでumask値が異なるので、
rootと一般ユーザーのデフォルトのパーミッションも異なる。　 


###rootの場合
umask値のパーミッション「022」を作成時のパーミッションから削除

||ディレクトリ|ファイル|
|:-----|---|------------:|
|作成時|rwx rwx rwx（777）|rw- rw- rw-（666）|
|umask値|--- -w- -w- （022）|--- -w- -w-（022）|
|デフォルト|**rwx r-x r-x  （755）**|**rw- r-- r--（644）**|

###一般ユ－ザーの場合
umask値のパーミッション「002」を作成時のパーミッションから削除

||ディレクトリ|ファイル|
|:-----|---|------------:|
|作成時|rwx rwx rwx（777）|rw- rw- rw-（666）|
|umask値|--- --- -w- （002）|--- --- -w-（002）|
|デフォルト|**rwx rwx r-x  （775）**|**rw- rw- r--（664）**|

　

まとめると、rootと一般ユーザーのデフォルトのパーミッションは以下になる。

|ユーザー|ディレクトリ|ファイル|
|:-----|---|------------:|
|root|rwx r-x r-x （755）|rw- r-- r--（644）|
|一般ユーザー|rwx rwx r-x（775）|rw- rw- r--（664）|




#ブラウザでファイルを表示するときのユーザーは？
所有者が「develop」のindex.htmlがWebサーバ上にあるとする。

ブラウザで`https://ドメイン/index.html`とURLを叩いて、index.htmlを読み込む時のユーザーは誰だ...？

root？ファイルの所有者のdevelop？
いろんな見知らぬ人がアクセスするからその他のユーザー？

答えはその他のユーザー。
しかし、**ブラウザからアクセスする人がユーザーではない。**


Webサーバがレスポンスを返す際に、
リクエストされたファイルへアクセスするのはWebサーバである。

WebサーバにApacheを利用している場合、
Apahceのユーザーとグループはhttpd.confに設定されている。


```:/etc/httpd/conf/httpd.conf
User apache
Group apache
```

　

つまりこの場合、**ファイルへアクセスするユーザーは「apache」**となる。
パーミッションのユーザー分類としては、「**Other**」に分類される。



そのため、Webサーバにディレクトリやファイルを配置する際には、
Otherのパーミッションを適切に設定する必要がある。

※所有者やグループをapacheに設定している場合は、Otherではないので注意。


#パーミッションを変更してWebサーバの挙動を確認

パーミッションを変更するとWebサーバの挙動はどうなるのか、
public_htmlとindex.htmlのディレクトリ・ファイル構造で確認してみる。

今回は、Webサーバが分類されるOtherのパーミッションを変更した場合の挙動を確認するので、
OwnerとGroupに設定しているパーミッションは今回は特に気にせずに！

■ディレクトリ
/home/develop/public_html
所有者：develop

■ファイル
/home/develop/public_html/index.html
所有者：develop

■ドキュメントルート
/home/develop/public_html



###よくあるデフォルトの設定
| dir / file |パーミッション|
|:-----------|------------:|
| public_html|rwx r-x r-x (755)|
| index.html |rw- r-- r-- (644)|

ふつうに開ける。
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/122907/3316dec1-9ddd-02ac-f043-ad44f4d3d034.png)



###ディレクトリから実行権限（ x ）を削除 / ファイルはデフォルト
ディレクトリはデフォルトの設定から実行権限をなくし、ファイルはデフォルトの設定。

| dir / file |パーミッション|
|:-----------|------------:|
| public_html|rwx r-x r-- (754)|
| index.html |rw- r-- r-- (644)|
　

ブラウザでアクセスしてみると、**403 Forbidden**でアクセスできなくなる。
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/122907/64eb16a9-d3b2-1702-b425-a208a872a056.png)

一見いけそうな気もするが、
これはカレントディレクトリとして移動する権限がないため、public_htmlにアクセスができないから。

| 種類     |何ができるか               |使用可能なコマンド例|
|:----------------|-----------------------|------------------:|
| x|カレントディレクトリとして移動可能。      |cd
　

Otherに分類されるユーザーで、コマンドでも試してみる。

```
[other@localhost ~]$ cd /home/develop/public_html/
-bash: cd: /home/develop/public_html/: 許可がありません
```
許可がないためpublic_htmlにアクセスできない。
　


index.htmlにもアクセスしてみる。

```
[other@localhost ~]$ less /home/develop/public_html/index.html
/home/develop/public_html/index.html: 許可がありません
```

index.htmlが配置されているpublic_htmlをカレントディレクトリにできないため、
index.htmlに読み取り権限があってもこちらもアクセスできない。






###ディレクトリはデフォルト / ファイルから読み取り権限（ r ）を削除
ディレクトリはデフォルトの設定で、ファイルはデフォルトの設定から読み取り権限をなくす。

| dir / file |パーミッション|
|:-----------|------------:|
| public_html|rwx r-x r-x (755)|
| index.html |rw- r-- --- (640)|

ブラウザでアクセスしてみると、**403 Forbidden**でアクセスできなくなる。
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/122907/64eb16a9-d3b2-1702-b425-a208a872a056.png)


Otherに分類されるユーザーで、コマンドでも試してみる。

```
[others@localhost ~]$ less /home/develop/public_html/index.html
/home/develop/public_html/index.html: 許可がありません
```
読み込み権限がないため、もちろん開けない。


#ブラウザでファイルへアクセスするためには
アクセスするファイルに到達するまでのディレクトリとファイルの
Otherのパーミッションの設定に、以下の権限が最低限必要になる。

・ディレクトリ　→ 「**実行 ( x )** 」
・ファイル　　　→ 「**読み取り ( r )** 」

ディレクトリに関しては、
**目的のファイルに到達するまでのディレクトリ全てに、実行権限が必要**なので要注意！

ブラウザからアクセスして403エラーになってしまう場合は、まずはこのへんを確認してみよう。

　
※所有者やグループをapacheに設定している場合は、Otherではないので注意。


#ディレクトリの中身が丸見えになってしまうケース :scream:
Webサーバとパーミッションの設定しだいでは、
ブラウザからリクエストした際に、Webサーバのディレクトリの中身が丸見えになってしまうケースがある...！

ブラウザでファイル名まで指定せずに、
`https:// ドメイン / ディレクトリ / `と入力してURLを叩くと、
Webサーバの設定しだいでは、ディレクトリの中身がブラウザに表示されてしまう。

###丸見え条件
・アクセスするディレクトリに**「読み取り ( r ) 」権限がある**
・アクセスするディレクトリ直下にhttpd.confの**DirectoryIndexで指定したファイルが存在しない**
・httpd.confのディレクティブの設定で**「Options」の項目に「Indexes」を設定**
・「**https:// ドメイン / ディレクトリ /** 」でリクエスト

###ディレクトリの「読み取り ( r ) 」権限
ディレクトリ内のリスト表示が可能。

###DirectoryIndex
ファイルを指定せずに、ディレクトリだけを指定してクライアントからリクエストを受けた場合に、
ディレクトリ直下のどのファイルをレスポンスとして返すかの設定

```:/etc/httpd/conf/httpd.conf
<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>
```

この場合、ファイルを指定せずにディレクトリだけを指定してリクエストを受けた場合、
そのディレクトリ直下のindex.htmlをレスポンスで返す。


###Options Indexes
DirectoryIndexで指定したファイルが存在しない場合に、ディレクトリ内ファイルの一覧を表示する

```:/etc/httpd/conf/httpd.conf
<VirtualHost *:80>
DocumentRoot /home/develop/public_html
ServerName develop.localdomain
<Directory "/home/develop/public_html/">
AllowOverride All
Require all granted
Options Indexes
</Directory>
</VirtualHost>
```
　

上記の設定で`http:// ドメイン / ディレクトリ / `でURLを叩いてみる。
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/122907/da8d7cb4-6120-8013-1fe4-e74206b99082.png)

**丸見えや :scream:！！**

もしconfigやlogファイル等がアクセスできる状態だったら、
ブラウザからファイルの中身が普通に表示できてしまう。

これはセキュリティ的によろしくない。

ちなみに**「Options」の項目自体を設定していない場合も**、
同様にディレクトリ内ファイルの一覧を表示する設定になるので要注意！

一覧表示をしないためには、「-」をつけてIndexesを無効にする必要がある。

```
Options -Indexes
```
　

もう一度アクセスしてみる。
![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/122907/e8663920-f62e-439a-8edb-a4620037afd0.png)
ディレクトリの中身が一覧表示されなくなった... :relaxed:！



#さいごに
ここまで読んでくださりありがとうございます。

パーミッションについて改めて学習する機会がありましたが、
具体的に使えるコマンドやWebサーバの挙動って意外とすぐ忘れてしまうので、学んだことをつらつら書いてみました。

誤りなどあればご指摘いただけるとありがたいです。

何か参考になれば幸いです〜！