home / vps / nginx nginx

サービス選定〜OSのインストール
サーバー類のインストール
>>> nginx
さくら de Ubuntu
サーバーの引越
バックアップ
Let's Encrypt
05 Nov 2018 rewriteと正規表現を併用した方法を追記、ダウンロードさせる方法にMIMEをいぢらない方法を追加。
27 Oct 2018 rewriteを使った方法、バイナリファイルとしてダウンロードさせる方法を追加。
07 Sep 2018 新規作成。

home / vps / nginx locationの正規表現

 基本的に部分一致なので、全体をマッチさせたいときは^$を使う必要がある。 正規表現の性質から最初や最後が.*のときはいらないけど。 自信なければ付けておいた方がいい。 あと、aliasを使う場合はキャプチャパターン($1など)が必要なので注意。

home / vps / nginx alias

 普通はこんな感じ。

location /hoge/ {
    alias /home/hoge/public_html/;
}

ただ、これだと http://www.example.jp/hogeのようなスラッシュなしのURLがヒットしない。 try_filesを指定していたとしても。 try_files以前にaliasに引っかからないのでトライしようがない。

location /hoge {
    alias /home/hoge/public_html/;
}

これは一応動く。 が、nginxはURLの/hoge/home/hoge/public_html/に置き換えているだけなので、スラッシュ抜きのURLでもアクセスできてしまう。 例えば、 http://www.example.jp/hogeindex.htm/home/hoge/public_html/index.htm になるので、アクセスできてしまう。

location /hoge {
    alias /home/hoge/public_html;
}

これも一応動く。 スラッシュを抜いたURLによるアクセスも防げる。 が、public_htmlから始まる他のファイルやディレクトリにもアクセスできてしまう。 例えば、 /home/hoge/public_html.txt というファイルがあったとすれば、 http://www.example.jp/hoge.txt でアクセスできてしまう。

 結局、これが正しい。

location = /hoge {
    alias /home/hoge/public_html/;
}
location /hoge/ {
    alias /home/hoge/public_html/;
}

これだとファイルの置いてあるパスが変わると2カ所書き換えないといけない。 rewriteを使えば、

location = /hoge {
    rewrite (.*) $1/ permanent;
}
location /hoge/ {
    alias /home/hoge/public_html/;
}

あるいは正規表現を使えば、URLもひとつにまとめることができて、

location ~ ^/hoge(/.*)?$ {
    alias /home/hoge/public_html/$1;
}

正規表現とrewriteを使った別解。

location ~ ^/[^/]+$ {
    rewrite (.*) $1/ permanent;
}
location /hoge/ {
    alias /home/hoge/public_html/;
}
location /fuga/ {
    alias /home/fuga/public_html/;
}

rewriteで末尾のスラッシュのないURLをスラッシュ付きのURLに飛ばして、あとは普通にプレフィックス指定でマッチさせる。 ?とか&とかを除外したい場合は[]の中身を考えたほうがよい。 [-A-Za-z0-9_.]とかの方がいいかも。

home / vps / nginx Apache httpdのrotatelogsを使う

 ログファイルに日付つけたいときはやっぱりrotatelogsが便利なので。 結構みんな苦労してるみたいけど、FIFO(名前付きパイプ)を使うと比較的簡単にできる。 まずどこかにFIFOを作る。 パーミッションを適当に設定しておく。

$ cd /var/log/nginx
$ mkfifo log.fifo
$ chown www-data log.fifo
$ chmod 600 log.fifo

nginxはこのFIFOにログを吐き出すようにする。

access_log /var/log/nginx/log.fifo;

で、rotatelogsの入力をFIFOにしてしまえばよい。 原理的にはsuかなんかでFIFOを読めるユーザー(この例ではwww-data)になって

$ rotatelogs /var/log/nginx/access_log.%y%m%d 86400 300 < /var/log/nginx/log.fifo

とすれば動くだろう。 実際にはsystemdから起動するが、systemdのサービスコマンド指定にはリダイレクトを直接書けないので、シェルを通して起動するように書くか、以下のようなシェルスクリプトを書く。

#!/bin/bash
umask 037
exec < /var/log/nginx/log.fifo
exec rotatelogs /var/log/nginx/access_log.%y%m%d 86400 300 < /var/log/nginx/log.fifo

この書き方の場合、最後のexecでシェルスクリプトを実行しているプロセスがrotatelogsと置き換わる形になるので無駄なプロセスが残らない。 最後にsystemdのサービスを書く。 死んだら再起動するようにしておくとよいだろう。 Requiresとかは自分で考えておくれ。

[Service]
User=www-data
Type=simple
ExecStart=.../nginx-rotatelogs.sh
Restart=always

 nginxやrotatelogsを殺したりしてみたが、これで問題なくログを取り続けてくれるようだ。 最後に、必要に応じてlogrotate(システムに元からくっついてくる方)の設定を確認する。 エラーログもあることを忘れずに。 ちなみに、オフセットに300(単位は分)と書いてあるのは、UTC+5で0時のときにログが切り替わるという意味で、JST=UTC+9ならば午前4時にログが切り替わる。

home / vps / nginx CGIまわり

 fcgiwrap経由で実行する。

location /gitweb/ {
    auth_basic "akamoz project";
    auth_basic_user_file /usr/local/etc/nginx/htpasswd;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
    fastcgi_param SCRIPT_FILENAME /usr/share/gitweb/gitweb.cgi;
    include /etc/nginx/fastcgi_params;
    location ~ ^/gitweb/(.+) {
        alias /usr/share/gitweb/$1;
    }
}

Ubuntuのパッケージの場合、includeするファイルにはfastcgi_paramsfastcgi.confがあるのだが、前者にはSCRIPT_FILENAMEがなく、後者にはある。 最初、上書きされるのかと思ったら、先勝ちっぽい感じ。 なので、安全を期すなら、SCRIPT_FILENAMEを指定する場合はfastcgi_paramsをincludeしておいた方がいい。

 この例はCGIの他、basic認証、locationの入れ子など、結構盛りだくさん。 パスワードファイルはパスワードをコロンでつないだ行をずらずらと。 パスワードはopenssl passwdで作れる。

 locationが入れ子になっている場合、内側のlocationで指示したURLは外側のlocationで指示したURLの階層下にないといけない。 外側が正規表現で、内側がプレフィックス指定の場合はたいていエラーになる。

 この入れ子locationは何をやっているかというと、/gitweb/をアクセスした場合はgitwebスクリプトを実行し、/gitweb/...をアクセスした場合は普通にファイルを返す。 こうしないと/gitweb/static以下にある画像ファイルなどがアクセスできない。 locationを分けてもよいが、入れ子にしておくと設定していないものは親locationのものが使われるので楽。 この場合は画像ファイルなどにもbasic認証が必要になる。

home / vps / nginx ファイルとしてダウンロードさせる

location = /hoge/download/ {
    alias /home/hoge/download/;
    types { }
    default_type application/octet-stream;
}

 MIMEタイプのマップをクリアした上で、デフォルトのMIMEタイプをapplication/octet-streamにする。

 強制的にダウンロードのダイアログを開かせるには、

    add_header Content-Disposition 'attachment';

を加える。


Copyright (C) 2018 akamoz.jp

$Id: nginx.htm,v 1.13 2019/05/24 15:20:20 you Exp $