結論から言うと Amazon Linux 2 の nginx
パッケージの問題でもあるけど Nginx の仕様も問題 ということになった。
Nginx を起動するときは特に問題ないのだけどログを見てると夜中のログローテーションのタイミングで何故かログが書き込みできなくなっていた。
2022/01/30 03:26:01 [emerg] 8725#8725: open() "/var/log/nginx/error.log" failed (13: Permission denied) 2022/01/30 03:26:01 [emerg] 8725#8725: open() "/var/log/nginx/access.log" failed (13: Permission denied)
Amazon Linux 2 のバージョンと Nginx のバージョン。(Docker だけど)
bash-4.2# uname -a Linux 82589fcda577 5.10.76-linuxkit #1 SMP Mon Nov 8 10:21:19 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux bash-4.2# yum info nginx Loaded plugins: ovl, priorities Installed Packages Name : nginx Arch : x86_64 Epoch : 1 Version : 1.20.0 Release : 2.amzn2.0.4 Size : 1.7 M Repo : installed From repo : amzn2extra-nginx1 Summary : A high performance web server and reverse proxy server URL : https://nginx.org License : BSD Description : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and : IMAP protocols, with a strong focus on high concurrency, performance and low : memory usage.
logrotate の設定ファイルを見ると postrotate
で kill -USR1
(nginx -s reopen
)している。
/etc/logrotate.d/nginx
/var/log/nginx/*log { daily rotate 10 missingok notifempty compress sharedscripts postrotate /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true endscript }
/var/log/nginx
は root:root 700
だけどマスタープロセスは root
で動いているし、起動や再起動のときにログに書き込みができないようなエラーは出ない。ただ、ローテーションしたタイミングでログファイルの所有権が nginx:root
に変わってるのが謎だった。
Nginx のインストール構成に問題があるのかと思ったので調べてみる。
RPM パッケージのスクリプトでは特にパーミッションを弄るような操作はしていない模様。
bash-4.2# yum reinstall --downloadonly --downloaddir=/tmp nginx bash-4.2# rpm -qp --scripts /tmp/nginx-1.20.0-2.amzn2.0.4.x86_64.rpm postinstall scriptlet (using /bin/sh): if [ $1 -eq 1 ] ; then # Initial installation systemctl preset nginx.service >/dev/null 2>&1 || : fi preuninstall scriptlet (using /bin/sh): if [ $1 -eq 0 ] ; then # Package removal, not upgrade systemctl --no-reload disable nginx.service > /dev/null 2>&1 || : systemctl stop nginx.service > /dev/null 2>&1 || : fi postuninstall scriptlet (using /bin/sh): systemctl daemon-reload >/dev/null 2>&1 || : if [ $1 -ge 1 ]; then /usr/bin/nginx-upgrade >/dev/null 2>&1 || : fi
--queryformat|--qf
オプションでコンテンツの内容を確認してみる。
bash-4.2# rpm -q --qf "[%{FILEMODES:perms} %{FILEUSERNAME}:%{FILEGROUPNAME} %{FILENAMES}\n]" nginx | column -t -rw-r--r-- root:root /etc/logrotate.d/nginx -rw-r--r-- root:root /etc/nginx/fastcgi.conf -rw-r--r-- root:root /etc/nginx/fastcgi.conf.default -rw-r--r-- root:root /etc/nginx/fastcgi_params -rw-r--r-- root:root /etc/nginx/fastcgi_params.default -rw-r--r-- root:root /etc/nginx/koi-utf -rw-r--r-- root:root /etc/nginx/koi-win -rw-r--r-- root:root /etc/nginx/mime.types -rw-r--r-- root:root /etc/nginx/mime.types.default -rw-r--r-- root:root /etc/nginx/nginx.conf -rw-r--r-- root:root /etc/nginx/nginx.conf.default -rw-r--r-- root:root /etc/nginx/scgi_params -rw-r--r-- root:root /etc/nginx/scgi_params.default -rw-r--r-- root:root /etc/nginx/uwsgi_params -rw-r--r-- root:root /etc/nginx/uwsgi_params.default -rw-r--r-- root:root /etc/nginx/win-utf -rwxr-xr-x root:root /usr/bin/nginx-upgrade -rw-r--r-- root:root /usr/lib/systemd/system/nginx.service drwxr-xr-x root:root /usr/lib64/nginx/modules -rwxr-xr-x root:root /usr/sbin/nginx drwxr-xr-x root:root /usr/share/doc/nginx-1.20.0 -rw-r--r-- root:root /usr/share/doc/nginx-1.20.0/CHANGES -rw-r--r-- root:root /usr/share/doc/nginx-1.20.0/README -rw-r--r-- root:root /usr/share/doc/nginx-1.20.0/README.dynamic -rw-r--r-- root:root /usr/share/doc/nginx-1.20.0/UPGRADE-NOTES-1.6-to-1.10 drwxr-xr-x root:root /usr/share/licenses/nginx-1.20.0 -rw-r--r-- root:root /usr/share/licenses/nginx-1.20.0/LICENSE -r--r--r-- root:root /usr/share/man/man3/nginx.3pm.gz -rw-r--r-- root:root /usr/share/man/man8/nginx-upgrade.8.gz -rw-r--r-- root:root /usr/share/man/man8/nginx.8.gz -rw-r--r-- root:root /usr/share/nginx/html/404.html -rw-r--r-- root:root /usr/share/nginx/html/50x.html drwxr-xr-x root:root /usr/share/nginx/html/icons lrwxrwxrwx root:root /usr/share/nginx/html/icons/poweredby.png -rw-r--r-- root:root /usr/share/nginx/html/index.html -rw-r--r-- root:root /usr/share/nginx/html/nginx-logo.png lrwxrwxrwx root:root /usr/share/nginx/html/poweredby.png -rw-r--r-- root:root /usr/share/vim/vimfiles/ftdetect/nginx.vim -rw-r--r-- root:root /usr/share/vim/vimfiles/ftplugin/nginx.vim -rw-r--r-- root:root /usr/share/vim/vimfiles/indent/nginx.vim -rw-r--r-- root:root /usr/share/vim/vimfiles/syntax/nginx.vim drwxrwx--- nginx:root /var/lib/nginx drwxrwx--- nginx:root /var/lib/nginx/tmp drwx------ root:root /var/log/nginx
これを見てみると /var/log/nginx
は最初から root:root 0700
なようだ。
Amazon Linux 1 はどうなっていたのか
Nginx のバージョンは 1.18 系。
bash-4.2# yum info nginx Loaded plugins: ovl, priorities Installed Packages Name : nginx Arch : x86_64 Epoch : 1 Version : 1.18.0 Release : 1.43.amzn1 Size : 1.5 M Repo : installed From repo : amzn-updates Summary : A high performance web server and reverse proxy server URL : https://nginx.org License : BSD Description : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and : IMAP protocols, with a strong focus on high concurrency, performance and low : memory usage.
bash-4.2# rpm -q --qf "[%{FILEMODES:perms} %{FILEUSERNAME}:%{FILEGROUPNAME} %{FILENAMES}\\n]" nginx | column -t -rw-r--r-- root:root /etc/logrotate.d/nginx drwxr-xr-x root:root /etc/nginx drwxr-xr-x root:root /etc/nginx/conf.d -rw-r--r-- root:root /etc/nginx/conf.d/virtual.conf drwxr-xr-x root:root /etc/nginx/default.d -rw-r--r-- root:root /etc/nginx/fastcgi.conf -rw-r--r-- root:root /etc/nginx/fastcgi.conf.default -rw-r--r-- root:root /etc/nginx/fastcgi_params -rw-r--r-- root:root /etc/nginx/fastcgi_params.default -rw-r--r-- root:root /etc/nginx/koi-utf -rw-r--r-- root:root /etc/nginx/koi-win -rw-r--r-- root:root /etc/nginx/mime.types -rw-r--r-- root:root /etc/nginx/mime.types.default -rw-r--r-- root:root /etc/nginx/nginx.conf -rw-r--r-- root:root /etc/nginx/nginx.conf.default -rw-r--r-- root:root /etc/nginx/scgi_params -rw-r--r-- root:root /etc/nginx/scgi_params.default -rw-r--r-- root:root /etc/nginx/uwsgi_params -rw-r--r-- root:root /etc/nginx/uwsgi_params.default -rw-r--r-- root:root /etc/nginx/win-utf -rwxr-xr-x root:root /etc/rc.d/init.d/nginx -rw-r--r-- root:root /etc/sysconfig/nginx drwxr-xr-x root:root /usr/lib64/nginx/modules -rwxr-xr-x root:root /usr/sbin/nginx drwxr-xr-x root:root /usr/share/doc/nginx-1.18.0 -rw-r--r-- root:root /usr/share/doc/nginx-1.18.0/CHANGES -rw-r--r-- root:root /usr/share/doc/nginx-1.18.0/README -rw-r--r-- root:root /usr/share/doc/nginx-1.18.0/README.dynamic drwxr-xr-x root:root /usr/share/licenses/nginx-1.18.0 -rw-r--r-- root:root /usr/share/licenses/nginx-1.18.0/LICENSE -r--r--r-- root:root /usr/share/man/man3/nginx.3pm.gz -rw-r--r-- root:root /usr/share/man/man8/nginx.8.gz drwxr-xr-x root:root /usr/share/nginx drwxr-xr-x root:root /usr/share/nginx/html -rw-r--r-- root:root /usr/share/nginx/html/404.html -rw-r--r-- root:root /usr/share/nginx/html/50x.html drwxr-xr-x root:root /usr/share/nginx/html/icons lrwxrwxrwx root:root /usr/share/nginx/html/icons/poweredby.png -rw-r--r-- root:root /usr/share/nginx/html/index.html -rw-r--r-- root:root /usr/share/nginx/html/nginx-logo.png lrwxrwxrwx root:root /usr/share/nginx/html/poweredby.png -rw-r--r-- root:root /usr/share/vim/vimfiles/ftdetect/nginx.vim -rw-r--r-- root:root /usr/share/vim/vimfiles/ftplugin/nginx.vim -rw-r--r-- root:root /usr/share/vim/vimfiles/indent/nginx.vim -rw-r--r-- root:root /usr/share/vim/vimfiles/syntax/nginx.vim drwxrwx--- nginx:root /var/lib/nginx drwxrwx--- nginx:root /var/lib/nginx/tmp drwxrwx--- nginx:root /var/log/nginx
1.18 系のときは /var/log/nginx
は nginx:root 770
だったようだ。
Amazon Linux 1 と Amazon Linux 2 でどこが変わったのか
色々差はあるけど今回問題なのはここ。
--- /tmp/1.txt 2022-02-05 10:44:56.000000000 +0900 +++ /tmp/2.txt 2022-02-05 10:44:30.000000000 +0900 @@ -45,4 +41,4 @@ -rw-r--r-- root:root /usr/share/vim/vimfiles/syntax/nginx.vim drwxrwx--- nginx:root /var/lib/nginx drwxrwx--- nginx:root /var/lib/nginx/tmp -drwxrwx--- nginx:root /var/log/nginx +drwx------ root:root /var/log/nginx
Nginx 1.18 系では nginx:root 770
になっていたものが 1.20 系では root:root 700
に変わっている。
Nginx をソースコードからビルドしたらどうなるのか
気になったので nginx-1.20.2 をビルドして動かしてみた。普通に make install
したら logs
ディレクトリは 755
。
bash-4.2# ls -l /usr/local/nginx total 36 drwxr-xr-x 2 root root 4096 Feb 5 02:02 conf drwxr-xr-x 2 root root 4096 Feb 5 02:02 html drwxr-xr-x 2 root root 4096 Feb 5 02:12 logs drwxr-xr-x 2 root root 4096 Feb 5 02:02 sbin
kill -USR1
でやっぱりログの所有権が変わってしまうようだが書き込みはできている模様。
bash-4.2# ls -l /usr/local/nginx/logs total 20 -rw-r--r-- 1 nobody root 173 Feb 5 02:13 access.log -rw-r--r-- 1 root root 31 Feb 5 02:07 access.log.gz -rw-r--r-- 1 nobody root 196 Feb 5 02:13 error.log -rw-r--r-- 1 root root 89 Feb 5 02:08 error.log.gz -rw-r--r-- 1 root root 6 Feb 5 02:08 nginx.pid
パーミッション変えてみたら書き込めなくなった。
bash-4.2# chmod 700 /usr/local/nginx/logs bash-4.2# rm /usr/local/nginx/logs/* bash-4.2# kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` bash-4.2# curl localhost bash-4.2# ls -l /usr/local/nginx/logs total 8 -rw-r--r-- 1 nobody root 0 Feb 5 02:15 access.log -rw-r--r-- 1 nobody root 0 Feb 5 02:15 error.log -rw-r--r-- 1 root root 6 Feb 5 02:08 nginx.pid
その後 770
も試してみたところ書き込みできているように見えるのに error.log
に Permission denied
が出たり意味不明。
また、logs
を 755
に戻しただけでは書き込みは再開されず、一旦 kill -USR1
する必要がある模様。ということは reopen
するときにログに書き込みできるかどうか見てるのだろうか。
Amazon Linux 2 の nginx-1.20.0 でも同じように 755
にして kill -USR1
したら問題なく書き込めることが確認できた。
なにこの挙動
Nginx を nginx
ユーザで動かしたときにアバウトに確認してみたところ下記のようになった(気がする)。
root:root | nginx:root | |
---|---|---|
777 | true | true |
775 | true | true |
770 | false | true |
755 | true | true |
750 | false | true |
707 | true | true |
705 | true | true |
700 | false | true |
reopen
時にログファイルが存在しているかどうかのチェックは実行ユーザでしていて書き込みは root
でしてるの…?
(ついでに)Nginx 公式の CentOS パッケージ
root:root
で 755
だそうです。
[root@66e4b0919a1e /]# ls -l /var/log total 52 -rw------- 1 root utmp 0 Nov 13 2020 btmp -rw-r--r-- 1 root root 193 Nov 13 2020 grubby_prune_debug -rw-r--r-- 1 root root 292000 Feb 5 03:55 lastlog drwxr-xr-x 2 root root 4096 Feb 5 03:55 nginx -rw------- 1 root root 64000 Feb 5 03:55 tallylog -rw-rw-r-- 1 root utmp 0 Nov 13 2020 wtmp -rw------- 1 root root 1665 Feb 5 03:55 yum.log
標準の動作だとログを削除して reopen
すると nginx:root
になるんだけど logrotate のときは nginx:adm
で create
するようにしてるっぽい。
/etc/logrotate.d/nginx
/var/log/nginx/*.log { daily missingok rotate 52 compress delaycompress notifempty create 640 nginx adm sharedscripts postrotate if [ -f /var/run/nginx.pid ]; then kill -USR1 `cat /var/run/nginx.pid` fi endscript }
結局どうするのがいいのか
- 一般ユーザがログを閲覧できていいなら
root:root
で755
- 一般ユーザにログを見せたくないなら
nginx:root
で700
かなぁ…