Infinite redirect - nginx - redirect

I seem to be having an issue with an infinite redirect with nginx. This has been driving me crazy for the las half hour or so because I am unable to identify where the infinite redirect is occurring.
vHost:
Server ID : SuperUser Shell : sites-available/ > # cat example.com-ssl
server {
listen 80;
server_name www.example.com example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.example.com$request_uri;
# This is for troubleshooting
access_log /var/log/nginx/www.example.com/access.log;
error_log /var/log/nginx/www.example.com/error.log debug;
}
server {
listen 443 default_server ssl;
server_name www.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/www.example.com/2017/www.example.com.crt;
ssl_certificate_key /etc/ssl/certs/www.example.com/2017/www.example.com.key;
ssl_trusted_certificate /etc/ssl/certs/www.example.com/2017/www.example.com.ca-bundle;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /etc/ssl/certs/www.example.com/2017/dhparam.pem;
add_header Strict-Transport-Security "max-age=63072000; includeSubexamples; ";
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
access_log /var/log/nginx/www.example.com/access.log;
error_log /var/log/nginx/www.example.com/error.log;
}
Server ID : SuperUser Shell : sites-available/ > #
Additional info:
I should also point out that this is a ghost blogging server and that I have updated config.js to reflect https instead of http:
Server ID : SuperUser Shell : ghost/ > # cat config.js
// # Ghost Configuration
// Setup your Ghost install for various [environments](http://support.ghost.org/config/#about-environments).
// Ghost runs in `development` mode by default. Full documentation can be found at http://support.ghost.org/config/
var path = require('path'),
config;
config = {
// ### Production
production: {
url: 'https://www.example.com',
mail: {},
database: {
client: 'sqlite3',
connection: {
filename: path.join(__dirname, '/content/data/ghost.db')
},
debug: false
},
server: {
host: '0.0.0.0',
port: '2368'
}
},
// ### Development **(default)**
development: {
url: 'https://www.example.com',
database: {
client: 'sqlite3',
connection: {
filename: path.join(__dirname, '/content/data/ghost-dev.db')
},
debug: false
},
},
...
Server ID : SuperUser Shell : ghost/ > #
I also restarted this java process using pm2 (What I use to keep ghost running). I even went as far as stopping the process and starting it again
cURL output:
... Same thing as below for 49 times
* Ignoring the response-body
* Connection #0 to host www.example.com left intact
* Issue another request to this URL: 'https://www.example.com/'
* Found bundle for host www.example.com: 0x263b920
* Re-using existing connection! (#0) with host www.example.com
* Connected to www.example.com (123.45.67.89) port 443 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: www.example.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
* Server nginx/1.4.6 (Ubuntu) is not blacklisted
< Server: nginx/1.4.6 (Ubuntu)
< Date: Sat, 26 Nov 2016 08:56:23 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 63
< Connection: keep-alive
< X-Powered-By: Express
< Location: https://www.example.com/
< Vary: Accept, Accept-Encoding
< Strict-Transport-Security: max-age=63072000; includeSubdomains;
<
* Ignoring the response-body
* Connection #0 to host www.bestredflags.com left intact
* Maximum (50) redirects followed
Questions:
Does anyone see where I am making my mistake?
I copied my nginx configuration from my RHEL 7.3 server running nginx version: nginx/1.10.2 (where there are no issues) to my Ubuntu 14.04 running nginx version: nginx/1.4.6 (Ubuntu) could this be part of my problem?
I did not receive an error from nginx -t before pushing the vHost config change.
This leads me to think that there is not an issue with my vHost but a vHost misconfiguration also seems to be the logical choice.
Something that I was wondering about earlier is that this seems quite a bit longer in nginx than redirecting null to www to https://www is in apache. Am I doing this right for nginx?
I am following documentation put forth here:
https://www.digitalocean.com/community/tutorials/how-to-create-temporary-and-permanent-redirects-with-apache-and-nginx
I hope that this is not too much information. I definitely don't want to give too little information.
Thanks for any help / pointers.

This is super embarrassing but I found out when comparing configs that my production server that ghost does not need to have https specified in config.js. This caused my first infinite redirect loop.
PROD : SuperUser Shell : ghost/ > # grep sitename config.js
url: 'http://www.sitename.com',
url: 'http://www.sitename.com',
PROD : SuperUser Shell : ghost/ > #
Secondly I received another redirect loop from CloudFlare when re-enabling DNS Protection
To correct this issue go to the Overview tab > Settings Summary > Click on SSL and change SSL from "Flexible " to "Full (Strict)".

Related

Nginx ssl redirection and certbot

I have a test server with docker compose + nginx + certbot (get certificates from let's encript).
Nginx config:
server {
listen [::]:80;
listen 80;
server_name testdomain.com www.testdomain.com;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/certbot;
}
server_tokens off;
# redirect http to https www
return 301 https://www.testdomain.com$request_uri;
}
#other server configs
certbot says in logs:
Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
Domain: testdomain.com
Type: connection
Detail: Fetching http://testdomain.com/.well-known/acme-challenge/vXDwOBgMA9DEq2IvxqUxxxxxxxxxx: Connection refused
Domain: www.testdomain.com
Type: connection
Detail: Fetching http://www.testdomain.com/.well-known/acme-challenge/shRZla5V7iFXB6D__xxxxx: Connection refused
Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot. Ensure that the listed domains serve their content from the provided --webroot-path/-w and that files created there can be downloaded from the internet.
I've put a temporary file to the /.well-known/acme-challenge/(http) but it can't be downloaded (if I try to open mydomain.com/index.html - works fine, but redirects to https version).
I think that problem is in the fact, my config tryes to redirect certbot requests to https, too. Do you have any idea how to get /.well-known/acme-challenge/ out of https rules?
I've found solution:
server {
listen [::]:80;
listen 80;
server_name testdomain.com www.testdomain.com;
location ^~ /.well-known/acme-challenge {
allow all;
root /var/www/certbot;
}
location / {
# redirect http to https www
return 301 https://www.testdomain.com$request_uri;
}
server_tokens off;
}
Now everithing is redirecting to https excluding content of this folder /.well-known/acme-challenge

NGINX redirects to http

I am a newbie to NGINX and have been trying to get this problem sorted out.
Here is the NGINX configuration that works pretty well for most of the part, however when a request is placed without the trailing slash at the end, it redirects to http://$host instead of https://$host. It was forwarding with the port earlier, but I turned off port_in_redirect, which disabled showing up the port number in the browser.
Somehow https://domain.com/xyz/abc still gets redirected to http://domain.com/xyz/abc/
My guess is try_files is somehow not retaining the domain name
I am sure there is something wrong in the configuration, but I have no deep insights on whats causing it
Any inputs is highly appreciate
server {
listen 8080;
server_name _;
location /xyz/abc {
alias /var/www/html/;
try_files $uri $uri/ /xyz/abc/index.html;
}
location ~ ^/xyz/foo/(.*) {
return 301 https://$host/xyz/abc/foo/$1;
}
Below is the curl output
curl -I https://domain.com/xyz/abc
HTTP/1.1 301 Moved Permanently
Server: nginx/1.6.3
Date: Thu, 27 Jan 2016 08:18:27 GMT
Content-Type: text/html
Content-Length: 184
Location: http://domain.com/xyz/abc/
Connection: keep-alive

Nginx dropping SSL handshakes with multiple virtual hosts

I have an Nginx server set up on an Ubuntu VPS with multiple hosts (1 IP). Previously, 1 host had certificates set up and NO redirecting (http allowed) and 1 host had certificates and forced HTTPS via 301. Now that I am attempting to force all of my hosts on SSL and force HTTPS, I am seeing that Nginx is dropping handshakes when I have more than 1 vhost with 301 directives. In particular, the error I am seeing is:
[error] 12370#0: *30 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: (removed), server: 0.0.0.0:443
The issue definitely seems to be with my 301's, because if I exclude them I do not have an issue. What's the best way I can force HTTPS and non-www in my server blocks?
All of my vhosts are in /etc/nginx/conf.d, along with ssl.conf (listed below). I can provide nginx.conf if requested, but I didn't see anything that would seem useful in there.
example1.conf
server {
server_name www.example1.com example1.com;
return 301 https://example1.com$request_uri;
}
server {
listen 443;
server_name www.example1.com
return 301 https://example1.com$request_uri;
}
server {
listen 443 ssl;
server_name example1.com;
ssl_certificate /etc/letsencrypt/live/example1.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/example1.com/privkey.pem;
root /var/www/example1.com;
location / {
try_files $uri $uri/ $uri.html =404;
}
access_log /var/log/nginx/example1.com.access.log;
error_log /var/log/nginx/example1.com.error.log;
}
example2.conf
same as example1.conf (except with example2.com instead of example1.com)
ssl.conf
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Perfect Forward Security
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS +RC4 RC4";
# HSTS
add_header Strict-Transport-Security max-age=31536000;
Pointing out other obvious errors is also appreciated.
Solved (at least for now) by removing
server {
listen 443;
server_name www.example1.com
return 301 https://example1.com$request_uri;
}
It seems that since there's no cert specified, this block would get hit for all HTTPS requests and then the connection would get dropped.

502 Bad Gateway when redirecting on nginx

I have a problem with nginx redirection. I work on nginx 1.4.4 and i have two seperate redirects. It should work two ways:
First redirect: Address address1.com redirects to address address2.com ->
Address address2.com redirects to addres2.com:1234 where the application resides.
Second redirect is directly from ddress2.com:
- address2.com redirects to address2.com:1234
Now the problem:
- Redirect from address1.com to address2.com works, but address2.com to address2.com:port doesn't. It ends with 502 Bad Gateway error. Configs and
errors from log are presented below:
Information from error.log:
[error] : *386 connect() failed (111: Connection refused) while connecting to upstream, client: {client ip addr}, server:{server name}, request:
"GET / HTTP/1.1", upstream: "https://127.0.0.1:{port}", host: "{server name}"
Nginx uses many .conf files stored in conf.d location.
address1.conf (This works):
server {
### server port and name ###
listen {ip_addr}:443;
ssl on;
server_name address1.com;
access_log /var/log/nginx/address1.log;
error_log /var/log/nginx/address1-error.log;
ssl_certificate /etc/httpd/ssl/servercert.crt;
ssl_certificate_key /etc/httpd/ssl/private/serverkey.key;
location / {
rewrite ^ $scheme://address2.com redirect;
}}
address2.com conf file (This doesn't):
server {
### server port and name ###
listen {ip_addr}:443;
ssl on;
server_name address2.com;
access_log /var/log/nginx/address2.log;
error_log /var/log/nginx/address2-error.log;
ssl_certificate /etc/httpd/ssl/servercert.crt;
ssl_certificate_key /etc/httpd/ssl/private/serverkey.key;
proxy_read_timeout 180;
location / {
proxy_pass https://127.0.0.1:{port};
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-HTTPS on;
}}
Funny thing is that I have another application working on the scheme addr3.com -> addr3.com:port and redirection works just perfect. The only
difference between address2.conf and address3.conf is port on which applications work. Each address uses https, Port 443 is open on the firewall.
Hope my description is detailed enough, if not just let me know.
I've been struggling with this problem for couple of days and haven't found any tips or solutions suitable for me.
I'd appreciate any help.
The problem might be with SELinux. Check to see if it running with sestatus. Since some forwarding is working for you, this command might be redundant, but others might require it:
sudo setsebool -P httpd_can_network_connect 1
To enable forwaring for specific ports, which might be your problem, run this command:
sudo semanage port -a -t http_port_t -p tcp 8088
Replace 8088 with the port in question.
The command semanage might not be found. How you install it is distro dependent, but you can most likely google for a solution to that.

CloudFront - CNAME doesn't match in nginx

I have a distribution with 2 CNAMES: example.com and www.example.com . My goal is redirect www.example.com to example.com
CloudFront points to a LoadBalancer, which points to a EC2 machine. This EC2 machines serves thought a nginx.
My config is:
server {
listen 80;
server_name default;
access_log /var/log/nginx/default.access.log;
root /xxxx/;
index index.html index.htm;
location /index.html {
add_header "Cache-Control" "public, must-revalidate, proxy-revalidate, max-age=0";
}
}
server {
listen 80;
server_name ~^(www\.)?(?<domain>.+)$;
return 301 https://$domain$request_uri;
}
The problem is that "server_name" receives "XXX-YYY-ZZZ-WWW.ap-northeast-1.elb.amazonaws.com", not the CNAME (so I don't have the information for get the domain).
Any solution?
You might try to enable forwarding of Host header in CloudFront (see details here: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html). Then you should use Host header value in your nginx config to trigger redirect