Nginx Proxy Manager is a reverse-proxy manager which allows for… reverse proxies. Go figure. This is most commonly used for binding nice service names to services on other ports or internal to a docker network; for example, https://gitea.my.domain is proxied to a docker container not otherwise reachable.
Setting up a proxy
- write setting up a proxy section
Using reverse proxy sites
For the proxy to work, you’ll have to get to the IP address of the proxy site. This means making a DNS request to proxysite.proxyhost.com — which means you need to have a DNS record for that host. Typically, it is inconvenient to do this for all proxied subdomains, so you will want to make a wildcard record.
If you self-host your DNS, see either Custom Wildcard Records or Custom Wildcard Records.
If you use Amazon Route53, you can simply make a *.my.domain A record and point it to the public elastic IP address.
SSL certificate management behind a firewall
If you run nginx-proxy-manager behind a firewall such that the open internet cannot access it, getting SSL certificates isn’t going to work by default. Instead, you have to use LetsEncrypt’s DNS-01 challenge. You will need to be able to update subdomains of your domain via API for this to work. I’m using AWS Route53 as my provider.
Account provisioning
First, you’ll need to set up an account for LetsEncrypt to use to update domains. You will need the ID of your hosted zone from Route 53; you can find it in the hosted zone you want to update, under the “Hosted zone details” dropdown at the top of the page.
- Go to IAM ⇒ Policies
- Click Create Policy
- In the Permissions dialog, select JSON
- Set the policies as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:GetChange"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/<your hosted zone ID here>"
]
}
]
}- Give the policy a name you can easily identify later (I used
letsencrypt-dns01-policy) - Click Create Policy
Next, create a user group with this policy attached.
- Go to IAM ⇒ IAM user groups
- Click Create User Group
- Give the group a name you’ll recognize later
- Under the “Attach permissions policies”, set “Filter by Type” to “Customer Managed”
- Select and add the permissions policy you created previously
Now, create the user.
- Go to IAM ⇒ IAM Users
- Click Create User
- Give the user a name you’ll recognize later
- Click Next
- Select the group you just created, and click Next, then Create User
Finally, you’ll need to get credentials for that user.
- Select the user you just created
- Go to Security Credentials
- Find Access Keys, and select Create Access Key
- Select Other
- Give the key a recognizable name
- Click Create
- Note down both the access key and secret access key. You’ll need them soon and won’t be able to see them after clicking Done.
Configuring DNS-01 challenge
To configure the DNS challenge:
- Go to Nginx-proxy-manager ⇒ Certificates
- Add a new certificate
- Set the URL to
*.your.domain.com(note the leading*.to certify subdomains!) - Select
Route 53 (Amazon)for the provider - In the credentials file content box, update the
aws_access_key_idwith the access key from IAM - In the credentials file content box, update the
aws_secret_access_keywith the secret key from IAM
Bug
Do NOT enter anything in the propagation seconds box! It’s currently broken. However, if you leave it alone, whatever the default option is seems to work. See https://github.com/NginxProxyManager/nginx-proxy-manager/issues/4702 .
- Click Save
- Be patient! This step may take up to 10 minutes as LetsEncrypt adds a DNS record, then has to wait for it to propagate throughout the DNS zone before it can verify your ownership of the domain.
If all goes well, the dialog should close itself shortly and you’ll have the certificate in the list.
Access lists
NPM can also selectively allow/block traffic to a service based on where it originates. This can be useful if you want to completely restrict access to a service even before someone gets the chance to log in.
- Go to the Access Lists tab
- Add a new access list (using Add Access List)
- Give it a name that you’ll use to select this control list when applying it to services
- Go to the Rules tab
- Add the rules you want to use (more on this shortly)
- Click Save
Now, to apply this control list to a service:
- Go to the Proxy Hosts menu
- Select (or create) the service to edit
- Under the Access List dropdown, select the list you want to use
Done.
I find it easiest to manage the access rules based on subnets, as I keep my network divided into separate subnets for each category of users (for example, my LAN is 192.168.30.0/24, while everything coming in from those I give VPN access to arrives from 192.168.33.0/24). So, to create a service which only I can access, I add one allow rule for 192.168.30.0/24. To create a “public” service (really, “available to those who I grant VPN access”), I additionally add the VPN subnet 192.168.33.0/24.
Docker networks
If you have multiple services which talk to each other using the reverse proxy, and which talk to each other on the same Docker host, you may also need to add the Docker networks to this allowlist, otherwise your services may be blocked by the proxy!