Securing applications with oauth2-proxy on Synology NAS
A Synology NAS can be convenient for hosting various Docker-based applications for personal use. Some applications have authentication built in, but others don’t. The latter approach is not unreasonable: it doesn’t make sense for every application to include its own custom user management and authentication.
Nevertheless, it may be desirable to make them accessible only to authenticated users. Luckily, oauth2-proxy is a (reverse) proxy service that lets us put authentication in front of any such application by delegating the authentication part to another service of choice, e.g. Google, GitHub, etc. In order to not depend on any external authentication service, it’s also possible to use the Synology DSM and its user management for authentication, just like it is for Synology’s own applications. And this post will show how to do exactly that.
Introduction
This post assumes that you have the Synology DSM accessible over HTTPS at https://example.com:5001, i.e. “example.com” stands for your own domain and Synology DSM is already configured with a valid HTTPS certificate for it. For example, this can be achieved using Let’s Encrypt or Tailscale.
The tutorial will set up the following:
- For example’s sake, the insecure unauthenticated application will be httpbin, which will not be exposed directly. This can be replaced with the insecure unauthenticated application of choice.
- The insecure oauth2-proxy will be exposed at http://example.com:5400 and will serve as a reverse proxy to httpbin once the user is authenticated. It is insecure only in the sense of HTTP — it is still authenticated.
- The secure oauth2-proxy will be exposed at https://example.com:5401 via a reverse proxy to the insecure version. This allows the HTTPS certificate for “example.com” to be reused without having to also set up a HTTPS certificate in oauth2-proxy itself.
- The authentication will be provided by Synology DSM at https://example.com:5001.
Step-by-step
All of the following steps are to be performed in the Synology DSM.
Reverse Proxy
- Navigate to Control Panel → Login Portal → Advanced → Reverse Proxy.
-
Create a new reverse proxy (Create) with the following details:
- Reverse Proxy Name: “oauth2-proxy”.
- Source:
- Protocol: HTTPS.
- Hostname: “example.com”.
- Port: 5401.
- Destination:
- Protocol: HTTP.
- Hostname: “localhost”.
- Port: 5400.
- Press “Save” and close the Reverse Proxy window.
SSO Server
- Install “SSO Server” from Package Center.
- Open SSO Server.
- Under General Settings, set Server URL: “example.com:5001” (the “https://” prefix will be implicitly there).
- Under Service → OIDC, Enable OIDC server.
-
Under Application, add a new application (Add) with the following details:
- Select an SSO protocol: OIDC.
- Application Name: “oauth2-proxy”.
- Redirect URI: “https://example.com:5401/oauth2/callback”.
- Select the just-added application from the list and click “Edit” in the toolbar.
- Make note of the generated “Application ID” and “Application secret”, which will be needed in the next step. You can just keep the Edit window open and come back to copy them when needed.
oauth2-proxy
Configuration
- In File Station, create a folder for oauth2-proxy configuration files, e.g.
/docker/oauth2-proxy
. - Using Text Editor, create the files
oauth2-proxy.cfg
andauthenticated_emails
with the contents described below, and save them into the previously-created folder.
oauth2-proxy.cfg
Copy the following:
http_address="0.0.0.0:5400"
reverse_proxy="true"
upstreams="http://httpbin"
# cookies
cookie_secret="TODO"
cookie_secure="true"
cookie_domains=["example.com"]
whitelist_domains=["example.com:5401"]
# Synology
provider="oidc"
oidc_issuer_url="https://example.com:5001/webman/sso"
client_id="TODO"
client_secret="TODO"
redirect_url="https://example.com:5401/oauth2/callback"
code_challenge_method="S256"
skip_provider_button="true"
# authentication
oidc_email_claim="sub"
authenticated_emails_file="/authenticated_emails"
Replace all TODOs as follows:
- Replace
cookie_secret
with a freshly-generated cookie secret, as described here. - Replace
client_id
with “Application ID” from SSO Server. - Replace
client_secret
with “Application secret” from SSO Server.
authenticated_emails
Write a list of authorized Synology usernames, one on each line. For example:
myuser
Despite the file and the oauth2-proxy configuration calling them emails, we don’t use emails here. Using emails from Synology users would be insecure because users can arbitrarily change their email. Hence, we make oauth2-proxy use usernames in place of emails using
oidc_email_claim="sub"
. I learned about this trick from Okta’s tutorial Add Auth to Any App with OAuth2 Proxy.
Permissions
- In File Station, navigate to the previously-created folder for oauth2-proxy configuration files.
- Right-click on
oauth2-proxy.cfg
and select “Properties”. - Switch to “Permission” tab.
-
Press “Create” in the toolbar and enter the following details:
- User or group: Everyone.
- Type: Allow.
- Permission: Read.
- Press “Done” and then “Save”.
- Repeat for
authenticated_emails
.
This is recommended by Synology to fix permissions issues with files mapped into Docker containers (in the next step).
Container
- Install “Container Manager” from Package Center.
- Navigate to Container Manager → Project.
-
Create a new project (Create) with the following details:
- Project name: “oauth2-proxy”.
- Path: “
/docker/oauth2-proxy
”. - Source: Create docker-compose.yml.
- Paste the following Docker Compose file into the text box below:
version: '3.0' services: oauth2-proxy: container_name: oauth2-proxy image: quay.io/oauth2-proxy/oauth2-proxy:v7.10.0 command: --config /oauth2-proxy.cfg hostname: oauth2-proxy volumes: - "./oauth2-proxy.cfg:/oauth2-proxy.cfg:ro" - "./authenticated_emails:/authenticated_emails:ro" restart: unless-stopped ports: - 5400:5400/tcp networks: httpbin: {} depends_on: - httpbin httpbin: container_name: httpbin image: kennethreitz/httpbin restart: unless-stopped ports: [] networks: httpbin: {} networks: httpbin: {}
- Press “Next”, “Next” and “Done”.
- Wait for the Docker containers to be downloaded and started.
Conclusion
If all went well, then you can now navigate to https://example.com:5401 in your browser. This should first redirect to Synology DSM login. However, since you should already be logged into Synology DSM, you will not be prompted to log in again. Finally, you will be redirected back to https://example.com:5401, but this time you’ll see the httpbin application instead.
You can replace the httpbin container with your desired Docker-based application. Importantly, it should not expose any ports
. Instead, it will only be accessed via the Docker network (also called httpbin in this case) by oauth2-proxy, which has access to the same network. You may need to adapt upstreams
in oauth2-proxy.cfg
for your application and restart the oauth2-proxy container for changes to take effect.