Using Caddy instead of Apache in FreePBX
I’m in the process of implementing Caddy in several applications we use internally. For now I have successfully migrated Gitea, Snipe-IT, Zabbix, and now FreePBX.
I want to share here what I did so I can get feedback, suggestions, etc. I’m posting this in Caddy and FreePBX forums.
The main reason for me to stop using the build-in web server (Apache + Certificate Manager + System Admin) in FreePBX distro is that it got complicated to administer the web certificate from a sysadmin point of view, specifically when dealing with automation and when you can’t open 80/443 to the internet.
The idea here is to completely replace Apache with Caddy, not to use Caddy as a front-end to Apache. So we need to use PHP-FPM and run it as asterisk user.
FreePBX distro: SNG7-PBX-64bit-2104-1
FreePBX: 15.0.17.64
Caddy: 2.4.6
-
Disable and mask Apache
systemctl mask --now httpd -
Install Caddy as documented here
Note: To use DNS challenge you need to download a Caddy binary with a plugin for your DNS provider. For testing you can install the RPM and just replace the binary.systemctl enable --now caddy.service -
Add user
caddyto groupasterisk, so the web server can read everything in/var/www/html.usermod -a -G asterisk caddy -
Install PHP-FPM
yum install php56w-fpm systemctl enable --now php-fpm.service -
Make sure this values are set in
/etc/php-fpm.d/www.confuser = asterisk group = asterisk listen.owner = asterisk listen.group = asteriskOr in one command:
sed -i 's/^;\?\(user\|group\|listen.owner\|listen.group\) = .*$/\1 = asterisk/g' \ /etc/php-fpm.d/www.confApply changes:
systemctl restart php-fpm.service -
Edit
/etc/caddy/Caddyfilepbx.example.com { root * /var/www/html php_fastcgi 127.0.0.1:9000 file_server header { Strict-Transport-Security max-age=31536000; } }Note: This Caddyfile is missing the DNS challenge configuration
Optionally you can add some restrictions from
.htaccesswith something like this:root * /var/www/html handle /admin/* { @blocked_admin { path */.* path */i18n/* path */helpers/* path */libraries/* path */node/* path */views/*php } respond @blocked_admin 403 php_fastcgi 127.0.0.1:9000 file_server } handle { @blocked_main { path */.* } respond @blocked_main 403 php_fastcgi 127.0.0.1:9000 file_server }Apply changes:
systemctl reload caddy.service
That’s it. It should work. With this setup I get an A+ with testssl.sh.
I only have two uses for the web front of FreePBX: Admin stuff (Edit extensions, routes, etc), and UCP for some users to listen to recorded calls. And it works great for this usage.
With the implementation of Caddy I no longer need the sysadmin module, and with this I removed all commercial modules. There is nothing wrong with the commercial modules, it’s just that I have not no use for them for the moment.
Please give your opinion. I’m interested in the hide .* part, which is supposed to block all . (hidden) files as the .htaccess does, but I’m not sure if that is the correct way or if I need more to add.
Updates 2022-01-05:
- There is no need to run Caddy as
asteriskuser, we can let it run ascaddy. As long as FPM is run byasteriskand we add the usercaddyto groupasteriskeverything should be fine. - Add a Caddyfile that tries to mimic what
.htaccessdoes. - This should work with WebRTC.
Thank you.