Is there any way to make your nginx proxy not forward HTTP -> HTTPS for a specific URL only? - nginx

I have auto SSL enabled for a VHOST, but I need to disabled that for a specific URL that needs to accept only non SSL requests.
This, put into vhosts, is working fine if the specific old URL was HTTPS, but it is HTTP. I cannot use HTTPS_METHOD=noredirect disabling auto SSL for the entire VHOST. Is it possible just to disable it for the context of this custom nginx location? I can see in the nginx-proxy logs that it gets a 301 before it even hits this nginx customization. So unfortunately I've only been able to get this proxy_pass config to work with HTTPS URLs, not HTTP.
Thanks for your help.
location /specific/old/http/URL {
proxy_pass http://service.new.tld/new;
proxy_set_header host http://service.new.tld;
proxy_ssl_certificate /etc/nginx/certs/new.tld/fullchain.pem;
proxy_ssl_certificate_key /etc/nginx/certs/new.tld/key.pem;
}
location /upstream {
proxy_pass http://service.new.tld;
proxy_ssl_certificate
/etc/nginx/certs/service.new.tld/fullchain.pem;
proxy_ssl_certificate_key
/etc/nginx/certs/service.new.tld/key.pem;
}

You need to Have one server directive for both http and https (will listen on 80 and 443) and you need to add the redirect script only on the wanted locations.
See example:
server {
listen 80;
listen 443 ssl;
server_name example.com www.example.com;
ssl on;
ssl_certificate example.crt;
ssl_certificate_key example.key;
location /specific/old/http/URL {
proxy_pass http://service.new.tld/new;
proxy_set_header host http://service.new.tld;
proxy_ssl_certificate /etc/nginx/certs/new.tld/fullchain.pem;
proxy_ssl_certificate_key /etc/nginx/certs/new.tld/key.pem;
}
location /upstream {
# add this condition only on the locations you want to redirect to https
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
proxy_pass http://service.new.tld;
proxy_ssl_certificate /etc/nginx/certs/service.new.tld/fullchain.pem;
proxy_ssl_certificate_key /etc/nginx/certs/service.new.tld/key.pem;
}

Related

Nginx reverse proxy to an https address behind corporate proxy

I am trying to setup an Nginx reverse proxy to an AWS API Gateway address like https://12345.execute-api.eu-central-1.amazonaws.com/v2 behind a corporate proxy.
I tried the following setup to www.example.com and it works. But as soon as I add https to it like https://www.example.com it fails. I add https since my API Gateway address is not accessible without it.
Current working config:
server {
listen 80;
listen [::]:80;
listen 443;
underscores_in_headers on;
location / {
proxy_pass_request_headers on;
proxy_set_header Host www.example.com;
proxy_pass http://myCorporateProxy.org:8080;
}
}
What I want to achieve and error I get:
Redirect all incoming traffic to localhost to be redirected to API Gateway address which looks similar to https://123456.execute-api.region.amazonaws.com/v2/
When trying following config, I get a 302 temporarily Moved error.
In configuration it would look like this:
server {
listen 80;
listen [::]:80;
listen 443;
underscores_in_headers on;
location / {
proxy_pass_request_headers on;
proxy_set_header Host https://www.example.com;
proxy_pass http://myCorporateProxy.org:8080;
}
}
You should try something like this. To redirect from http to https is a little different.
server {
listen 80;
server_name myCorporateProxy.org www.myCorporateProxy.org;
return 301 https://myCorporateProxy.org$request_uri;
}

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

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

How to replace Nginx default error 400 "The plain HTTP request was sent to HTTPS port" page with Play! Framework backend.

I have a website using Play! framework with multiple domains proxying to the backend, example.com and example.ca.
I have all http requests on port 80 being rewritten to https on port 443. This is all working as expected.
But when I type into the address bar http://example.com:443, I'm served nginx's default error page, which says
400 Bad Request
The plain HTTP request was sent to HTTPS port
nginx
I'd like to serve my own error page for this, but I just can't seem to get it working. Here's a snipped of my configuration.
upstream my-backend {
server 127.0.0.1:9000;
}
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
keepalive_timeout 70;
server_name example.com;
add_header Strict-Transport-Security max-age=15768000; #six months
location / {
proxy_pass http://my-backend;
}
error_page 400 502 error.html;
location = /error.html {
root /usr/share/nginx/html;
}
}
It works when my Play! application is shut down, but when it's running it always serves up the default nginx page.
I've tried adding the error page configuration to another server block like this
server {
listen 443;
ssl off;
server_name example.com;
error_page [..]
}
But that fails with the browser complaining about the certificate being wrong.
I'd really ultimately like to be able to catch and handle any errors which aren't handled by my Play! application with a custom page, or pages. I'd also like this solution to work if the user manually enters the site's IP into the address bar instead of the server name.
Any help is appreciated.
I found the answer to this here https://stackoverflow.com/a/12610382/4023897.
In my particular case, where I want to serve a static error page under these circumstances, my configuration is as follows
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
keepalive_timeout 70;
server_name example.com;
add_header Strict-Transport-Security max-age=15768000; #six months
location = /error.html {
root /usr/share/nginx/html;
autoindex off;
}
location / {
proxy_pass http://my-backend;
}
# If they come here using HTTP, bounce them to the correct scheme
error_page 497 https://$host:$server_port/error.html;
}

Nginx - Stop forcing HTTPS on subdomain

I have a site which is ran with nginx, and with the structure where we have a load balancer, and currently only one web server behind it (currently no real traffic so one web server only).
Anyways, in load balancer nginx config, we forced HTTPS on each request:
server {
listen 80;
server_name www.xyz.com xyz.com
return 301 https://www.xyz.com$request_uri;
}
This works fine, but now I want to say "on this subdomain - dev.xyz.com, allow HTTP too and don't do the forcing".
At first, the server_name param was "any", and thought that might be the problem, so I specifically typed the names as in the above samples, and when I type http://www.dev.xyz.com, I get redirected back to the https://www.xyz.com.
Below server block, we have SSL definitions too:
server {
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/xyz.com.pem;
ssl_certificate_key /etc/nginx/ssl/xyzPrivateKeyNginx.key;
keepalive_timeout 70;
server_name www.xyz.com;
root /usr/local/nginx/html;
client_max_body_size 25M;
client_body_timeout 120s;
# Add trailing slash if missing
rewrite ^([^\.]*[^/])$ $1/ permanent;
}
Thanks! :)
it turned out the solution was simple, I only inserted a simple redirect:
server {
listen 80;
server_name www.dev.xyz.com
location / {
proxy_pass http://xxyyzz;
}
}
Where xxyyzz is:
upstream xxyyzz{
ip_hash;
server 10.100.1.100:80;
}
Thanks anyways!

Resources