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
caddy
to 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.conf
user = asterisk group = asterisk listen.owner = asterisk listen.group = asterisk
Or in one command:
sed -i 's/^;\?\(user\|group\|listen.owner\|listen.group\) = .*$/\1 = asterisk/g' \ /etc/php-fpm.d/www.conf
Apply changes:
systemctl restart php-fpm.service
-
Edit
/etc/caddy/Caddyfile
pbx.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
.htaccess
with 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
asterisk
user, we can let it run ascaddy
. As long as FPM is run byasterisk
and we add the usercaddy
to groupasterisk
everything should be fine. - Add a Caddyfile that tries to mimic what
.htaccess
does. - This should work with WebRTC.
Thank you.