1. The problem I’m having:
I was with @dunglas today and we were trying to port Drupal apache config to Caddyfile. I’m having a problem with a regex used to deny access to certain files, while allowing certain paths.
What we have in the apache config:
<FilesMatch "\.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config|yarn\.lock|package\.json)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$">
Paths that matches the regex:
core/modules/system.module
core/modules/system.yml
.toto
.haccess
.plop
Entries
composer.json
package.json
Path that do not match the regex:
.well-known/change-password
As expected the problem here is the (?!well-known)
part for porting that to Caddyfile.
What I tried to do in Caddyfile is:
@protectedFilesRegexp {
not path /.well-known*
path_regexp \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^\/(\..*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config|yarn\.lock|package\.json)$|^\/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$
}
error @protectedFilesRegexp 403
All the paths that are supposed to match, match, but it also matches https://localhost/.well-known/change-password
, I’m getting a 403 when accessing that url.
3. Caddy version:
I’m using caddy through frankenphp and it’s frankenphp
root@044e65faae38:/opt/drupal# frankenphp --version
FrankenPHP v1.1.2 PHP 8.3.4 Caddy v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=
4. How I installed and ran Caddy:
I used the docker stack from Caddyfile by theodoreb · Pull Request #25 · dunglas/frankenphp-drupal · GitHub
d. My complete Caddy config:
# Adapted from https://caddy.community/t/caddyfile-for-drupal-10/21607/5
{
{$CADDY_GLOBAL_OPTIONS}
frankenphp {
{$FRANKENPHP_CONFIG}
}
# https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm
order php_server before file_server
order php before file_server
}
{$CADDY_EXTRA_CONFIG}
{$SERVER_NAME:localhost} {
root * web/
encode zstd br gzip
@hiddenFilesRegexp path_regexp (^|/)\.
error @hiddenFilesRegexp 403
@hiddenPhpFilesRegexp path_regexp \..*/.*\.php$
error @hiddenPhpFilesRegexp 403
@notFoundPhpFiles path_regexp /vendor/.*\.php$
error @notFoundPhpFiles 404
@notFoundPhpFilesRegexp path_regexp ^/sites/[^/]+/files/.*\.php$
error @notFoundPhpFilesRegexp 404
@privateDirRegexp path_regexp ^/sites/.*/private/
error @privateDirRegexp 403
@protectedFilesRegexp {
not path /.well-known*
path_regexp \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^\/(\..*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config|yarn\.lock|package\.json)$|^\/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$
}
error @protectedFilesRegexp 403
@static {
file
path *.avif *.css *.eot *.gif *.gz *.ico *.jpg *.jpeg *.js *.otf *.pdf *.png *.svg *.ttf *.webp *.woff *.woff2
}
header @static Cache-Control "max-age=31536000,public,immutable"
{$CADDY_SERVER_EXTRA_DIRECTIVES}
php_server
}```