From 3f83eccfbd7f553c593d8e89d173699fb4cd2b61 Mon Sep 17 00:00:00 2001 From: Josh Aas Date: Fri, 23 Sep 2016 17:50:39 -0500 Subject: [PATCH] improvements for Linux systemd integration (#1127) * Remove unnecessary config options from systemd service so it will work with earlier versions of systemd. Simplify the systemd service instructions and make them more complete. * Minor systemd README improvements. * Add back some of the optional systemd 229 stuff but commented out for compat. * A bunch of updates to the README for linux systemd. --- dist/init/linux-systemd/README.md | 161 ++++++++++++++++---------- dist/init/linux-systemd/caddy.service | 16 +-- 2 files changed, 108 insertions(+), 69 deletions(-) diff --git a/dist/init/linux-systemd/README.md b/dist/init/linux-systemd/README.md index b99677cc..cd1a0818 100644 --- a/dist/init/linux-systemd/README.md +++ b/dist/init/linux-systemd/README.md @@ -1,84 +1,127 @@ -# systemd unit for caddy +# systemd Service Unit for Caddy Please do not hesitate to ask on [caddyserver/support](https://gitter.im/caddyserver/support) -if you have any questions. -Feel free to prepend to your question the username of whoever touched the file most recently, -for example `@wmark re systemd: …`. +if you have any questions. Feel free to prepend to your question +the username of whoever touched the file most recently, for example +`@wmark re systemd: …`. -The provided file is written for **systemd version 229** or later! +The provided file should work with systemd version 219 or later. It might work with earlier versions. +The easiest way to check your systemd version is to look at the version of the installed package +(e.g. 'sudo yum info systemd' on RedHat/Fedora systems). -## Quickstart +## Instructions -In the following sections, we will assume that you want to run caddy -as user `www-data` and group `www-data`, with UID and GID 33. -Adjust this to your liking according to the preferences of your Linux distribution! +We will assume the following: + +* that you want to run caddy as user `www-data` and group `www-data`, with UID and GID 33 +* you are working from a non-root user account that can use 'sudo' to execute commands as root + +Adjust as necessary or according to your preferences. + +First, put the caddy binary in the system wide binary directory and give it +appropriate ownership and permissions: ```bash -groupadd -g 33 www-data -useradd \ +sudo cp /path/to/caddy /usr/local/bin +sudo chown root:root /usr/local/bin/caddy +sudo chmod 755 /usr/local/bin/caddy +``` + +Give the caddy binary the ability to bind to privileged ports (e.g. 80, 443) as a non-root user: + +```bash +sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy +``` + +Set up the user, group, and directories that will be needed: + +```bash +sudo groupadd -g 33 www-data +sudo useradd \ -g www-data --no-user-group \ --home-dir /var/www --no-create-home \ --shell /usr/sbin/nologin \ --system --uid 33 www-data -mkdir /etc/caddy -chown -R root:www-data /etc/caddy -mkdir /etc/ssl/caddy -chown -R www-data:root /etc/ssl/caddy -chmod 0770 /etc/ssl/caddy +sudo mkdir /etc/caddy +sudo chown -R root:www-data /etc/caddy +sudo mkdir /etc/ssl/caddy +sudo chown -R www-data:root /etc/ssl/caddy +sudo chmod 0770 /etc/ssl/caddy ``` -- Install the unit configuration file: `cp caddy.service /etc/systemd/system/` -- Reload the systemd daemon: `systemctl daemon-reload` -- Make sure to [configure](#configuration) the service unit before starting caddy. -- Start caddy: `systemctl start caddy.service` -- Enable the service (automatically start on boot): `systemctl enable caddy.service` -- A folder `.caddy` will be created inside the home directory of the user that runs caddy; - you can change that by providing an environment variable `HOME`, - i.e. `Environment=HOME=/var/lib/caddy` will result in `/var/lib/caddy/.caddy` - -## Configuration - -- Prefer `systemctl edit` over modifying the unit file directly: - - `systemctl edit caddy.service` to make user-local modifications - - `systemctl edit --full caddy.service` for system-wide ones -- In most cases it is enough to override arguments in the `ExecStart` directive: - -```ini -[Service] -; an empty value clears the original (and preceding) settings -ExecStart= -ExecStart=/usr/local/bin/caddy -conf="/etc/caddy/myCaddy.conf" -``` - -- To view the resulting configuration use `systemctl cat caddy` -- systemd needs absolute paths, therefore make sure that the path to caddy is correct. -- Double check permissions of your *document root* path. - The user caddy runs as needs to have access to it. For example: +Place your caddy configuration file ("Caddyfile") in the proper directory +and give it appropriate ownership and permissions: ```bash -# caddy would run as www-data:www-data -# serving, in this example: /var/www - -sudo -u www-data -g www-data -s \ - ls -hlAS /var/www - -# Got an error? Revisit permissions! +sudo cp /path/to/Caddyfile /etc/caddy/ +sudo chown www-data:www-data /etc/caddy/Caddyfile +sudo chmod 444 /etc/caddy/Caddyfile ``` -## Tips +Create the home directory for the server and give it appropriate ownership +and permissions: -- Use `log stdout` and `errors stderr` in your Caddyfile to fully utilize **journald**. -- `journalctl` is *journald's* log query tool. -- Did caddy not start? Check the logfiles for any error messages using `journalctl --boot -u caddy.service` -- To follow caddy's log output: `journalctl -f -u caddy.service` -- If your GNU/Linux distribution does not use *systemd* with *journald* then check any logfiles in: `/var/log` +```bash +sudo mkdir /var/www +sudo chown www-data:www-data /var/www +sudo chmod 555 /var/www +``` -- If you have more files that start with `caddy` – like a `caddy.timer`, `caddy.path`, or `caddy.socket` – then it is important to append `.service`. - Although if `caddy.service` is all you have, then you can just use `caddy` without any extension, such as in: `systemctl status caddy` +Let's assume you have the contents of your website in a directory called 'example.com'. +Put your website into place for it to be served by caddy: -- You can make other certificates and private key files accessible to a user `www-data` by command `setfacl`, if you must: +```bash +sudo cp -R example.com /var/www/ +sudo chown -R www-data:www-data /var/www/example.com +sudo chmod -R 555 /var/www/example.com +``` + +You'll need to explicity configure caddy to serve the site from this location by adding +the following to your Caddyfile if you haven't already: + +``` +example.com { + root /var/www/example.com + ... +} +``` + +Install the systemd service unit configuration file, reload the systemd daemon, +and start caddy: + +```bash +sudo cp caddy.service /etc/systemd/system/ +sudo chown root:root /etc/systemd/system/caddy.service +sudo chmod 744 /etc/systemd/system/caddy.service +sudo systemctl daemon-reload +sudo systemctl start caddy.service +``` + +Have the caddy service start automatically on boot if you like: + +```bash +sudo systemctl enable caddy.service +``` + +If caddy doesn't seem to start properly you can view the log data to help figure out what the problem is: + +```bash +journalctl --boot -u caddy.service +``` + +Use `log stdout` and `errors stderr` in your Caddyfile to fully utilize systemd journaling. + +If your GNU/Linux distribution does not use *journald* with *systemd* then check any logfiles in `/var/log`. + +If you want to follow the latest logs from caddy you can do so like this: + +```bash +journalctl -f -u caddy.service +``` + +You can make other certificates and private key files accessible to the `www-data` user with the following command: ```bash setfacl -m user:www-data:r-- /etc/ssl/private/my.key diff --git a/dist/init/linux-systemd/caddy.service b/dist/init/linux-systemd/caddy.service index aa13366d..536cb3a1 100644 --- a/dist/init/linux-systemd/caddy.service +++ b/dist/init/linux-systemd/caddy.service @@ -35,16 +35,12 @@ ProtectSystem=full ; This merely retains r/w access rights, it does not add any new. Must still be writable on the host! ReadWriteDirectories=/etc/ssl/caddy -; Drop all other capabilities. Important if you run caddy as privileged user (which you should not). -CapabilityBoundingSet=CAP_NET_BIND_SERVICE -; … but permit caddy to open ports reserved for system services. -; This could be redundant here, but is needed in case caddy runs as nobody:nogroup. -AmbientCapabilities=CAP_NET_BIND_SERVICE -; … and prevent gaining any new privileges. -NoNewPrivileges=true - -; Caveat: Some plugins need additional capabilities. Add them to both above lines. -; - plugin "upload" needs: CAP_LEASE +; The following additional security directives only work with systemd v229 or later. +; They further retrict privileges that can be gained by caddy. Uncomment if you like. +; Note that you may have to add capabilities required by any plugins in use. +;CapabilityBoundingSet=CAP_NET_BIND_SERVICE +;AmbientCapabilities=CAP_NET_BIND_SERVICE +;NoNewPrivileges=true [Install] WantedBy=multi-user.target