Subdomain returns root domain's index page - nginx

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?

Related

Nginx choosing wrong server

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.

Subdomain is unexpectedly resolving despite Nginx not being set up to reverse proxy it

So I have been setting up my home network to host a few websites under a domain (and it's subdomains) using a combination of cloudflare to proxy and provide DDoS protection/HTTPS to the sites, and an Nginx reverse proxy running on my network to allow multiple sites to return from behind the same gateway that the DNS records in cloudflare are pointed at.
For the purposes of this explanation, I will replace my real domain name with [domainNameHere].
The first thing to explain is my DNS setup on cloudflare.
I have 4 CNAME records setup to do the following:
Note that I'm using CNAME records because I do not have a static home IP, therefore I'm using a Dynamic DNS address that resolves to the IP address of my gateway. This same Dynamic DNS address is used in place of an A record as I'm aiming to not need to update A records all the time, and instead just have it resolve via a automatically updating Dynamic DNS record.
[domainNameHere].net - Reverse proxy returns the root site when this domain is requested.
www.[domainNameHere].net - Behaves the same as the above, just there to handle any www requests, the reverse proxy returns the same root site for both wwww and the root domain name.
map.[domainNameHere].net - When this subdomain of [domainNameHere] is called, the reverse proxy instead returns a different site (a map, as you might have guessed).
test.[domainNameHere].net - This is a proxied DNS record setup in cloudflare for future purposes, I do not yet intend for it to actually return a site.
Now, the expected behaviour is that all of these DNS records should currently return a site, expect for test.[domainNameHere].net which shouldn't - I'd expect it to just return a standard ERR_NAME_NOT_RESOLVED like any other DNS record that doesn't actually go anywhere.
Instead though, when test.[domainNameHere].net is used, it returns the root site that [domainNameHere].net and www.[domainNameHere].net resolve to?
Using map, www or the root domain name all return the expected content.
I believe that I have configured something incorrectly in the Nginx settings, below are the two configuration files that are currently in my sites-enabled directory:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.nginx-debian.html;
server_name [domainNameHere].net www.[domainNameHere].net;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
listen [::]:80;
server_name test.[domainNameHere].net;
location / {
proxy_pass http://jake-server:8123;
}
}
Is there anything wrong with my Nginx setup? I thought the behaviour would be that if I haven't setup test.[domainNameHere].net within Nginx, then it wouldn't resolve on the reverse proxy and therefore wouldn't return anything, or would just return the Nginx 404/403 page?
Is it maybe something to do with how the first setup file is setup to point to local files on the proxy, rather than using proxy_pass like is usually done in a reverse proxy?
Or is this not an issue with Nginx, and is an issue with how I've set Cloudflare up?

Allow access from one domain with NGINX

I'm looking for a solution to prevent hot-linking with NGINX for JWPlayer. Say I have a NGINX server configured as a reverse proxy at http://mydomain1.com, I'll get the url http://mydomain1.com/file.mp4 to put on my website hosted on another VPS at http://mydomain2.com. How do I restrict the file so it can be played on http://mydomain2.com only and nowhere else?
I tried allow & deny directives but then I realized this is a HTML5 streaming so the directives will block the stream to users.
On nginx of mydomain1.com. Make sure you have one additional block which listens to default host and deny all traffic. Then in the existing listen block we add a rule to allow only www.mydomain2.com
map $http_referer $not_allowed {
default 0;
"~www.mydomain2.com" 1;
}
server {
listen 80 default_server;
server_name _;
deny all;
}
server {
listen 80;
server_name www.mydomain1.com
location / {
if ($not_allowed)
{
return 404 "Not sure its there";
}
}
}
Because the mp4 url will be put in a HTML5 player, this means the remote address (user's machine) will always communicate directly with the reverse proxy. So that's impossible to restrict the access using other methods except nginx secure link module. With this module I'm now able to restrict the access basing on the user's ip, expiration time, url and a secret word.

Is it possible to host static pages on HTTP and Meteor on HTTPS using nginx w/ a redirect?

I have a site I am working on for someone that involves a static informational site with some custom Meteor app. I would like to have the static site serviced through HTTP with one URL serving as a redirect to HTTPS, where the Meteor app would live.
I have tried several things, with this being the latest attempt for the HTTP-side:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
# Make site accessible from http://localhost/
server_name dev.mysite.com;
location /app {
return 301 https://$http_host$request_uri$is_args$query_string;
}
location / {
root /var/lib/www;
index index.html index.htm;
try_files $uri $uri/ =404;
}
}
The idea here is that the static site is created and generated from the Blocs app, and would include a nav link to /app that would then redirect back to HTTPS. The issue I am running into is that, once the browser (tried Chrome and Firefox) has "seen" the HTTPS site, it will not go back to the non-HTTPS site at all. Any attempt to go to the HTTP site for any URL forces you back to HTTPS. Also, the redirect on /app doesn't seem to work. I am deploying the Meteor app through mupx, if that helps.
Is this setup even possible, and if so, where is my config wrong?
I don't know if you've managed to resolve this yet, but here are a few starting points as far as the NGINX configuration goes.
When you access dev.mysite.com/, it defaults to the / location block and your content gets served. However, when you access dev.mysite.com/app, it's returning over https, so you'll need to configure an additional server block to listen on 443 (or you could use listen ssl) and set the root or proxy_pass in this block to serve your secure content.
For the case of navigating back to non-HTTPS, it might be that the link you're following specifies to use HTTPS, so I would start there. Also, your URL may contain .../app/... in which case it would fall into the /app location block and return HTTPS.
One last comment:
If you have a certificate to secure dev.mysite.com, it might be easier to serve all content over HTTPS. If you don't want to do this, then give your static non-HTTPS site a different subdomain name so that the link can reference this instead and NGINX will be able to deal with it.

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?

Resources