Skip to content

Instantly share code, notes, and snippets.

@X448NAX
Created December 25, 2021 08:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save X448NAX/4ec53b4501b3dc5cfb430617c9d09660 to your computer and use it in GitHub Desktop.
Save X448NAX/4ec53b4501b3dc5cfb430617c9d09660 to your computer and use it in GitHub Desktop.
How to hide and customise the server info in the HTTP header for Nginx on Ubuntu server (good security practice and a bit of fun)

How to hide and customise the Nginx server string in the HTTP header on Ubuntu

Note: only tested on Ubuntu 20.04.3 LTS. Should work with other versions of Ubuntu Server as well as distros based on Ubuntu or Debian.

Based on reading it seems to not be so easy for other distros however. If you use a distro not derived from Ubuntu or Debian you may need to compile Nginx yourself.

But assuming you're running an Ubuntu server, all you need to do is run this command:

sudo apt install libnginx-mod-http-headers-more-filter

A lot of guides online (see Stack Overflow link above) suggested you needed to install the entire nginx-extra package. Nope, you can just install that one extra module, no need to install a load of extra stuff you don't want.

What is this for?

When you run any web server or reverse proxy, it sends a string in the HTTP header that basically tells any piece of software connecting to it the name and version by default.

Most of the time there is no benefit at all to broadcasting this information for the internet to see as it's not something browsers or apps need to know, but it is useful info to adversaries who may wish to attempt to gain unauthorised access to your server ("hack" into it).

As such, it's a good idea to stop your server from broadcasting this information everywhere.

The standard Nginx package you get when you type sudo apt install nginx into Ubuntu doesn't provide a feature that allows you to do this. It does provide a simple setting that hides the version which is helpful, but it still shows you are running Nginx.

So let's apply that function to hide the version, then use the newly exposed config option from libnginx-mod-http-headers-more-filter to change the Nginx string in the HTTP header too!

How to do it - TL;DR version

  1. sudo apt install libnginx-mod-http-headers-more-filter
  2. sudo nano /etc/nano/nginx.conf
  3. Scroll down a little until you see the line # server_tokens off;
  4. Remove the # so it just says server_tokens off;
  5. Now make a new line below it and paste more_set_headers "Server: Molly Percocet";
  6. Not a Future fan? I question your taste, but feel free to change the string to say whatever you like, just make sure you keep the Server: bit there. So more_set_headers "Server: Chase a check never chase a bitch"; will work but more_set_headers "Chase a check never chase a bitch"; will likely throw an error.
  7. Save that file
  8. Optionally, if you want different virtualhosts, subdomains, etc to show different server strings, you can add a more_set_headers directive to individual configuration files too. This way foo.example.com and bar.example.com can show different server versions. Or if you run multiple domains from the same VPS you can also make foo.com and bar.com show different server strings on their respective HTTP headers too. You get the idea.
  9. When you're done just run sudo systemctl restart nginx and your changes will take effect instantly.
  10. You can check it's working here: https://httpstatus.io or by running curl -I https://example.com

Can I seriously just make it say whatever I want?

Server Name

Yep!

It's not working!

If, even after rebooting the server fully, you still don't see the custom string, and you installed the module and set the directives correctly in the configs, what is showing instead? Is it Nginx or the name of the web app you're reverse proxying to?

If you are using Nginx as a reverse proxy, open up the config file for the reverse proxy and look for a line that says proxy_pass_header Server; and try commenting it out or just deleting it. If you are only setting the new server name in the individual config files, not the global nginx.conf file, also make sure you set both server_tokens off; and more_set_headers "Server: Blah Blah Blah"; inside the reverse proxy block, even if they're already set outside of it.

That not the problem? Run sudo systemctl status nginx to get a better idea of what's going on. Nginx as a rule provides useful error messages so if it doesn't make sense to you, odds are pasting it into Google/DDG will net a solution.

Important note

While this does allow you to fully customise the server name provided by the HTTP header, the Nginx string will still show up in error messages. To fix this just install custom error pages. There's many nicely designed custom ones on GitHub. These are quite comprehensive and minimalist like an error message should be. They're not branded with the name of your server software at all. And as they're simple HTML files they're easy to customise to your own needs too. This can be automated with the template if you have Jekyll installed.

To actually install them on your Nginx server you can follow the basic tutorial here.

Bish bash bosh m8.

@ftpmorph
Copy link

I remember looking this up ages ago and only seeing a page from Nginx saying you needed to buy Nginx Plus to do this. Had no idea it was as easy as installing one package and adding a single line to the configuration. Amazing work cheers and Merry Christmas!

@X448NAX
Copy link
Author

X448NAX commented Dec 25, 2021

I remember looking this up ages ago and only seeing a page from Nginx saying you needed to buy Nginx Plus to do this. Had no idea it was as easy as installing one package and adding a single line to the configuration. Amazing work cheers and Merry Christmas!

I appreciate it.

Truthfully I cannot take credit for much aside from previous experience of Nginx giving me a hunch that it is highly modular and this one feature wouldn't require the full nginx-extra package - turns out I was correct - but the rest is either common knowledge or just cobbled together from either my years of experience with using and troubleshooting Nginx.

Nonetheless thank you for the kind and welcoming words especially since I mostly wrote this up for future reference and in the vague hope someone else may find it helpful at some point in the future. So I am happy it already has proven useful. I will write more gists like this as they come to me or I come along something while conducting a project that I feel is worth writing up, or at least pasting a working config file or short script for, and so on. In the latter case, frequently commented whenever possible and necessary.

As you can probably tell already I have a tendency to blabber on a bit ;)

So I often have to try fight that urge or at least stick a well marked TL;DR section in my posts so everyone doesn't just get bored and click off.

Anywayyyyyy, glad you found this helpful, lots more cool stuff to come in the new year and not just using gists as blog posts... few Python programs in the works, repos go up when the initial releases are ready, generally.

Oh, and a very merry Christmas to you too!

@chaicado
Copy link

@X448NAX Thanks for sharing this. Unfortunately, on debian11, I'm facing the following issue

The following packages have unmet dependencies:
2024-04-15T09:31:42Z:     amazon-ebs.aws:  nginx : Conflicts: nginx-common but 1.18.0-6.1+deb11u3 is to be installed
2024-04-15T09:31:42Z: ==> amazon-ebs.aws: E: Unable to correct problems, you have held broken packages.

I'm trying to install the module as follows:

sudo apt-get -y install nginx nginx-common libnginx-mod-http-headers-more-filter

Full stacktrace

2024-04-15T09:31:42Z:     amazon-ebs.aws: Reading package lists...
2024-04-15T09:31:42Z:     amazon-ebs.aws: Building dependency tree...
2024-04-15T09:31:42Z:     amazon-ebs.aws: Reading state information...
2024-04-15T09:31:42Z:     amazon-ebs.aws: Some packages could not be installed. This may mean that you have
2024-04-15T09:31:42Z:     amazon-ebs.aws: requested an impossible situation or if you are using the unstable
2024-04-15T09:31:42Z:     amazon-ebs.aws: distribution that some required packages have not yet been created
2024-04-15T09:31:42Z:     amazon-ebs.aws: or been moved out of Incoming.
2024-04-15T09:31:42Z:     amazon-ebs.aws: The following information may help to resolve the situation:
2024-04-15T09:31:42Z:     amazon-ebs.aws:
2024-04-15T09:31:42Z:     amazon-ebs.aws: The following packages have unmet dependencies:
2024-04-15T09:31:42Z:     amazon-ebs.aws:  nginx : Conflicts: nginx-common but 1.18.0-6.1+deb11u3 is to be installed
2024-04-15T09:31:42Z: ==> amazon-ebs.aws: E: Unable to correct problems, you have held broken packages.

Happen to know why there's the version mismatch [despite using the latest/default versions for all 3 packages: nginx, nginx-common and *-headers-more-filter ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment