nginx dynamic HTTP/S resolves to https://_ - nginx

I'm trying to let all traffic for my nginx be redirected to HTTPS, independent of server name. So, any other vhost should be redirected to its HTTPS counterpart.
example.com -> https://example.com
test.com -> https://test.com
...
Yet, instead of using the incoming $server_name or $host (tried both), it keeps redirecting to a plain https://_. Is my config incorrect?
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$server_name$request_uri;
}

Okay, rather silly. If you have previously setup any non-working configuration (e.g. one which will result in the faulty redirect), the browser will remember this redirect without asking the server again (as according to HTTP 301 - permanently moved). So, either clear the browser's data or try with a different one.

Related

nginx: 502 bad gateway if /index.html is not in URL

i don't understand what i'm doing wrong so i hope somebody can help :)
When i access http://10.0.0.54/index.html i get the right page but if i try to access http://10.0.0.54 instead of showing the index file it redirects me to https://10.0.0.54 showing error 502 bad gateway.
This is the configuration /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/salvaderi;
index index.html;
server_name _;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html/salvaderi;
}
location / {
root /var/www/html/salvaderi;
index index.html;
}
}
I am running nginx 1.18.0 on ubuntu 22.04
i tried changing parameters inside location /{} but i always get the same result. I also changed the root directory and made sure permission where set right. Searching on for the solution i saw other people having problems about PHP and FastCGI but i am not using it.
Your configuration about to be right.
Possible there is some kind of proxy or load-balancer is placed between you and nginx you configuring since you got redirect to HTTPS whether there is no any redirection instructions in your config and, in the same time, there is no listen 443 ssl in config, but you still got response on HTTPS request.
I'd check next:
Is 10.0.0.54 in fact IP of your server?
Is there any return 301, return 302 or rewrite instructions in your nginx config (the better
way is to dump config with nginx -T command and look over).
Didn't
you previously have configured some redirects that may have been
cached by your web client previously? Try to send GET request with
curl instead of web browser (if browser been used for tests).

How to redirect all https domain from www to non www using nginx config file nginx.conf?

I want to redirect all domain from www to non-www using Nginx config file nginx.conf.
I have tried using the below configuration but it only work for URL start with HTTP but does not work for HTTPS
I have added below server block
server {
server_name "~^(?!www\.).*" ;
return 301 $scheme://$1$request_uri ;
}
Since you didn't specify listening port in the server block you've shown in your question, it will listen on a plain HTTP TCP port 80 by default. You need to specify
listen 443 ssl;
to listen on an HTTPS TCP port 443. However to make the server block workable via the HTTPS protocol, you'd need to specify an SSL certificate/key (at least), and to made a user browser following a redirect returned by nginx, that certificate should be a valid one, issued for the domain name you want to be redirected, or the browser will complain about invalid certificate and won't follow the redirect location.
So if you want to use some kind of universal server block for redirecting every HTTPS request from www to non-www domain, it will be impossible unless you have a certificate that include every domain name you want do redirect (which seems to be impossible to have for a custom non-predefined list of domain names).
Update
Although this isn't a thing I'd do for myself in a production environment, actually there is a way to achieve workable solution using the lua-resty-auto-ssl (see the documentation examples), OpenResty/lua-nginx-module and the following sever block (remember that server names specified by domain prefix have the lowest priority comparing to exact matched server names, e.g. www.example.com, or server names specified by domain suffix, e.g. *.example.com):
init_by_lua_block {
auto_ssl = (require "resty.auto-ssl").new()
auto_ssl:set("allow_domain", function(domain)
return true
end)
auto_ssl:init()
}
map $host $basename {
~^www\.(.+) $1;
default $host;
}
server {
listen 443 ssl;
server_name www.*;
ssl_certificate_by_lua_block {
auto_ssl:ssl_certificate()
}
ssl_certificate /path/to/dummy.crt;
ssl_certificate_key /path/to/dummy.key;
return 301 https://$basename$request_uri;
}
In order for this to work you'd also need the corresponding plain HTTP block to allow ACME challenge(s) to be successfully completed:
server {
listen 80;
server_name www.*;
location / {
return 301 https://$basename$request_uri;
}
location /.well-known/acme-challenge/ {
content_by_lua_block {
auto_ssl:challenge_server()
}
}
}

Redirection to newsite in nginx

We have an nginx 1.20.1 webserver on Ubuntu 16.04 hosting many sites. One site is oldsite.example.com and while we're building a newsite.example.com we wish for users to start using the new URL (newsite.example.com). We already made a DNS change but wanted clarity on the nginx part. New URL has to work with both HTTP/HTTPS and we have separate SSL cert it as well.
Thank you for reading.
oldsite nginx conf:
server {
server_name oldsite.example.com
;
listen 80;
if ($host = oldsite.example.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
add_header Content-Security-Policy upgrade-insecure-requests;
For your question about redirection, a simple 302 will do the trick. It is similar to the 301 redirection you are already using:
return 301 https://$host$request_uri;
And you can return sth. like this, but in your ssl server section:
server {
listen 443 ssl;
server_name newsite.example.com;
return 302 https://oldsite.example.com$request_uri;
...
But I would recommend a proxy_pass, or just copy & paste your old configs into the new one. It will save you a redirection.
And for all of your misunderstandings about the protocol,
There is a server name indicator, or SNI, in plain text, in a TLS request (at least for now). If you know about the Host: header, that is it. You can have multiple HTTPS sites on the same host distinguished by server_name, which is exactly what you do for HTTP sites.
Even for HTTP sites, the Host: header is required (for HTTP/1.1 or higher, but no higher), and the server will look at it. You cannot simply CNAME (or sth. similar) a domain into another without modifying server configuration.
wouldn't the user's browser, when they type newsite.example.com and end up at oldsite.example.com
As I said, there is a server name indicator and the server will look at it, as it will look at Host: header. You can distinguish different sites on the same host by different server names.

Fourth-Level Subdomain Forwarding

I've recently been trying to set up a reverse proxy that would forward certain 4th-level subdomains to particular locations. So, for example, this is what I'm trying to accomplish (configuration in my nginx file):
server {
listen 80;
server_name *.server.domain.com;
rewrite ^ https://$server_name$request_uri;
}
The goal here being that if someone went to, for example, http://item1.server.domain.com, they would be re-routed to https://item1.server.domain.com. However, with this configuration, the URL gets rewritten to https://%2A.server.domain.com.
Is there a way to fix this so that the full domain (item1) gets added correctly to the rewritten URL? Ideally, I wanted it to eventually be able to rewrite any subdomain on server.domain.com directly to https.
Thanks!
The $server_name variable contains the text from the value of the server_name directive. The %2A is a URL encoded representation of the leading *.
Use $host or $http_host to obtain the hostname actually requested by the client. See this document for more.
For example:
server {
listen 80;
server_name *.server.domain.com;
return 301 https://$host$request_uri;
}
Note: Restart nginx and clear the browser cache between each test. Check the configuration using nginx -T.

Catch all non-handled requests with HTTP 200 + static file

I am trying to catch all traffic not caught by a sites-enabled configuration file, and instead of throwing the default 404, to instead throw a 200 with a blank response instead.
So, for example, if my site is https://www.example.com at ip x.x.x.x and somebody maps https://www.bad.com to my ip at x.x.x.x they would simply get a 200 with a blank content.
To accomplish this, I have a file located at /var/www/index.html that is a blank file, and have the following rule set up in {nginxdir}/conf.d/200catchall.conf which is imported in the standard {nginxdir}/nginx.conf file:
# Serve blank page to any requests not intended for one of our servers
server {
listen 443;
server_name _;
location / {
root /var/www
}
}
This works great for rendering the 200 blank screen for a request to https://www.bad.com. However, it tries to traverse the directory when something like https://www.bad.com/cgibin/nofile.php is requested, and ends up throwing an error to error.log and results ultimately in a 404.
I've also attempted to replace the root directive with a try_files /var/www/index.html directive, which seems to give the same result...
Have been pulling my hair out for a while on this - any advice?
To avoid sending any content back, minimal load for your server, return a 204 No Content response instead. See Wikipedia Entry.
server {
listen 80 default_server;
listen 443 ssl default_server;
return 204;
}
An alternative approach to setting up a catch all server is described here.
Simplest catch-all looks like this:
server {
listen 80 default_server;
listen 443 ssl default_server;
return 200;
}

Resources