Local HTTPS? Wireguard Docker

1. Caddy version (caddy version):


2. How I run Caddy:

a. System environment:

ubuntu, docker, dockstarter

b. Command:

docker restart caddy

c. Service/unit/compose file:

version: "3.7"

    image: caddy
    restart: unless-stopped
      - "80:80"
      - "443:443"
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

    external: true
    external: true
    name: customnetwork

d. My complete Caddyfile or JSON config: {
     reverse_proxy bitwarden

3. The problem I’m having:

I have a VPS setup on oracle cloud which I use wireguard into. I believe what I am trying to do is setup local https? I also have pihole so I can get vanity names in my /etc/hosts.

4. Error messages and/or full log output:

{“level”:“info”,“ts”:1636298041.4719021,“logger”:“tls.obtain”,“msg”:“acquiring lock”,“identifier”:“”}
{“level”:“info”,“ts”:1636298041.4733467,“logger”:“tls”,“msg”:“finished cleaning storage units”}
{“level”:“info”,“ts”:1636298041.4760349,“logger”:“tls.obtain”,“msg”:“lock acquired”,“identifier”:“”}
{“level”:“info”,“ts”:1636298041.4788804,“logger”:“tls.obtain”,“msg”:“certificate obtained successfully”,“identifier”:“”}
{“level”:“info”,“ts”:1636298041.478903,“logger”:“tls.obtain”,“msg”:“releasing lock”,“identifier”:“”}
{“level”:“warn”,“ts”:1636298041.4792109,“logger”:“tls”,“msg”:“stapling OCSP”,“error”:“no OCSP stapling for []: no OCSP server specified in certificate”}
{“level”:“info”,“ts”:1636298041.4719021,“logger”:“tls.obtain”,“msg”:“acquiring lock”,“identifier”:“”}
{“level”:“info”,“ts”:1636298041.4733467,“logger”:“tls”,“msg”:“finished cleaning storage units”}
{“level”:“info”,“ts”:1636298041.4760349,“logger”:“tls.obtain”,“msg”:“lock acquired”,“identifier”:“”}
{“level”:“info”,“ts”:1636298041.4788804,“logger”:“tls.obtain”,“msg”:“certificate obtained successfully”,“identifier”:“”}
{“level”:“info”,“ts”:1636298041.478903,“logger”:“tls.obtain”,“msg”:“releasing lock”,“identifier”:“”}
{“level”:“warn”,“ts”:1636298041.4792109,“logger”:“tls”,“msg”:“stapling OCSP”,“error”:“no OCSP stapling for []: no OCSP server specified in certificate”}

#This site can’t be reached took too long to respond.

5. What I already tried:

I tried following the guides in relevant resources no luck :frowning:

6. Links to relevant resources:

I think there’s a mistake, section 4 is completely empty. What is actually your question / what is wrong?

I don’t know if I am using the right term but, I believe I am trying to setup “local HTTPS” on my VPS. Is my Caddyfile correct?

This log message shows that you do indeed have a certificate for the hostname, issued by Caddy’s local CA.

What exactly is the problem? What are you trying to do? I’m not seeing anything not working as intended there. Caddy is doing exactly what you told it to do :thinking:

Try making a request to your server with curl -v, and if you haven’t set up your machine to trust Caddy’s local CA, then you can use curl -vk instead to ignore trust verification.

Hello, I am trying to get local HTTPS on my VPN. I created a simplified version of my caddyfile

bitwarden.private {
        respond hello

Within Pi-Hole I configured the domain to point to the ip address of the docker container like so:

But I am not getting a hello response it just goes to the docker container with no https.

Here is the output from curl -v

C:\Users\Ryan>curl -v bitwarden.private
* Rebuilt URL to: bitwarden.private/
*   Trying
* Connected to bitwarden.private ( port 80 (#0)
> GET / HTTP/1.1
> Host: bitwarden.private
> User-Agent: curl/7.55.1
> Accept: */*
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Cache-Control: public, max-age=600
< Server: Rocket
< Feature-Policy: accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; camera 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'none'; sync-xhr 'self' https://haveibeenpwned.com https://2fa.directory; usb 'none'; vr 'none'
< Referrer-Policy: same-origin
< X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: frame-ancestors 'self' chrome-extension://nngceckbapebfimnlniiiahkandclblb chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh moz-extension://* ;
< Content-Length: 1121
< Date: Sun, 07 Nov 2021 20:24:07 GMT
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=1010"><meta name="theme-color" content="#175DDC"><title page-title>Bitwarden Web Vault</title><link rel="apple-touch-icon" sizes="180x180" href="images/icons/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="images/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="images/icons/favicon-16x16.png"><link rel="mask-icon" href="images/icons/safari-pinned-tab.svg" color="#175DDC"><link rel="manifest" href="manifest.json"><link href="app/main.5c0db323b598138d1784.css" rel="stylesheet"></head><body class="layout_frontend"><app-root><div class="mt-5 d-flex justify-content-center"><div><img src="images/logo-dark@2x.png" class="mb-4 logo" alt="Bitwarden"><p class="text-center"><i class="fa fa-spinner fa-spin fa-2x text-muted" title="Loading" aria-hidden="true"></i></p></div></div></app-root><script src="app/polyfills.5c0db323b598138d1784.js"></script><script src="app/vendor.5c0db323b598138d1784.js"></script><script src="app/main.5c0db323b598138d1784.js"></script></body></html>* Connection #0 to host bitwarden.private left intact

Here are my new errors

{"level":"error","ts":1636317014.4285805,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"bitwarden.private","issuer":"acme.zerossl.com-v2-DV90","error":"HTTP 400 urn:ietf:params:acme:error:rejectedIdentifier - Invalid DNS identifier [bitwarden.private]"}
{"level":"error","ts":1636317014.4286773,"logger":"tls.obtain","msg":"will retry","error":"[bitwarden.private] Obtain: [bitwarden.private] creating new order: attempt 1: https://acme.zerossl.com/v2/DV90/newOrder: HTTP 400 urn:ietf:params:acme:error:rejectedIdentifier - Invalid DNS identifier [bitwarden.private] (ca=https://acme.zerossl.com/v2/DV90)","attempt":1,"retrying_in":60,"elapsed":1.019920711,"max_duration":2592000}

That’s because that domain isn’t considered by Caddy to be a “local domain”, because .private isn’t one of the TLDs Caddy automatically considers as local. See the docs:

The error is basically that Caddy is trying to get a certificate for that domain from a public ACME issuer, ZeroSSL, but failing because bitwarden.private isn’t a real domain.

To fix this, you can add tls internal to your Caddyfile’s site block to force Caddy to issue the certificate with its local issuer.

bitwarden.private {
    tls internal
    reverse_proxy bitwarden:80

It still says the site is insecure and I am not getting the hello response. Here are my logs:

{"level":"info","ts":1636317815.4783926,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
{"level":"warn","ts":1636317815.4800608,"msg":"input is not formatted with 'caddy fmt'","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":27}
{"level":"info","ts":1636317815.4812255,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["localhost:2019","[::1]:2019",""]}
{"level":"info","ts":1636317815.482164,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x40003fe700"}
{"level":"info","ts":1636317815.4835522,"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}
{"level":"info","ts":1636317815.483666,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1636317815.4844124,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["feed.ryanrambharose.dev","chat.ryanrambharose.dev","ryanrambharose.dev","bitwarden.private","bitwarden.ryanrambharose.dev","portainer.ryanrambharose.dev","pihole.ryanrambharose.dev","media.ryanrambharose.dev"]}
{"level":"info","ts":1636317815.4845974,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
{"level":"warn","ts":1636317815.5005624,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [bitwarden.private]: no OCSP server specified in certificate"}
{"level":"info","ts":1636317815.5026546,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1636317815.5187714,"logger":"pki.ca.local","msg":"root certificate is already trusted by system","path":"storage:pki/authorities/local/root.crt"}
{"level":"info","ts":1636317815.518986,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1636317815.5190046,"msg":"serving initial configuration"}

Is it clear what I am trying to do?

I’m only seeing startup logs in that last post, nothing useful to comment on.

What behaviour are you seeing now? What does it look like when you make a request with curl -v? etc.

This is my curl -v


My current caddy file:

bitwarden.private {
        tls internal
        respond hello

That was an HTTP request, and it never reached Caddy. There’s no Server: Caddy response header. It reached your Bitwarden server directly.

How do I make sure it reaches Caddy? As noted earlier, I am using PiHole DNS I setup it like so:


Are you sure that’s the right IP address? Do you have more than one machine? Is that actually the IP for your bitwarden machine, instead of your Caddy one? I don’t have a good picture of your setup here.

I am using a VPS on oracle cloud. I have a VPN connection to the server via wireguard. Wireguard, Caddy, and BItwarden, PiHole are running in Docker. Should I be sending bitwarden.private to my Caddy Docker?

Ok that was issue.

Now it says not secure. I believe I to add the keys to my key store on windows?

Screenshot 2021-11-08 111101

Yeah. You can find the root CA cert in your caddy_data volume. You can find its location with docker volume inspect caddy_data. The cert will be in there at pki/authorities/local/root.crt. You can copy it to your Windows machine and install it to your Windows and/or browser trust stores. Google will give you instructions.

All that said, have you considered using the DNS challenge to get a publicly trusted cert instead for this service? That way you won’t need to muck with installing root certs. The site can still be private, but you can use a public domain and get a public cert.

How would I use the DNS challenge? Would that be using ACME server?

See the DNS challenge section:

Involves installing Caddy with a plugin for your DNS provider (see the docs on Docker Hub for building Caddy with plugins, in particular the section “Adding custom Caddy modules”), then configuring Caddy to use that DNS provider’s API, with whatever credentials it may require.