Wildcard SSL for Custom Domain on Synology NAS (No Traefik/Coolify)

Requesting a Let's Encrypt certificate for a custom domain (e.g. yourdomain.com) on Synology DSM always fails with: "Let's Encrypt is unable to validate this domain name..."

Wildcard SSL for Custom Domain on Synology NAS (No Traefik/Coolify)
Photo by Jonny Gios / Unsplash

The Problem

Requesting a Let's Encrypt certificate for a custom domain (e.g. yourdomain.com) on Synology DSM always fails with:

"Let's Encrypt is unable to validate this domain name..."

Root cause: DSM's nginx never listens on port 80 by default. Let's Encrypt's HTTP-01 challenge requires port 80 to respond. Additionally, DSM only loads nginx configs named http.*.conf — any other filename is silently ignored.


Requirements

  • Real public IPv4 (not CGNAT — confirm your router WAN IP matches whatismyip.com)
  • Ports 80 and 443 forwarded in your router to the NAS
  • SSH access enabled on DSM

Fix

1. Create the nginx port 80 config

SSH into your NAS and run:

sudo bash -c 'cat > /etc/nginx/conf.d/http.acme-challenge.conf << '\''EOF'\''
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com *.yourdomain.com;

    location /.well-known/acme-challenge/ {
        root /var/lib/letsencrypt;
        allow all;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}
EOF'

sudo mkdir -p /var/lib/letsencrypt/.well-known/acme-challenge
sudo nginx -t && sudo nginx -s reload

Verify nginx is now on port 80:

sudo netstat -tlnp | grep ':80'

2. Request the certificate

DSM → Control Panel → Security → Certificate → Add → Get from Let's Encrypt

  • Domain: yourdomain.com
  • Subject Alternative Name: *.yourdomain.com

3. Assign the certificate

DSM → Control Panel → Security → Certificate → Settings

Assign the new wildcard cert to all reverse proxy entries using your custom domain.

4. Automate with a boot-up task

⚠️ DSM wipes /etc/nginx/conf.d/ on every update/reboot. Automate the restore.

DSM → Control Panel → Task Scheduler → Create → Triggered Task → User-defined script

  • User: root
  • Event: Boot-up
  • Script:
#!/bin/bash
cat > /etc/nginx/conf.d/http.acme-challenge.conf << 'EOF'
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com *.yourdomain.com;

    location /.well-known/acme-challenge/ {
        root /var/lib/letsencrypt;
        allow all;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}
EOF
mkdir -p /var/lib/letsencrypt/.well-known/acme-challenge
nginx -s reload

Result

✅ Wildcard cert *.yourdomain.com covering all subdomains
✅ Auto-renews every 90 days without manual intervention
✅ Survives DSM updates and reboots


Doesn't Work?

CauseFix
Behind CGNATUse DNS-01 challenge instead (no port 80 needed)
ISP blocks port 80Use DNS-01 challenge instead
Nginx config ignoredFilename must match http.*.conf pattern
Reverse proxy conflictTemporarily delete the conflicting yourdomain.com proxy entry before requesting the cert