DSM has its own Let’s Encrypt integration, but it cannot authenticate to a certificate authority that requires External Account Binding, which is what commercial CAs use. So the working route is to issue the certificate with acme.sh on a machine you already run, and let acme.sh’s synology_dsm deploy hook push it into DSM at every renewal. The hook does the whole job, including replacing the certificate in place and letting DSM restart the services that use it.
Under CA/Browser Forum ballot SC-081v3, publicly trusted TLS certificates have been capped at 200 days since March 15, 2026, dropping to 100 days on March 15, 2027 and to 47 days on March 15, 2029. Uploading a certificate into DSM by hand was an annual task; it is on its way to being a monthly one, which is the whole argument for setting the deploy hook up properly rather than bookmarking the upload page.
Before you start
- A NAS on DSM 7. The certificate screens described here have been stable across the DSM 7 line; current releases are DSM 7.4, released in June 2026, and DSM 7.3 from October 2025, with 7.2.2 still receiving security updates.
- A DSM account in the administrators group. The deploy hook fails with error 105 and the message that the current user is not an administrator otherwise.
- A host to run acme.sh on, any Linux, BSD or macOS machine that stays powered on and can reach both your CA and the NAS. It does not need to be reachable from the internet.
- A domain name with a record for the NAS. With DNS validation it does not need to resolve to a public address.
- Your CA’s ACME directory URL, EAB Key ID and EAB HMAC Key, from your CA account portal.
Step 1: Install acme.sh
curl https://get.acme.sh | sh -s [email protected]
source ~/.bashrc
acme.sh --version
The installer places the client in your home directory and adds a cron entry that checks daily for certificates due for renewal. That cron entry is what makes everything after Step 5 unattended, so install as a user account that will still exist next year.
Step 2: Register the ACME account with EAB
acme.sh --register-account \
--server https://acme.yourca.example/v2/DV \
--eab-kid "YOUR_EAB_KEY_ID" \
--eab-hmac-key "YOUR_EAB_HMAC_KEY" \
--accountemail "[email protected]"
Run this once per CA, and use the same --server value consistently from here on. acme.sh has defaulted to ZeroSSL since version 3.0, so a command without it goes to the wrong authority. If registration is refused with a complaint about decoding the HMAC key, the value picked up a stray character between the CA portal and your terminal.
Step 3: Issue the certificate with DNS validation
DNS-01 is the right challenge here. A NAS normally sits behind NAT with no inbound port 80, and DNS validation never connects to the device: the CA reads a TXT record at _acme-challenge under your domain and nothing else. It is also the only challenge that can issue a wildcard.
Give acme.sh an API credential for your DNS provider so it publishes and removes the record itself. The example uses Cloudflare; acme.sh ships integrations for most providers, each with its own variables.
export CF_Token="your_cloudflare_api_token"
acme.sh --issue --dns dns_cf \
-d nas.example.com \
--server https://acme.yourca.example/v2/DV
Do not use manual DNS mode for this. acme.sh will not renew a certificate validated by hand, and says so in its own error text: manual mode cannot renew automatically and you have to issue it again yourself. Choosing it means every renewal needs a person to publish a TXT record, which contradicts the entire point of the deploy hook you are about to configure. If your DNS provider genuinely has no API, point _acme-challenge.nas.example.com at a zone that does with a CNAME and use acme.sh’s alias mode via --challenge-alias.
After issuance the files are in ~/.acme.sh/nas.example.com/: fullchain.cer is the certificate plus intermediate, nas.example.com.key is the private key, and ca.cer is the chain alone. You will not copy these anywhere by hand.
Step 4: Import it once through DSM
Do this first import in the interface even though the hook can create certificates, because it lets you choose the description that everything afterwards keys on.
- In DSM, go to Control Panel > Security > Certificate.
- Click Add, choose Add a new certificate, and click Next.
- Enter a description. This is the name the deploy hook matches on later, so pick something stable and write it down.
- Tick Set as default certificate if this certificate should serve DSM itself.
- Select Import certificate and continue.
- Supply the private key and the certificate. Use nas.example.com.key as the private key and fullchain.cer as the certificate.
Then click Settings on the same screen to map services to certificates: the DSM interface itself, File Station, Web Station, reverse proxy entries, WebDAV, Drive and anything else that presents TLS. These assignments are made once. They survive renewals, because the hook replaces the existing certificate rather than adding a new one each time.
Step 5: Configure the deploy hook
Back on the acme.sh host, set the variables the hook reads and run the deployment.
export SYNO_USERNAME="acme-deploy"
export SYNO_PASSWORD="the_account_password"
export SYNO_HOSTNAME="nas.example.com"
export SYNO_SCHEME="https"
export SYNO_PORT="5001"
export SYNO_CERTIFICATE="the description you typed in Step 4"
acme.sh --deploy -d nas.example.com --deploy-hook synology_dsm
The capitalisation is not cosmetic. The hook reads SYNO_USERNAME and SYNO_PASSWORD in full uppercase. Older guides use SYNO_Username and SYNO_Password, which were the earlier spelling, and acme.sh does carry a migration for those, but the migration only converts values already saved in the certificate’s configuration file from a previous run. It does not read a mixed-case shell variable you export today. Export the old names on a fresh setup and the hook stops with the message that you must set either SYNO_USE_TEMP_ADMIN or both SYNO_USERNAME and SYNO_PASSWORD.
Set the scheme and port explicitly too. Their defaults are http and port 5000, not the HTTPS port most people assume, so a NAS reached on 5001 over TLS needs both lines above.
SYNO_CERTIFICATE is what ties this to Step 4: the hook looks up the DSM certificate whose description matches, and replaces that one. If no certificate matches and you have not set SYNO_CREATE, it stops with a message that it cannot find the certificate. To let it create one instead of importing by hand first, add SYNO_CREATE=1.
Two notes on the account. It has to be in the administrators group, and acme.sh saves these values into the certificate’s configuration file so renewals can reuse them, which means the password is written to disk on the acme.sh host. Create a dedicated DSM account for this rather than reusing your own login, and protect that host accordingly. If the account has two-factor authentication enabled, the hook accepts SYNO_OTP_CODE and SYNO_DEVICE_NAME so the first run does not stop to prompt.
There is a third option worth knowing if you decide to run acme.sh on the NAS itself: SYNO_USE_TEMP_ADMIN=1 makes the hook create a throwaway administrator with a random password for the duration of the deployment and remove it afterwards, so no standing password is stored. It only works locally on DSM, because it depends on the synouser, synogroup and synosetkeyvalue commands, and it has to run as root.
Step 6: What happens from now on
acme.sh stores the deploy hook against the domain, so the daily cron entry from Step 1 renews the certificate when it is due and then runs the hook again with the settings you just saved. In detail, the hook uploads the key, the certificate and the intermediate to DSM’s certificate API, matched to the description; if the certificate it is replacing is the default one, it stays the default; and DSM restarts its HTTP services itself, which the hook reports as either succeeded or not necessary.
That last detail is why there is no separate restart step here, and why the service assignments from Step 4 keep working. Prove the whole path once rather than waiting months to find out:
acme.sh --renew -d nas.example.com --force
Certificate authorities apply rate limits, so run this once rather than repeatedly. Then confirm what the NAS actually presents, from another machine:
openssl s_client -connect nas.example.com:5001 -servername nas.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
If the NAS is reachable publicly, the SSL Checker also reports whether the intermediate is being served with the leaf certificate.
When the deployment fails
- It asks you to set SYNO_USERNAME and SYNO_PASSWORD although you already did. Check the capitalisation, as described in Step 5. This is the most common cause by a wide margin.
- Error 105, not an administrator. The DSM account is not in the administrators group.
- It cannot find the certificate. SYNO_CERTIFICATE does not match any description in Control Panel, so compare the two exactly, including spaces. Avoid backslashes in the description; the hook rejects them.
- The connection is refused or times out. Check SYNO_SCHEME and SYNO_PORT against how you actually reach DSM, remembering the defaults are http and 5000.
- Validation, not deployment, is what failed. Confirm the DNS API credential can write records in the zone, and that the TXT record is publicly visible before blaming the hook.
- You need to see the exchange. Add
--debugto the acme.sh command to log both the CA and the DSM side.
For error strings that come from the ACME protocol rather than from acme.sh or DSM, such as badNonce, unauthorized or a CAA record refusing issuance, see our guide to fixing ACME SSL certificate errors.
Frequently Asked Questions
Almost always because the variables were exported as SYNO_Username and SYNO_Password rather than SYNO_USERNAME and SYNO_PASSWORD. The mixed-case forms are the old spelling and acme.sh migrates them, but only from values already stored in the certificate’s configuration file by an earlier run, not from a shell variable you set now. Shell variables are case-sensitive, so the hook sees nothing.
You can, over SSH or in a container, and doing so unlocks SYNO_USE_TEMP_ADMIN=1, which avoids keeping an administrator password on disk because the hook creates and deletes a temporary admin per run. The trade-off is that DSM updates can disturb anything installed outside the package system, so a separate host is the lower-maintenance choice for most people. Neither option is wrong; pick based on whether you would rather manage an extra host or an extra password.
No. DSM keeps serving the certificate it was last given, so a renewal that is not pushed leaves the NAS drifting toward an expiry warning while perfectly good files sit on the other machine. That is what the deploy hook exists for: acme.sh runs it as part of the renewal and reports a failure if it does not succeed, which a calendar reminder cannot do.
No, and this is the reason for importing once with a description in Step 4. The hook replaces the certificate that matches that description instead of adding a new one, and if the one it replaces was the default it stays the default. Service assignments point at the same certificate entry, so they carry over untouched, and DSM restarts the HTTP services itself.
You can import one manually, which DSM has always supported. What DSM’s built-in ACME automation cannot do is authenticate with External Account Binding, and that is what commercial authorities require, so it cannot request or renew such a certificate for you. That gap is the reason this guide runs the client elsewhere.
Yes. Issue it with -d “*.example.com” using DNS validation, since no CA validates a wildcard over HTTP, and deploy it exactly as above. Quote the argument so the shell does not expand the asterisk. Be deliberate about where else that key is copied, because a wildcard covers every subdomain it names.
Yes, unchanged. DNS validation never connects to the NAS, so the CA does not care where it sits or whether it has a routable address. The only reachability that matters is between the acme.sh host and the NAS, which is usually a local network path.
For more on the protocol behind all of this, see what the ACME protocol is and our ACME SSL certificates page. For the manual route, see our guides to generating a CSR on a Synology NAS and installing an SSL certificate on a Synology NAS.
Save 10% on SSL Certificates when ordering from SSL Dragon today!
Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10

