I don't want anyone to be able to detect that I'm using NGINX or even Ubuntu from the internet. There are tools out there (such as BuiltWith) which scan servers to detect what tools they're using. Also, some cracking tools might help with deteting. What's the best / closest to that I can get to hiding all this info from the outside?
12 Answers
You can stop it outputting the version of Nginx and OS by adding
server_tokens off;
to a http
, server
, or location
context.
Or if you want to remove the Server header completely, you need to compile Nginx with the Headers More module in, as the header is hard coded in the Nginx source, and this module allows changing any http headers.
more_clear_headers Server;
However, there are many hidden ways servers perform by accident via their implementation which may help identify the system. e.g. How it responds to a bad SSL request. I don't see a practical way of preventing this.
Some of the things I might suggest:
- change error templates
- block all ports except the services needed
- 115
- 7
- 3,705
- 1
- 19
- 9
-
18Agreed. Look at nmap's OS detection for instance - this looks at the target hosts's responses to IP/TCP requests and is able to determine the OS that way. It's really not worth putting effort into this. – EEAA Dec 19 '10 at 21:52
-
6+1 on ErikA's advice. Better to secure your server as best as you can rather than relying on security through obscurity. – Andy Smith Dec 19 '10 at 21:54
-
4Server tokens only turn off the version number. Nginx does not allow for completely removing the header. – Martin Fjordvald Dec 20 '10 at 18:46
-
64disregarding important security factors like "no version numbers" and probably even "no server vendor name" entirely is just ... a beginners mistake. **Of course** security through obscurity does nothing for your security itself **but** it sure as hell will at least protect against the most mundane, simplistic attack vectors - security through obscurity is a **necessary** step, it may be the first one and should **never** be the last security measurement -skipping it completely is a _very_ bad mistake, even the most secure webservers can be cracked if a version-specific attack vector is known. – specializt Apr 27 '15 at 14:23
-
7There is a still an annoying server name "Nginx" returned in the body of a 301 redirect response and found no way to avoid that so far, the rule to use a custom html template does not work for 301. – Guillaume Perrot Feb 17 '16 at 03:30
-
This is helpful: https://nmap.org/misc/defeat-nmap-osdetect.html#IPPERSONALITY – hookenz Oct 27 '16 at 20:16
-
1@specializt that is a most excellent comment! – orokusaki Mar 06 '18 at 03:19
-
1No need to re-compile nginx with the "Headers More module", just install the needed package e.g with `apt install libnginx-mod-http-headers-more-filter` – rubo77 May 05 '20 at 08:07
-
Current documentation of "server_tokens" you can find here: https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens – S. Doe Oct 28 '21 at 16:32
If you have installed nginx using apt-get in Debian or Ubuntu, you might need to install the package nginx-extras to set or clear "Server" header
Once this is done, you can add the lines below in nginx.conf (usually /etc/nginx/nginx.conf):
To clear the "Server" header altogether:
more_clear_headers Server;
To Set a custom string as "Server"
more_set_headers 'Server: some-string-here';
- 771
- 6
- 5
-
1Confirmed `more_clear_headers Server;` works as well on Debian Jessie 8.5 nginx version: nginx/1.6.2 – Brandon Jul 21 '16 at 19:54
-
This answer needs more upvotes. Although perhaps it should be noted that the directive needs to be placed inside the http block of the conf file (I think) – Andy Oct 25 '16 at 20:41
-
2This works in `http`, `server`, `location`, and `location if` contexts. Source: [ngx_headers_more documentation](https://github.com/openresty/headers-more-nginx-module#more_clear_headers) – Kelvin Nov 18 '16 at 14:09
-
2For ubuntu users: `sudo apt-get install nginx-extras` and then set the headers – jchnxu Jul 20 '19 at 06:09
-
5For me this failed with `unknown directive "more_set_headers"`. Solved it via enabling the module explicitly in `/etc/nginx/nginx.conf`. Simply add `load_module modules/ngx_http_headers_more_filter_module.so;` at the beginning of the config file. – rapstacke Sep 06 '19 at 09:46
-
14`nginx-extras` installs a lot of extra extras. If you only need to overwrite the Server header then you can also simply only install `sudo apt-get install libnginx-mod-http-headers-more-filter` – rapstacke Sep 06 '19 at 10:21
@Martin F. Yes it does. You will have to compile it from source and change what's needed before compiling the source.
I assume you downloaded the last stable version you decompressed it and you know where the files are. If that's the case, do the following:
nano src/http/ngx_http_header_filter_module.c
Then look for line 48 if I recall correctly.
static char ngx_http_server_string[] = "Server: nginx" CRLF;
Replace nginx with MyWhateverServerNameIWant e.g.
static char ngx_http_server_string[] = "Server: MyWhateverServerNameIWant" CRLF;
Then
nano src/core/nginx.h
look for the line
#define NGINX_VER "nginx/" NGINX_VERSION
change "nginx/" to "MyWhateverServerNameIWant/" so it will read
#define NGINX_VER "MyWhateverServerNameIWant" NGINX_VERSION
Finally if you want also change the version number
look for the line #define NGINX_VERSION "1.0.4"
and change "1.0.4" for whatever version you want. For example it will read
#define NGINX_VERSION "5.5.5"
Hope it helps. Nevertheless. Securing a server goes far beyond not showing what's running. PHP is by nature insecure, and so is linux. Off course linux can be pretty secure if all needed measures are taken in order to achieve a decent security. As far as PHP is concerned I would recommend using Suoshin to help harden the security of your code.
-
5+1, thanks. I'm leaving @Andy's as the official, just due to the easier approach, but this is excellent information. – orokusaki Jun 12 '11 at 02:47
-
1) Install nginx-extras
package alongside nginx
:
apt install nginx-extras
2) Open nginx.conf
and add following lines inside http
block:
more_clear_headers Server;
server_tokens off;
3) Restart nginx
- 103
- 4
- 201
- 2
- 4
After a lot of time working out how to do a custom flavor of nginx on ubuntu I realized you can use the lua module for this.
On ubuntu 14.04 if you install the nginx-extras
package you can remove the server header by using:
header_filter_by_lua 'ngx.header["server"] = nil';
Throw this in the http block and every request will be lacking a Server
header.
If it doesn't work run nginx -V
to verify that you have the lua module compiled into your copy of nginx. If not, there is likely an alternate package you can use to get it.
- 329
- 3
- 4
-
-
1On debian testing this doesn't seem to work BUT installing `nginx-extra` made `more_set_headers "Server: whatever";` work, so +1 :D – Shautieh Sep 15 '16 at 07:07
-
Instead of the header_filter_by_lua it is recommended to use the new directive header_filter_by_lua_block which inlines the Lua source directly between curly braces ({}
). With this it is not needed to escape special characters.
header_filter_by_lua_block {
ngx.header["server"] = nil
}
https://github.com/openresty/lua-nginx-module#header_filter_by_lua_block
- 71
- 1
- 2
Just want to point out that even though the server header is removed from response, the name of the server (nginx or openresty e.g.) is still clearly visible in the html error response that the server sends in case of an error.
Anyone can very easily get this response by e.g. sending a header that is too long. Nginx will return a 400 Bad Request, that does not contain a server header (if fixed), but the html itself will show it:
P.S. I don't know how to get rid of this one as well, really the html itself will give it away, so there should be a way perhaps to not generate these at all?
- 151
- 1
- 2
-
1Use the `error_page` directive for all the errors you want to customize. For instance, `error_page 400 /err/400` will serve whatever's at `/err/400` in place of the default response. – Ivan Vučica Nov 16 '20 at 18:44
First and foremost: Why using an extra module as Headers More Nginx? Only to hide the server header. If a few lines, simple patch can reach the same solution for you.
As using an extra module could result in instability (how well has it been tested with your environment? With your other modules etc.) or insecurity (is this module regularly updated with bug and/or security related fixes?)
Secondly. This thread describes as reply 279389 how you can adjust the Nginx code to change the server header. Problem is that they have forgotten HTTP/2. In short, nothing will change. The server header will still be visible.
Less is more is better. Ok I admit, I have also been looking for a good solution for a long time. But finally found:
Nginx server header removal patch
I am finally redeemed from that annoying Nginx server header.
- 11
- 1
Use below methods in source; to eliminate nginx string from error messages
sed -i 's@"nginx/"@"-/"@g' src/core/nginx.h
sed -i 's@r->headers_out.server == NULL@0@g' src/http/ngx_http_header_filter_module.c
sed -i 's@r->headers_out.server == NULL@0@g' src/http/v2/ngx_http_v2_filter_module.c
sed -i 's@<hr><center>nginx</center>@@g' src/http/ngx_http_special_response.c
then re-compile
- 1
- 1
- 3
Nginx-extra package is deprecated now.
The following therefore did not work for me as I tried installing various packages:
more_set_headers 'Server: My Very Own Server';
You can just do the following and no server or version information will be sent back
server_tokens '';
If you just want to remove the version number this works:
server_tokens off;
-
This appears to be available on _commercial version only_ since 1.9.13 - http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens – Shagglez Nov 18 '20 at 12:27
-
4I can confirm, that empty string (`""` or `''`) is an invalid value for `server_tokens` directive even for (community) nginx version `1.15.7` – helvete Mar 31 '21 at 14:23
-
Based on https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens, only commercial subscription can set empty string disables the emission of the “Server” field – Zesky Jun 30 '22 at 05:52
As mentioned by rapstacke in the comments, nginx-extras
installs a lot extra stuff (surprise). In addition to that, I found out that after installing nginx-extras, nginx would fail to restart after executing systemctl reload nginx
a couple of times.
If you only want to remove the server header, you should install libnginx-mod-http-headers-more-filter:
sudo apt-get install libnginx-mod-http-headers-more-filter
This works for me without any problems on Ubuntu 20.04.
- 266
- 1
- 7
Run this bash function in nginx source code folder. In nginx-$version, not in src/.
Based on this answer.
hidengxver () {
read -r -p "Your own http_server_string for safety: " http_server_string
first_string="static char ngx_http_server_string\[\] = \"Server: nginx\" CRLF;"
second_string="static char ngx_http_server_string\[\] = \"$http_server_string\" CRLF;"
sed -ire "s/$first_string/$second_string/g" src/http/ngx_http_header_filter_module.c
read -r -p "Your own NGINX_VER const: " nginx_ver
third_string="\#define NGINX\_VER \"nginx\/\" NGINX\_VERSION"
forth_string="\#define NGINX\_VER \"$nginx_ver\" NGINX\_VERSION"
sed -ire "s/$third_string/$forth_string/g" src/core/nginx.h
real_nginx_version=$( grep '#define NGINX_VERSION' src/core/nginx.h | gawk -F'"' '{print $2}' )
read -r -p "Your own NGINX_VERSION const: " new_nginx_version
fifth_string="\#define NGINX\_VERSION \"$real_nginx_version\""
sixth_string="\#define NGINX\_VERSION \"$new_nginx_version\""
sed -ire "s/$fifth_string/$sixth_string/g" src/core/nginx.h
}
- 1
- 1