If you deployed Nginx Proxy Manager via Docker in your home directory you can edit this file with
nano~/data/nginx/custom/http.conf
All you need to do is add the following at the top:
http.conf
more_set_headers'Server: CuteKitten';
Then, restart your Nginx Proxy Manager. If you’re using Docker, like I am, a simple docker compose restart will do the trick.
With this, the custom Server header will be applied to every request, including those to the Nginx Proxy Manager UI itself. If you check the response headers of this website, you’ll see the header I set—proof of how easy and effective this customization can be!
Understanding more_set_headers vs add_header
When working with Nginx Proxy Manager, you may encounter two ways to handle HTTP headers:
add_header
more_set_headers
What is add_header?
add_header is a built-in Nginx directive that allows you to add new headers to your HTTP responses. It’s great for straightforward use cases where you just want to include additional information in your response headers.
What is more_set_headers?
more_set_headers is part of the “headers_more” module, an extension not included in standard Nginx but available out of the box with Nginx Proxy Manager(since it uses OpenResty). This directive gives you much more flexibility:
It can add, overwrite, or remove headers entirely.
It works seamlessly with Nginx Proxy Manager, so there’s no need to install anything extra.
You don’t need to modify or remove existing headers.
Example:
add_header X-Frame-OptionsSAMEORIGIN;
Use more_set_headers if:
You need to replace or remove existing headers, such as Server or X-Powered-By.
You want headers to apply to all responses, including error responses (e.g., 404, 500).
Example:
# Replace the default Nginx Server headermore_set_headers "Server: MyCustomServer";
Why Use more_set_headers?
The key advantage of more_set_headers is that it provides full control over your headers. For example:
If you want to customize the Server header, add_header won’t work because the Server header is already set internally by Nginx, you would have to remove it first.
more_set_headers can replace the Server header or even remove it entirely, which is particularly useful for security or branding purposes.
Since Nginx Proxy Manager includes the headers_more module by default, using more_set_headers is effortless and highly recommended for advanced header management.
A Note on Security
Many believe that masking or modifying the Server header improves security by hiding the server software you’re using. The idea is that attackers who can’t easily identify your web server (e.g., Nginx, Apache, OpenResty) or its version won’t know which exploits to try.
While this may sound logical, it’s not a foolproof defense:
Why It May Be True: Obscuring server details could deter opportunistic attackers who rely on automated tools that scan for specific server types or versions.
Why It May Be False: Determined attackers can often gather enough information from other headers, server behavior, or fingerprinting techniques to deduce what you’re running, regardless of the Server header.
Ultimately, changing the Server header should be seen as one small layer in a broader security strategy, not as a standalone solution. Real security comes from keeping your software updated, implementing proper access controls, and configuring firewalls—not just masking headers.
Today, I’m going to show you how you can obtain real, trusted SSL certificates for your home network or even a public website. Using this method, you can achieve secure HTTPS for your web services with certificates that browsers recognize as valid. Fun fact: the very website you’re reading this on uses this same method!
This guide focuses on using ACME-DNS with Nginx Proxy Manager (NPM), a popular reverse proxy solution with a user-friendly web interface. Whether you’re setting up a self-hosted website, Nextcloud, or any other service, this approach can provide you with certificates signed by a trusted Certificate Authority (CA) for your home network or the public.
Prerequisites
I am assuming you are on a Debian based Linux distribution (I will use a Debian 12 LXC). This should work an any host supporting Docker though.
You should have some knowledge of Docker and Docker Compose and it should be installed. You can find a step by step guide here.
You need your own domain. I get mine from Namecheap but any provider works. (I usually change the Nameserver to Cloudflare and manage them there since Namecheap is cheaper to buy)
Please make sure you have these packages installed:
Bash
aptinstallcurljqnano
(Jup, I like nano. Feel free to use your editor of choice.)
For our installation we will be using Docker with Docker Compose:
docker-compose.yml
services: npm: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: - '443:443' - '81:81' # Admin Port# - '80:80' # not needed in this setup volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt# - ./custom-syslog.conf:/etc/nginx/conf.d/include/custom-syslog.conf
I only like to expose port 443, since we will be using ACME-DNS we will not need 80. Port 81 will be exposed for now, but once configured we will remove this too.
Now just run this command and you will be able to log in via http://your-ip:81 (replace “your-ip” with the actual IP of your machine, you can try http://127.0.0.1:81 if run locally)
Please take note of your output and copy it to a file or note taking tool for later.
We will need to edit this a little. If you set this up for your home network it is usually a good idea to use subdomain and a wildcard certificate, this will enable you to secure anything under that subdomain.
There should be a “data” directory in your current one from the docker command earlier. We will create a JSON config file for Nginx Proxy Manager, you can name it whatever you want.
Bash
ls# check if "data" dir existscddatananoacme__you_domain.json# use your domain name, but name does not matter
In this file you will need to paste the config. I suggest using a subdomain like “home”.
It is important to note that with a wildcard like this you can not do something like: “plex.media.home.your-domain.com”, you can only use the specified level of subdomain, if you did want to do a “sub-sub” you would need to use “*.media.home.your-domain.com” and so on.
A note on the “allowfrom": []“. If you have a static IP that you will always be coming from this is a good idea. Since this guide focuses on SSL for home you most likely have a dynamic IP which will work until it changes, so probably 24h or a week.
Configuring DNS Records
You need to edit your local DNS server and edit these in your registrar. I am using Cloudflare
Cloudflare
go to “your Domain -> DNS -> Records” there you will need to add a CNAME record.
In the “Name” field put “_acme-challenge.YOUR-SUBDOMAIN” in our example that would be like you see in the image below. In the “Target” field you put the “fulldomain” from your config, like “XXXX040a-XXXX-XXXX-XXXX-XXXX f8525a11.auth.acme-dns.io“. Leave “Proxy status” on “DNS only”.
(If you are doing a public and not home only setup you would also add a A, AAAA or CNAME record pointing to your public IP. For home setup you do not need this.)
Local DNS
The devices in your network need to know that your reverse proxy aka. Nginx Proxy Manager is handling “*.home.your-domain.com” you need to add this to your local DNS server so whenever someone goes to “*.home.your-domain.com” it is directed to your proxy. Now if you have a Pi-Hole, AdGuard, pfSense, OPNSense or in your Router varies, technically you could even edit the hosts file of each device. I am using a Unifi Dream Machine :
In your dream machine go to: /network/default/settings/routing/dns
there you create a new entry like so:
Please use your configured domain and the IP of your system.
Bringing it all together
All we need to do now I configure our setup in the Nginx Proxy Manager. Go to your Admin interface at http://your-ip:81/nginx/certificates then click on “Add SSL-Certificate” and choose “Let’s Encrypt”
There is a lot going on here but I will explain:
In “Domain Names” enter the domains you have configured
Enter your E-Mail Address
Choose “ACME-DNS” in the Provider menu
In the API URL enter “https://auth.acme-dns.io”
the registration file is the JSON file we created earlier. Add whatever you called it in there, the path “/data/” should be fine if you followed all the steps.
Leave propagation empty
Finally just agree and save.
Your new certificate will pop up once the loading screen goes away.
It should look like this:
By the way, I have a profile image because I used my Gravatar email address for the admin login.
Securing the Nginx Proxy Manager Admin
Now that we have a certificate let us use it directly on our admin interface.
Add a new proxy host. Enter the domain of your choosing (you need to change “your-domain.com”. Since it is accessing itself in the Docker network the hostname is “npm” this is its name from the “docker-compose.yml” at the beginning.
Under the “SSL” tab just choose your created certificate.
You do not have to choose the options for Force SSL, HTTP/2 and Block Common Exploits for this to work.
Okay now press Save and test!
If it works you can now remove the port from the compose:
Now you can access your Nginx Proxy Manager admin interface via your new domain with a trusted SSL certificate.
Conclusion
Using ACME-DNS with Nginx Proxy Manager is a powerful way to obtain SSL certificates for your home network or website. It simplifies the process of handling DNS challenges and automates certificate issuance for secure HTTPS. You also will no longer have to expose your local services to the internet to get new certificates.
By following this guide, you’ve gained the tools to secure your online services with minimal hassle. Stay tuned for more tips on managing your self-hosted environment, and happy hosting!
Manage Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.