How to Build a Self-Hosted Reverse Proxy with Valid SSL for Local-Only Access on Synology NAS

Running multiple self-hosted apps on a Synology NAS is easy—until you want them to feel “production clean”: one HTTPS URL per app (no ports), trusted certificates (no browser warnings), and LAN-only access (nothing exposed to the public internet).
This guide shows two proven ways to do it:
Option A (Best for “publicly trusted” SSL): Use a real domain + Let’s Encrypt DNS-01 challenge so certificates are valid even if your NAS is never reachable from the internet. (Recommended for most people.)
Option B (Best for purely internal names): Use a private CA (step-ca or Caddy’s internal CA) for internal-only domains like *.lan or *.home.
You’ll also lock access down so the reverse proxy only works inside your home network.
Target Outcome
You’ll end up with URLs like:
- https://vaultwarden.home.example.com
- https://photos.home.example.com
- https://ha.home.example.com
All of them:
- terminate TLS at the NAS reverse proxy
- show a valid certificate
- route to internal services (Docker containers, NAS packages, other LAN servers)
- are not reachable from the internet
What You Need
Hardware / software
- Synology NAS on DSM 7.x
- Your apps running on the NAS (Docker/Container Manager or Synology packages) or on other LAN hosts
Network & DNS
A way to resolve your chosen hostnames inside your LAN:
- your router’s DNS, or
- Pi-hole / Technitium / AdGuard Home, or
- Synology DNS Server package
For Option A (publicly trusted SSL)
- A real domain you control (e.g., example.com)
- DNS provider that supports API access (Cloudflare, Route53, etc.) for automated TXT records
Core Design: Reverse Proxy + Split DNS + Firewall
1) Reverse proxy on Synology
DSM includes a reverse proxy UI where you map:
Source (public-facing in LAN): https://app.example.com:443
→ Destination (your real service): http://127.0.0.1:8080 (or another LAN IP/port)
Synology documents this under Control Panel → Application Portal → Reverse Proxy (DSM 7).
2) Local DNS
Your LAN clients must resolve app.example.com to your NAS LAN IP (e.g., 192.168.1.10). That’s the key to “local-only” without exposing anything publicly.
3) Local-only enforcement
You ensure no WAN access by:
- not forwarding ports 80/443 on your router
- adding Synology firewall rules to only allow LAN subnets to connect (details below)
Option A (Recommended): Valid Public SSL with Let’s Encrypt DNS-01 (No Public Exposure)
Why DNS-01 is the trick
Let’s Encrypt normally validates using HTTP (requires your server to be reachable). But DNS-01 proves ownership via a TXT record in DNS, so the server does not need to be internet-accessible.
Synology’s built-in certificate flow has limitations around DNS challenge support (varies by setup/provider), so a common reliable approach is using acme.sh and then deploying the cert into DSM.
Step A.1 — Pick a naming scheme
A clean pattern is:
*.home.example.com for all internal apps
Example:
- vaultwarden.home.example.com
- ha.home.example.com
- nas.home.example.com
This makes wildcard certs very convenient.
Step A.2 — Configure DNS (public + local)
Public DNS (at your domain registrar/DNS provider)
You only need DNS access for the TXT records (ACME challenge). You can choose one of these:
Approach 1 (Simple):
Set A records for *.home.example.com to your NAS private IP (e.g., 192.168.1.10). This works for most home setups, but you are publishing a private IP in public DNS (not dangerous by itself, just messy).
Approach 2 (Cleaner): Split DNS
Public DNS: *.home.example.com can point anywhere (or not exist at all; DNS-01 can still work with wildcard issuance depending on provider/tooling).
Local DNS: create A records so your LAN resolves *.home.example.com → 192.168.1.10.
Most people prefer split DNS so internal services don’t “depend” on public resolution.
Step A.3 — Issue a wildcard certificate with acme.sh (DNS API)
Where to run acme.sh
- In a Docker container on the NAS, or
- via Synology SSH + Task Scheduler (Docker is usually cleaner)
acme.sh provides a Synology DSM deploy hook (synology_dsm.sh) specifically to install certs into DSM automatically.
Example (conceptual) issuance flow
You’ll use your DNS provider’s acme.sh DNS plugin (example: Cloudflare plugin name is dns_cf, other providers differ).
Typical commands look like:
Issue:
acme.sh --issue --dns <dns_plugin> -d "*.home.example.com" -d "home.example.com" Deploy into DSM:
acme.sh --deploy --deploy-hook synology_dsm -d "*.home.example.com" The DSM deploy hook is a standard approach used in real Synology DNS-challenge setups.
Important: the deploy hook needs DSM credentials/host details (set as environment variables per the hook documentation/script).
Step A.4 — Make renewal automatic
Let’s Encrypt certs are short-lived (90 days). Your goal is zero manual renewals.
Common patterns:
- Run acme.sh container with a cron-like schedule
- Or use Synology Task Scheduler to run the renew/deploy command daily
acme.sh is designed to renew automatically and redeploy when needed.
Step A.5 — Assign the certificate in DSM
Once the cert is installed in DSM:
- Go to Control Panel → Security → Certificate
- Ensure the wildcard cert is set as default, and/or assigned to the services (Reverse Proxy / DSM / apps)
(Some deployments apply it automatically; if not, you assign it in DSM.)
Configure DSM Reverse Proxy Rules (Works for both Option A and B)
Step RP.1 — Create a reverse proxy entry
DSM 7 path (varies slightly by DSM build, but typically):
Control Panel → Application Portal → Reverse Proxy → Create
You’ll set:
Source
- Protocol: HTTPS
- Hostname: vaultwarden.home.example.com
- Port: 443
Destination
- Protocol: HTTP (or HTTPS if your backend uses it)
- Hostname: 127.0.0.1 (or container host / LAN IP)
- Port: 8080 (example)
Repeat per app.
Tip: Keep backends on HTTP internally unless you truly need end-to-end TLS. The reverse proxy is your TLS boundary for LAN.
Step RP.2 — (Optional but recommended) Add security headers
In Synology reverse proxy “Custom Header” settings (if available), common additions:
- HSTS (only if you’re sure you want HTTPS always)
- X-Forwarded-Proto, X-Forwarded-For (often automatic)
Keep it minimal unless you know the app requirements.
Lock It to Local-Only Access
Step L.1 — Do NOT port-forward 80/443 from your router
This is the biggest lever. If WAN traffic can’t reach your NAS, your proxy stays local.
If you previously had port forwards, remove them.
Step L.2 — Use Synology Firewall to allow LAN subnets only
Enable DSM firewall and create rules like:
- Allow your LAN subnet (example: 192.168.1.0/24) to ports 443 (and 80 only if you need HTTP→HTTPS redirects)
- Deny everything else (catch-all)
Rule ordering matters in DSM firewall.
Note: If you find reverse proxy behaves unexpectedly with firewall rules, you’re not alone—there are community reports around reverse proxy and firewall interactions, so test from both LAN and a non-LAN client (like phone on cellular).
Step L.3 — Ensure LAN DNS is authoritative for your internal hostnames
Make sure your devices actually use your LAN DNS (router DNS, Pi-hole, etc.). Otherwise, they may query public DNS and not reach your NAS correctly.
Option B: Valid HTTPS for Internal-Only Domains Using a Private CA (step-ca or Caddy Internal CA)
If you want names like:
- https://vaultwarden.lan
- https://ha.home.arpa
or you simply don’t want to use a public domain at all, you need a private CA.
Two solid approaches
B.1) step-ca (Private ACME CA)
- step-ca runs as your internal Certificate Authority
- ACME clients can request/renew certs automatically (similar workflow to Let’s Encrypt, but private)
Pros:
- Fully internal
- Automated issuance/renewal using ACME
Cons:
- You must distribute and trust your root CA on your devices (once per device/OS)
B.2) Caddy’s internal CA mode
Caddy can issue and manage internal certificates (not publicly trusted) and can do internal PKI flows.
Pros:
- Very simple if you’re already using Caddy
- Automatic renewals
Cons:
- Same trust distribution requirement (install CA root on clients)
Practical note: If your goal is “no warnings on every device without installing anything,” Option A (public domain + DNS-01) is usually the winner.
Troubleshooting Checklist
Certificate issuance fails
- DNS API credentials wrong or missing
- TXT record not propagating quickly enough
- Using an internal-only TLD (public CAs won’t issue for .lan, .internal, etc.) — you’ll see errors like “does not qualify for a public certificate” in some setups
Reverse proxy works by IP:port but not by hostname
- LAN DNS doesn’t resolve app.home.example.com to the NAS LAN IP
- Client is using a different DNS server than you think
It’s accessible from the internet (you don’t want that)
- Router port forward is still enabled
- DSM firewall rule order is wrong (allow rules must be above deny-all)
Recommended “Best Practice” Setup Summary (Most Homes)
- Use *.home.example.com
- Local DNS resolves those names to NAS LAN IP
- Issue wildcard Let’s Encrypt cert via DNS-01 using acme.sh
- Deploy cert into DSM with synology_dsm deploy hook
- DSM Reverse Proxy maps each hostname → internal service
- No router port forwards
- DSM firewall: allow LAN → 443, deny everything else



