Setting up Synology’s reverse proxy server

Update: I’ve since moved on to using LinuxServer.io’s SWAG. You can run SWAG on a Synology NAS (if it supports Docker), but I’m running it in Ubuntu on other hardware. I’ve learned a lot since posting this, but I’m leaving it up in case it’s still helpful to anyone else.


In several previous posts, I detailed how to secure various services with a Let’s Encrypt certificate, installed in DSM. I approached each one individually, figuring out how to link the certificate in a way that each application accepted.

On my post about securing Ubooquity, jcd suggested I use Synology’s built-in reverse proxy server instead (and linked to this tutorial). Honestly, this was the best advice, and I’ve since switched away from the various methods I detailed before. Please check out Graham Leggat’s tutorial – this post isn’t meant to be a retelling, but hopefully adds some useful notes that I learned along the way.

Essentially, here’s how a reverse proxy works: you have a service running inside of your firewall over HTTP (not secured). Here are some of your options for opening that service outside of your network:

  • Open it as-is, unsecured. This is generally not a good idea.
  • Secure the service and open it outside of your network. You’ll need to read documentation, and possibly convert the certificate and put it in a place the application expects. Furthermore, as you open up more services outside of your network, you’ll need to open separate ports for each – it’s a lot to manage when you just want to access your service outside of your firewall.
  • You can use a reverse proxy.

A reverse proxy is a separate server, sitting in between your service and the internet, which will encrypt all traffic, seamlessly. When you connect from outside of your firewall, you’ll communicate securely to your reverse proxy, which will then pass along your traffic to your unencrypted applications.

There are many benefits to this approach: this works with nearly every application, requires very little configuration (past the initial setup), allows you to set up memorable URLs without using weird ports, etc.

Some prerequisites:

  • First, I’m going to assume you have an application/service that you want to open outside of your network, securely. Set it up on an unused TCP port. I recommend checking this list to avoid commonly used ports.
  • You’ll need a domain name, and be able to add custom DNS entries.
  • You’re also going to need a wildcard certificate. I paid for one, but Let’s Encrypt offers them for free, too (you’ll probably need to use this script).
  • If you don’t pay your ISP for a static IPv4 address, you’ll need to set up Synology’s QuickConnect service. It’s free, but requires a Synology.com account.

Now that you’ve got all of that squared away, let’s proceed.

  1. First, we’ll need to forward port 443 to your Synology server. See here for instructions on how to do that for most types of routers.
  2. Add your wildcard certificate to DSM.
  3. At your domain registrar, edit the DNS settings for your domain name. Add an entry with the following:
    1. Type: CNAME
    2. Name: application.yourdomain.com
    3. Value: (your QuickConnect address – example.synology.me)
  4. Unless your domain name is brand new, it shouldn’t take long for your new subdomain to resolve to your Synology server’s IP address.
  5. In DSM, click Control Panel, then Application Portal, then the Reverse Proxy tab. Click the Create button. Fill in these details:
    1. Description: (name of your application)
    2. Source
      1. Protocol: HTTPS
      2. Hostname: application.yourdomain.com
      3. Port: 443
      4. (don’t check any of the boxes)
    3. Destination
      1. Protocol: HTTP
      2. Hostname: (the local IP address of the server running your application, such as 192.168.1.3 or 127.0.0.1)
      3. Port: (the port you’re currently using to access your application, such as 80 or 8080)
  6. Click Save, then try to access https://application.yourdomain.com in a web browser. If you did everything right (and I didn’t miss any steps!), you should be able to load your application and see that the connection is secure. If you click the lock, you should see your wildcard certificate.

Going forward, you can do this for multiple applications – and each one can use port 443, so you don’t need to open additional ports outside of your firewall or remember anything more than your unique subdomain for each application.

Previous

Using Munki to enable sudo for Touch ID

Next

Smart Home, Part Two

15 Comments

  1. oscar

    “You’ll need a domain name, and be able to add custom DNS entries.” Are you able to use Synology’s ****.synology.me Dynamic DNS for this?

    • Unfortunately, I don’t think that’d work. You’d need to be able to set up sub-subdomains from that, such as application.example.synology.me. You’d also need to have the SSL certificate for that, and since you’re not Synology, that wouldn’t be possible.

      You might be able to get something working with Let’s Encrypt. When my certificate renewal comes up, I might try that route to save some money.

  2. Fred

    Thanks for this nice tutorial.. 2 things tough:

    1. Cname for a subdomain? With not a A record instead?
    2. Port forwarding on the router.. What’s the way to do it? Outside 443 to inside Synology 443 or Outside 443 to all synology ports?
    3. Did you tried with Synology.me?

    • Hey Fred, I’m glad this was helpful! I noticed that Synology changed some parts of the interface in DSM 7, but hopefully this is still useful to people. I’ve since moved away from using DSM as my reverse proxy (I’m using SWAG as a Docker container now), so I’ll probably put a disclaimer at the top of this post.

      That said, I’ll do my best to answer your questions:

      1. You might be able to get away with an A record. If you have the option of a wildcard subdomain, I’d suggest using that instead.
      2. 443 needs to be open outside of your network, and that traffic needs to be able to reach DSM. Inside of your LAN, you can use any port you’d like, as long as your router is sending that traffic back out as 443.
      3. I’ve used Synology.me for dynamic DNS, but not for anything else.

  3. Craig

    The service you are setting up is also a dynamic DNS service/subdomain, not a QuickConnect service. QuickConnect is a reverse proxy that doesn’t require opening any ports on a firewall, however you cannot redirect to any sites, subdomains, or ports not supported by QuickConnect through it.

    • Craig

      Rather than purchasing an additional certificate, your own dns domain, or anything extra, as long as you’re ok with using different external ports you could have a service running on your subdomain.Synology.me address using port 8083 forwarded to your Synology and it will reverse proxy to your application on port 80 internally, or whatever port you choose using port translation.

  4. Brad

    Hi Mike – I found your page by your reference to SWAG. I’m curious what you did with your ports on your Synology? Did you try to mess with the Synology Ngnx to claim port 443? In my case, I’m using Tailscale rather than having my nas open to the world.

    • Hey Brad! I looked into messing with DSM’s config files, but I wasn’t crazy about having to reapply my config changes every time I updated DSM (or rebooted, I think). If you’re looking to run SWAG (or any other reverse proxy) on your Synology NAS, there’s an even easier way. SWAG listens on port 443, but you can map that outside of the container to any other port via Synology’s Docker app – I used port 444. From there, on my router, I just set up the port forwarding so that requests to port 443 were forwarded to port 444 at my NAS’s IP address.

      I hope this helps! 🙂

      • Zach

        Hello,

        I switched to SWAG as well and it works great! My old lets encrypt cert using the synology built in functionality expired and i deleted it moving all my services to one of the synology certs.

        I’m trying to figure out if i can get SWAG to update a cert for synology services. Did you ever do that?

        • Yep, you can absolutely do that. You’ll need to write a shell script to copy the relevant files from SWAG to the correct place in DSM, though. Looking at SWAG’s documentation:

          https://github.com/linuxserver/docker-swag#using-certs-in-other-containers

          you can see that the private key, cert, and cert chain are all located starting at wherever you mapped config. So, that’d be: /path/to/swag/config/etc/letsencrypt/live/yourdomain.com/.

          From there, just pop a script like this one into DSM’s Task Scheduler (warning: untested by me – also, you’ll need to change the cd path on line 5):

          #!/bin/sh

          syno_id=$(/bin/cat /usr/syno/etc/certificate/_archive/DEFAULT)

          cd /volume1/path/to/swag/config/

          /bin/cp cert.pem /usr/syno/etc/certificate/_archive/"$syno_id"/cert.pem
          /bin/cp fullchain.pem /usr/syno/etc/certificate/_archive/"$syno_id"/fullchain.pem
          /bin/cp privkey.pem /usr/syno/etc/certificate/_archive/"$syno_id"/privkey.pem

          /usr/syno/bin/synosystemctl restart nginx

          exit

          I’d probably set this to run once a week – since Let’s Encrypt certs are good for 90 days, that should be enough time to swap out the cert before it fully expires.

          • Zach

            Nice! Thank you!!

          • Zach

            Oh, one note, I have this script that does the opposite, uses the synology cert for plex. It’s copied from and attributed to a script someone else created. I think i’ll use the date check functionality to determine when to complete the copy.

            I like seeing the logic behind the syno_id, thank you for that.

          • zach

            And I didn’t include a link for the script, sorry: https://github.com/zachg99/synology-plex-cert-autorenew

          • Gio

            trying this but I get:

            bash /volume1/homes/xxx/refreshcerts.sh
            /volume1/homes/xxx/refreshcerts.sh: line 2: $’\r’: command not found
            /volume1/homes/xxx/refreshcerts.sh: line 4: $’\r’: command not found
            /volume1/homes/xxx/refreshcerts.sh: line 5: cd: $’/volume1/configs/Swag/etc/letsencrypt/archive/xxx.me/\r’: No such file or directory
            /volume1/homes/xxx/refreshcerts.sh: line 6: $’\r’: command not found
            /bin/cp: cannot stat ‘cert1.pem’: No such file or directory
            /bin/cp: cannot stat ‘fullchain1.pem’: No such file or directory
            /bin/cp: cannot stat ‘privkey1.pem’: No such file or directory
            /volume1/homes/xxx/refreshcerts.sh: line 10: $’\r’: command not found
            Fail to restart [].
            /volume1/homes/xxx/refreshcerts.sh: line 12: $’\r’: command not found

            any suggestions?

  5. Hi Gio –

    What script are you running there? It doesn’t look like that matches the scripts Zach or I posted.

    That said, it looks like the directories you’re trying to use might not be correct. Does your script actually reference /volume1/homes/xxx/, or did you change that for your comment on this post?

Leave a Reply to MikeCancel reply

Powered by WordPress & Theme by Anders Norén