Redirecting in nginx results in errors - nginx

Environment: Ubuntu 18.04, nginx, WordPress
WordPress is running fine at https://www.example.org. In addition, the following rule is defined to direct http to https:
server {
if ($host = www.example.org) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.example.org;
return 404; # managed by Certbot
}
With this, a user's request to http://www.example.org automatically gets redirected to https://www.example.org.
Now, I am trying to define a rule such that https://example.org can also be redirected to https://www.example.org.
Here is my new nginx rule:
server {
listen 443 ssl;
server_name example.org;
return 301 https://www.example.org$request_uri;
}
However, this seems results in breaking the whole site. Even https://www.example.org, that was working fine earlier, gives an error that "this site can't be reached."
This is the last error from nginx error.log:
no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: blah, server: 0.0.0.0:443
To recap,
https://www.example.org works fine
http://www.example.org properly gets redirected to https://www.example.com
https://example.org does not work. It should also have been redirected to https://www.example.org
Can someone please tell me what is it that I am doing wrong? Regards.

You haven't specified if you need all URIs to redirect, but here are several options. Make sure you are restarting the nginx service after these changes.
Specific URIs
server {
listen 80;
server_name example.org www.example.org;
return 301 https://example.org$request_uri;
}
All URIs
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}

Related

Configuring Nginx - routing traffic from HTTP to HTTPS and BAD REQUEST error (local host, no domain)

I'm trying to configure my Nginx in a way so that all HTTP requests are redirected to HTTPS. This is a testing environment and I don't have the domain, hence, I'm not sure whether the redirect can function properly. The host part is simply 127.0.0.1. This is the current configuration:
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name _;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
...
I also tried:
removing server_name _;
putting the return 301 in a location block;
adding further ssl settings, such as ssl_session_timeout, ssl_protocols, ssl_prefer_server_ciphers.
ssl on has been removed.
The syntax has been tested, nginx reloaded, the ports have been tested with nmap (both 80 and 443 are open).
When I curl -k (since the certificate is self-signed) 127.0.0.1 I get this message:
301 Moved Permanently
nginx/1.14.0 (Ubuntu)
When I curl -k 127.0.0.1:443 I get this message:
400 The plain HTTP request was sent to HTTPS port 400 Bad Request The
plain HTTP request was sent to HTTPS port nginx/1.14.0 (Ubuntu)
Could someone help me to understand what am I doing wrong? I'd be happy to provide more information. Thank you so much!!
So here is an nginx config that is working for me.
upstream app {
server app:8080;
}
server {
listen 80;
listen [::]:80;
server_name webprojects-dev.co.uk;
return 301 https://webprojects-dev.co.uk$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 http2;
server_name webprojects-dev.co.uk;
include /etc/nginx/common.conf;
include /etc/nginx/ssl.conf;
location / {
proxy_pass http://app;
include /etc/nginx/common_location.conf;
}
}
In this instance nginx is running in a stack of docker containers networked with docker compose but that shouldnt have any bearing on how it works.
The upstream is the app container (and port) for a reverse proxy.
The first server block is forwarding on requests to https. As you can see the main difference between mine and yours is the server_name is the domain name and is also included in the return 301 statement.
The second server block is for https. Again server_name is a domain but other than that the only other difference I can see is I don't have ssl on the line listen [::]:443.
Disclaimer: Not an expert on nginx. I just hacked away till I had a reverse proxy config that works for me and now I just copy and paste it for everything.

Want to https://www.example.org to https://example.org in Nginx

I want to redirect https://www.example.com to https://example.com in Nginx.
I tried to do this using with below code, but I have to redirect multiple domains so can't mention specific "example.com" in the return line. I have around 30 different domains for which this need to be done.
I have gone through many suggested solutions but all are with one domain which doesn't meet my requirement. Like if there are domains (example.com,example.com,xyz.com etc) all need to redirect to https://respectivedomain(non-www)
server {
listen 443 ssl http2;
server_name www.example.com;
# redirects www to non-www. wasn't work for me without this server block
return 301 $scheme://example.com$request_uri;
}
Update:
server {
server_name "www.(.+?\.\w+)" ;
return 301 https://$1$request_uri;
}
I tried the above code but still, there is an error "NET::ERR_CERT_COMMON_NAME_INVALID".
The site is working with below
example.com
http://example.com
https://example.com
but not with adding www to a domain, SSL certificate is issued to non-www domain
You can redirect using configuration below.
Single domain
server {
listen 443 ssl http2;
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
Multiple domains
server {
listen 443 ssl http2;
server_name "~^www\.(.*)$" ;
return 301 $scheme://$1$request_uri;
}
source

why site is not redirecting with nginx

I am trying to redirect the domain example.com to another website example.blogspot.com (which is not hosted in my server).
I had been using htaccess and cpanel, so it was easy to redirect. But why redirect is not working in nginx.
No effects seen with following way in the version nginx/1.15.10 and latest vesta control panel,
Still showing the default page (index.html) generated by vesta control panel. Should I have to change in public_html ? Or restart server ?
I have edited nginx.conf with following code.
method 1
http{
server{
listen 80;
server_name example.com www.example.com;
return 301 https://example.blogspot.com$request_uri;
}
.....
}
method 2
http{
server{
listen [::]:80;
listen 80;
server_name example.com www.example.com;
return 301 https://example.blogspot.com$request_uri;
}
.....
}
method 3
http{
server {
server_name .example.com;
return 301 $scheme://example.blogspot.com;
}
....
}
restarting ngix after save
sudo service nginx restart
sudo systemctl restart nginx
Finally, adding Server Ip address with listen port redirect domain
http{
server{
listen my.server.ip.address:80;
server_name example.com www.example.com;
return 301 https://example.blogspot.com$request_uri;
}
.....
}

Nginx subdomain redirect rule

I have 2 different server, Already added A record entry
I wanted redirect subdomain to different server.
I made changes in nginx configuration, but its still not working.
server {
server_name example.com subdomain.example.com;
return 301 https://www.example.com$request_uri;
}
How about:
server {
listen 80;
# listen [::]:80;
server_name example.com subdomain.example.com;
return 301 https://www.example.com$request_uri;
}
I'm not a nginx expert but usually you have to define the ports you want the server to listen to. Maybe you forgot that.

Nginx server_name & listen matches specified patterns

In this example the domain has been replaced with domain.com
Our main issue:
When i type https://domain.com i don't get redirected to https://www.domain.com, we currently don't have a rule for this what would be the best way to solve this?
According to our nginx configuration we have not specified 443 for https://domain.com but still its accessible, why is that?
We have valid ssl certificates for both domain.com and www.domain.com.
We do not have a wildcard certificate *.domain.com.
Our Configuration:
#All non-matching patterns
server
{
listen 80;
#enabling this will cause things to break.
#2015/12/18 09:21:54 [error] 32165#0: *1661 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: *censored*, server: 0.0.0.0:443
#listen 443 ssl;
#Horrible looking match all pattern.
server_name _ "" domain.com *.domain.com;
return 301 https://www.domain.com$request_uri;
}
#Main site ssl enforced
server
{
listen 443 ssl;
server_name www.domain.com ios.domain.com android.domain.com;
...
}
#Staging / Test site
server
{
listen 443 ssl;
listen 80;
server_name stage.domain.com;
...
}
#Rental cars site ssl enforced
server
{
listen 443 ssl;
server_name hyrbil.domain.com;
...
}
#ios redirect to enforce https
server
{
listen 80;
server_name ios.domain.com;
return 301 https://ios.domain.com$request_uri;
}
#android redirect to enforce https
server
{
listen 80;
server_name android.domain.com;
return 301 https://android.domain.com$request_uri;
}
Bonus question:
Is it possible to match all ssl traffic and do a redirect unless it matches a specific domain, for example make https://xxx.domain.com pass a 301 to https://www.domain.com even tho i don't have a certificate for xxx.domain.com without showing "This page is unsecure, are you sure that you want to proceeed"?
If you have one virtualhost listening on 443, all traffic reaches your IP address will be served by that virtualhost.
Create an SSL virtualhost for domain.com and put a simple redirect in it.
Or create a "catch all/default" SSL virtualhost, and check the HOST header and redirect regarding that, like:
if ($host !~* ^www\.doman\.com$) {
rewrite ^(.*)$ http://www.domain.com$1 permanent;
}
But it will show SSL certificate error on all FQDNs not included in your certificate!

Resources