HTTPS out of the box with the Caddy secure web server
Simply Secure
Caddy lets even the most inexperienced user set up a secure web server.
After hundreds of high-profile attacks on large and small websites, the web world is gradually giving up on old-fashioned, unsafe, unencrypted HTTP and is moving to the safer, encrypted variant known as HTTPS. HTTPS is based on the SSL/TSL protocols, which means you need to install, maintain, and regularly renew digital certificates for the website. The certificates are only valid for a limited period, which can vary between three months to 10 years, depending on the certificate authority.
All the major web servers, such as the Apache HTTP server, Microsoft's Internet Information Services (IIS), and Nginx, provide some means for HTTPS support, but the configuration steps are often complicated and more trouble than you need, especially if you just operate a small website.
Caddy [1] is a simple and easy web server that delivers simple and convenient HTTPS support. Caddy uses the Let's Encrypt [2] project for easy access to free digital certificates. (See the box titled "Simply Encrypted.") Caddy also includes support for HTTP/2 (see "From HTTP 1.1 to HTTP/2"), and it comes with other useful features, such as support for the Markdown and AsciiDoc formatting languages.
From HTTP 1.1 to HTTP/2
Version 2.0 of HTTP [3] was released in February 2015. HTTP/2, which is described in RFC 7540 [4], has been gradually replacing HTTP 1.1 since 1997. Evaluations of WWW data traffic revealed a 20 percent share of HTTP/2 traffic at the end of 2017. HTTP/2 comes with a number of innovations, including data compression of the HTTP headers and parallel execution of requests with a single TCP connection ("pipelining"). In general, the protocol aims to make better use of the available computing power and to minimize the time required to transmit a request.
Simply Encrypted
The Let's Encrypt project is the first major initiative of the non-profit organization Internet Security Research Group (ISRG). The goal of the ISRG is to make encrypted WWW connections the standard; in other words, HTTPS for everyone. Let's Encrypt uses domain validation certificates for encryption. To check whether the person submitting a certification request actually owns the domain, Let's Encrypt creates and sends a token to the requesting domain. This step is followed by a web or DNS query, in which the domain is verified using a key derived from this token. This ensures that the content actually originates from the operator of the website. Let's Encrypt also offers the greatest possible transparency for its own trustworthiness. The project uses free software and open standards, in combination with the regular publication of transparency reports. To date, the project has already issued certificates for 63 million domains.
Caddy is written in the Go programming language, and it is available as a free community version for private use. If you want to use the web server commercially, the developers would be happy to receive a one-off payment of $25. The project is licensed under Apache 2.0.
This article is adapted to Debian 9 and is partly based on a blog post by Supriyo Biswas [5].
Installation
Caddy is available for Linux, Windows, many BSD variants, and Mac OS. The Caddy developers do not provide separate versions for different Linux distributions. In the download area of the website, a configurator helps you select the appropriate binary for your system, as well as plugins you might want to integrate (Figure 1). The software then generates a package to suit your needs.
If you prefer to set up Caddy at the command line, say, for use on a headless system, first pick up a shell script from the Caddy project website (Listing 1, line 1), make it executable (line 2), and download the desired software image (line 3) by calling the script. You can specify additional plugins in the call as comma-separated parameters (line 4). Table 1 shows a small selection of available extensions.
Listing 1
Get Caddy
# wget https://getcaddy.com -O getcaddy # chmod +x getcaddy # ./getcaddy personal # ./getcaddy personal http.ipfilter,http.cache
Table 1
Caddy Plugins
dyndns |
Dynamic DNS, for example, via Cloudflare |
http.cache |
Caching for HTTP |
http.cgi |
Extension with CGI scripts |
http.expires |
Setting an expiration date |
http.git |
Publication/updates via |
http.ipfilter |
Block access by selected IP addresses |
http.webdav |
Extension for WebDAV |
Basic Setup
To test the functionality, first create an index.html
file in the current directory; this file consists only of the HTML header and the body "Hello World." Then, launch Caddy by typing ./caddy
in the same directory. To access the page in the web browser, use either the IP address of the host or localhost or 127.0.0.1 and add port number 2015, on which Caddy listens for HTTP requests without any further settings (Figure 2).
To secure Caddy and set it up as a system service, create a separate account for Caddy, then assign it a home directory of /opt/caddy/
with the -rmd
option (Listing 2, first line). This directory also contains the configuration files and the actual content of the website.
Listing 2
Securing Caddy
# useradd -rmd /opt/caddy caddy # mkdir /opt/caddy/{store,logs,web} # chown -R caddy: /opt/caddy
You'll need to create the three subdirectories store
, logs
, and web
(Listing 2, second line); store
contains – among other things – the SSL certificates, log
contains the logfiles for the web server, and web
contains the actual website. To make sure that Caddy can access it, assign the three directories to the previously created caddy account (Listing 2, last line).
Next, copy the previously created index.html
file to /opt/caddy/web/
. Caddy now needs some help in the form of a configuration file to find the contents. You can choose the name of the configuration file – in this article, the file is called /opt/caddy/caddy.config
. Enter the contents from Listing 3, which is the configuration for a single website on the local computer.
Listing 3
Configuring a Website
01 http:// { 02 root /opt/caddy/web/default 03 log /opt/caddy/logs/default.log 04 gzip 05 }
Line 1 is for serving up HTTP content on port 80; line 2 defines the root directory of the website, and line 3 defines the corresponding logfiles. Line 4 contains the Gzip module, which ensures that Caddy delivers compressed HTML and text files. With the performance of today's systems, compression causes only a minimal delay, which more than compensates for the transmission time saved.
If you want to provide multiple web services on the system, you need to create a separate block for each service. In Listing 4, the third code block describes a web server that delivers its data via port 8080. All you need to do is enter :8080
after the domain name.
Now you need to set up Caddy as a regular service. For systems with a systemd, create a separate entry in the /etc/systemd/system/caddy.service
file (Listing 5). In the Unit
section, name the service and enter a description. The Service
section defines the user and group, the environment variables, the start parameters, what happens when the process is restarted, and the limits for the number of open files and parallel processes. The Install
section determines the target or runlevel for which the service is available.
Listing 4
Multiple Sites
http:// { root /opt/caddy/web/default log /opt/caddy/logs/default.log gzip } http://out-of-space.example.net { root /opt/caddy/web/out-of-space log /opt/caddy/logs/out-of-space.log gzip } http://on-the-road.example.net:8080 { root /opt/caddy/web/on-the-road log /opt/caddy/logs/on-the-road.log gzip }
Listing 5
caddy.service
[Unit] Description=Caddy HTTP/2 web server [Service] 06 User=caddy Group=caddy Environment=CADDYPATH=/opt/caddy/store ExecStart=/usr/local/bin/caddy -agree=true -log=/opt/caddy/logs/caddy.log -conf=/opt/caddy/caddy.config -root=/dev/null ExecReload=/bin/kill -USR1 $MAINPID LimitNOFILE=1048576 LimitNPROC=64 [Install] WantedBy=multi-user.target
Use the first two commands from Listing 6 to start the previously configured service and check whether it is running correctly (Figure 3). Then, visit the website and check its accessibility. This time Caddy is no longer listening on port 2015, but on the usual port 80 for HTTP.
Listing 6
Start the Service
# systemctl enable caddy.service # systemctl status caddy.service # systemctl restart caddy.service
If you change the configuration at a later time, you need to restart the service, as shown in the last line of Listing 6.
Switching to HTTPS
Caddy impresses with its integration of Let's Encrypt for secure HTTPS connections. To add Let's Encrypt, you must have a domain. In the second block of Listing 4, change http
to https
in the first line. Then add line 5 to the block (Listing 7). Let's Encrypt informs you about changes in the certificate for HTTPS, especially before it expires and needs to be renewed.
Listing 7
Adding Let's Encrypt
https://out-of-space.example.net { root /opt/caddy/web/out-of-space log /opt/caddy/logs/out-of-space.log gzip tls admin@out-of-space.example.net }
You do not need an explicit statement for HTTP. All requests for this protocol will automatically switch to HTTPS on port 443. Now restart Caddy, and it will automatically connect to Let's Encrypt and set up a certificate.
Buy this article as PDF
(incl. VAT)