Nginx choosing wrong server - nginx

I want to handle to handle sub.domain.com and domain.com with different server blocks.
So I created the following config:
server {
listen 443 ssl;
server_name sub.domain.com;
location / {
...
}
}
server {
listen 443 ssl;
server_name domain.com;
location / {
...
}
}
Requests to sub.domain.com get correctly handled tby the first server block. However requests to domain.com also get handled by the first one.
Why?
From what I understand from the docs, requests to domain.com shouldn't be matched by sub.domain.com?

Probably won't apply to all cases but for me I was using a .dev domain (which requires https). I hadn't set up the cert yet and I guess nginx was just using the first https enabled site it could find even though the server_name was not a match.
Once I enabled https using certbot and enabled the 443 redirect it started working.

I had a similar problem and this question was quite high up in the Google results.
In my case I had a development subdomain running http only, and the main domain running https. One of the redirects on the main domain caught the subdomain request and forwarded it to the main site.
The fix was to specify http:// in the web browser or to enable https for the development domain.

Related

Temporarily redirect https domain to http

How can I configure my NGINX conf file to temporarily redirect an https domain to the http version?
I've found ways to redirect http to https, which is more common, but not the other way around. The reason I need to do this is because I'm in the process of setting up an SSL certificate for a website and somehow, some https URLs are being indexed, on which some assets don't load without the certificate. Thank you in advance!
The problem with redirecting https to http is that you still need a certificate for https - so if you want to redirect because you do not have the certificate yet, this will probably not solve anything, because the secure https connection happens before the redirect.
Otherwise redirecting from https to http works the same as the other way round - it could look something like this: (server block in your http config)
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /certificate.pem;
ssl_certificate_key /certificate.key;
return 302 http://$host$request_uri;
}
You just need to adjust the domain name and the certificate paths/filenames.

Trying to prevent direct IP access Nginx SSL

I've been searching for the answer here regarding the following code:
server {
listen 443 ssl;
server_name "host.domain.com";
location / {
proxy_pass http://host.domain.com;
}
ssl_certificate /etc/httpd/ssl/Sample_StarCert.crt;
ssl_certificate_key /etc/httpd/ssl/Sample-NPW.key;
}
This does what it's supposed to do for the most part by reverse-proxying SSL requests to an http server on the same machine for host.domain.com requests (by design).
The problem arises when I try to access the same site https://ipaddress
Now the browser accessing the site in this manner is confronted with a certificate warning. I need that certificate warning to go away under these circumstances and to either get that attempt blocked, or redirected to a FQDN request. Either is fine.
I've been trying to accomplish this with other server blocks, but the problem I keep running into is that SSL server blocks seem to really want to begin presenting the certificate to the browser before processing the request which is strange to me since I thought SNI (which this server is compiled with) is designed to recognize the request before presenting a certificate is necessary? It's very likely I just misunderstand how this all works and would welcome the guidance.
I tried conditional statements with no success as well. Any ideas?
I've often seen this attempt for port 80:
server {
listen 80;
server_name _;
return 444;
}
However, this won't work for SSL and cause your website from not being accessible when requesting through the domain.
I figured out, you can simply check if the http host is the server name in the primary server block for SSL, like so:
server {
listen 443 ssl;
server_name YOUR_DOMAIN;
index index.php index.html;
root /var/www/html/;
# block direct IP access
if ($http_host != $server_name) {
return 444;
}
}
This attempt also works for HTTP, if you prefer some consistency.

Subdomain returns root domain's index page

I am trying to configure wildcard subdomains for my app but whenever I enter the subdomain I receive my root domain's index page. My app is configured through cloudflare and then I have an Nginx server that either serves the static files or pipes the request to a node app.
Within cloudflare I've added two rules in this order
http://*domain.com/*
-always use https
http://*.domain.com
-always use https
Then within nginx I have two server blocks
server
{
listen 80;
server_name www.domain.com domain.com;
//this will redirect user to use https
}
server
{
listen 443;
//this is my root domain's server that should handle all traffic for the root domain
}
then I have a block for the subdomains
server
{
listen 443;
server_name ~[^(www)|0-9A-Z]\.domain.com
//proxies the request to the node app
}
The strange thing is that I am seeing the request being handled by the correct routes within the node app but I am getting the wrong file (the root domain's index page).
I am a bit confused since at first I suspected it might have been cloudflare caching the index page and serving that for all subdomains but then if that were the case why I am able to see the requests reaching my server?

nginx: Redirect request with server having a dynamic ip

I have a nginx server set up behind a router that gets a new ip-adress every day.
Now I want to redirect every user who accesses the site via
http://[IP]/
to
https://[IP]/
this works fine inside the local network, but if I access the site from outside it obviously doesn't.
Here's an extract from my nginx-configuration-file (/etc/nginx/sites-avaliable/ ...)
server_name $hostname;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key
# redirect to HTTPS
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
How can I make server_name change every day, when the public IP changes?
I can't use something like dyndns or noIP.
Is it even possible to change this during runtime without restarting nginx?

How to configure nginx to proxy another service serving http and https on different ports?

Use case:
Using nginx as a frontend for several websites / services running on both 80 and 443 (several virtual hosts).
Having service x running on localhost that serves http:8090 and https:8099
How do I need to configure nginx so people can access using only the name, without specifying the port.
This a fairly normal setup. Configure the hosts served directly on Nginx as normal. Since they need to listen on both 80 and 443, each host entry would have this in it:
server {
listen 80;
listen 443 ssl;
}
The Nginx SSL docs has the full details.
Then proxy traffic for one server{} definition to the backend service:
server {
server_name example.com;
location / { proxy_pass http://127.0.0.1:8090; }
}
You only need one proxy connection to the backend server, either 'http' or 'https'. If the connection between the two servers is secure, you can 'http', even for connections that arrive to nginx over https. This might be appropriate if the service is on the same machine. Otherwise, all the traffic could be proxied through https if the connection between nginx and the backend server needs to be secured.
We use the following with our host:
http {
server {
server_name ~^(www\.)?(?<domain>.+)$;
listen *:80;
location / {
proxy_pass $scheme://<origin>$uri$is_args$args;
include basic-proxy-settings.conf;
}
}
server {
server_name ~^(www\.)?(?<domain>.+)$;
listen *:443 ssl;
location / {
proxy_pass $scheme://<origin>$uri$is_args$args;
include basic-proxy-settings.conf;
}
include ssl-settings.conf;
}
}
This allows our upstream proxy to talk to our origin server over HTTP when a request is made by a client for an insecure resource, and over SSL/HTTPS when a request is made for a secure one. It also allows our origin servers to be in charge of forcing redirects to secure connections, etc.
Next time, why not provide a code sample detailing what you've tried, what has worked, and what hasn't?

Resources