Need help getting HTTPS on internal NAT network

Hello all,

I would like to ask for help with configuring Bitwarden_RS with HTTPS on an internal network (no external access) behind my router.

Here’s how I have it set up.

I have a Windows 10 Pro Machine which I am using as a server.
I have installed Docker CE, and that works.

That Windows 10 Pro machine has internet access outbound, but no inbound access. Meaning, when I run Bitwarden_RS on it, it is only accessible via my local network (192.168.x.x). That’s what I want it to do.

The goal is that Bitwarden_RS is used by myself, my wife, and my son, on our computers, and our phones. We used to use Keepass and loved it, but needed the ability to share passwords/entries. We would only add/edit entries while on our home network. If we have to take our laptops/phones outside (out of network), we will use the cached data in the apps.

I have tried a few things and came up with a very convoluted solution, but I think to myself, that this can’t be right. It’s just way to crazy.

Here’s my convoluted solution which temporarily works:

  1. I used duckdns.org to register my home IP to a URL, so, like this: rick1.duckdns.org -> home IP (x.x.x.x).

  2. I have a domain hosted on a webhost, so I created a CNAME to point to that duckdns, and thus the IP. so like this: bitwarden.rick1.org -> CNAME -> rick1.duckdns.org

  3. I did port-forwarding temporarily on my router, ports 80 and 443 to my Windows 10 Server.

I ran docker-compose with this yml file:
# docker-compose.yml
version: ‘3’

services:
  bitwarden:
    image: bitwardenrs/server
    environment:
      DOMAIN: 'https://bitwarden.rick1.org'
      WEBSOCKET_ENABLED: 'true' # Required to use websockets
      SIGNUPS_ALLOWED: 'true'   # set to false to disable signups
      LOG_FILE: '/data/bitwarden.log'
      ADMIN_TOKEN: some_random_token_as_per_above_explanation
    restart: always
    volumes:
      - D:/DockerData/bitwardenrs/:/data/
    

  caddy:
    image: abiosoft/caddy
    restart: always
    volumes:
      - D:/DockerData/Caddyfile:/etc/Caddyfile:ro
      - D:/DockerData/caddycerts:/root/.caddy
    ports:
      - 80:80 # needed for Let's Encrypt
      - 443:443
    environment:
      ACME_AGREE: 'true'              # agree to Let's Encrypt Subscriber Agreement
      DOMAIN: 'bitwarden.rick1.org'         # CHANGE THIS! Used for Auto Let's Encrypt SSL
      EMAIL: '<myEmail>'        # CHANGE THIS! Optional, provided to Let's Encrypt

volumes:
  caddycerts:

When Caddy runs, it generates the Let’s Encrypt certificates for future use, and that works.

Then, to clean up stuff, I have to shut off port forwarding on my router.
I then also change the CNAME entry to an A RECORD which is my internal Windows 10 IP, so like bitwarden.rick1.org --> 192.168.1.10

That way, when I point my browser & app to https://bitwarden.rick1.org, there is a valid certificate, and it points to my internal Windows 10 server.

Now, the question was, is there a much better and simpler way to do this? Because I have to then repeat a few steps every 2.5 months as I renew the SSL certificate.

Thank you.

If you can use the DNS challenge to renew the certificates, that works much, much better.

For example I have a domain bw.dani.example, managed by cloudflare and caddy has support for DNS challenges with Cloudflare, so i just add tls cloudflare to the CADDYFILE and set two environment variables and done, it gets autorenewed by itself even if the IP that the domain points at is internal.

There’s support for a lot of providers too

Thank you. I am still a bit new to all of this.

A couple of questions:

  1. I know that some parts of cloudflare are free. Is there a free tier to accomplish this?
  2. Can you post the two environment variable lines to be added to caddyfile?

That would really help me out. Thank you very much!

Yeah I only use the free tier, you need to add your domain and configure it’s dns servers (this is done from your domain provider’s side). Once done, you configure all your dns entries from cloudflare.

Then you need to generate an API key which is what you supply with env variables:

CLOUDFLARE_EMAIL=your_email
CLOUDFLARE_API_KEY=your_api_key

Thank you! I will try this out, and let you know if I have success or more questions. Really appreciate it!

Thank you Dani. I got it working with your help. The hold up was figuring out which API key to use, as I was trying to use one of the lowest security requirement, but apparently it needs the master key.

Thank you again!