Temporarily redirect https domain to http - nginx

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.

Related

Is it possible to redirect HTTPS to HTTPS with nginx?

I have the following issue.
I created this danish website flaatinfo.dk that is also accessible by flåtinfo.dk.
The domain manager gave me a certificate for flaatinfo.dk but said that they could not generate one for flåtinfo.dk because it contains a special character.
Is there a way (in nginx setup) that I can redirect all HTTPS requests from flåtinfo.dk to flaatinfo.dk??
HTTP redirects seem to work fine but if I try to redirect HTTPS like this I get cert error in browser:
server {
listen 443 ssl;
server_name flåtinfo.dk www.flåtinfo.dk;
return 301 https://flaatinfo.dk$request_uri;
}
www.flåtinfo.dk is an internationalized domain name (IDN).
According to NGINX documentation for internationalized names:
domain names (IDNs) should be specified using an ASCII (Punycode)
representation in the server_name directive
So you should specify it in NGINX configuration as xn--fltinfo-fxa.dk.
As for why your plain HTTP redirect worked anyway, it's probably because it didn't match any other domain so NGINX had to eventually choose it as default.
I get cert error in browser
Naturally, since you don't have a TLS certificate for your IDN, browsers will issue warnings. You need to get a TLS certificate for IDN to get rid of the warning. Let's Encrypt supports issuing certs for IDNs and is free of charge.

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.

How to use server_name in Nginx under HTTP/2?

I want to use 2 server blocks.
The first is:
server {
listen 443 ssl http2 fastopen=3 reuseport;
server_name a.example.xyz;
include server_safe.conf;
root /home/www/blog/;
}
The second is:
server {
listen 443 ssl http2;
server_name b.example.xyz;
include server_safe.conf;
}
What I want:
I want the server_name to be valid, that is , if I use a c.example.xyz to visit my website, both a.example.xyz,b.example.xyz,c.example.xyz is the same IP , the server should block the c.example.xyz request because it is not in the server_name.
However, if I enter https://c.example.xyz, the Nginx will still receive the request and reponse as a.example.xyz
I know HTTP/2 has no host in its header, it has a :authority instead.
My question is that : How can I reject any other request? I only want to accept the request under(with) the host(:authority) = a(b).example.xyz
The problem is the first Server block is used by default if no other name matches.
Therefore to achieve what you want, you need to create a default block, before the other two, and have it block or redirect, or show an error page.
The downsides of this are:
Unless you have HTTPS certificates that all the domain names (or use a wildcard cert that covers this), then they will get an error when going to https version of your site and use this default config. Though this would happen under your current set up anyway. There is no way AFAIK to send a block message before the HTTPS negotiation happens.
Older clients that don't support SNI (primarily Windows XP) will go to default config, whereas previously they would have gotten through for Server A as it was the default (though not for server B).
The alternative is to write a redirect rule based on the hostname provided. Not 100% sure how to do this on nginx to be honest but if not possible by default then is possible with ModSecurity. Again it will only take effect after the HTTPS negotiation has happened so still leaves you with a potential incorrect cert problem.

ERR_CONNECTION_REFUSED when we use https:// without www

Suppose, https://www.domain.com is my website URL
When I have set redirection from
http://domain.com
or
http://www.domain.com
to
https://www.domain.com
it is working perfect
but when i am opening website with https:// and without www then it is giving
ERR_CONNECTION_REFUSED error.
Any response will be highly appriciable.
This error (Error 102) means Azure is not listening on port 443 or there is a firewall which rejects your connection on the host.
So add Listen directive to your configuration:
Listen 443

How to fix Sinatra redirecting https to http under nginx

I have a Sinatra app running in nginx (using thin as a back-proxy) and I'm using redirect '/<path>' statements in Sinatra. However, when I access the site under https, those redirects send me to http://localhost/<path> rather than to https://localhost/<path> as they should.
Currently, nginx passes control to thin with this command proxy_pass http://thin_cluster, where thin_cluster is
upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; }
How can I fix this?
In order for Sinatra to correctly assemble the url used for redirects, it needs to be able to determine whether the request is using ssl, so that the redirect can be made using http or https as appropriate.
Obviously the actual call to thin isn't using ssl, as this is being handled by the front end web server, and the proxied request is in the clear. We therefore need a way to tell Sinatra that it should treat the request as secure, even though it isn't actually using ssl.
Ultimately the code that determines whether the request should be treated as secure is in the Rack::Request#ssl? and Rack::Request#scheme methods. The scheme methods examines the env hash to see if one of a number of entries are present. One of these is HTTP_X_FORWARDED_PROTO which corresponds to the X-Forwarded-Proto HTTP header. If this is set, then the value is used as the protocol scheme (http or https).
So if we add this HTTP header to the request when it is proxied from nginx to the back end, Sinatra will be able to correctly determine when to redirect to https. In nginx we can add headers to proxied requests with proxy_set_header, and the scheme is available in the $scheme variable.
So adding the line
proxy_set_header X-Forwarded-Proto $scheme;
to the nginx configuration after the proxy_pass line should make it work.
You can force all links to go to https in the nginx layer.
in nginx.conf:
server{
listen 80;
server_name example.com;
rewrite ^(.*) https://$server_name$1 redirect;
}
This is good to have too to assure that your requests are always https

Resources