結論から言うと 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
かなぁ…