HTTPS Made Easy: Setting up Caddy for PHP 7 on Debian Jessie

Caddy is a modern open source HTTP/2 webserver written in Go. One of its most attractive features over other webservers (Apache, nginx, lighttpd, etc.) is that Caddy integrates with the free LetsEncrypt certificate authority to ensure all of your websites support HTTPS, out of the box.

(Caveat: localhost and IP address virtual hosts are excluded from this automatic HTTPS, which also makes Caddy suitable for local development environments.)

What follows is a step-by-step guide for getting the latest version of Caddy (0.8.3) set up on a freshly installed Debian Linux 8.5 (Jessie) server. Please note that this was written on July 17, 2016; if you are reading this in the distant future, some of the steps may be incorrect. (In all likelihood, it will become easier.)

First Step: Hardening your Linux Kernel

Before you do anything else, make sure you're running the latest version of everything. This ensures you're not running vulnerable software.

sudo apt-get update sudo apt-get dist-upgrade

Next, we generally recommend installing a Linux kernel with the grsecurity/PaX kernel patches. This adds a strong layer of exploit mitigation to the software running on your environment. This step is not required, but we highly recommend everyone use a hardened Linux kernel.

sudo apt-get install linux-image-grsec-amd64

Restart to boot into the new kernel, then proceed to install PHP 7.

Setting up PHP 7 with the FastCGI Process Manager (FPM)

Debian doesn't ship with PHP 7.0 by default. Fortunately, there's dotdeb for that. Verify then install their GPG public key, then add those entries as an apt source, like so:

echo "deb http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list echo "deb-src http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list.d/dotdeb.list wget https://www.dotdeb.org/dotdeb.gpg # SHA-384 is not vulnerable to length-extension attacks. However, this is a weak # verification that only stops transmission errors. # # You should verify the full fingerprint manually. echo "ac6336bcd3883126c9976bd1e4aeff45be1a24e430be575c197954ce0b9288d0f4b35dfa675d72fb94bd35fd073aec27 dotdeb.gpg" | sha384sum -c if [ $? -eq 0 ]; then sudo apt-key add dotdeb.gpg else echo "Wrong public key" exit 1 fi sudo apt-get update sudo apt-get install php7.0-fpm

This is also a good point to install any PHP extensions (e.g. libsodium from PECL) that you may need.

Setting up the Caddy web server

The best place to get Caddy is from the Caddy website, which allows you to customize which features you need. However, if you just need the core features accessible from wget , then the Github releases are your destination. (There is a freshly opened ticket to request Caddy releases be cryptographically signed. Once that's implemented, we will update this post with specific instructions.)

After you download and extract the release, you'll need to delve into systemd configuration. This can get complicated quickly, and the instructions provided in the init/ directory target a newer version than Debian provides. Through trial and error, we managed to get the following instructions to work reliably:

mkdir /tmp/caddy && cd /tmp/caddy wget https://github.com/mholt/caddy/releases/download/v0.8.3/caddy_linux_amd64.tar.gz # Extract: tar zxvf caddy_linux_amd64.tar.gz # Place the caddy binary in a standard location: sudo mv caddy_linux_amd64 /usr/bin/caddy # Remove newer systemd token (%I) from the caddy.service file and change the group # from 'http' to 'www-data': sed -e 's/%I//' init/linux-systemd/caddy\@.service | \ sed -e 's/=http/=www-data/' > \ /lib/systemd/system/caddy.service # Make a global configuration directory: sudo mkdir /etc/caddy systemctl daemon-reload

The above commands set up the systemd service (in /lib/systemd/system/ ), create a directory /etc/caddy for placing your Caddyfile and any other configuration files, then reloads the systemd configuration.

Next, you'll need to create a Caddyfile and store it at /etc/caddy/Caddyfile . Note that you can edit /lib/systemd/system/caddy.service if you want to change the location of the Caddyfile. An example Caddyfile follows:

example.com:80, example.com:443 { log /var/log/www_access.log fastcgi / /run/php/php7.0-fpm.sock php root /var/www/my_project/public rewrite { to {path} {path}/ /index.php?{query} } }

Once this is all done, enable then start the Caddy service and you're all set:

systemctl enable caddy.service systemctl start caddy.service

Next Steps

Read the documentation to learn how to better configure your website. If you're connecting to a domain name, it should automatically be served over HTTPS with a fresh LetsEncrypt certificate. It is for this reason that we highly recommend everyone use Caddy for web development in 2016 and beyond.