Cross-platform, written in Rust, straightforward configuration, secure defaults, also has a hardened container image and a hardened NixOS module.
I wouldn't recommend Caddy. Their official docker image runs as root by default [1], and they don't provide a properly sandboxed systemd unit file [2].
[1]: https://github.com/caddyserver/caddy-docker/issues/104
[2]: https://github.com/caddyserver/dist/blob/master/init/caddy.s...
EDITED: phrasing
[Unit]
Description=Caddy webserver
Documentation=https://caddyserver.com/docs/
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
StartLimitIntervalSec=14400
StartLimitBurst=10
[Service]
User=caddy
Group=caddy
# environment: store secrets here such as API tokens
EnvironmentFile=-/var/lib/caddy/envfile
# data directory: uses $XDG_DATA_HOME/caddy
# TLS certificates and other assets are stored here
Environment=XDG_DATA_HOME=/var/lib
# config directory: uses $XDG_CONFIG_HOME/caddy
Environment=XDG_CONFIG_HOME=/etc
ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
# Do not allow the process to be restarted in a tight loop.
Restart=on-abnormal
# Use graceful shutdown with a reasonable timeout
KillMode=mixed
KillSignal=SIGQUIT
TimeoutStopSec=5s
# Sufficient resource limits
LimitNOFILE=1048576
LimitNPROC=512
# Grants binding to port 443...
AmbientCapabilities=CAP_NET_BIND_SERVICE
# ...and limits potentially inherited capabilities to this
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# Hardening options
LockPersonality=true
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectControlGroups=true
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectSystem=strict
ReadWritePaths=/var/lib/caddy
ReadWritePaths=/etc/caddy/autosave.json
ReadOnlyPaths=/etc/caddy
ReadOnlyPaths=/var/lib/caddy/envfile
[Install]
WantedBy=multi-user.targetBesides, we should be creating and using software that is secure by default: https://www.cisa.gov/sites/default/files/2023-06/principles_...
Some things were never meant to be, like downloading CRLs over HTTPS.
You might still use HTTP on an internal network in a DMZ or other trusted network.
And a C program, written by a single developer, with only 27 issues ever being filed? With all due respect, that's guaranteed to have some nasty bugs in there.
Treat any web request like you would a real user on a Linux system you'd need to give access to to download files via scp. Chroot, strict permissions, etc. Can't escape what you can't escape. A ../ should return the same as expected in the shell, permission denied
I've run a couple of websites (WordPress or Hugo based, including my personal blog) like that and it's great.
I personally prefer something like Github Pages, though - it doesn't get much more hands-off than that!