reverse proxy Synology docker

Synology: Docker Reverse Proxy

Synology Jan 6, 2023

This guide will help you set up a reverse proxy for Synology docker containers. This will allow you to deploy a docker container application to its designated subdomain. Of course, we want this docker application nicely secured with its own TLS (SSL) certificate so that everything is excellent and secure. This post is compatible with DSMv6 and DSMv7.

Shortly I will also write a guide on achieving the same for Synology services.

Prerequisites

Your router must forward all HTTP and HTTPS traffic from the internet to your Synology. This is required because the Let’s Encrypt service, which is used to obtain a genuine certificate, must verify that you are the specified subdomain owner.

Check out my earlier post on how to configure Synology External Access.

Guide

There are three steps to configure a docker container to be available on a subdomain. Get a certificate, configure the reverse proxy for the Synology docker container to expose the application of the docker container, and then glue the first two steps together, with the third step as the final step. In this guide, we will use mynas.diskstation.me as described in my earlier post on configuring your Synology for external access. The subdomain we will be using throughout this guide is service. The FQDN (Fully Qualified Domain Name) will become service.mynas.diskstation.me. Please replace this with the FQDN you created in the Synology external access guide, and replace the service with the name of the docker container service you want to make externally available.

A real-world example for clarity, let’s say that we are using this guide to export the UI of the docker management application portainer to the public internet, and we have our Synology publicly available on the domain gtimmer.diskstation.me. Then the FQDN will become portainer.gtimmer.diskstation.me. I have planned on writing a post on how to set up portainer anyway, so shortly, I will link that article here.

Why do we need a TLS (SSL) certificate?

We want our service to have a TLS (SSL) certificate so the browser will show it as safe. We also want this to be an official certificate so that it does not only look professional, but we also want every browser to accept the website as secure. Maybe you came across it on the internet, those browser warnings that a website is not secure. Please take a look at the image below; we want to avoid this.

TLS (SSL) Certificate Expired: This is what we do not want

We will be using Let’s Encrypt as our certificate provider to secure our Synology; if we get a certificate from Let’s Encrypt, every browser will recognize it as a valid certificate, and we do not get the warning above. Let’s Encrypt is a free provider, so we do not have to pay for the certificates. Let’s Encrypt certificates are valid for 90 days. However, do not worry. Synology DSM comes with full support for Let’s Encrypt, which means that if you set it up correctly, as I will be teaching here, your Synology will automatically refresh the certificates before they expire and obtain a new one from Let’s Encrypt without any interaction required from you. Yeah!, no maintenance😊.

Get a Let’s Encrypt certificate

So let’s start.

  1. Login into DSM as an administrator
  2. Open Control Panel
  3. Open Security
  4. Goto tab Certificate
  5. Choose Add
DSM 7: Add new certificate
DSM 6: Add new certificate
  1. Choose Add a new certificate
  2. Click Next
DSM 7: Add a new certificate
DSM 6: Add a new certificate
  1. Choose Get a certificate from Let's Encrypt
  2. It is highly recommended to enter a description, even while it’s optional; it is shown within the Security > Certificate overview screen. Entering a description will improve documentation and maintenance over a long period. I usually put the FQDN (Fully Qualified Domain Name) as the description. The certificate overview screen within Synology favors the description. Certificates can also be used for multiple services. Quite useful when using a wildcard certificate. Therefore a good practice is to put in the certificate DNS name. Example: portainer.myns.diskstation.me
  3. Click Next
DSM 7: Get a certificate from Let’s Encrypt
DSM 6: Get a certificate from Let’s Encrypt
  1. Fill the FQDN (Fully Qualified Domain Name) address you want a certificate for in the field Domain Name.
  2. Enter your e-mail address. Each certificate must have an e-mail. This email address will also be encoded within your certificate. You can receive e-mails from Let’s Encrypt regarding your certificate, so please use a real one.
  3. Optional; Subject Alternative Names, this is a very excellent option. It allows you to add additional domain names to a certificate. This can be used to have multiple addresses use the same certificate.

    Say that you make the earlier mentioned docker service available on the address portainer.mynas.diskstation.me; while creating this certificate, you conclude that it also would be nice to have the address docker.mynas.diskstation.me also point to portainer. So you have two addresses. This is where Subject Alternative Names come into play. You can add additional domains to a certificate (alternatives) which are also valid for this certificate. Domain names must be separated with a semicolon ;
  4. Issue the certificate by clicking on Apply or Done
Example: Multiple domains

Domain Name: admin.mynas.diskstation.me

Subject Alternative Names: management.mynas.diskstation.me;dsm.mynas.diskstation.me

A requested certificate with the configuration as stated above will be valid for the following domains:

  • admin.mynas.diskstation.me
  • management.mynas.diskstation.me
  • dsm.mynas.diskstation.me

There is a limit of maximum of 100 Names per certificate

So that you know, there are limits to requesting certificates from Let’s Encrypt. If you exceed certain limits, there is no other way around it than to wait until your limit has reset itself after a certain period.

Details about the limits for Let's Encrypt can be found here: Let’s Encrypt Rate Limits

DSM 7: Issue new certificate
DSM 6: Issue new certificate

The certificate will now be issued and appear in the Certificate overview tab, where you can start using it. One possibility of using your certificate is to secure a Synology service or a reverse proxy entry.

What is a reverse proxy?

We have arrived at our next step for setting up a reverse proxy for a Synology docker container. Our next step will be to expose the containerized application to the outside. We will be using a reverse proxy to achieve this.

What is a reverse proxy?

A reverse proxy is a service that sits between two sides. Let’s call them frontend and backend. So how does this apply to Synology? Well, the front end would be the traffic from the internet to your router and end at Synology. There it will hit the Synology reverse proxy. This will then forward this traffic to a specific backend. In our case, this will be the target docker container. Without putting this into place, the traffic will hit port 80 (HTTP) or port 443 (HTTPS) and stop. Why does the traffic stop? Because for safety, Synology does not run a service on those ports. (Except if you are running WebStation, which is intended to host websites.

So there are two ways we can connect the reverse proxy to the docker container. The first is through localhost; you can map the port in the container to the host, making this port available on localhost. The second possibility is to obtain the IP address of the docker container and connect the reverse proxy directly to the docker container and to the port on which the application inside the docker container is running.

To explain, imagine a docker container running an nginx web service and exposing port 80. In the first possibility, you will map this port inside the container to a port on the host, such as port 1080. This means that when you access localhost:1080, your connection will end inside the container on port 80. See the docker documentation for more information. If you are using docker-compose for your docker container, documentation about this can be found here.

On Linux-based systems, your host can talk directly to the IP of a docker container as if it were running on your local network. With the second option, you obtain the docker container’s internal IP address; these IP addresses commonly start with 172.x.x.x. Then in the reverse proxy, you will enter this information to connect to the docker container.

I prefer this option because it’s cleaner. Local mapped ports can conflict with ports reserved for Synology services. This situation occurs when installing a package and the Synology service fails to start because you accidentally took away a port reserved for this service.

Get docker container network information

To get the information we need, we can use several methods. If we use the technique where we will be using the local port forwarding, we need to get the port on the host. You can find how to do this in the first two tabs, with the built-in docker tool on either DSM 6 or DSM 7. You can also use portainer, but that is now out of scope. If you are going with the method I prefer you probably already know the port on which the application is running.

If you have configured your container with docker-compose, you probably already know which port this is. This is almost always in the documentation of the container in question on its DockerHub information page. Or in the documentation from where you obtained the container.

In either case, you need to get the IP address of the container, which cannot be obtained through the built-in docker application. Portainer does show the IP address of a container. As mentioned before, this is out-of-scope for now. We will be getting the IP address of the container through SSH.

If you have decided to go with the second method, where you directly connect to the container on its IP address, then you can skip the next section and go straight to configuring the reverse proxy.

  1. Open the Synology application Docker
  2. Open the tab Container
  3. Click on the container you want to expose
  4. Either click on the button details or right-click on the container and choose Details.
DSM 7: Docker container overview
DSM 6: Docker container overview
  1. Login to your Synology with SSH
  2. Run the following command; replace CONTAINER_NAME with the name of your container
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' CONTAINER_NAME

This command will print the container IP number.

  1. On the details screen locate the Port Settings tab. Here you will find the local port address. The Local Port is the one in which are interested because this is the port which is open on localhost.
DSM 7: Docker container details

Configure a reverse proxy entry

To configure a reverse proxy, we do require some information. A reverse proxy has a source from which traffic is coming and a destination to which the traffic needs to be directed.

  • Domain name: service.mynas.diskstation.me
  • The hostname of the container; this is either localhost or the IP address of the container
    • localhost OR 172.x.x.x
  • Port number of the application; this is either the local mapped port on the host or it is the port number the application is running on in the container.

To ensure everything is understood, we have one of the following sets of information.
localhost with a host port, OR, we have 172.x.x.x with the port number of the application.

Because the location of the reverse proxy within DSM is quite different between DSM 7 and DSM 6, I have separated the steps required to create a reverse proxy entry.

Now that we have all of our information we are ready to configure the reverse proxy. Follow the steps for your DSM version below. This will continue the steps from the previous section.

Important

A reverse proxy on Synology docker works with a Source and Destination. We will configure HTTPS (TLS/SSL) on the front end, and in most cases, we will configure the connection to the docker container with HTTP. This means all the traffic to and from the Synology is nice and secure. But only on the Synology, the connection is unencrypted. This is fine and a common practice because most only provide their application without TLS/SSL ability. Most docker containers assume that you take care of this before the traffic reaches the container. This is what a reverse proxy is also for.

Open the reverse proxy panel

  1. Open Control Panel
  2. Goto Login Portal
  3. Open the tab Advanced
  4. Open Reverse Proxy
  5. Click Create
  1. Open Control Panel
  2. Goto Application Portal
  3. Open the tab Reverse Proxy
  4. Click Create

Create reverse proxy entry

Finally we are creating the reverse proxy entry for a Synology docker container.

  1. Please enter the name of our service in the Reverse Proxy Name; I always choose to use the service part of the FQDN we created earlier. Example: portainer.
  2. Next we configure the Source this is the outside traffic reaching the Synology.
    • Protocol: Choose HTTPS; we are configuring HTTPS here. This will result in the fact that in our final step, we can assign the earlier created certificate to this service.
    • Now Hostname, this is going to be the fun part. This is the FQDN (Fully Qualified Domain Name) we created earlier. You will type this web address into your browser to access the application. Our guide uses service.mynas.diskstation.me for this as an example value.
    • Port: 443, This must be set to 443, little note here is that it looks like with the grayed-out text it’s already filled in, but this is just a suggestion for its default value. We use port 443 because this is the default port for HTTPS traffic. This means that our service will become exposed as https://service.mynas.diskstation.me.
    • Optional; you can enable HSTS (HTTP Strict Transport Security). When you enable this, it will result in the situation that if there is an issue with your certificate, for example, your NAS did not renew it in time and it expired; you will not be presented with the Advanced button to bypass security as is shown in the first image of this post. I think it’s a good idea to enable this. It will make your website more secure.
    • DSM 6 Only: On DSM 6 you are also presented with an option to enable HTTP/2 this means forcing the protocol to use HTTP/2. DSM 7 is HTTP/2 by default. I recommend enabling this.
    • Both DSM 7 and DSM 6 both an option to use something called Access Control Profile for now this is out of scope. I’m planning on writing a separate guide about this. For now skip this option.
  3. Our final step in configuring the reverse proxy is het Destination this is where we are going to route our traffic to, and to no surprise, this is the docker container hosting the application we want to expose.
    • Protocol: Choose HTTP most docker containers as described earlier above most containers provide their application unencrypted. Unless you have configured your container with TLS (SSL).
    • Hostname: This is what we talked about earlier. This is either localhost when we are using the local mapped port method, or it is the docker container IP address.
    • Port: This is the port matching the method we choose earlier. The local mapped port or the port on which the application runs inside the docker container.
  4. Custom Headers (Optional). Sometimes it’s required that additional HTTP headers are set on the reverse proxy. For example, allow WebSocket connections to pass through the reverse proxy to the docker container behind it. This is what the tab Custom Header is used for. If you have a docker application that uses WebSocket, you can easily add these by clicking on the arrow new to the Create button. This will represent you with a WebSocket option to quickly add the required headers. You can also add additional custom headers here.
  5. Click Save (DSM 7) or OK (DSM 6) to create the reverse proxy entry.

I provided images for both cases. In the images, I use an Nginx container for this example; Nginx runs inside the container on port 80. The images should clear any confusion about the different methods.

Assign certificate

When you have issued or imported a certificate in your DSM security center you can then assign them to services and reverse proxy entries.

  1. Open Control Panel
  2. Open Security
  3. Goto tab Certificate
  1. Click on Settings
  1. Click on Configure
  1. The certificate assignment panel consists of two columns. The left is the Services, and the right is the Certificate. Look for the domain name we just created with the reverse proxy entry. Use the drop-down on the right of your service entry to assign your issued certificate. Also, earlier in this guide, I mentioned that I always advise filling in the Description field when issuing a new certificate, this will be shown in the drop-down menu.
  2. Click OK, and the certificate you issued is now assigned to the domain we created in the reverse proxy.
DSM 6/7: Certificate assignment

Ready, test, go

After assign your certificate you can go to your browser and test it out. If everything was configured correctly you should be able to access your service on the domain name for which you created a certificate.

Enjoy your exposed service with a real TLS (SSL) certificate.

Conclusion

I hope this guide is helpful to you for setting a reverse proxy for a Synology docker container. This guide is lengthy, but I wanted to discuss all the options, their meaning, and why we are doing things. Please leave a comment and let me know what you think.

Tags