nginxnginx-configserver-configuration

Conceal nginx based servers


I am setting up a server running nginx and I need some configuration tips. For example, my goal is to ensure only people accessing the correct subdomain with main domain is given access to my nginx panel. Meaning if someone excludes the sub domain or uses my servers actual ip address I want the request dropped without sending any data back to the user.

So far, I think the following does a nice job however, I am concerned if I specify my actual SSL cert in the default block designed to drop invalid HTTPS traffic then an attacker could inspect the SSL cert and see the domain. This is mainly an issue for scanners that can specify my servers ip address and then try and determine the domain behind it. So, I wonder if I can specify a dummy cert or something any ideas?

My second concern is that when nginx does get pinged it for some reason gets icons like favicons/apple-touch-icon.png and favicons/favicon-32x32.png from my actual servers ip address instead of using the cloud flare reverse proxy. This makes no sense to me unless it's some sort of default config that was hard coded into nginx when I set it up? The last question and least significant question I have is, is there a way to hide details like the fact I am using nginx at all?

# HTTP catch-all server block to drop all connections
server {
    listen 80 default_server;
    server_name _;
    return 444;  # No response for HTTP
}

# Catch-all server block to drop all connections that do not match defined server names
server {
    listen 443 ssl default_server;
    server_name _;

    ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem;  # Needed for SSL to work on 443
    ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem;

    return 444;  # No response
}

 server {
    listen 80;
    server_name examplePanel1.example.net;
    return 301 https://$server_name$request_uri;
}


server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;


 server_name examplePanel1.example.net;

    ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.net/chain.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM->
    ssl_prefer_server_ciphers on;

    # See https://hstspreload.org/ before uncommenting the line below.
    # add_header Strict-Transport-Security "max-age=15768000; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header Content-Security-Policy "frame-ancestors 'self'";
    add_header X-Frame-Options DENY;
    add_header Referrer-Policy same-origin;

Solution

  • So, I wonder if I can specify a dummy cert or something any ideas?

    Sure. For dummy cert you can look at this example, and since nginx 1.19.4 you have an additional option to use ssl_reject_handshake directive, which made the default_server block even more simple:

    server {
        listen 80 default_server;
        listen 443 ssl http2 default_server;
        ssl_reject_handshake on;
        return 444;
    }
    

    You can use the openssl s_client command to check what certificate information is available to possible attacker, e.g.:

    openssl s_client -showcerts -connect <IP>:443
    

    My second concern is that when nginx does get pinged it for some reason gets icons like favicons/apple-touch-icon.png and favicons/favicon-32x32.png from my actual servers ip address instead of using the cloud flare reverse proxy.

    Don't know this, maybe those are some common icon filenames and such requests used to check is there any site hosted at the server at all?

    The last question and least significant question I have is, is there a way to hide details like the fact I am using nginx at all?

    Check the server_tokens directive.