05 Nov 2018 | rewrite と正規表現を併用した方法を追記、ダウンロードさせる方法にMIMEをいぢらない方法を追加。
|
27 Oct 2018 | rewrite を使った方法、バイナリファイルとしてダウンロードさせる方法を追加。
|
07 Sep 2018 | 新規作成。 |
基本的に部分一致なので、全体をマッチさせたいときは^
と$
を使う必要がある。
正規表現の性質から最初や最後が.*
のときはいらないけど。
自信なければ付けておいた方がいい。
あと、alias
を使う場合はキャプチャパターン($1
など)が必要なので注意。
普通はこんな感じ。
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_.]
とかの方がいいかも。
ログファイルに日付つけたいときはやっぱり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時にログが切り替わる。
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_params
とfastcgi.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認証が必要になる。
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 $