【Laravel】ログファイルのパーミッションの問題で500エラーが出るのを防ぐ【メモ】

先日「JSON.stringifyが空要素をNULLに変換するようになってハマる」について調べていたときに気が付いたことです






問題は解決したはずなのに500エラーが出る

JSON.stringifyが空要素をNULLに変換するようになってハマる



この問題が解決されてプログラム的に動くようにしたはずなのに翌日になったらまた500エラーを出すようになりました。なんでなんだろうなと思って調べてみたら、それほど重大ではない(既に登録済みだったから新規登録はしなかったよ、程度の)エラーログが出力されており、そのログをログファイルに書き込む過程で失敗していることがわかりました。道理でエラーログにエラーがないわけだ。

よくよく見てみるとログディレクトリはこんな感じになってました(抜粋)。


$ ls -al storage/logs
total 2548
-rw-rw-r--  1 ec2-user apache 208778 Feb 20 23:45 laravel-2023-02-20.log
-rw-rw-r--  1 ec2-user apache 171624 Feb 21 23:45 laravel-2023-02-21.log
-rw-rw-r--  1 ec2-user apache 171624 Feb 22 23:45 laravel-2023-02-22.log
-rw-r--r--  1 apache apache 171624 Feb 23 23:45 laravel-2023-02-23.log


所有者が「ec2-user」になっているファイルが前日までにパーミッションを変更したログファイル。一方所有者が「apache」になっているファイルはバッチが自動的に生成したログファイルです。バッチが生成したログファイルは書き込み権限が「644」になっていて、Laravelの実行ユーザである「ec2-user」に書き込み権限がありません。それで書き込みが失敗してしまっていたんですね。



常套手段は、apacheとec2-userを同じグループに入れてファイルを664で生成

パーミッション「664」なら同じグループに属しているユーザーには書き込み権限があることになります。手順は以下の以下の通り。


  1. apacheのコマンドでグループを生成、ユーザーを追加
  2. ログディレクトリを1のグループに属させる
  3. Laravelのconfigを設定


apacheのコマンドでグループを生成、ユーザーを追加

例えば「laravel」というグループを作成し「root」「apache」「ec2-user」の3ユーザーを所属させます。


$ sudo groupadd laravel
$ sudo gpasswd -a root laravel
$ sudo gpasswd -a apache laravel
$ sudo gpasswd -a ec2-user laravel

ログディレクトリを1のグループに属させる

$ sudo chown -R :laravel ./storage/logs

Laravelのconfigを設定

Laravelのconfig/logging.phpで、ログファイルのパーミッションを設定することが出来ます。


'daily' => [
   'driver' => 'daily',
   'path' => storage_path('logs/laravel.log'),
   'level' => 'debug',
   'days' => 14,
   'permission' => 0664,    // ← 追加
],


これで大丈夫!……あれ?



ダメなときはACLを設定しましょう

僕の環境ではこうなってました。再びログディレクトリ。


$ ls -al storage/logs
total 2548
-rw-rw-r--  1 ec2-user laravel 208778 Feb 20 23:45 laravel-2023-02-20.log
-rw-rw-r--  1 ec2-user laravel 171624 Feb 21 23:45 laravel-2023-02-21.log
-rw-rw-r--  1 ec2-user laravel 171624 Feb 22 23:45 laravel-2023-02-22.log
-rw-rw-r--  1 ec2-user laravel 171624 Feb 23 23:45 laravel-2023-02-23.log
-rw-r--r--  1 ec2-user laravel 171624 Feb 24 23:45 laravel-2023-02-24.log


グループは設定出来ているものの、パーミッションは相変わらず644でした。元がどういう設定だったか今となってはわかりませんが、configを上回る(恐らくApache側の)なんらかの設定によって新規に生成されるログファイルのパーミッションは644に制限されているようです。じゃあ、これを上書きしましょう。

というわけで、こう。


$ sudo setfacl -R -d -m g:laravel:rwx ./storage/logs


これを実行すると、ACLが追加されます。確認してみるとこんな感じ。


$ getfacl storage/logs
# file: storage/logs
# owner: ec2-user
# group: laravel
# flags: -s-
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:laravel:rwx
default:mask::rwx
default:other::r-x


「default」以下が追加されたルールで、「default:group:laravel:rwx」はlaravelグループのユーザーに書き込み権限を与えることを示しています。これで解決。



ちなみに:ACLを削除するときは

このコマンドでOKらしいです。


$ sudo setfacl -b ./storage/logs


しかしこれは僕の個人サーバだから適当でも構わないですけど、実際の場面では個別のディレクトリに個別のアクセスコントロールを設定するのは運用上問題があるよなあと思います。きちんとApacheの設定を見てしかるべきセキュリティ設定をすべきじゃないのかと思ったんですけど、残念ながらそこまではわかりませんでした。どうするのが完全に正解なのかな?