Skip to content

Setting up SSL certificates for Promox using AWS Route 53

Posted on:November 23, 2023

Setting up SSL certificates for Proxmox can feel like a headache, but it doesn’t have to be.

You can set it up in under 10 minutes using a domain registered on AWS Route 53. In this post I’ll show you how to get proxmox.naz.com to redirect to your Proxmox host, with SSL enabled. I’ll also show you how to get your hosted services working under subdomains like adguard.naz.com and plex.naz.com.

All without opening any firewall ports or exposing your network to the internet.

Quick guide

If you want explanations for what each step is doing, see the end of this post. If you just want to get it working quickly, then follow along:

Setup Route 53

  1. Log in to the AWS console and go to Route 53 Hosted Zones
  2. Select the zone for your domain. In this example I’ll refer to naz.com
  3. Click ‘Create record’ and create a new record with the following info:
    • ‘Record name’ should be proxmox or whatever you want to refer to your host as. This will be accessed at proxmox.naz.com
    • Record type should be A
    • The value should be your private IP address to the proxmox host server: e.g. 192.168.1.100
    • Set TTL to 60 for now (useful if you make any mistakes)
    • Click ‘Create records’ Create Records
  4. Once that’s done, click ‘Hosted zone details’ at the top and then copy your ‘Hosted zone ID’ to a text file. You’ll need it for the next step.

Setup AWS Permissions

  1. Log in to the AWS IAM console and click ‘Users’ on the left.
  2. Then click ‘Add users’.
  3. Give the user a name, e.g. ‘proxmox’ and click ‘Next’.
  4. Select ‘Attach policies directly’ and then click ‘Create policy’. This should open a new window.
  5. Click ‘JSON’ and paste the following, remembering to replace XXXXXXXXXXXXXXXX with the zone ID you copied earlier:
{
  "Version": "2012-10-17",
  "Id": "proxmox-letsencrypt",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["route53:ListHostedZones", "route53:GetChange"],
      "Resource": ["*"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets",
        "route53:ListResourceRecordSets"
      ],
      "Resource": ["arn:aws:route53:::hostedzone/XXXXXXXXXXXXXXXX"]
    }
  ]
}
  1. The click ‘Next’ and give it a name, e.g. proxmox-route53 and click ‘create policy’ Create policy
  2. Close this window and go back to the previous one where you were creating the user. Click the refresh button and then search for the policy. Then select it and click ‘Next’.
  3. No need to change anything on the next page. Just click ‘Create user’
  4. Select the new user you just created (e.g. proxmox) and then click on ‘Security credentials’.
  5. Scroll down to ‘Access keys’ and click ‘Create access key’. Select ‘Application running outside AWS’ and then click Next.
  6. Set the description tag value to proxmox-host-key and click ‘create’.
  7. On the next page copy both the Access key and the Secret access key to a text file. You’ll need these later. Note that you will not be able to see the secret access key again. If you forget to copy it, delete this key and repeat steps 10 and 11 again.

Setup Proxmox

  1. Log in to your proxmox host then click on ‘Datacenter’ in the top left and ‘ACME’ in the menu.
  2. Under ‘Accounts’ click ‘Add’. Put default as the account name (anything works), then add your email, select Let’s Encrypt V2 as the ACME directory and accept the TOS Register account
  3. Then under ‘Challenge Plugins’ click ‘Add’ and type dns-01 as the Plugin ID, set Amazon Route53 (AWS) as the DNS API and put in your AWS key id and secret access key you copied earlier. Add access keys
  4. Then click on your Proxmox Node in the far left menu and select System > Certificates in the right menu. Under ACME click ‘Add’ Add certificate
  5. Change the Challenge Type to DNS, select dns-01 as the plugin and type in the domain your want to use for your proxmox host (e.g. proxmox.naz.com) and click Create. Use DNS01
  6. Once that is done click ‘Order Certificates Now’ and it should obtain an SSL certificate and apply it on your Proxmox host!
  7. (Optional extra): If you want to be able to type proxmox.naz.com without the :8006 at the end, follow the steps in the extras section further below.
  8. You should now be able to login to your proxmox host using the domain proxmox.naz.com:8006 instead of your local IP address.

If you only care about a domain name for the host, you can stop here.

If you want to create domain names for each of your hosted services (e.g. plex.naz.com) as well then follow the next steps.

Installing SSL certificates for locally hosted services

In this section I’ll show you how to set up domains for locally hosted services.

Again, this is without opening your network to the internet or exposing any ports on your router. In order to make it work we need to install Nginx, a reverse proxy. This is a piece of software that will map the domain names to the local services along with making them accessible on port 80 so you can type plex.naz.com instead of plex.naz.com:32400.

It sounds more difficult and long-winded than it is, so let’s jump in.

Setup NGINX

  1. Install Nginx Proxy Manager. This can be done with a single command by opening the Shell on your Proxmox host and then pasting this:
bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/nginxproxymanager.sh)"
  1. Select ‘Yes’ to proceed (press enter to select) and then when it asks ‘Use default settings’ select ‘Advanced’.
  2. Keep pressing enter until you get to ‘Choose Distribution’ then select ‘Debian’ and press spacebar then enter.
  3. Select ‘Bookworm’ as the version.
  4. Select ‘Unprivileged’ as the Type.
  5. Set a root password for ssh access.
  6. Set anything as the container ID (I used 301)
  7. Leave the hostname as nginxproxymanager
  8. Leave the disk size at 4 gb.
  9. Leave 1 as the number of CPU cores.
  10. Leave 1024 as the RAM.
  11. Set your bridge (mine is vmbr0)
  12. Then type in your desired static IP address and netmask. The IP can be anything in the valid range. The netmask must be correct (typically /24 if your don’t know). Here I set my IP to 192.168.1.8: Setting IP range
  13. Set the correct gateway IP address (typically your router’s IP address): Setting gateway
  14. Disable IPv6 unless you’re using it.
  15. Leave MTU size blank.
  16. Leave DNS Search Domain blank.
  17. If you’re using a DNS server for local domains you can set it now (I left it blank as my router managers my DNS servers).
  18. Leave MAC address blank.
  19. Leave VLAN blank.
  20. Select ‘No’ for ‘Enable Root SSH access’.
  21. Select ‘No’ for Verbose mode.
  22. Select ‘Yes’ to create the LXC
  23. You should see the installer running which will look something like this: Console

While this is running, let’s add an extra Route53 domain name for the subdomains. This will point at the NGINX instance we’re setting up.

Point Route53 at NGINX

  1. Log back into the Route53 console and select your hosted zone.
  2. Under records click ‘Create Record’.
  3. Put * as the Record Name and the IP of the NGINX service (e.g. 192.168.1.8) as the Value. Set TTL to 60 and the record type to A as you did before and click “Create Records”.
  4. We’re done creating the DNS records. In order to proceed we need to wait until these records have propagated. You can test it by typing dig +short '*.naz.com' in any terminal (either on a proxmox VM, the host, or your own machine). If it returns the IP you set in step 3 then you’re good to go. If it is blank then wait 5 minutes and try again - DNS records can take some time to propagate across the internet.

Setup NGINX to automatically obtain SSL certificates

  1. Navigate in your browser to http://192.168.1.8:81 (replace the IP with the static one you set when setting up nginx). You can also copy it from the Proxmox shell where you ran the install command.
  2. Log in with the default email address admin@example.com and the password changeme
  3. Set a new login (remember the email address) and password.
  4. When you’re logged in click on ‘SSL Certificates’ and then ‘Add SSL Certificate’ Add SSL certificate
  5. Enter *.naz.com (replace the domain with yours but keep the *) as the domain name and press enter. Then enter your email address and select ‘Use a DNS challenge’
  6. Select Route 53 (Amazon) as the DNS provider and copy and paste the AWS key id and AWS secret key from earlier.
  7. Leave propagation seconds blank and select ‘I agree to the terms.’ Then click ‘Save’. Adding a certificate
  8. You’ll now get a loading screen for a few minutes whilst the SSL certificates are obtained. When it’s complete you should see this: Success

Adding subdomains for each service

We’ll now set up subdomain routing for your hosted services.

In this example I’ll show how to set up a domain for the nginx proxy manager we just installed.

It works similarly for other services so you can repeat these steps as many times as you need.

  1. Go to the nginx proxy manager dashboard and click ‘Hosts’, then ‘Proxy Hosts’ and then ‘Add Proxy Host’
  2. Set the domain name you desire, ensuring it’s a subdomain of the wildcard domain you set earlier. e.g. if you set up *.naz.com you can use any subdomain such as nginx.naz.com or webserver.naz.com
  3. Set the local IP of the server and the port it uses (e.g. 81 for nginx or 32400 for plex). Usually you want to leave the Scheme as http but for some SSL-enabled services it needs to be https Adding the domain name
  4. Then click ‘SSL’ and under ‘SSL certificate’ select the SSL certificate you just obtained (usually the last option)
  5. Then click ‘Force SSL’ and ‘HTTP/2 Support’ Force SSL
  6. Click ‘Save’
  7. You should now be able to access the management console from nginx.naz.com (or whatever you set it to), without having to add :81 to the URL

Everything is now set up and you can access the service via a domain name with a valid SSL certificate set.

You can repeat the ‘Adding subdomains’ steps above to make other services available on different domains. With this setup you can use any subdomain under the wildcard domain you set earlier. You do not need to change anything in Route 53 again.

Congratulations!

FAQ

How can I access the Proxmox host without having to put :8006 as the port?

Follow this amazing video guide to route port 8006 connections to port 80.

How does it all actually work?

There are a few different things going on:

  1. Domain name -> IP routing.

    • The Route 53 DNS records are set so that when you type proxmox.naz.com the resolved address 192.168.1.100
  2. SSL certificates

    • A service called Let’s Encrypt is used to get signed certificates.
    • In order to prove to Let’s Encrypt you control the domain, you have to add a special TXT record to the DNS config. Let’s Encrypt then verifies this and issues the SSL certificates.
    • For the proxmox.naz.com domain this is handled by the Proxmox ACME service. For the service subdomains it is handled by Nginx proxy Manager.
    • This is why we need to create a new AWS user with Route 53 permissions. The TXT records are typically removed after validation (they only last a few minutes) so you won’t typically see them in Route 53.
    • The TXT records need to be refreshed every 3 months to renew the SSL certificates, so the permissions for Nginx and ACME need to remain. Both services will automatically refresh the certificates when needed.
    • Nginx Proxy Manager obtains a wildcard SSL certificate which means all subdomains under the domain registered are valid. This is why setting up routes with Nginx works.
  3. Nginx Proxy Manager redirects domains to local ips & ports

    • When setting up a proxy route in Nginx, we’re telling it to serve a specific local service (and port) at the requested domain name.
    • e.g. When a user types plex.naz.com, it will resolve to the IP for Nginx Proxy Manager (since all subdomains resolve to nginx).
    • Nginx then sees this request and knows that the user is looking for plex.naz.com. If it has any rules set up for this domain, it knows to instead serve a local service, and which port to get it from.
    • If set up with ‘Force SSL’ as instructed it will tell the browser to use HTTPS instead and then use the valid wildcard certificate for TLS encryption.

Why can’t I use Nginx Proxy Manager to also serve the Proxmox host domain?

Whilst it’s possible to set this up, due to the way Nginx works it will break the ‘Console’ functionality of the Proxmox host (and perhaps other things).

In order to get it working smoothly the ACME service on the Proxmox host needs to obtain its own SSL certificate.

ACME isn’t able to service SSL certificates for local services so we need Nginx to do the routing.