Skip to content

Instantly share code, notes, and snippets.

@MatthewVance
Last active March 6, 2025 16:33
Show Gist options
  • Save MatthewVance/876d1c0fe044c83e5bf80bd1a2dcd001 to your computer and use it in GitHub Desktop.
Save MatthewVance/876d1c0fe044c83e5bf80bd1a2dcd001 to your computer and use it in GitHub Desktop.
Caddy config (Caddyfile) and systemd service to reverse proxy Restic REST server running via Rclone.
[Unit]
Description=Caddy HTTP/2 web server
Documentation=https://caddyserver.com/docs
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
Restart=on-abnormal
; User and group the process will run as.
User=www-data
Group=www-data
; Letsencrypt-issued certificates will be written to this directory.
Environment=CADDYPATH=/etc/caddy/ssl/
; Always set "-root" to something safe in case it gets forgotten in the Caddyfile.
ExecStart=/usr/local/bin/caddy -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/www/caddy/error.lan
ExecReload=/bin/kill -USR1 $MAINPID
; Use graceful shutdown with a reasonable timeout
KillMode=mixed
KillSignal=SIGQUIT
TimeoutStopSec=5s
; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
LimitNOFILE=1048576
; Unmodified caddy is not expected to use more than that.
LimitNPROC=512
; Use private /tmp and /var/tmp, which are discarded after caddy stops.
PrivateTmp=true
; Use a minimal /dev (May bring additional security if switched to 'true', but it may not work on Raspberry Pi's or other devices, so it has been disabled in this dist.)
PrivateDevices=true
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=true
; Make /usr, /boot, /etc and possibly some more folders read-only.
ProtectSystem=full
; … except /etc/caddy/ssl, because we want Letsencrypt-certificates there.
; except log directory because want to write logs there
; This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
ReadWriteDirectories=/etc/caddy/ssl/
ReadWriteDirectories=/var/log/caddy/rclone-restic-rest/
; The following additional security directives only work with systemd v229 or later.
; They further restrict 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
bind 192.168.1.106:8889
tls /etc/caddy/ssl/host_name-bundle.pem /etc/caddy/ssl/end_device-key.pem {
protocols tls1.2 tls1.3
}
# Reverse proxy to rclone restic rest service
proxy / localhost:8080 {
# health_check /
transparent
max_conns 1024
}
root /var/www/caddy/rclone-restic-rest/
header / {
# Enable HTTP Strict Transport Security (HSTS) to force clients to always
# connect via HTTPS (do not use if only testing)
# Strict-Transport-Security "max-age=31536000;"
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type
X-Content-Type-Options "nosniff"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
# Hide server header field
-Server
# Disable caching since https
# The cache should not store anything about the client request or server response.
Cache-Control "no-store"
Pragma "no-cache"
}
# Better manage server connectivity in the face of buggy or malicious clients.
timeouts {
read 10s # Maximum duration for reading the entire request, including the body.
header 10s # The amount of time allowed to read request headers.
write 10s # The maximum duration before timing out writes of the response.
idle 2m # The maximum time to wait for the next request (when using keep-alive).
}
# Limit the HTTP header and body sizes to reasonable values
# Increase if legitmate traffic results in HTTP 413 errors
limits {
header 4kb
#body / 10mb
}
# use gzip compression if the client supports it.
gzip
log / /var/log/caddy/rclone-restic-rest/access.log {
rotate_size 5 # Rotate after the log file reaches this size (in megabytes)
rotate_age 90 # Keep rotated files for this many days
rotate_keep 40 # Keep at most this many log files (older files get pruned)
rotate_compress # compress rotated log files. gzip is the only format supported.
}
errors /var/log/caddy/rclone-restic-rest/error.log {
rotate_size 5 # Rotate after the log file reaches this size (in megabytes)
rotate_age 90 # Keep rotated files for this many days
rotate_keep 40 # Keep at most this many log files (older files get pruned)
rotate_compress # compress rotated log files. gzip is the only format supported.
}
[Unit]
Description=rclone - rsync for cloud storage
Documentation=https://rclone.org/docs/
After=network-online.target
Before=caddy.service
Wants=network-online.target systemd-networkd-wait-online.service
Requires=caddy.service
[Service]
Restart=on-abnormal
; User and group the process will run as.
User=restic
Group=restic
EnvironmentFile=/etc/rclone/rclone-pw.txt
ExecStart=/usr/local/bin/rclone --config /etc/rclone/rclone.conf serve restic --addr 127.0.0.1:8080 --append-only --htpasswd /etc/rclone/htpasswd restic:/Volumes/storage/matt/backup/repos/shared
ExecReload=/bin/kill -USR1 $MAINPID
; Use graceful shutdown with a reasonable timeout
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=5s
; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
LimitNOFILE=1048576
LimitNPROC=512
; Use private /tmp and /var/tmp, which are discarded after rclone stops.
PrivateTmp=true
; Use a minimal /dev (May bring additional security if switched to 'true', but it may not work on Raspberry Pi's or other devices, so it has been disabled in this dist.)
PrivateDevices=true
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=true
; Make /usr, /boot, /etc and possibly some more folders read-only.
ProtectSystem=full
; … except /root/backup/restic/repos/, because we want to backup there.
; This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
ReadWriteDirectories=/Volumes/storage/matt/backup/repos/shared/
ReadWriteDirectories=/etc/rclone/
; The following additional security directives only work with systemd v229 or later.
; They further restrict privileges that can be gained by rclone. 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment