Nginx is not running in the HTTPS - amazon-web-services

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 :)

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 - https://www not 301 redirecting

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;
}

Nginx 2 different domains on one server

I'd like to know how to configure nginx to get 2 domains working on one server (1 ip address).
I want to setup a Keycloak SSO next to a bookstack instance.
My issue is that when I want to access bookstack.domain.com it redirects to keycloak.domain.com.
Here's my /etc/nginx/conf.d/keycloak.conf :
upstream keycloak {
# Use IP Hash for session persistence
ip_hash;
# List of Keycloak servers
server 127.0.0.1:8080;
}
server {
listen 80;
server_name keycloak.domain.com;
# Redirect all HTTP to HTTPS
location / {
return 301 https://\$server_name\$request_uri;
}
}
server {
listen 443 ssl http2;
server_name keycloak.domain.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/certificate_key.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
location / {
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-Proto $scheme;
proxy_pass http://keycloak;
}
}
Here's my /etc/nginx/conf.d/bookstack.conf :
server {
listen 3480;
access_log /var/log/nginx/bookstack_access.log;
error_log /var/log/nginx/bookstack_error.log;
server_name bookstack.domain.com;
root /var/www/bookstack/public;
#
# redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
#
return 301 https://$host$request_uri;
}
server {
listen 5443 ssl http2;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/certificate_key.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AE;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem;
server_name bookstack.domain.com;
#HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/bookstack/public;
access_log /var/log/nginx/bookstack_access.log;
error_log /var/log/nginx/bookstack_error.log;
client_max_body_size 1G;
fastcgi_buffers 64 4K;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README) {
deny all;
}
location ~ \.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/var/run/php-fpm.sock;
}
location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
expires 30d;
access_log off;
}
}
Please let me know :)
This is exactly expected nginx behavior for the given configuration. One of the server blocks always act as default server for any request arriving on some IP/port combination no matter what is the Host HTTP header value. Here is an official documentation on this subject. You can use default_server parameter for the listen directive to explicitly specify server block that should act as the default server or it will be the first server block that listen on those IP/port otherwise. On multihomed servers things can be more complicated, as discussed here.
Now back to the question. You have four server blocks in your configuration: first one listen on TCP port 80 (default port for http:// scheme), second one listen on TCP port 443 (default port for https:// scheme), one listen on port 3480 and the last one listen on port 5443. Since there is only one server block listening each port, each server block will act as default server for any request coming to that port. So if you type http://bookstack.domain.com in your browser address bar, default port 80 for http:// scheme will be used and your request will be redirected to https://keycloak.domain.com. You are using
return 301 https://\$server_name\$request_uri;
for redirection, and the $server_name variable will be always keycloak.domain.com for that server block (read this answer to understand the difference between $host, $http_host and $server_name variables). If you explicitly specify the port and type http://bookstack.domain.com:3480, your request will be served by the third server block thus being redirected to https://bookstack.domain.com (here your are using $host variable which is right). Default TCP port https:// scheme is 443. But the only server block that listen on that port is for keycloak.domain.com! Oops. The only way you can reach your bookstack.domain.com is to type https://bookstack.domain.com:5443 in your browser. And if you correctly understand all the above information, you can type https://keycloak.domain.com:5443 too, it won't made any difference.
Well, I tried to explain what happened here with your nginx configuration. Get rid of non-standard ports as #Evil_skunk recommends you in his answer. Don't forget to clear your browser cache before trying new configuration - permanent HTTP 301 redirects are often cached by the browsers, unlike temporary HTTP 302 redirects.
Your keycloak config seems ok
It listen on port 80 (http) and port 443 (https) and all requests to 80 (http) are redirected to 443 (https)
Your bookstack config looks wrong for me
It does not listen to port 80 or 443 (instead it listen to 5443 and 3480). If you don't have some kind of special port forwarding then I think request to bookstack.domain.com will never reach the nginx-server defined in bookstack.conf and as a result the only matching server will serve the request => keycloak
You should change bookstack.conf's Listen ports:
server {
listen 80;
#... redirect to https
}
server {
listen 443 ssl;
#ssl config, webroot, ...
}

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.

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 ...
}