Nginx - https://www not 301 redirecting - amazon-web-services

I am moving to a new domain and have set up 301 redirects on my ec2 instance.
Currently I have the following:
server {
listen 80;
server_name olddomain.co.uk;
return 301 $scheme://www.newdomain.com$request_uri;
}
this works fine for www.olddomain.co.uk and olddomain.co.uk. However it does not work for https://www.olddomain.co.uk
I am wondering how I can make it so the redirect also works with https://www...
Thanks

Your server isn't listening to https:// i.e. 443 port. Connection to https://www.olddomain.co.uk would simply be refused. Add proper ssl configurations to your nginx file and it should be fine.
server {
listen 80;
listen 443 ssl;
server_name olddomain.co.uk;
return 301 $scheme://www.newdomain.com$request_uri;
}

server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}

Related

AWS Amplify redirect change from post to get?

I'm trying to connect to my backend api, usually anything that is /intApi/<*> gets sends over to different api.domain.com. but for some reason the request changes from post to get.
+
I'm using nginx to do
listen 80;
listen [::]:80;
server_name api.domain.com www.api.domain.com;
location / {
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 http2 ssl;
server_name api.domain.com www.api.domain.com;
ssl_certificate /etc/nginx/ssl/live/api.domain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/api.domain.com/privkey.pem;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://backendDocker:3500/;
}
location ~ /.well-known/acme-challenge/ {
root /usr/share/nginx/web/api;
}
}
To push it further and nginx output is either OPTIONS or GET instead of POST.
What am I doing wrong here? I tried 301/302 redirects. Same issue :/

Nginx is not running in the HTTPS

I installed Nginx in the Amazon Linux machine and using the config file:
http {
upstream allbackend {
#round robin private IP
server 172.31.xx.xxx:8080;
server 172.31.xx.xx:8080;
}
server {
listen 80;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/xxx.ddns.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.ddns.net/privkey.pem;
ssl_protocols TLSv1.3;
location / {
proxy_pass http://allbackend/;
}
}
}
events { }
However, the site xxx.ddns.net only works in the HTTP and not in the HTTPS. The security groups are defined:
The cURL returns this to me:
curl https://xxx.ddns.net/
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to xxx.ddns.net:443
What's the issue here?
You need one server-block for port 80 (HTTP) and one for port 443 (HTTPS). The server-block for port 80 just redirects to the server-block for port 443. The whole configuration looks something like this:
server {
listen 80;
server_name xxx.ddns.net www.xxx.ddns.net;
return 301 https://xxx.ddns.net$request_uri;
}
server {
listen 443 ssl http2;
server_name xxx.ddns.net www.xxx.ddns.net;
ssl on;
ssl_certificate /etc/letsencrypt/live/xxx.ddns.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.ddns.net/privkey.pem;
ssl_protocols TLSv1.3;
location / {
proxy_pass http://allbackend:port;
}
}
Hope this helps solving your problem :)

Nginx redirect (non-www to www) not working with Certbot

I have a website running with a Python/Django/uWSGI/Nginx setup. I also use Certbot to enable https on my site. My redirects from non-www to www (e.g. "example.com" to "www.example.com") result in a "Bad Request (400)" message even though I couldn't spot any deviations from the Nginx/Certbot documentation. Here is the relevant part of my sites-available Nginx code:
server {
listen 80;
server_name example.com www.example.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/myname/example;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/activities.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; #managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; #managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
I found a similar StackOverflow answer (Nginx: redirect non-www to www on https) but none of the solutions worked for me. I have SSL certificates for both example.com and www.example.com. I also tried creating a separate 443 ssl server block for example.com based on the comments in that answer but it didn't work either. My sites-available and sites-enabled code is the same.
What am I doing wrong?
It seems that server_name when translated to the $host variable selects the first in the list of server_name. Let me know if that works. I can't quite test this currently.
Try swapping server_name to server_name www.example.com example.com; as well as changing return 301 https://$host$request_uri; to return 301 https://$server_name$request_uri;
server {
server_name www.example.com example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
# SSL CERT STUFF.
server_name example.com;
return 301 https://www.$server_name$request_uri;
}
server {
listen 443 ssl;
# SSL CERT STUFF.
server_name www.example.com;
# LOCATION STUFF
}
This is not an efficient configuration for Nginx request processing. It's messy, your if condition gets evaluated on every request and I don't see where your non www to www is even meant to happen.
I'd split http and https:
server {
listen 80 default_server;
return 301 https://www.example.com$request_uri;
}
Thats all non https traffic taken care of in a single redirect. Now for the https:
server {
listen 443 default_server ssl;
server_name www.example.com;
root # should be outside location blocks ideally
......
}
The default server directive means this server will handle any requests which do not have a matching server configuration. If you don't want that then add example.com after www.example.com, not before it. Any requests ending up here will display the first entry in the client browser bar.
Based on your comments you might need to add a separate block for the other domain to avoid an SSL certificate mismatch. Try this:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate .....;
ssl_certificate_key .....;
return https://www.example.com$request_uri;
}
Although the OP has accept one of the answers as the solution, I just want to point out that it may not be the best practice.
The correct way is to use $host instead of $server_name (as per Mitchell Walls' example) or hardcoded www.exmple.com (as per miknik's example). Both results an extra 443 server directive that is not necessary and messy.
server {
listen 80 default_server;
server_name www.example.com example.com;
root /var/www/html; # define your root directory here
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
# SSL CERT STUFF.
#server_name www.example.com; you don't need to specify again here
# LOCATION STUFF
}
There is a difference between $host and $server_name:
$host contains "in this order of precedence: host name from the request line, or host name from the 'Host' request header field, or the server name matching a request".
$server_name contains the server_name of the virtual host which processed the request, as it was defined in the nginx configuration. If a server contains multiple server_names, only the first one will be present in this variable.

Rewrite to another TLD for all subdomains

I want to achieve the following rewrite with nginx:
example.com -> example.io
*.example.com -> *.example.io
So anything that is related to example.com should be redirected to example.io, while preserving the subdomain if there is one.
You just need a simple server block to listen on example.com and redirect to example.io
http {
map $server_name $redirect_to {
default example.io;
"~*^(.*)\.example.com$" $1.example.io;
}
server {
listen 80;
listen 443 ssl;
server_name example.com *.example.com;
ssl_certificate ...;
ssl_certificate_key ....;
return 302 $scheme://$redirect_to$request_uri;
}

letsencrypt standalone certification not showing up on GET request

I was able to create certifications under the path /etc/letsencrypt/{{mywebdomain}}/ and set under my server where the ssl_cert and ssl_cert_key absolute pathfile locations for my nginx server.
When I run the command sudo nginx -t I receive a successful configuration output and the nginx server is running in the reverse proxy for Django without any problems. But when I access the root of my website on my chrome browser, I'm receiving the "http://website.com" instead of "https://website.com".
Please point me in the right direction if anyone was able to correctly encrypt their domain content with gunicorn-django-nginx configuration.
My website snippet conf:
upstream app_server {
unix:/home/me/Documents/masterdomain/src/portfolio_revamp.sock;
}
server {
client_max_body_size 4M;
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
listen www.mysite.com:80;
server_name example.com www.example.com;
http://example.com;
ssl_certificate
/etc/letsencrypt/live/mysite.com/fullchain.pem;
ssl_certificate_key
/etc/letsencrypt/live/mysite.com/privkey.pem;
root /home/akeem/Documents/SpencerMaster/src;
index templates/home.html templates/main.html;
location / {
proxy_pass
http://unix:/home/me/Documents/masterdomain/src/portfolio_revamp.sock;
alias /home/me/Documents/master/templates/home.html;
}
location ~ /.well-known {
allow all;
}
location /static {
autoindex on;
alias /home/me/Documents/masterdomain/static;
}
location /media {
autoindex on;
alias /home/me/Documents/masterdomain/media;
}
}
I'm running a xenial ubuntu 16.04 server if that makes a difference.
I believe the issue is that you aren't redirecting to HTTPS - unless you specifically enter https://example.com, you'll be directed to the standard http://example.com.
I use this guide from DigitalOcean which recommends two server blocks. In your case it will look something like:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mysite.com www.mysite.com;
return 301 https://$server_name$request_uri;
}
server {
client_max_body_size 4M;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
No server_name required here
... Everything else ...
}