--- Alias: ["caddy"] Tag: ["💻", "🖥️", "Reverse-Proxy"] Date: 2021-09-19 DocType: "Personal" Hierarchy: "NonRoot" TimeStamp: location: [51.514678599999996, -0.18378583926867909] CollapseMetaTable: true --- Parent:: [[Selfhosting]], [[Server Tools]] --- ^Top   ```button name Save type command action Save current file id Save ``` ^button-caddySave   # Configuring caddy   ```ad-abstract title: Summary collapse: open This note runs through [caddy](https://caddyserver.com), a free tool webserver allowing for reverse-proxy and automatic SSL certifications. ```   ```toc style: number ```   ---   ### Installation [[#^Top|TOP]]   #### Program installation 1. **Pull the software signature key & image** ```ad-command ~~~bash echo "deb [trusted=yes] https://apt.fury.io/caddy/ /" | sudo tee -a /etc/apt/sources.list.d/caddy-fury.list ~~~ ``` 3. **Install caddy** ```ad-command ~~~bash sudo apt update sudo apt install caddy ~~~ ``` Installing caddy will create a default user 'caddy'. 4. **Test install** Go to the homepage to see the caddy default page.   #### Installing php PHP needs to be enabled for caddy to work. ```ad-command ~~~bash sudo add-apt-repository ppa:ondrej/php sudo apt install php-cli php-fpm php-mysql ~~~ ``` Check if php is installed correctly: ```ad-command ~~~bash php --version ~~~ ```   ---   ### Configuration of caddy [[#^Top|TOP]]   Caddy will fetch a **SSL certificate** for all sub-domains and addresses present in the config file automatically, once the declaration is made properly.   #### Basic files & directories [[#^Top|TOP]] 1. Create a default website folder ```ad-command ~~~bash sudo mkdir -p /var/www/html ~~~ ``` 2. Create a default log folder ```ad-command ~~~bash sudo mkdir /var/log/caddy sudo chown -R caddy:caddy /var/log/caddy ~~~ ```   ---   #### Caddy configuration file [[#^Top|TOP]] Caddy's configuration file is inder: ```ad-path /etc/caddy/Caddyfile ``` Default configuration is: ```ad-code ~~~javascript (localhost) { root * /var/www/html encode gzip zstd php_fastcgi unix//run/php/php7.4-fpm.sock tls (service email) { protocols tls1.2 tls1.3 } } ~~~ ```   ---   #### PHP configuration file [[#^Top|TOP]] To update php, edit the following file: ```ad-path /etc/php/7.4/fpm/pool.d/www.conf ``` Change all 'www-data' user reference with 'caddy' including: ```ad-code ~~~yaml listen.owner = caddy listen.group = caddy ~~~ ``` Once this is done, restart php: ```ad-command ~~~bash sudo systemctl restart php7.4-fpm ~~~ ```   ---   #### Configuring CORS [[#^Top|TOP]]   ##### Preliminary CORS code snippet ```ad-code ~~~javascript (cors) { @origin{args.0} header Origin {args.0} header @origin{args.0} Access-Control-Allow-Origin "{args.0}" } ~~~ ```   ##### CORS for a sub-domain ```ad-code ~~~javascript import cors (http://subdomain.tld) header Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT" header Access-Control-Allow-Headers "*" ~~~ ```   ---   #### Configuration of a sub-domain suffix [[#^Top|TOP]] Configuration requires to add the following in the sub-domain definition of the [[Configuring Caddy#Caddy configuration file|Caddyfile]]: ```ad-code ~~~javascript handle_path /(suffix)* { root * /(path to suffix) file_server } ~~~ ```   ---   #### Configuring with the docker network [[#^Top|TOP]] Configuration of a service attached to the docker network is easy: ```ad-code ~~~javascript (hostname) { encode zstd gzip reverse_proxy xxx.yyy.zzz.aaa:port } ~~~ ```   ---   #### Configuring login with a cookie [[#^Top|TOP]] ```ad-info title: Tutorial [Link](https://josheli.com/knob/2021/02/24/single-sign-on-in-caddy-server-using-only-the-caddyfile-and-basic-authentication/) ```   ##### Preliminary login code snippets 1. **Creat hashed passwords** ```ad-command ~~~bash caddy hash-password ~~~ ``` 2. **Define the array of users and hashed password** In the [[Configuring Caddy#Caddy configuration file|Caddyfile]]: ```ad-code ~~~javascript (basic-auth) { basicauth / { user hashed-password } } ~~~ ``` 3. **Define the snippet to test whether the cookie is installed** In the [[Configuring Caddy#Caddy configuration file|Caddyfile]]: ```ad-code ~~~javascript (proxy-auth) { % if cookie not = some-token-nonsense @no-auth { not header_regexp mycookie Cookie myid=(regex-to-match-id) } % store current time, page and redirect to auth route @no-auth { header Set-Cookie "myreferer={scheme}://{host}{uri}; Domain=example.com; Path=/; Max-Age=30; HttpOnly; SameSite=Strict; Secure" redir https://auth.example.com } } ~~~ ```   ##### Intermediary authentication page [[#^Top|TOP]] After setting up a new subdomain/page and appropriate DNS records, define it as follows in the [[Configuring Caddy#Caddy configuration file|Caddyfile]]: ```ad-code ~~~javascript auth.example.com { route / { % require authentication import basic-auth % upon successful auth, set a client token header Set-Cookie "myid=some-long-hopefully-random-string; Domain=example.com; Path=/; Max-Age=3600; HttpOnly; SameSite=Strict; Secure" % delete the referer cookie header +Set-Cookie "myreferer=null; Domain=example.com; Path=/; Expires=Thu, 25 Sep 1971 12:00:00 GMT; HttpOnly; SameSite=Strict; Secure" % redirect back to the original site redir {http.request.cookie.myreferer} } % fallback respond "Hi." } ~~~ ```   ##### Adding authentication to a subdomain Simply add the following at the top of all declarations for sub-domain definitions: ```ad-code ~~~javascript import proxy-auth ~~~ ```   ---   #### Configuring logging for Caddy 1. In the [[Configuring Caddy#Caddy configuration file|Caddyfile]], add a logging module: ```ad-code title: logging script ~~~javascript (log) { log { output file /var/log/caddy/caddy.log { roll_local_time # Other parameters can be found on the Caddy website } format json # (or console) level INFO # (or ERROR) } } ~~~ ```   2. In the global configuration section, add the `import log` directive ```ad-code ~~~javascript { import log } ~~~ ``` 2. In each subdomain definition, add the following line `import log`   ---   ### Utilities [[#^Top|TOP]]   #### SSL Certification location Look for a folder with the following sequence: ```ad-path /.local/share/caddy ```   #### Reading the log file Caddy does offer a `common_log` field in their JS log that can be called for consumption by other software: ```ad-command ~~~bash sudo cat /var/log/caddy/caddy.log | jq -r ' .. | .common_log? | select(. !=null)' ~~~ ```   #### Sending logs to user In order to consume the logs, it is sent through a cron job to a [[Configuring Telegram bots|Telegram bot]]. The script is below: ```ad-code ~~~bash ~~~ ```   ---   ### Basic commands [[#^Top|TOP]] A full repository of commands can be found [here](https://caddyserver.com/docs/)   #### Start/Stop/Restart ```ad-command ~~~bash sudo systemctl start/stop/restart caddy ~~~ ```   #### Reload config Once config amended just run: ```ad-command ~~~bash sudo systemctl reload caddy ~~~ ``` [[#^Top|TOP]]