From d5fab6af2444bb2abf2229bf62534cc94082d51d Mon Sep 17 00:00:00 2001 From: MDLeom <2809763-curben@users.noreply.gitlab.com> Date: Sat, 23 May 2020 11:24:12 +0100 Subject: [PATCH] post: 'Upgrading Caddy from v1 to v2' --- source/_posts/caddy-upgrade-v2-proxy.md | 143 ++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 source/_posts/caddy-upgrade-v2-proxy.md diff --git a/source/_posts/caddy-upgrade-v2-proxy.md b/source/_posts/caddy-upgrade-v2-proxy.md new file mode 100644 index 0000000..78e7e59 --- /dev/null +++ b/source/_posts/caddy-upgrade-v2-proxy.md @@ -0,0 +1,143 @@ +--- +title: Upgrading Caddy reverse proxy from v1 to v2 syntax +excerpt: route, strip_prefix, rewrite +date: 2020-05-23 +tags: +- server +- caddy +--- + +Caddy v2 brought many major changes, particularly to the Caddyfile syntax. This [site](https://mdleom.com/) is powered by the reverse proxy feature of Caddy, so I need to make sure everything works before I finally upgrade. While v2 has been released for more than 2 weeks by now (after months of beta testing), I only managed get my feet wet last weekend, even though I should've done it during the beta releases. After testing v2 on a local server (plus some forum posts), I would say it is _mostly_ working. While v2.0 has reached feature parity with v1, Caddyfile has not; there are two TLS/HTTPS options that are not yet supported in Caddyfile (see [#3219](https://github.com/caddyserver/caddy/issues/3219), [#3334](https://github.com/caddyserver/caddy/issues/3334); planned to be released in v2.1). So, if you don't need HTTPS--like my {% post_link tor-hidden-onion-nixos 'Tor' %} and {% post_link i2p-eepsite-nixos 'I2P' %} proxies--it should be safe to upgrade. + +## proxy to reverse_proxy + +`proxy` directive is updated to `reverse_proxy`. + +Reverse proxy the whole website: + +``` plain v1 +proxy / https://backend.com +``` + +In v2, the matcher needs `*`: + +``` plain v2 +reverse_proxy /* https://backend.com +``` + +If no matcher is specified, it defaults to `/*` which match every path: + +``` plain v2 +reverse_proxy https://backend.com +``` + +### Custom path + +Reverse proxy a certain path, like `/api`: + +``` plain v2 +reverse_proxy /api/* https://backend.com +``` + +Requests to `https://example.com/api/foo/bar/` is redirected to `https://backend.com/api/foo/bar/`. + +To remove the path prefix: + +``` plain v1 +proxy /api https://backend.com { + without /api +} +``` + +Requests to `https://example.com/api/foo/bar/` is redirected to `https://backend.com/foo/bar/`. + +v2 doesn't have `without` directive, instead you need to use `route` the request and remove the prefix using `uri strip_prefix`: + +``` plain v2 +route /api/* { + uri strip_prefix /api + reverse_proxy https://backend.com +} +``` + +### Backend with custom path + +Reverse proxy with custom path: + +``` plain v1 +proxy /img https://backend.com/img/blog { + without /img +} +``` + +![v1 syntax](20200523/proxy.png) + +v2 doesn't support custom path, instead you need to use `rewrite` to prepend the path: + +``` plain v2 +route /img/* { + uri strip_prefix /img + + rewrite * /img/blog{path} + + reverse_proxy https://backend.com +} +``` + +![v2 syntax](20200523/reverse_proxy.png) + +## header_upstream to header_up + +``` plain v1 +proxy / https://backend.com { + header_upstream Host backend.com +} +``` + +``` plain v2 +reverse_proxy https://backend.com { + header_up Host backend.com +} +``` + +## header_downstream to header_down + +``` plain v1 +proxy / https://backend.com { + header_downstream -server +} +``` + +``` plain v2 +reverse_proxy https://backend.com { + header_up -server +} +``` + +## HTTP only (disable HTTPS/TLS) + +``` plain v1 +example.com:8080 { + tls off +} +``` + +In v2, `tls` doesn't have `off` option, instead you can specify `http://` to listen on HTTP only: + +``` plain v2 +http://example.com:8080 { + +} +``` + +## Disable HTTP -> HTTPS redirects + +In v2, Caddy automatically listens on HTTP (port 80) and redirects to HTTPS, whereas in v1, you need add a separate `redir 301`. This is handy is most use cases, but doesn't apply to my {% post_link caddy-nixos-part-3 'use case' %}--listens on HTTPS only. + +In v2.0, this can only be disabled in [JSON](https://caddyserver.com/docs/json/apps/http/servers/#automatic_https/disable_redirects); it will be configurable using Caddyfile in [v2.1](https://github.com/caddyserver/caddy/issues/3219). + +## TLS client authentication + +Client authentication adds another step to TLS connection process whereby a client needs to present a certificate (that has been signed by a CA certificate) to the server (which has the CA certificate) when it attempts to establish a TLS connection. Once the client is authenticated, the process is reversed and client authenticates the server instead. The padlock icon next to the web address indicates that the website's certificate is valid. Client authentication is only used in private web server to restrict access to authorised clients only. In my case, I restrict my origin server to [Cloudflare CDN](https://support.cloudflare.com/hc/en-us/articles/204899617-Authenticated-Origin-Pulls) only; mdleom.com is only accessible via Cloudflare, direct connection to the origin server will be dropped. + +In v2.0, this can only be disabled in [JSON](https://caddyserver.com/docs/json/apps/http/servers/tls_connection_policies/#client_authentication); it will be configurable using Caddyfile in [v2.1](https://github.com/caddyserver/caddy/issues/3334).