how to disable direct access to a web site by ip address - nginx

I have a website on a VPS.
The issue I am having is that when I enter the IP of the server, it links to the website.
Even when entering mail.domain.com, it does the same thing.
How do I disable that, so a visitor would get a message or be directed to the domain?
I tried disabling the IP and mail a record on cloud flare but it didn't work.
My setup is:
VPS on Linux Debian
Nginx
no control panel just command line
Cloudflare
DNS setup with BIND

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name "";
return 444;
}
You need to specify default_server parameter so that all non available server requests goes to this server block which throws 444 error.
444 : CONNECTION CLOSED WITHOUT RESPONSE
ref: https://httpstatuses.com/444

You can use redirect, nginx config:
server {
listen 80;
server_name IP_ADDRESS;
return 301 http://YOUR.DOMAIN;
}

You can just add a server directive before others.
server {
listen 80;
server_name _;
return 404;
}

You can use redirect, nginx config:
server {
listen 80;`enter code here`
server_name IP_ADDRESS;
return 301 http://YOUR.DOMAIN;
}

you can return any error you find suitable. A list of errors can be found here List_of_HTTP_status_codes
server {
listen x.x.x.x:80;
server_name x.x.x.x;
return 404;
}

You may try to set the server IP address in:
/etc/nginx/conf.d/default.conf
So it looks like this:
server {
listen 80;
server_name localhost IP.OF.VPS.HERE;
Then you can specify the subdomain vhost, like:
server {
listen 80;
server_name subdomain.domain.com;
And the main domain, like:
server {
listen 80;
server_name www.domain.com domain.com;
Then restart Nginx:
/etc/init.d/nginx restart
Each vhost should have its own *.conf file (for better organization), like:
/etc/nginx/conf.d/subdomain.domain.com.conf
/etc/nginx/conf.d/domain.com.conf
/etc/nginx/conf.d/default.conf

Put this at top of your /etc/nginx/conf.d/SERVER_IP_ADDRESS.conf file and comment everything what is below it.
#disabling accesing server by ip address
server {
listen SERVER_IP_ADDRESS:80 default;
server_name _;
return 404;
}
Then restart your Nginx server (on Ubuntu it is done by service nginx restart this command)
Now when you will put your server's ip address to browser url field you will get 404 error.

server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 default_server;
listen [::]:443 default_server;
return 444;
}
Don't bother supporting HTTP/2 or SSL connection for a sink.
It does catch-all without those unnecesities.
For the unsupported, it just refuses such connections.
See https://stackoverflow.com/a/68042877/4510033.

Neither of above helped in my case - IP connection to http works as expected but https was redirecting to alphabetically first https virtual site.
What was working witn nginx below 1.19.4 was to add null certificate to block:
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 default_server;
listen [::]:443 default_server;
ssl_certificate /etc/ssl/null.crt;
ssl_certificate_key /etc/ssl/null.key;
server_name "";
return 444;
}
Certificte can be generated with empty CN so you need no worry about fill it.
openssl req -x509 -newkey rsa:2048 -days 10000 -nodes -subj '/CN=' -keyout null.key -out null.crt
Then http/https returns 444 (ERR_EMPTY_RESPONSE), in different configurations https returns ERR_HTTP2_PROTOCOL_ERROR with your null certificate which is also fine to show there is nothing there.
For nginx 1.19.4 it is simpler.
It introduced ssl_reject_handshake on | off (http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake) you can replace certificates 'stuff' with:
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 default_server;
listen [::]:443 default_server;
ssl_reject_handshake on;
server_name "";
return 444;
}
And now you get http 444 (ERR_EMPTY_RESPONSE) and for https ERR_SSL_UNRECOGNIZED_NAME_ALERT. No null certificates are needed.

if ($http_host != "example.com") {
return 301 https://example.com;
}

Related

Nginx How to prevent processing requests with undefined server names

Nginx is 1.14.1 version
have several virtual hosts and default in the /etc/nging/sites-enabled:
I've tried to configure using this doc: http://nginx.org/en/docs/http/request_processing.html
default
server {
listen 80;
server_name "";
return 444;
}
server {
listen 443 ssl http2 default_server;
server_name _;
ssl_certificate ....
ssl_certificate_key .....
add_header Strict-Transport-Security 'max-age=31536000';
return 444;
}
domain1
server{
listen 80;
server_name domain1;
return 301 https://$server_name;
}
server {
server_name domain1;
listen 443 ssl;
..................
}
but when tried to get access using server IP nginx redirect to domain1. please help what's wrong here. I'd like to deny access by IP to sites and leave only requests with domain name

Nginx configure root domain redirect to subdomain

my current setup of webpage is:
forum.xyz.pl
I need xyz.pl redirect to forum.xyz.pl
current nginx.conf:
nodebb.conf
I am using aws route53, not sure what value should I put there for root domain also.
thanks
pl to forum.xyz.pl you can simply do:
server {
server_name xyz.pl;
rewrite ^ forum.xyz.pl$request_uri? permanent;
}
This should solve your problem, let me know if you have any other problems. I don't really understand the problem with Route 53 since it is just handling the DNS entries.
I'd do it like this
server {
listen 80;
server_name xyz.pl;
return 301 https://forum.xyz.pl/;
}
server {
listen 80;
server_name forum.xyz.pl;
#Force Https
return 301 https://$host$request_uri;
}
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
#listen [::]:80;
#listen 80;
server_name forum.xyz.pl;
##rest of config goes here
}

Privacy error after changing nginx config

We have a website that was previously available under 3 addresses
report.example.com
www.live.example.com
live.example.com
all working with https and http and using letsencrypt certs.
It's been decided that the site will only be available under 1 address - live.example.com
The nginx config is setup as follows
server {
listen 80;
server_name report.example.com www.live.example.com live.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name report.example.com www.live.example.com live.example.com;
...
}
I have changed this to the following:-
server {
listen 80;
listen 443 ssl;
server_name report.example.com www.live.example.com;
return 301 $scheme://live.example.com$request_uri;
}
server {
listen 80;
server_name live.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name live.example.com;
...
}
However when I try and navigate the site with the new config I get
Attackers might be trying to steal your information from www.live.example.com (for example, passwords, messages or credit cards). Learn more
NET::ERR_CERT_COMMON_NAME_INVALID
The certificate is the same, so contains all the correct details.
Turns out that as they're on the same server I had to include the certificate details in the old virtualhost as well as the new one

Ngnix setup for dedicated subdomains

I want Ngnix to handle only a few subdomains and if it is not matching it should return an 404.
The following subdomains should work: domain.com, www.domain.com, api.domain.com and ftp.domain.com.
I use the following config:
server {
listen 80;
listen [::]:80;
server_name *.domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
listen [::]:443 ipv6only=on;
server_name domain.com www.domain.com api.domain.com ftp.domain.com;
.....
}
server {
listen 443 default_server;
server_name _;
return 444;
}
The problem is that the website keeps working on every subdomain like test.domain.com. Of casurse the DNS is setup with an wildcard and I don't want to change that.
With adding the default_server I'm getting ssl errors?
Any suggestions?

Nginx - is it possible to redirect to different https servers based on the servername?

Currently , I am redirecting http request this way :
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name emberhub.me www.emberhub.me test.emberhub.me;
return 301 https://$host$request_uri;
}
# HTTPS server static html
#
server {
listen 443 ssl;
server_name emberhub.me www.emberhub.me;
root html;
index index.html index.htm;
ssl on;
....
location / {
try_files $uri $uri/ =404;
# HTTPS server proxy Node.js app
#
server {
listen 444 ssl;
server_name test.emberhub.me;
ssl on;
...
location / {
proxy_pass http://127.0.0.1:8080;
When user request :
http://emberhub.me or http://www.emberhub.me , he is correctly redirected to https://emberhub.me or https://www.emberhub.me ( on default port 443 )
But when user request:
http://test.emberhub.me , he is redirected ALSO to port 443 and get the static html page, not to the node.js app
If the user request it with the port 444
http://test.emberhub.me:444, then he is correctly proxied to the node.js app...
Is there a way to filter the request based on the server_name and redirect it with the correct SSL port ? or is there another better way to perform these redirections ?
thanks for feedback
UPDATE 1 :
I tried to change the server declaratives , as following, but I still get the same issue ... http://test.emberhub.me , is always redirected to port 443
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name emberhub.me;
return 301 https://$host$request_uri;
}
server {
listen 80;
# listen [::]:80 ipv6only=on;
server_name www.emberhub.me;
return 301 https://$host:443$request_uri;
}
server {
listen 80;
# listen [::]:80 ipv6only=on;
server_name test.emberhub.me;
return 301 https://$host:444$request_uri;
}
UPDATE 2
I updated the default config to
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name test.emberhub.me;
return 301 https://$host:444$request_uri;
}
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name emberhub.me www.emberhub.me;
return 301 https://$host$request_uri;
}
using curl -v everything runs fine ...
$ curl -v http://emberhub.me
* Rebuilt URL to: http://emberhub.me/
...
< Connection: keep-alive
< Location: https://emberhub.me/
...
Connection #0 to host emberhub.me left intact
$ curl -v http://www.emberhub.me
...
< Connection: keep-alive
< Location: https://www.emberhub.me/
Connection #0 to host www.emberhub.me left intact
curl -v http://test.emberhub.me
Rebuilt URL to: http://test.emberhub.me/
...
< Location: https://test.emberhub.me:444/
Connection #0 to host test.emberhub.me left intact
BUT requesting http://test.emberhub.me in the browser display https://test.emberhub.me on port 443 ...
If you need different behavior on that server then make a separate config for it:
server {
listen 80;
server_name test.emberhub.me;
return 301 https://$host:444$request_uri;
}

Resources