EC-CUBE 4.1 から execise/htmlpurifier-bundle
パッケージが追加されたようです。
フロント入力項目のサニタイズ · EC-CUBE/ec-cube@871ba01 · GitHub
2021 年 6 月だから最近というわけでも無いのですが、これによってキャッシュ削除処理でパーミッション問題が出るようになったっぽいです。
Failed to remove file "/var/www/eccube/var/cache/dev/htmlpurifier/URI/4.14.0,3478238e680361cd87bf880f5b3cc50a1e7abc6c,1.ser": unlink(/var/www/eccube/var/cache/dev/htmlpurifier/URI/4.14.0,3478238e680361cd87bf880f5b3cc50a1e7abc6c,1.ser): Permission denied
execise/htmlpurifier-bundle
と一緒に ezyang/htmlpurifier
パッケージがインストールされますが、こいついがパーミッション設定を独自に持っていてプロセス(Apache やら PHP-FPM など)の Umask を無視して勝手にパーミッション設定をしてしまうことにより下記のディレクトリや配下のファイルのパーミッションが 755
または 644
になりグループ権限がリードだけになってしまいます。
var/cache/ENV/htmlpurifier/CSS
var/cache/ENV/htmlpurifier/HTML
var/cache/ENV/htmlpurifier/URI
で、これらのキャッシュが Web サーバのプロセスによって生成された場合、作業用ユーザーとは異なるので console c:c
などしたときにこいつらが消せなくなります。(かといって sudo
で console c:c
するとキャッシュのオーナーが root
になるのでダメ)
管理画面から削除すればいいんですがプロキシやらスキーマの更新のときにいちいちそんなことはしたくないですよね。
ディレクトリとファイルを生成している Serializer.php
を見てみると mkdir()
の引数にパーミッションを与えている部分と chmod()
でパーミッションを変更している部分が見つかります。
vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer.php
private function _prepareDir($config) { $directory = $this->generateDirectoryPath($config); $chmod = $config->get('Cache.SerializerPermissions'); if ($chmod === null) { if (!@mkdir($directory) && !is_dir($directory)) { trigger_error( 'Could not create directory ' . $directory . '', E_USER_WARNING ); return false; } return true; } if (!is_dir($directory)) { $base = $this->generateBaseDirectoryPath($config); if (!is_dir($base)) { trigger_error( 'Base directory ' . $base . ' does not exist, please create or change using %Cache.SerializerPath', E_USER_WARNING ); return false; } elseif (!$this->_testPermissions($base, $chmod)) { return false; } if (!@mkdir($directory, $chmod) && !is_dir($directory)) { trigger_error( 'Could not create directory ' . $directory . '', E_USER_WARNING ); return false; } if (!$this->_testPermissions($directory, $chmod)) { return false; } } elseif (!$this->_testPermissions($directory, $chmod)) { return false; } return true; }
private function _write($file, $data, $config) { $result = file_put_contents($file, $data); if ($result !== false) { // set permissions of the new file (no execute) $chmod = $config->get('Cache.SerializerPermissions'); if ($chmod !== null) { chmod($file, $chmod & 0666); } } return $result; }
いずれも $config->get('Cache.SerializerPermissions')
で Cache.SerializerPermissions
の値を拾っているようですが、これは YAML などには記述されていません。恐らく ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt
の中に書いてある DEFAULT
の値を見ているような気がします。
ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt
Cache.SerializerPermissions TYPE: int/null VERSION: 4.3.0 DEFAULT: 0755 --DESCRIPTION-- <p> Directory permissions of the files and directories created inside the DefinitionCache/Serializer or other custom serializer path. </p> <p> In HTML Purifier 4.8.0, this also supports <code>NULL</code>, which means that no chmod'ing or directory creation shall occur. </p> --# vim: et sw=4 sts=4
しかし、この値を変更しても変化はなく、恐らく変更したあとに ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema/schema.ser
にシリアライズしなければならないのではないかと思ってます。詳しくは調べてません。vendor
配下を変更したくないので。
似たような値に Cache.SerializerPath
というものがあり、こちらは README によれば exercise/htmlpurifier-bundle
から default_cache_serializer_path
によって変更できるようになっているようです。
## Configuration in Symfony 4 and up If you do not explicitly configure this bundle, an HTMLPurifier service will be defined as `exercise_html_purifier.default`. This behavior is the same as if you had specified the following configuration: ``yaml # config/packages/exercise_html_purifier.yaml exercise_html_purifier: default_cache_serializer_path: '%kernel.cache_dir%/htmlpurifier' ``
しかし、今回やりたいことは Cache.SerializerPermissions
で、これは exercize_html_purifier.default_cache_serializer_permissions
のような形で渡せるようにはなっていないようです。
明確な答えはどこにも書いてなかったのですが、README の各例から推測して Core.Encoding
などの値同様に exercize_html_purifier.html_profiles.default.config.Cache.SerializerPermissions
として渡すことができるようです。
app/config/eccube/packages/exercise_html_purifier.yaml
exercise_html_purifier: html_profiles: default: config: Cache.SerializerPermissions: 0777
これでディレクトリは 777
、ファイルは 666
となります。Cache.SerializerPermissions: 0775
とすればディレクトリは 775
、ファイルは 664
です。
軽く検索したところ現時点では日本語の情報は特に出てこなかったのだけど Web サーバのプロセスと SSH でユーザーが違うときに同じ問題に遭遇してる人はまだいないのだろうか。(深追いしすぎてたまに余計なことしてることもあるからそれほど悩む問題でもないのかもしれない)
参考: Permissions issue when clearing cache · Issue #22 · Exercise/HTMLPurifierBundle · GitHub
EC-CUBE 4.3
Cache.SerializerPermissions
で 0777
とかで指定するとおかしなことになってました。
公式のドキュメントを見てみると default_cache_serializer_permissions
で 10 進数(なぜ)で指定するようになったようです。
10 進数 511
は 8 進数で 777
です。
app/config/eccube/packages/exercise_html_purifier.yaml
exercise_html_purifier: default_cache_serializer_path: '%kernel.cache_dir%/htmlpurifier' default_cache_serializer_permissions: 511