LIMEHAWK - Managed IT
Synology Wildcard SSL — infrastructure
dateJan 20, 2025
statusIMPLEMENTED
Summary

Deployed automated wildcard SSL certificate management for Synology NAS using acme.sh, Let's Encrypt, and Cloudflare DNS validation. Custom directory structure for organized storage, automatic renewal with DSM deployment hooks. Eliminates manual certificate management while maintaining security.

The Challenge

Synology DSM includes built-in Let's Encrypt support, but it has significant limitations:

no wildcardscan't do *.domain.com
requires exposureport 80 or 443 for HTTP validation
limited flexibilityinternal subdomains problematic
no DNS validationbehind-firewall systems blocked

For internal infrastructure with multiple subdomains that shouldn't be publicly accessible, we needed wildcard certificates using DNS validation.

Solution Architecture

acme.sh is a pure shell script ACME client supporting DNS validation via multiple providers. Combined with Cloudflare API and Synology DSM hooks, it provides fully automated certificate management.

acme.shlightweight ACME client
Let's Encryptfree certificate authority
Cloudflare APIautomated DNS for validation
DSM Hookauto-deploy to Synology services
Step 0: Install acme.sh

Install into custom directories for clean management and easy backup:

# Create custom directories
mkdir -p /var/services/homes/sysadmin/acme.sh/acme_certs
mkdir -p /var/services/homes/sysadmin/acme.sh/acme_config

# Install acme.sh with custom paths
curl https://get.acme.sh | sh -s [email protected] \
  --home /var/services/homes/sysadmin/acme.sh/acme_config \
  --config-home /var/services/homes/sysadmin/acme.sh/acme_config \
  --cert-home /var/services/homes/sysadmin/acme.sh/acme_certs
--homeacme.sh scripts location
--config-homeconfiguration and logs
--cert-homewhere certificates are saved
emailLet's Encrypt notifications
Step 1: Test in Staging

Test with Let's Encrypt staging environment to avoid rate limits (5 certs per domain per week) during troubleshooting:

CF_Token="YOUR_CLOUDFLARE_API_TOKEN" \
CF_Email="[email protected]" \
SYNO_USE_TEMP_ADMIN=1 \
/var/services/homes/sysadmin/acme.sh/acme_config/acme.sh \
  --home /var/services/homes/sysadmin/acme.sh/acme_config \
  --cert-home /var/services/homes/sysadmin/acme.sh/acme_certs \
  --config-home /var/services/homes/sysadmin/acme.sh/acme_config \
  --staging \
  --issue \
  -d '*.internal.example.com' \
  --dns dns_cf
--staginguses test environment (untrusted certs)
--dns dns_cfCloudflare DNS validation
CF_TokenCloudflare API for DNS updates
SYNO_USE_TEMP_ADMINbypasses 2FA for deployment
-d '*.domain.com'wildcard certificate

DNS validation: acme.sh creates TXT record at _acme-challenge.domain.com via Cloudflare API. No port exposure required.

Step 2: Production Certificate

After successful staging, issue production certificate:

CF_Token="YOUR_CLOUDFLARE_API_TOKEN" \
CF_Email="[email protected]" \
SYNO_USE_TEMP_ADMIN=1 \
/var/services/homes/sysadmin/acme.sh/acme_config/acme.sh \
  --home /var/services/homes/sysadmin/acme.sh/acme_config \
  --cert-home /var/services/homes/sysadmin/acme.sh/acme_certs \
  --config-home /var/services/homes/sysadmin/acme.sh/acme_config \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --issue \
  -d '*.internal.example.com' \
  --dns dns_cf
--serverproduction API endpoint
removed --stagingissues real certificates
browser-trustedvalid for 90 days
API Endpoints

https://acme-staging-v02.api.letsencrypt.org/directory

untrusted certs, no rate limits

https://acme-v02.api.letsencrypt.org/directory

browser-trusted, 5 certs/domain/week limit

Step 3: Automated Renewal

Set up automatic renewal and deployment via Synology Task Scheduler:

# Combined Renew + Deploy (add to Task Scheduler)
CF_Token="YOUR_CLOUDFLARE_API_TOKEN" \
CF_Email="[email protected]" \
SYNO_USE_TEMP_ADMIN=1 \
/var/services/homes/sysadmin/acme.sh/acme_config/acme.sh \
  --home /var/services/homes/sysadmin/acme.sh/acme_config \
  --cert-home /var/services/homes/sysadmin/acme.sh/acme_certs \
  --config-home /var/services/homes/sysadmin/acme.sh/acme_config \
  --renew \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --deploy \
  --deploy-hook synology_dsm \
  -d '*.internal.example.com'
--renewchecks if renewal needed (30 days before expiry)
--deploydeploys renewed cert to services
--deploy-hooksynology_dsm for DSM services
safe to run dailyexits gracefully if not needed

1. Control Panel → Task Scheduler

2. Create → Scheduled Task → User-defined script

3. User: root (required for cert deployment)

4. Schedule: Daily at 3:00 AM

Security Considerations

create scoped token (not Global API Key)

permission: Zone → DNS → Edit

zone: specific domain only

stored in acme_config/account.conf

permissions auto-set to 600

backup securely

creates temp admin for cert deployment

removes after (2-3 seconds)

required for DSM certificate deployment

Outcome

Fully automated wildcard SSL certificate management for internal infrastructure. Certificates auto-renew 30 days before expiration and deploy to all DSM services without intervention. No exposed ports. Zero maintenance.

single wildcardcovers all subdomains
DNS validationworks behind firewall
auto renewalprevents expiration outages
custom directoriesclean backup and migration
Cloudflare APIno manual DNS changes
built-in Synology Let's Encrypt is limited
DNS validation superior for internal infra
always test in staging first
custom directories prevent DSM update conflicts
Tools & References

https://github.com/acmesh-official/acme.sh

pure shell ACME client, 50+ DNS providers

https://letsencrypt.org/

free CA, 90-day certificates

automated TXT records for ACME DNS-01 validation

acme.sh includes native deployment hooks

Get Help

Need infrastructure automation? We handle the tedious stuff - SSL certificates, backups, monitoring, deployments. No more 2 AM expiration alerts.