nginxの所有者・グループ・パーミション

sudo apt-get install nginxでインストールしたnginxのディレクトリ及びファイルのディレクトリは、
ディレクトリのファイルと所有者、グループがrootアカウント及びrootグループに設定されます。

これを一部ディレクトリとファイルを除き、所有者をnginxアカウントにグループをnginxグループに変更します。

所有者やグループをシステムアカウントに変更するのは、パーミッションの設定とあわせてセキュリティを高めることが目的です。

対象のディレクトリとファイル

nginxのディレクトリとファイルは、以下に要約されます。
詳細については、nginx 初期構成をご確認下さい。

ファイルまたはディレクトリ 概要
/usr/sbin/nginx nginxコマンド本体
/etc/nginx nginxの設定ファイル格納先ディレクトリ
/usr/shere/nginx/html nginxのデフォルトのドキュメントルート
/var/log/nginx nginxのアクセスログ、実行ログ格納先ディレクトリ
/etc/logrotate.d/nginx ログローテション機能におけるnginxの設定ファイル
/usr/lib/nginx nginxの動的モジュールの格納先ディレクトリ
/var/lib/nginx nginxのモジュール別(proxy,fastcgiなど)の作業用ディレクトリ
/etc/init.d/nginx nginxのデモーン(サービス)用スクリプトファイル
/etc/ufw/applications.d/nginx ubuntuのファイヤーウォール機能であるUFW(uncomplicated firewall)のnginx用設定ファイル
/usr/share/doc/nginx nginxのライセンスドキュメントやREADMEドキュメント格納先
/usr/share/lintian/overrides/nginx debianの説明
5.14. {package.,source/}lintian-overridesをご確認下さい。
/var/cache/nginx nginxのproxy機能などを有効にした場合のキャッシュファイルなどを格納するディレクトリ

1つ1つ丁寧にチェックして、所有者・グループ・パーミションを変更した後に動作確認をしていきます。

所有者、グループ、パーミッションについて

nginxアカウント(Ubuntu)の概要図にあるように nginxのmasterプロセスはrootアカウントで実行され、workerプロセスは設定ファイル/etc/nginx/nginx.confの「user nginx;」指定されたnginxアカウント(システムアカウント)で実行されます。

rootアカウントは、ディレクトリ及びファイルの所有者、グループ、パーミッションの権限に関係なく全てのディレクトリ、ファイルを操作できます。 逆にnginxアカウントは、nginxアカウントまたはnginxグループに適切なパーミッションを付与しなければ、ファイルの実行、開閉やディレクトリアクセスで権限エラーになります。 同様にユーザアカウントinfra01(nginxグループ)でwebコンテンツの配備やnginxの設定変更などもnginxグループに対する適度なパーミッションを付与する必要があります。

【厳禁】動かすために動作原理が良く分からないから、取り合えず動く777のパーミッションを付与してしまう。

これだけは避けて下さい。アカウント、グループ、パーミッション、ミドルウェアが必要な最低な権限を抑えていれば、
777以外の適切なパーミッションを付与できます。

所有者以外グループ、その他に対するパーミッションに「7(全権限)」が付与された時点で、「この権限必要?」と疑問を感じて下さい。

ドキュメントルート

まずは、nginxのドキュメントルートに関して変更してみましょう。
nginxのデフォルトのドキュメントルートは、設定ファイル(/etc/nginx/conf.d/default.conf)にroot /usr/share/nginx/htmlと定義されています。

前提条件としては、phpなどの動的なスクリプト(動的にhtmlを出力する機能)を利用していないこととします。

Teratermなどのsshクライアントからユーザーアカウントinfra01(nginxグループ)からwebサーバにログインします。

/usr/share/nginx/のデフォルト値を確認する
$ cd /usr/share
$ ls -la | grep nginx
$ drwxr-xr-x    3 root root  4096  4月 26 10:53 nginx
						

sudo apt-getコマンドでインストールされたnginxのドキュメントルートの所有者はroot,グループもrootです。
パーミッションは、umaskで設定されている0022が減算値となり、755になっています。

nginxのworkerプロセスがドキュメントルートの各ディレクトリのwebリソースを読み込みhttpのレスポンスとして出力するには、

ディレクトリは、nginxのworkerプロセス即ちnginxアカウントに対して実行権限x(200)さえあれば実行できる。
ファイル(html,css,js,画像)は、nginxのworkerプロセス即ちnginxアカウントに対して読取り権限r(400)さえあれば実行できる。

ドキュメントルートのファイル権限を検証する

実際に所有者、グループ、パーミッションを変えて検証します。

  1. ユーザアカウント(infra01[nginxグループ])でリモートログインします。
  2. ドキュメントルートのhtmlを確認
    $ cd /usr/share/nginx/html
    $ ls -la 
    $ -rwxr-xr-x 1 root  root   612  5月  8 20:06 index.html
    							
  3. webブラウザから、webサーバのIPアドレスを指定してデフォルト頁が表示されることを確認します。
  4. 所有者、グループをrootからnginxアカウント、nginxグループに変更します。
  5. ドキュメントルートのhtmlの所有者、グループを変更
    $ chown -R nginx:nginx index.html
    $ ls -la
    $ -rwxr-xr-x 1 nginx nginx  612  5月  8 20:06 index.html
    							
  6. webブラウザから、webサーバのIPアドレスを指定してデフォルト頁が表示されることを確認します。
  7. 実行権限のみのパーミッションを確認します。
  8. ファイルの実行権限のみ付与します。
    $ sudo chmod 100 index.html
    $ ls -la
    $ ---x------ 1 nginx nginx  612  5月  8 20:06 index.html
    							
  9. webブラウザから、webサーバのIPアドレスを指定すると「403 Forbidden」画面が表示されます。
    更にアクセスログ(/var/log/nginx/access.log)、実行ログ(/var/log/nginx/error.log)にHTTP403エラーが出力されます。
    実行権限を厳しくしてファイルの読取りエラーがログでどのように出力されているかが重要になります。
  10. ログファイルの確認
    $ cd /var/log/nginx
    $ cat access.log 
    $ 192.168.109.2 - - [22/May/2017:10:04:24 +0900] "
      GET / HTTP/1.1" 403 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
      AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" "-"
    $ cat error.log
      2017/05/22 10:04:24 [error] 933#933: *31 open() "/usr/share/nginx/html/index.html" 
      failed (13: Permission denied), client: 192.168.109.2, server: localhost, request: "GET / HTTP/1.1", host: "192.168.109.4"
    							
  11. 次に書込み権限のみのパーミッションを確認します。
  12. ファイルの実行権限のみ付与します。
    $ cd /usr/share/nginx/html
    $ sudo chmod 200 index.html
    $ ls -la
    $ --w------- 1 nginx nginx  612  5月  8 20:06 index.html
    							
  13. webブラウザから、webサーバのIPアドレスを指定すると「403 Forbidden」画面が表示されます。
    更にアクセスログ(/var/log/nginx/access.log)、実行ログ(/var/log/nginx/error.log)にHTTP403エラーが出力されます。
    ここまでの過程でwebコンテンツを表示するだけの目的には、webリソースに「実行権限(1)」「書込み権限(2)」は不要だと分かります。
  14. 次に読込み権限のみのパーミッションを確認します。
  15. ファイルの実行権限のみ付与します。
    $ cd /usr/share/nginx/html
    $ sudo chmod 400 index.html
    $ ls -la
    $ -r-------- 1 nginx nginx  612  5月  8 20:06 index.html
    							
  16. webブラウザから、webサーバのIPアドレスを指定するとデフォルト画面(index.html)が表示されます。
    このことから、ドキュメントルート内のwebリソースは、nginxアカウントに対して読取り権限(4)即ち400さえあれば、
    静的コンテンツは、表示できるという事が分かります。

ドキュメントルートのディレクトリ権限を検証する

次にドキュメントルートのディレクトリ(/usr/share/nginx/html)の権限を変更してきます。

  1. ユーザアカウント(infra01[nginxグループ])でリモートログインします。
  2. ドキュメントルートディレクトリを確認
    $ cd /usr/share
    $ ls -la | grep nginx
    $ drwxr-xr-x    3 root root  4096  4月 26 10:53 nginx
    							
  3. nginx及び配下のhtmlディレクトリの所有者、グループをnginxアカウント、nginxグループに変更します。
  4. ディレクトリの所有者、グループを変更
    $ sudo chmod -R nginx:nginx nginx
    $ ls -la | grep nginx
    $ drwxr-xr-x   3 nginx nginx  4096  4月 26 10:53 nginx
    $ cd nginx
    $ ls -la 
    $ drwxr-xr-x   3 nginx nginx  4096  5月 22 09:47 html
    							
  5. webブラウザから、webサーバのIPアドレスを指定するとデフォルト画面(index.html)が表示されます。
  6. /usr/share/nginx/htmlディレクトリの権限を変更して検証します。
  7. ディレクトリのパーミッションを変更
    $ cd /usr/share/nginx
    $ sudo chmod 100 html
    $ ls -la 
    $ d--x------   3 nginx nginx  4096  5月 22 09:47 html
    							
  8. webブラウザから、webサーバのIPアドレスを指定するとデフォルト画面(index.html)が表示されます。
    この結果からディレクトリに対しては、実行権限(1)があればよいというのが分かります。
  9. /usr/share/nginx/htmlディレクトリの権限を書込みに変更して検証します。
  10. ディレクトリのパーミッションを書込み権限に変更
    $ cd /usr/share/nginx
    $ sudo chmod 200 html
    $ ls -la 
    $ d-w-------   3 nginx nginx  4096  5月 22 09:47 html
    							
  11. webブラウザから、webサーバのIPアドレスを指定すると「403 Forbidden」画面が表示されます。が表示されます。
    アクセスログ(/var/log/nginx/access.log)と実行ログ(/var/log/nginx/error.log)を確認します。
  12. /usr/share/nginx/htmlディレクトリの権限を読込みに変更して検証します。
  13. ディレクトリのパーミッションを読込み権限に変更
    $ cd /usr/share/nginx
    $ sudo chmod 400 html
    $ ls -la 
    $ dr--------   3 nginx nginx  4096  5月 22 09:47 html
    							
  14. webブラウザから、webサーバのIPアドレスを指定すると「403 Forbidden」画面が表示されます。が表示されます。
    アクセスログ(/var/log/nginx/access.log)と実行ログ(/var/log/nginx/error.log)を確認します。
  15. 以上の結果からnginxのworkerプロセスのアカウントnginxがwebリソースにアクセスするためには、
    nginxアカウントが所有者であるディレクトリに対して、実行権限(1)が最低限必要であることが分かります。
  16. /usr/share/nginx/htmlディレクトリの権限を実行権限に変更して次の検証をします。
  17. ディレクトリのパーミッションを実行権限に変更
    $ cd /usr/share/nginx
    $ sudo chmod 100 html
    $ ls -la 
    $ d--x------   3 nginx nginx  4096  5月 22 09:47 html
    							

ドキュメントルートにwebコンテンツを配備する

/usr/share/nginx/htmlディレクトリにwebコンテンツを配備します。

  1. gakumon.techにリリースしたトップ画面をnginxに公開してみます。
    以下のディレクトリ階層は、gakumon.techのトップ画面を構成するwebリソースです。
  2. webコンテンツ
  3. まずは、zipファイルで固めます。
    プロジェクトコードである「education」を右クリックし、「.zip」-[圧縮]を実行します。
  4. winSCPを起動します。
    [転送プロトコル]にSFTP、[ホスト名]にnginxをインストールしたIPアドレス、[ユーザ名]に作業用ユーザアカウントを指定します。
  5. winscp
  6. Teraterm又はwinSCPで事前に作業者アカウントの作業ディレクトリを作成します。
    /home/infra01/work/YYYYMMDD(年月日)を作成します。
  7. ディレクトリのパーミッションを読込み権限に変更
    $ cd  ※./home/infra01にカレントデイレクリを移動
    $ mkdir work
    $ cd work
    $ mkdir 20170522
    							
  8. winSCPの左側のエクスプローラーから先に作成した「education.zip」ファイルをドラック&ドロップして、
    /home/infra01/work/20170522ディレクトリファイル転送します。
  9. winscp
  10. Teratermからwebサーバに転送したeducation.zipを解凍します。
  11. zipファイルの解凍
    $ cd  ※./home/infra01にカレントデイレクリを移動
    $ cd work/20170522
    $ ls -la
    $ rw-r--r-- 1 infra01 infrateam 3374127  5月 22 11:08 education.zip
    $ unzip education.zip
    $ ls -la
    $ drwxr-xr-x 6 infra01 infrateam    4096  5月 22 11:29 education
    $ -rw-r--r-- 1 infra01 infrateam 3374127  5月 22 11:08 education.zip
    							
    コンテンツの権限変更
    $ cd ~/work/20170522
    $ chown -R nginx:nginx education
    # ※.education以下のディレクトリ権限を775に変更
    $ find education -type d -print | xargs sudo chmod 775  
    # ※.nginx以下のファイル権限を664に変更
    $ find education -type f -print | xargs sudo chmod 664
    							
  12. ドキュメントルートにコンテンツを上げる
  13. コンテンツを上げる
    $ pwd
    $ /home/infra01/work/20170522
    $ cp -r education/* /usr/share/nginx/html/
    							
  14. 重要ここで、/usr/share/nginx/htmlの権限がnginxアカウントに対して、実行権限(1)しか付与していないため、
    作業者アカウント(infra01)の/home/infra01/work/20170522/education以下のファイル及びディレクトリがコピーできません。
  15. 作業者アカウント(infra01)には、nginxグループを付与しているので、nginxグループが読書きできるように/usr/share/nginx/htmlの権限を変更します。
    nginxアカウントとnginxグループに全ての権限を付与、その他には、ディレクトリの一覧表示と読取り権限のみを付与します。
  16. ドキュメントルートの権限変更
    $ cd /usr/share
    $ chown -R nginx:nginx nginx
    # ※.nginx以下のディレクトリ権限を775に変更
    $ find nginx -type d -print | xargs sudo chmod 775  
    # ※.nginx以下のファイル権限を664に変更
    $ find nginx -type f -print | xargs sudo chmod 664
    							
  17. 再度ドキュメントルートにコンテンツを上げる
  18. コンテンツを上げる
    $ cd ~/work/20170522
    $ pwd
    $ /home/infra01/work/20170522
    $ cp -rf education/* /usr/share/nginx/html/
    							
  19. コピー後の権限類を確認します。
  20. 所有者、グループ、パーミッションの確認
    $ cd /usr/share/nginx/html
    $ ls -la
    $ drwxrwxr-x 4 nginx nginx  4096  5月 22 12:28 css
    $ -rw-rw-r-- 1 nginx nginx  4286  1月 18 01:56 favicon.ico
    $ drwxrwxr-x 2 nginx nginx  4096  5月 22 11:59 fonts
    $ drwxrwxr-x 2 nginx nginx  4096  5月 22 12:10 images
    $ -rw-rw-r-- 1 nginx nginx 11959  5月 17 20:50 index.html
    $ drwxrwxr-x 4 nginx nginx  4096  5月 22 11:59 js
    
    							
  21. webブラウザからwebサーバにアクセスします。
    貴方が作成したコンテンツが表示されればOKです。
  22. index.htmlのスクリーンショット

    ドキュメントルートのパーミッションについて

    私は、ディレクトリのパーミッションに対して、nginxアカウントとnginxグループに7(全権限)を付与しました。
    これは、nginxグループに所属するアカウントinfra01ユーザアカウントがコンテンツをアップロードするために付与しました。
    同様にファイルに関しても、nginxアカウントとnginxグループに6(読取り+書込み[削除含む])を付与しました。

    この結果ディレクトリに775を付与して、ファイルには664を設定しました。

    多くの書籍、webで情報が不足しているのが、作業者のユーザアカウントとそのグループ、ホームディレクトリを明示せずに
    755,644とnginxアカウントのみに権限を付与しています。
    これでコンテンツをアップロードできるアカウントは、nginxアカウントかrootアカウント(sudo)となります。

    本書の例では、775を755に664を644に変更した場合には、 cp -rf education/* /usr/share/nginx/html/を
    sudo cp -rf education/* /usr/share/nginx/html/ に変更すれば実行可能です。

    よく見かける755と644ですが、sudoコマンドをどうせ使うのであれば何故、550,440や100と400にしないのでしょうか?

    これは、あくまでも推測でしかないのですが、755,644を付与してsudo cpコマンドが明記されていない
    情報の製作者が利用しているアカウントは、root又はnginxをログイン(nologinを解除)して、実行されているからでしょう。

    また、Linuxの慣習から755と644に従っているだけで、そのようにすべきと定義された情報を知っている人は数少ないと思います。

    以下にアカウント設計、ディレクトリのパーミッション設計時に留意して欲しい内容を明記します。

    • 755,644の理由を説明する必要がある。
    • コンテンツをアップロードし、ドキュメントルートに公開するユーザアカウントを明示する。
    • 作業者のユーザアカウントにnginxグループを付与する設計を私は推奨します。
    • nginxアカウントは、nologin(su でスイッチできない)を維持すること。
    • ドキュメントルートを作業者アカウントのホームディレクトリにしてはいけない。
    • sudo コマンドを必要とする場合には、手順に明記する必要がある。
    • スーパーユーザrootと管理者ユーザ(インストール時に作成したユーザ)での作業は避ける。
    • root権限によるcpなどは、作業用アカウントにsudoグループを付与する。

    以上から、nginxのドキュメントルートのパーミッションに関しては、ディレクトリが775~100、ファイルが664~400を ベースに会社のセキュリティポリシーを鑑みて、インフラチーム、運用チーム、共通チームと相談して具体的な設定値を確定します。