Synology Docker Macvlan Vaultwarden

1. Output of caddy version:

Unsure, I believe it’s a container running within the Vaultwarden docker image

2. How I run Caddy:

The Vaultwarden docker container runs caddy within the prebuilt docker image

a. System environment:

I’m using Synology and docker is installed on /volume2/docker directory

I created a vaultwarden with that three folders; vw-data, caddy-config, caddy-data

b. Command:

sudo docker-compose --project-name vaultwarden -f vaultwarden.yaml up -d

c. Service/unit/compose file:

version: '3'

services:
    vaultwarden:
        image: vaultwarden/server:latest
        container_name: vaultwarden
        networks:
            vlan10-macvlan:
                ipv4_address: 192.168.1.200
        restart: always
        environment:
            WEBSOCKET_ENABLED: "true"  # Enable WebSocket notifications.
        volumes:
            - '/volume2/docker/vaultwarden/vw-data:/data'
    caddy:
        image: caddy:2
        container_name: caddy
        restart: always
        networks:
            vlan10-macvlan:
                ipv4_address: 192.168.1.201
        ports:
            - 80:80  # Needed for the ACME HTTP-01 challenge.
            - 443:443
        volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile:ro
            - '/volume2/docker/vaultwarden/caddy-config:/config'
            - '/volume2/docker/vaultwarden/caddy-data:/data'
        environment:
            SITE: "https://vw.site .com"  # Your site.
            EMAIL: "hostmaster@site .com"   # The email address to use for ACME registration.
            LOG_FILE: "/data/access.log"
networks:
    vlan10-macvlan:
        external: true

d. My complete Caddy config:

{$SITE}:443 {
  log {
    level INFO
    output file {$LOG_FILE} {
      roll_size 10MB
      roll_keep 10
    }
  }

  # Use the ACME HTTP-01 challenge to get a cert for the configured site.
  tls {$EMAIL}

  # This setting may have compatibility issues with some browsers
  # (e.g., attachment downloading on Firefox). Try disabling this
  # if you encounter issues.
  encode gzip

  # Notifications redirected to the WebSocket server
  reverse_proxy /notifications/hub vaultwarden:3012

  # Proxy everything else to Rocket
  reverse_proxy vaultwarden:80 {
       # Send the true remote IP to Rocket, so that vaultwarden can put this in the
       # log, so that fail2ban can ban the correct IP.
       header_up X-Real-IP {remote_host}
  }
}

3. The problem I’m having:

I have other docker containers running using macvlan docker network driver successfully. This allows each docker container to have a unique IP address on the LAN.

I’ve been trying to modify the default Vaultwarden docker compose to include the macvlan configuration.

I’m able to run the compose and both the Vaultwarden and Caddy containers successfully run. I am able to connect to 192.168.1.200 and see the vaultwarden http page, however I am unable to connect to 192.168.1.201 (caddy), and see the https version.

I have created a DNS entry that resolves A record (vw.site .com) to 192.1681.201, but it does not connect and I am not presented with a webpage.

4. Error messages and/or full log output:

Browser returns: ERR_SSL_PROTOCOL_ERROR

5. What I already tried:

I spend a long time modifying the docker compose file, and had many errors which are now resolved. I feel that I’m really close to getting this to working, but am unsure what I am missing…

6. Links to relevant resources:

This is the link to the Vaultwarden docker compose instructions. It doesn’t mention macvlan, as this is something which I feel is a little more advanced and not common.

Please note, I was unable to post this topic with the word"domain", so I replaced with the word “site”.

Hi Johnny001,
You mentioned:

Browser returns: ERR_SSL_PROTOCOL_ERROR

By my experience, Caddy will reverse_proxy HTTPS by default.
So you code below is trying to connect HTTPS through port 80, resulted the error.

  reverse_proxy vaultwarden:80 {
       # Send the true remote IP to Rocket, so that vaultwarden can put this in the
       # log, so that fail2ban can ban the correct IP.
       header_up X-Real-IP {remote_host}
  }  

try adding http:// for your reverse_proxy to tell Caddy to use HTTP instead

reverse_proxy http://vaultwarden:80

Cheers

1 Like

Can you share the output of

sudo docker-compose --project-name vaultwarden -f vaultwarden.yaml logs caddy

Automatic HTTPS — Caddy Documentation will try to issue a publicly-trusted certificate for non-local hostnames by default, which requires external ACME providers (like LetsEncrypt or ZeroSSL) to reach your Caddy server from the internet (when using the HTTP/TLS-ALPN challenge, which is the default).

So if your DNS record is set to something internal - from your intranet - then those ACME providers won’t be able to reach you - from the internet - and thus no certificate can be obtained.

Either

  • change the DNS record and set up port forwarding
  • or replace tls {$EMAIL} in your Caddyfile with tls internal to use a self-signed certificate
  • or use the DNS challenge instead.

Please see Automatic HTTPS — Caddy Documentation and feel free to ask any questions if something is unclear :innocent:


No, this is wrong.
The reverse_proxy directive defaults to http:// for the upstream, unless you specify https://, :443 or use any of the transport http { tls_* } options. See docs/caddyfile/directives/reverse_proxy#tls

2 Likes

Thanks for the assistance.

The DNS A record created was only on my internal DNS server. I’ll create an A record on my external DNS.

If I open up port 80 and 443 from the internet through my firewall, which IP do I port forward to as the destination; 192.168.1.200 or 192.168.1.201?

root@synology:~# sudo docker-compose --project-name vaultwarden -f vaultwarden.yaml logs caddy
Attaching to caddy
caddy          | {"level":"info","ts":1672571606.4031694,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
caddy          | {"level":"warn","ts":1672571606.4051363,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy          | {"level":"info","ts":1672571606.406052,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
caddy          | {"level":"info","ts":1672571606.406236,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy          | {"level":"info","ts":1672571606.4062526,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy          | {"level":"info","ts":1672571606.4062638,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000229030"}
caddy          | {"level":"info","ts":1672571606.4065824,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
caddy          | {"level":"info","ts":1672571606.4065924,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy          | {"level":"info","ts":1672571606.4066117,"logger":"tls","msg":"finished cleaning storage units"}
caddy          | {"level":"info","ts":1672571606.406619,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy          | {"level":"info","ts":1672571606.4066694,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size for details."}
caddy          | {"level":"info","ts":1672571606.4067338,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy          | {"level":"info","ts":1672571606.4067402,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["vw.site .com"]}
caddy          | {"level":"info","ts":1672571606.5397282,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy          | {"level":"info","ts":1672571606.5397563,"msg":"serving initial configuration"}
caddy          | {"level":"info","ts":1672571606.5398269,"logger":"tls.obtain","msg":"acquiring lock","identifier":"vw.site .com"}
caddy          | {"level":"info","ts":1672571606.7278328,"logger":"tls.obtain","msg":"lock acquired","identifier":"vw.site .com"}
caddy          | {"level":"info","ts":1672571606.7280357,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"vw.site .com"}
caddy          | {"level":"info","ts":1672571608.2420964,"logger":"http","msg":"waiting on internal rate limiter","identifiers":["vw.site .com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"hostmaster@site .com"}
caddy          | {"level":"info","ts":1672571608.2421176,"logger":"http","msg":"done waiting on internal rate limiter","identifiers":["vw.site .com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"hostmaster@site .com"}
caddy          | {"level":"info","ts":1672571608.788159,"logger":"http.acme_client","msg":"trying to solve challenge","identifier":"vw.site .com","challenge_type":"tls-alpn-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
caddy          | {"level":"error","ts":1672571609.4346952,"logger":"http.acme_client","msg":"challenge failed","identifier":"vw.site .com","challenge_type":"tls-alpn-01","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"no valid A records found for vw.site .com; no valid AAAA records found for vw.site .com","instance":"","subproblems":[]}}
caddy          | {"level":"error","ts":1672571609.4347346,"logger":"http.acme_client","msg":"validating authorization","identifier":"vw.site .com","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"no valid A records found for vw.site .com; no valid AAAA records found for vw.site .com","instance":"","subproblems":[]},"order":"https://acme-v02.api.letsencrypt.org/acme/order/896812617/156227514727","attempt":1,"max_attempts":3}
caddy          | {"level":"info","ts":1672571611.0802114,"logger":"http.acme_client","msg":"trying to solve challenge","identifier":"vw.site .com","challenge_type":"http-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
caddy          | {"level":"error","ts":1672571611.7160506,"logger":"http.acme_client","msg":"challenge failed","identifier":"vw.site .com","challenge_type":"http-01","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"no valid A records found for vw.site .com; no valid AAAA records found for vw.site .com","instance":"","subproblems":[]}}
caddy          | {"level":"error","ts":1672571611.7161236,"logger":"http.acme_client","msg":"validating authorization","identifier":"vw.site .com","problem":{"type":"urn:ietf:params:acme:error:dns","title":"","detail":"no valid A records found for vw.site .com; no valid AAAA records found for vw.site .com","instance":"","subproblems":[]},"order":"https://acme-v02.api.letsencrypt.org/acme/order/896812617/156227518737","attempt":2,"max_attempts":3}
caddy          | {"level":"error","ts":1672571611.716189,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"vw.site .com","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:dns - no valid A records found for vw.site .com; no valid AAAA records found for vw.site .com"}
root@synology:~# ^C
root@synology:~# 

192.168.1.201, since that’s the IP of the Caddy container :slight_smile:

1 Like

He did declare {$SITE}:443 { and tls {$EMAIL} in Caddy config :slight_smile:
By default, Caddy HTTPS all site , for example

example.com {
    reverse_proxy *  192.168.0.1
}

Caddy will proxy through HTTPS/443 if didn’t specify to use HTTP/80 :slight_smile:

1 Like

That did the trick!

I’m now able to view the site when typing in https://vw.site .com for IP x.201.

One other question if you will, regarding the VW container 192.168.1.200, do you know if this needs to have an IP exposed on the LAN, or could I remove the macvlan in the docker compose file and Caddy and VW container will chat within the parent container via alias docker network names?

Really appreciate your assistance to determine what was needed!

Thank you both!

root@synology:~# sudo docker-compose --project-name vaultwarden -f vaultwarden.yaml logs caddy
Attaching to caddy
caddy          | {"level":"info","ts":1672598010.560746,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
caddy          | {"level":"warn","ts":1672598010.5627894,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy          | {"level":"info","ts":1672598010.5635445,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
caddy          | {"level":"info","ts":1672598010.563712,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy          | {"level":"info","ts":1672598010.5637262,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy          | {"level":"info","ts":1672598010.5637498,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000220e70"}
caddy          | {"level":"info","ts":1672598010.564054,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy          | {"level":"info","ts":1672598010.5641074,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size for details."}
caddy          | {"level":"info","ts":1672598010.5641065,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
caddy          | {"level":"info","ts":1672598010.5641406,"logger":"tls","msg":"finished cleaning storage units"}
caddy          | {"level":"info","ts":1672598010.564164,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy          | {"level":"info","ts":1672598010.5641859,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy          | {"level":"info","ts":1672598010.5641913,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["vw.site .com.com"]}
caddy          | {"level":"info","ts":1672598010.5643942,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy          | {"level":"info","ts":1672598010.5644016,"msg":"serving initial configuration"}
caddy          | {"level":"info","ts":1672598010.5648396,"logger":"tls.obtain","msg":"acquiring lock","identifier":"vw.site .com.com"}
caddy          | {"level":"info","ts":1672598010.59666,"logger":"tls.obtain","msg":"lock acquired","identifier":"vw.site .com.com"}
caddy          | {"level":"info","ts":1672598010.5969145,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"vw.site .com.com"}
caddy          | {"level":"info","ts":1672598012.4605436,"logger":"http","msg":"waiting on internal rate limiter","identifiers":["vw.site .com.com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"hostmaster@site .com.com"}
caddy          | {"level":"info","ts":1672598012.4605696,"logger":"http","msg":"done waiting on internal rate limiter","identifiers":["vw.site .com.com"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"hostmaster@site .com.com"}
caddy          | {"level":"info","ts":1672598012.891356,"logger":"http.acme_client","msg":"trying to solve challenge","identifier":"vw.site .com.com","challenge_type":"http-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
caddy          | {"level":"info","ts":1672598013.4000382,"logger":"http","msg":"served key authentication","identifier":"vw.site .com.com","challenge":"http-01","remote":"34.219.86.40:33200","distributed":false}
caddy          | {"level":"info","ts":1672598013.4064746,"logger":"http","msg":"served key authentication","identifier":"vw.site .com.com","challenge":"http-01","remote":"3.144.111.37:15822","distributed":false}
caddy          | {"level":"info","ts":1672598013.5564077,"logger":"http","msg":"served key authentication","identifier":"vw.site .com.com","challenge":"http-01","remote":"23.178.112.103:40744","distributed":false}
caddy          | {"level":"info","ts":1672598013.9461253,"logger":"http.acme_client","msg":"authorization finalized","identifier":"vw.site .com.com","authz_status":"valid"}
caddy          | {"level":"info","ts":1672598013.9461455,"logger":"http.acme_client","msg":"validations succeeded; finalizing order","order":"https://acme-v02.api.letsencrypt.org/acme/order/897198237/156284852377"}
caddy          | {"level":"info","ts":1672598015.19931,"logger":"http.acme_client","msg":"successfully downloaded available certificate chains","count":2,"first_url":"https://acme-v02.api.letsencrypt.org/acme/cert/03bd54a01a9d1d128c033958c0d5ff8a93c6"}
caddy          | {"level":"info","ts":1672598015.199703,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"vw.site .com.com"}
caddy          | {"level":"info","ts":1672598015.199769,"logger":"tls.obtain","msg":"releasing lock","identifier":"vw.site .com.com"}
1 Like

Yes but the site address is not the same thing as the reverse proxy upstream address. Different contexts. Caddy defaults to serving sites over HTTPS, but defaults to proxying over HTTP. What @emilylange said is accurate. The proxy will default to port 80 if no scheme or port is specified. You can verify by reading the code if you like.

1 Like

Good to know. Is this info documented anywhere in Caddy Doc ?

Yes:

This topic was automatically closed after 30 days. New replies are no longer allowed.