1

I have a nginx reverse proxy that acts as a one to many (single public IP) proxy for three other web servers.

I have all the blocks set up to redirect to each server depending on what URL is provided by the client.

What happens if the client simply puts the reverse proxy's IP address in their browser instead of an URL? How does nginx determine where to send the traffic to?

I just tried it and it seems to send the traffic to the last server that it forwarded traffic to?

How do I drop/deny traffic that does not match one of the three server blocks in my configuration (i.e. traffic that uses an IP instead of URL)?

Update: For my configuration, here is the only conf file in sites-enabled:

######## Server1 ########
server {
        if ($host = server1.domain.com) {
                return 301 https://$host$request_uri;
        }
    listen 80;
    server_name server1.domain.com;
    return 404;

} server { listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/server1.domain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/server1.domain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    server_name server1.domain.com;

    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
            proxy_pass_request_headers on;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass https://192.168.20.2:443;
    }

    location ^~ /wp-login.php {
            satisfy any;
            allow 172.20.5.2;
            deny all;

            proxy_pass https://192.168.20.2:443;
    }

} ######## Server2 ######## server { if ($host = server2.domain.com) { return 301 https://$host$request_uri; }

    listen 80;
    server_name server2.domain.com;
    return 404;

}

server { listen 443 ssl http2; ssl_certificate /etc/letsencrypt/live/server2.domain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/server2.domain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    server_name server2.domain.com;

    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
            proxy_pass_request_headers on;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass https://192.168.20.3:443;
    }

}

######## Server3 ######## server { if ($host = server3.domain.com) { return 301 https://$host$request_uri; }

    listen 80;
    server_name server3.domain.com;
    return 404;

} server { listen 443 ssl http2; ssl_certificate /etc/letsencrypt/live/server3.domain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/server3.domain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    server_name server3.domain.com;

    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
            proxy_pass_request_headers on;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass https://192.168.20.4:443;
    }

}

Nginx reverse proxy IP is 192.168.20.6

So what I am seeing is if I put in just the IP into my browser, NGINX appears to go to the first server block in my conf file, which tracks with this link: https://nginx.org/en/docs/http/request_processing.html

And it does try and load server1 in my case, but since the serving of website content is based upon the URL, it sorta breaks some features of my three web servers.

Looking at that link above, I see that I can employ a block like this at the beginning to block IP only requests?

server {
    listen      80;
    listen      443;
    server_name "";
    return      444;
}

1 Answers1

0

"default_server"

There are times you do not want visitors accessing services via your IP Address and the most effective method, at lease for me, is disabling direct IP access though using Nginx's default_server.

The contents of file /etc/nginx/sites-enabled/default_server.conf are;

listen 192.168.0.100:80 default_server;
listen 192.168.0.100:443 ssl default_server;
server_name ""; ## see update edit below
access_log off;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

return 444;

If you'd prefer to redirect them to your actual site un-comment below.

return 301 https://example.com$request_uri;

}

Reload Nginx and visitors attempting access via IP directly will be refused. ​

Visitors should not be able to go directly to your back end server directly. Nginx should be the only public facing http server.

Hackers will often access your IP directly - they are the bad-guys!

Update Edit

I've just noticed the last line of the conf example above was incorrect. To redirect to a URL you need to include "return 301 https://example.com$request_uri;"

In my answer I failed to include "return 301". Typing error on my part.

In addition, I was wrong in setting "server_name _;". According to Nginx docs the correct method is 'server_name "";'

http://nginx.org/en/docs/http/request_processing.html