http and https redirect on nginx with port 80 closed - http

I have a project and use nginx to reverse proxy the request on the respectively port without having the port open. I also use Lets encrypt for ssl certification and everything works fine.
What I wanted to do was, to close port 80 and leave 443 open. I thought that ,
one more port close = a bit more security.
BUT, now the http to https redirect doesn't work (obviously I guess). Now the link only works if I type the prefix "https://" in front.
So I have two questions,
1) Is there a way to redirect the link to https without opening port 80?
2) How safe can we assume it is to leave port 80 open in order to make the redirection work, if the only app running is this one and only ports 443 and 22 are open?
my configuration file goes like this:
server {
listen 80;
server_name domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name domain.com;
add_header Strict-Transport-Security "max-age=31536000";
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://127.0.0.1:PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

No you can't forward trafffic from one port when it's closed on your server itself.
If possible and you have advanced network management you might be able to redirect traffic from 80 to 443 before it reaches your server.
For instance in Digital Ocean you have the ability under networks to add a loadbalancer and setup a redirect from port 80 to 443. That way you can leave port 80 closed on your server.

Related

NGINX Incorrectly Forwarding Requests to Default Location

I have a React web application that I'm trying to deploy on an AWS EC2 instance and I'm using NGINX. I am trying to set it up so that all http requests get redirected to https. Right now it does appear to be redirecting all http requests to https, but NGINX is forwarding the request to the default path /usr/share/nginx/html/ instead of to the web application that I have running on localhost. I have read dozens of articles and have been trying to figure this out for days. Pointers would be much appreciated. Thanks in advance.
Here is my NGINX server configuration at /etc/nginx/sites-available/default:
server {
listen 80;
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2 default_server;
listen 443 ssl http2 default_server;
ssl on;
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
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1h;
location / {
proxy_pass http://127.0.0.1:3839;
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 https;
}
}
Also, the application is running and accessible at the port specified in my location block. I can reach it on the machine with curl 127.0.0.1:3839 with no problems. I am able to see in /var/log/nginx/error.log that nginx is attempting to serve requests out of the /usr/share/nginx/html/ directory which is how I figured out that is the issue. I just have no idea why it's sending requests there instead of to the port on localhost that I specified in my location block. If I go to the root url for my application I get the "Welcome to NGINX" page. If I go to any subpath under my root url like example.com/login, then I get a 404 and error.log shows that it couldn't find resource /usr/share/nginx/html/login for example. Thanks :)
Update:
Inside of the listen 80 server block I added
location / {
proxy_pass http://127.0.0.1:3839;
}
and now it seems to be working correctly, but I have no idea why I would need to define a location block in the listen 80 server definition if requests in that block are just being redirected to be caught by the other server definition listening on 443. Any idea why this is working now?
I figured out the reason that location block in the http server definition worked. In AWS I accidentally had my load balancer forwarding all requests to port 80 on the EC2 instance. So even though my http server definition was redirecting to the https version of the site, those https requests were still ending up being handled by that same http server definition and since it didn't have a location block at all previously, that was causing it to fail. In the end, I removed the location block from the http server definition and then correctly updated my load balancer to forward https requests to port 443 on the EC2 instance and now everything works as expected.

Nginx ignores return directive

The problem:
I have an application running with Nginx serving as a reverse proxy. I have a ssl certificate to a certain example.com, but I also want my application to respond to example.organization.com (even without a certificate for the domain).
My idea was to set a return directive to return the desired URL and 301 as the status code... The problem is, my directive is not being used by Nginx. The nginx does force a HTTPS connection, but with any URL used and returning 302, so with the example.organization.com the browser does not accept it because of the lack of a ssl certificate. Even when the listen 80 block is disabled the redirect still goes on. Nginx is running inside a Docker container and it's hitting another Docker container (I don't think it is influencing the behavior, but I'm not sure)
What I've tried:
I tried to use the rewrite ^ https://example.com$request_uri permanent instead of the return 301 https://example.com$request_uri.
I also tried this:
server {
listen 443 ssl;
server_name example.com;
if ($host != "example.com") {
return 301 https://example.com;
}
}
But it didn't work.
server configuration:
server {
listen 80;
server_name example.com example.organization.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/conf/cert.crt;
ssl_certificate_key /etc/nginx/conf/cert.key;
location / {
proxy_pass http://container:80/
}
proxy_set_header HOST $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

Enable cloudflare on multiple subdomains when using VPS with nginx?

There is a VPS machine with nginx’om configured on which 10 sites are spinning structure
tester.example.com
api-one.tester.example.com
api-two.tester.example.com
api-3.tester.example.com
api-4.tester.example.com
api-5.tester.example.com
api-6.tester.example.com
central site spinning on a separate hosting
in nginx, I configured the default site tester.example.com to use ssl from the cloudflare service
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name tester.example.com www.tester.example.com;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
ssl on;
ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/private.pem;
ssl_client_certificate /etc/ssl/certs/cloudflare.crt;
ssl_verify_client on;
server_name tester.example.com www.tester.example.com;
root /var/server/site/;
index index.html index.htm index.nginx-debian.html;
location / {
# try_files $uri $uri/ =404;
proxy_pass http://localhost:8880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
without https - using regular ip: Port, opening passes through all services
how can I make api-one.tester.example.com config, etc. so that they also open via ssl?
I tried to change the port in the subdomain config (8443 which supports cloudflare), but does not give the desired result
.....
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
ssl on;
.....
You normally have to setup subdomains separately in Cloudflare DNS settings, unless you use *.wildcard, but I don't think they support that any more.
If you want Cloudflare to route all subdomains on https/ssl, there is an option on Cloudflare dashboard > Crypto > Always use HTTPS. In this case, your domains will redirect to https if they were accessed by plain http. This of course requires that your server is setup to support SSL for the domain (regardless of Cloudflare) OR that you are using "Flexible" under Crypto > SSL settings, which allows Cloudflare to serve your website to the client on https, although the data from your server to Cloudflare is served without SSL.

Qtorrent web GUI behind Nginx reverse proxy not loading login webpage css

Torrent client, qtorrent, has web GUI.
Torrent client on one server with unique ip address.
Nginx reverse proxy setup with unique ip address.
Have setup Nginx reverse proxy to point subdomain address internal ip address with specific port (traffic HTTPS via letsencrypt).
Can load Torrent Client GUI login page, but no page formatting (images provided below).
enter image description here
enter image description here
Can access Torrent Client GUI when on local network, via local ip address:port.
When login details are entered in site (that is accessed via domain address sub.example.com), a blank white web page is loaded and the web address changes to "https://www.sub.example.com/?username=UNameExample&password=PASSWORDExample"
Any advise on where to confirm or check configurations.
Below worked for Nginx Reverse Proxy setup for qtorrent.
Original found solution here.
#
#Code below is for SSL
#
server {
listen 80;
listen [::]:80;
server_name bittorrent.example.com www.bittorrent.example.com;
include snippets/letsencrypt.conf;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name bittorrent.example.com;
ssl_certificate /etc/letsencrypt/live/bittorrent.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bittorrent.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/bittorrent.example.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
return 301 https://www.bittorrent.example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name www.bittorrent.example.com;
ssl_certificate /etc/letsencrypt/live/bittorrent.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bittorrent.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/bittorrent.example.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
location / {
proxy_pass http://192.168.0.10:9091/;
proxy_set_header X-Forwarded-Host $server_name:$server_port;
proxy_hide_header Referer;
proxy_hide_header Origin;
proxy_set_header Referer '';
proxy_set_header Origin '';
add_header X-Frame-Options "SAMEORIGIN";
}
}

Make it so nginx always has site using https

NOTE: example.com is just that. Per the rules of stackoverflow, I'm not using an actual domain.
I've been trying to get it so my nginx server for a single site always uses https.
I have the certificate installed and if I view the site with:
https://www.example.com it works fine.
But by default it goes to http and shows the site as insecure.
Here is the config:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/nodeapp;
index index.html index.htm;
server_name www.example.com example.com;
location / {
proxy_pass https://[IP address here]:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I esentially want everything to point to https://www.example.com
Because your site has both of http and https. (80 port and 443 port).
To activate the only https you have to remove the config for http.
Please remove listen 80 and use listen 443 instead.
If you want to redirect all traffics to https,
you could add redirection config as following.
server{
if ($host = your_domain) {
return 301 https://$host$request_uri;
}
server_name your_domain;
listen 80;
return 404;
}
I've assumed that your config has ssl part in your main config.
For example,
listen 443 ssl;
ssl_certificate /etc/***/fullchain.pem;
ssl_certificate_key /etc/**/privkey.pem; # managed by Certbot
ssl_dhparam /etc/**/ssl-dhparams.pem; # managed by Certbot

Resources