Sample: Synology Local SSL

synology-nas-web

Synology Local SSL

The Agilicus connector can facilitate a publicly trusted local certificate for your Synology Web Interface.

Overview

100% of connections from the public networks into Agilicus AnyX are protected by Transport Level Security (TLS/SSL). Each endpoint has its own publicly-trusted certificate allocated, no wildcards, no fake certificates or certificate authority trusts to be injected. This is all done in a fully automatic fashion.

In some cases, you wish to access the same resource from the local side, without going through Agilicus AnyX. Although we do not generally recommend this (it lowers the overall security since there is no strong authentication and multi-factor), it can be useful or required. In this sample, we show how to setup a Synology DS120 NAS web interface such that the local DNS resolves to its local IP, and, it is protected by the same public certificate that the Agilicus AnyX platform allocated. In this fashion a user on the local network can directly access the NAS without seeing broken ‘do you want to trust this site” messages.

Setup

Create Web Application

First, configure the Synology web interface as a ‘Web Application’. We assign it a name (ds120), we select its via a connector we have previously installed on this NAS. We use ‘localhost’ and ‘port 5000’ for the upstream configuration (which is how we reach the web interface from inside the NAS). We then assign permission to our user.

At this stage we should be able to navigate to the url, and reach the NAS. If you take your mobile phone, disconnect the WiFi, and then reach the url, it should work. If your local DNS overrides, you may still see the NAS directly with its TLS/SSL error, we will resolve that in the next section.

fb3086e2 image
a568960b image
67062561 image
cefae7a4 image
057ac301 image
22dcf92c image

Export Certificate

Referring to the instructions for exporting certificates, we see that the Connector will export the certificate if a Python script exists in a certain location (/opt/agilicus/agent/plugins/certificate-exporter.py).

We can see where the Synology looks for its certificate:

# ps -ef|grep nginx
root      6609   654  0 17:22 pts/0    00:00:00 grep --color=auto nginx
root      6872     1  0 Sep19 ?        00:00:00 nginx: master process /usr/bin/nginx -c /etc/nginx/nginx.conf.run -g pid /run/nginx.pid; daemon on; master_process on;
http     31327  6872  0 Sep23 ?        00:01:24 nginx: worker process
http     31328  6872  0 Sep23 ?        00:01:02 nginx: worker process
# grep cert /etc/nginx/nginx.conf.run
    include /usr/syno/etc/www/certificate/system_default/cert.conf*;
# ls -ld /usr/syno/etc/www/certificate/system_default/cert.conf*
-rw------- 1 root root 224 Feb 20  2023 /usr/syno/etc/www/certificate/system_default/cert.conf
# cat /usr/syno/etc/www/certificate/system_default/cert.conf
ssl_certificate          /usr/syno/etc/www/certificate/system_default/73b8b5b1-7f63-4764-a54f-1a0d78d58dfd.pem;
ssl_certificate_key      /usr/syno/etc/www/certificate/system_default/d27d6342-50fb-423f-b850-386b6a68e5ab.pem;

OK, lets take a look at the ‘factory’ certificates:

# openssl x509 -in /usr/syno/etc/www/certificate/system_default/73b8b5b1-7f63-4764-a54f-1a0d78d58dfd.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 6280518885899342 (0x1650194132fc4e)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = TW, L = Taipel, O = Synology Inc., CN = Synology Inc. CA
        Validity
            Not Before: Feb 20 06:15:00 2023 GMT
            Not After : Feb 21 06:15:00 2024 GMT
        Subject: C = TW, L = Taipel, O = Synology Inc., CN = synology
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:df:33:80:97:f8:9d:88:a8:9f:49:35:7f:20:7a:
                    ba:68:26:47:3e:ed:7f:9f:79:3f:f3:6f:2c:31:1c:
                    38:36:cd:36:36:ed:bb:47:bf:29:cc:8c:e2:d2:3d:
                    16:4b:16:5b:16:7c:36:4e:c8:e8:05:f4:33:d6:7f:
                    91:7b:2c:c4:8b:3d:1e:18:19:d7:60:84:d4:08:db:
                    8e:b4:63:5e:bc:fa:e6:31:1f:5d:f8:64:27:76:4c:
                    a2:63:d4:a5:03:c7:cd:e9:83:f3:31:a7:29:c8:1d:
                    ed:bf:35:b5:02:c0:53:18:83:29:71:85:b2:15:b2:
                    0d:4e:11:0d:b1:4b:73:34:29:20:e4:5a:5c:f3:6d:
                    bf:9e:f7:85:f9:f6:8b:fd:63:26:66:d2:ac:0f:f5:
                    5b:e7:38:34:4d:e7:2d:db:ae:77:9f:69:0d:e6:3b:
                    3a:15:b1:28:ae:94:49:98:40:ed:d9:0f:2d:d6:bb:
                    f9:b3:64:33:7e:c0:6c:de:f0:eb:5d:f0:8d:3b:67:
                    60:01:69:b1:fa:b2:db:f3:33:88:a0:9c:e4:e9:f2:
                    3c:3a:eb:b5:b3:de:94:50:f3:3b:f0:70:a1:8d:f7:
                    e6:a6:c1:74:47:97:45:4d:b3:9a:27:f8:ad:44:db:
                    24:20:57:03:3f:01:e6:0b:82:dd:1f:49:ba:f7:cd:
                    e4:99
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            Netscape Comment:
                mod_ssl generated custom server certificate
            Netscape Cert Type:
                SSL Server
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Alternative Name:
                DNS:synology
    Signature Algorithm: sha256WithRSAEncryption
         6d:38:84:e7:22:8f:f7:65:69:8a:98:8b:e7:fd:03:86:13:ce:
         ba:27:75:0a:c9:95:7c:38:07:6c:0c:7f:6f:2e:23:e8:68:52:
         cf:de:57:bd:d5:ee:75:1b:6e:f9:cf:58:74:36:f9:9a:3a:8c:
         4d:e0:7e:d7:21:00:ef:81:5e:4c:0c:59:34:cb:fe:37:60:0e:
         5a:81:f4:a6:fa:fb:39:82:1d:74:f7:6d:75:d4:72:e3:95:bc:
         a7:d3:76:df:e3:4f:d5:be:83:5a:3b:af:26:b8:1e:9f:d0:42:
         99:c3:6a:6a:36:13:a9:ef:bd:6f:88:42:71:d1:2f:ad:14:8d:
         5b:d9:17:b0:fc:bc:8b:f8:20:b2:26:25:c6:83:93:b7:2a:36:
         cc:85:f7:84:d3:01:13:40:a5:b9:ef:60:4e:47:46:26:84:b7:
         0e:da:eb:88:6c:75:9f:44:4c:0f:ab:f6:1b:0d:76:dc:4d:f1:
         04:87:11:e9:26:c4:12:cb:fe:ea:57:58:4b:85:1d:cc:de:c7:
         23:1d:55:1d:a1:d5:06:36:c6:4a:d0:15:e2:f0:34:9b:a2:05:
         2a:2c:b0:14:e1:a8:a4:95:99:17:df:3d:f7:f6:c3:ab:49:ff:
         b3:d9:ab:b2:50:51:cb:bb:aa:3c:72:e4:ba:a6:cf:4a:b1:4c:
         96:1d:1f:a6
-----BEGIN CERTIFICATE-----
MIIDsjCCApqgAwIBAgIHFlAZQTL8TjANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQG
EwJUVzEPMA0GA1UEBwwGVGFpcGVsMRYwFAYDVQQKDA1TeW5vbG9neSBJbmMuMRkw
FwYDVQQDDBBTeW5vbG9neSBJbmMuIENBMB4XDTIzMDIyMDA2MTUwMFoXDTI0MDIy
MTA2MTUwMFowSTELMAkGA1UEBhMCVFcxDzANBgNVBAcMBlRhaXBlbDEWMBQGA1UE
CgwNU3lub2xvZ3kgSW5jLjERMA8GA1UEAwwIc3lub2xvZ3kwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDfM4CX+J2IqJ9JNX8gerpoJkc+7X+feT/zbywx
HDg2zTY27btHvynMjOLSPRZLFlsWfDZOyOgF9DPWf5F7LMSLPR4YGddghNQI2460
Y168+uYxH134ZCd2TKJj1KUDx83pg/MxpynIHe2/NbUCwFMYgylxhbIVsg1OEQ2x
S3M0KSDkWlzzbb+e94X59ov9YyZm0qwP9VvnODRN5y3brnefaQ3mOzoVsSiulEmY
QO3ZDy3Wu/mzZDN+wGze8Otd8I07Z2ABabH6stvzM4ignOTp8jw667Wz3pRQ8zvw
cKGN9+amwXRHl0VNs5on+K1E2yQgVwM/AeYLgt0fSbr3zeSZAgMBAAGjgZYwgZMw
OgYJYIZIAYb4QgENBC0WK21vZF9zc2wgZ2VuZXJhdGVkIGN1c3RvbSBzZXJ2ZXIg
Y2VydGlmaWNhdGUwEQYJYIZIAYb4QgEBBAQDAgZAMA4GA1UdDwEB/wQEAwIFoDAd
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEwYDVR0RBAwwCoIIc3lub2xv
Z3kwDQYJKoZIhvcNAQELBQADggEBAG04hOcij/dlaYqYi+f9A4YTzrondQrJlXw4
B2wMf28uI+hoUs/eV73V7nUbbvnPWHQ2+Zo6jE3gftchAO+BXkwMWTTL/jdgDlqB
9Kb6+zmCHXT3bXXUcuOVvKfTdt/jT9W+g1o7rya4Hp/QQpnDamo2E6nvvW+IQnHR
L60UjVvZF7D8vIv4ILImJcaDk7cqNsyF94TTARNApbnvYE5HRiaEtw7a64hsdZ9E
TA+r9hsNdtxN8QSHEekmxBLL/upXWEuFHczexyMdVR2h1QY2xkrQFeLwNJuiBSos
sBThqKSVmRffPff2w6tJ/7PZq7JQUcu7qjxy5Lqmz0qxTJYdH6Y=
-----END CERTIFICATE-----

OK, it is expecting a FQDN of ‘synology’, and, is self-signed. We don’t want this. lets overwrite it with our properly signed one. To do so, place a script called certificate-exporter.py in /opt/agilicus/agent/plugins (you may need to make this directory). The script might look as below (notice I hard-coded in my host name since this connector services more than one endpoint, and I only want to export one certificate).

#!/bin/python

import sys
import json
import base64
import os

# load the certificate export json from stdin
# see https://agilicus.com/www/api/certificate-export.schema.json
cert_obj = json.loads(sys.stdin.readline())

def import_certificate(obj):
    if obj.get("common_name") == "ds120.dbt.agilicus.cloud":
        with open("/usr/syno/etc/www/certificate/system_default/cert.conf", "w") as fd:
            fd.write("ssl_certificate   /usr/syno/etc/www/certificate/nas.pem;\nssl_certificate_key /usr/syno/etc/www/certificate/nas.key;\n");
        with open("/usr/syno/etc/www/certificate/nas.pem", "w") as fd:
            fd.write(obj.get("certificate"))
        with open("/usr/syno/etc/www/certificate/nas.key", "w") as fd:
            fd.write(obj.get("key"))

        with open("/usr/syno/etc/certificate/_archive/DEFAULT", "r") as fd:
            def_cert_name = fd.read()
            def_cert_name = def_cert_name.strip()
        with open(f"/usr/syno/etc/certificate/_archive/{def_cert_name}/cert.pem", "w") as fd:
            fd.write(obj.get("certificate"))
        with open(f"/usr/syno/etc/certificate/_archive/{def_cert_name}/privkey.pem", "w") as fd:
            fd.write(obj.get("key"))

        os.system("/bin/systemctl reload nginx")

import_certificate(cert_obj)

Testing

To test, we can remove the cached files (exported_certs.*) and then restart the connector

-rwxr-xr-x 1 agilicus agilicus  844 Nov 13 18:29 certificate-exporter.py
-rw------- 1 root     root     5788 Nov 13 18:38 exported_certs.json
-rw------- 1 root     root        0 Nov 13 18:38 exported_certs.json.lock
# rm exported_certs*
# systemctl restart agilicus-agent

We can test with curl and a DNS override:

curl -v https://ds120.dbt.agilicus.cloud/ --resolve ds120.dbt.agilicus.cloud:443:172.16.0.109