Nginx reverse proxy https to https - ssl

I have a QNAP TS-253A with its admin interface exposed to the internet.
The qnap has it's own certificate installed by a dedicated tool (ie. I don't know exactly where to locate the certificate).
https://mydomain.myqnapcloud.com points to my static IP, and my router has a firewall rule, which forwards port 443 to 192.168.200.6 which is the internal address of my QNAP.
That all works as it should.
Now I have spun up a Docker container on 192.168.200.18, which I would like to expose to https://identity.someotherdomain.com.
My Idea was to spin up another container with an Nginx reverse proxy (192.168.200.8), and change the firewall rule to forward 443 (and 80) to the reverse proxy.
There are lots of guides to use nginx to sit in front of a http server and add SSL certificate thereby converting an existing http site to https. But my use case should be even simpler as the server i forward to, is already https.
I have tried this, which doesn't work:
upstream qnap {
server 192.168.200.6:443;
}
server {
listen 192.168.200.8:443;
server_name mydomainmyqnapcloud.com;
location / {
proxy_pass https://qnap;
}
}
How do I configure nginx to forward traffic intended for https://mydomain.myqnapcloud.com to https://192.168.200.6
and traffic intended for https://identity.someotherdomain.com to https://192.168.200.18

The way I got this working was to locate the certificate and key on the Qnap (in /etc/stunnel) and copy them to a folder shared into the reverse proxy docker image and include them in the nginx.conf:
server {
listen 443 ssl;
server_name mydomain.myqnapcloud.com;
ssl_certificate /etc/ssl/private/backup.cert;
ssl_certificate_key /etc/ssl/private/backup.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
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 https://192.168.200.6;
proxy_read_timeout 90;
proxy_redirect https://192.168.200.6 https://mydomain.myqnapcloud.com;
}
}

Related

Certbot/LetsEncrypt HTTPS for NGINX reverse proxy not working

I've been trying to set up SSL for my websites to no avail. I'm using NGINX on Ubuntu 18.04 as a reverse proxy for two NodeJS Express web servers. I used Certbot following these instructions. However, when trying to access my site via HTTPS, I get a "Site can't be reached"/"Took too long to respond" error.
Here's what my NGINX config in /etc/nginx/sites-available looks like:
server {
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
server_name MYURL.com www.MYURL.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/MYURL.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/MYURL.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
access_log /var/log/nginx/MYURL.access.log;
error_log /var/log/nginx/MYURL.error.log;
client_max_body_size 50M;
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 https://localhost:3001;
}
}
When I replace the listen [::]:443 ssl and listen 443 ssl lines with listen 80; and try to access the site with HTTP, it works fine.
Any idea what the problem might be?
EDIT: Also, I feel I should mention that my UFW status has 22/tcp (LIMIT), OpenSSH (ALLOW), and Nginx Full (ALLOW), as well as their v6 counterparts
It turns out the DigitalOcean firewall was not allowing HTTPS connections. I allowed HTTPS and switched proxy_pass https://localhost:3001; to http:// and everything works now!

My NGINX reverse proxy does not re-route traffic to an external VM

I am having two VM, on hosts Nginx and the other is also a standalone server.
I will call the VMs as follows;
a standalone = Cash serving https
the one hosting the Nginx= LOCAL serving http
In order for LOCAL to communicate with CASH, we use a NGINX reverse proxy proxy to redirect HTTP traffic to HTTPS and handle the TLS handshakes and in case the CASH makes a call to LOCAL the NGINX again accepts this HTTPS traffic and redirecting it to LOCAL's HTTP as shown;
upstream api_http_within_this_vm {
server 127.0.0.1:9001; #LOCAL VM caal it HOST VM application
}
# SENDING HTTP TRAFFIC TO OUR HTTPS ENDPOINT Call CASH
server {
listen 80;
listen [::]:80;
server_name 10.0.0.13;
location / {
proxy_pass https:// api_https_to_another_vm;
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_ssl_certificate /etc/nginx/sites-available/signed_by_CASH.pem;
proxy_ssl_certificate_key /etc/nginx/sites-available/local_key_used_to_generate_csr_for_CASH_to_sign.key;
proxy_ssl_protocols TLSv1.2;
proxy_ssl_ciphers HIGH:!aNULL:!MD5;
proxy_ssl_trusted_certificate /etc/nginx/sites-available/CASH_CA.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on;
}
}
upstream api_https_to_another_vm {
server 10.0.0.13:8080; # CASH's VM IP and PORT
}
# RECIEVING HTTPS TRAFFIC ENDPOINT from CASH TO OUR LOCAL HTTP ENDPOINT
server {
listen 5555 ssl http2;
listen [::]:5555 ssl http2;
server_name 1270.0.0.1;
location / {
proxy_pass http://api_http_within_this_vm;
proxy_set_header X_CUSTOM_HEADER $http_x_custom_header;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_request_headers on;
}
ssl_certificate /etc/nginx/sites-available/signed_by_CASH.pem;
ssl_certificate_key /etc/nginx/sites-available/local_key_used_to_generate_csr_for_CASH_to_sign.key;
ssl_verify_client off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
}
MY SUCCESS
The traffic from CASH to LOCAL work well.
MY CHALLENGE
The traffic from LOCAL to CASH does NOT work. I get 502 Bad Request yet when I use curl https://10.0.0.13:8080/ directly without Reverse proxyLOCAL to CASH I see some output even if no handshake happens.
Anywhere am going wrong, please advise.....
Secondly, does Nginx only redirect traffic to IPs within the VM or even to other VMs?
I majorly want to achieve this kind of leg that has failed on my side.
I have tested this configuration over time, I had to trace with a tcpdump and even checked my logs because I suspected the problem is network driven. I found out the actually the client CASH was dropping the connection before the TLS handshake completes.
2019/03/02 06:54:58 [error] 27569#27569: *62 peer closed connection in SSL handshake (104: Connection reset by peer) while SSL handshaking to upstream, client: xx.xx.xx.xx, server: 1270.0.0.1, request: "GET / HTTP/1.1", upstream: "https://xx.xx.xx.xx:1000/", host: "xx.xx.xx.xx:80"
Thanks to all that viewed, but the script is correct.

Nginx reverse proxy apache on centos 7, configuring both http and https

I am configuring nginx at port 80 as proxy server to Apache server on port 8080, using Centos 7.
I successfully configure both for http, but after installing lets encrypt certificate for Apache, I see Apache is directly receiving traffic for https. I tried to make nginx receive traffic for all HTTP and HTTPS, but face issue,
I do a lot of changes like disable apache to listen on port 443, and only listen to 8080.
I configure nginx to listen both at 80 and 443, additionally I remove certificate for apache and add to nginx configuration files. currently.
nginx configuration is as follow:
server {
listen 80;
listen [::]:80 default_server;
#server_name _;
server_name www.example.com;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://my.server.ip.add:8080;
root /usr/share/nginx/html;
proxy_redirect off;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
server {
listen 443 default_server;
server_name www.example.com;
root /usr/share/nginx/html;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.example.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
#ssl_dhparam /etc/pki/nginx/dh2048.pem;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA--REMOVED-SOME-HERE-SHA';
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
Note: I am using php 7.0
currently site is working on both https and http with 1 known issue i.e. User images are not loading. but I am not sure it is served by apache or nginx, in RESPONSE I can see "nginx/1.10.2"
What I was actually going to implement: I was trying to run both
node.js and apache using nginx. I donot start node yet.
My questions:
Is it really beneficial to use nginx in front and apache at the backend? (I read it protect from dDos attacks).
Where should we put certificate at nginx or apache?
How can I add node.js in nginx configuration? I already installed node js.
What can be best configuration of using both nginx and apache?
Good evening,
First of all all the considerations you have made at the infrastructure level are very good and in my opinion the proxy configuration despite the difficulties of implementation at this time is the best.
I've been using it for some time now and the benefits are enormous. However, I would like to ask you what type of cloud infrastructure you are using because there are so many things that change depending on the technical infrastructure. For example, I use only Google Cloud Platform that is completely different from CloudFlare or Other AWS.
The configuration made is too articulated and unclear from the point of view of the structure. You should try this way:First, enter the http context with the upstream domain name directive and inside the server IP address with Apache, and then make declarations for server and location contexts by including the parameters of the proxy_params file and snippet ssl.
If you want and help me understand the infrastructure we adopt, we can see how to make the configuration together but so it is imminent because each infrastructure responds to a different configuration.
It also applies to php7.0. For example, configuring PrestaShop 1.7.1.1 with php7.0 I had to make a lot of changes to the php.ini code of the CMS as I did not use CGI in FPM but this as I said was very varied.
see https://www.webfoobar.com/node/35

Nginx configure SSL load balancer

I have a Docker Server where I have installed GitLab from sameersbn/docker-gitlab
I have a nginx container that listen to 443:433 and 80:80, I will use this one to load balance HTTP and HTTPs (with signed cert) requests
nginx.conf
worker_processes auto;
events { worker_connections 1024; }
http {
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
upstream gitlab {
server gitlab:10080;
}
server {
listen 80;
listen 443 ssl;
server_name www.domain.tld;
ssl on;
ssl_certificate /usr/local/share/ca-certificates/domain.crt;
ssl_certificate_key /usr/local/share/ca-certificates/domain.key;
ssl_trusted_certificate /usr/local/share/ca-certificates/GandiStandardSSLCA2.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
root /usr/share/nginx/html;
location /git/ {
proxy_pass http://gitlab;
proxy_set_header X-Forwarded-Ssl on;
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;
}
}
Without SSL, working url to acces gitlab is http://www.domain.tld:10080/git
With SSL, I want the url to be https://www.domain.tld/git
Using this nginx load balancer configuration
When I go on http://www.domain.tld/git
400 Bad Request
The plain HTTP request was sent to HTTPS port
When i go on https://www.domain.tld/git
ERR_CONNECTION_REFUSED
These are my first signed certificate, how is this supposed to work ?
To solve the problem there are 2 steps required:
make Nginx redirect HTTP to HTTPS
Make Gitlab to listen port
80 via HTTP
Why to make Gitlab to listen port 80? This technique called SSL offload that prevent redundant HTTPS encryption/decryption to happen between upstream and web-server. It is rarely required and only makes sense in case of different hosts with complex security requirements.
Nginx
server {
listen 80;
server_name www.domain.tld;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name www.domain.tld;
[....]
}
Gitlab
vi ./gitlab/config.yml
gitlab_url: "http://server1.example.com" # http rather than https

Apache handeling SSL requests and passing them through to HAproxy

I am trying to set up as a front end reverse proxy with Haproxy forwarding requests to Apache web servers in the back end. My problem is that I have been unsuccessful in getting it to work with SSL requests using Apache.
I know that Haproxy can not handle SSL requests so I am trying to set up Apache to accept the clients requests on port 443 and forward it to Haproxy which will then pick up and forward the requests to the right Apache back end web server. Has anyone done this successfully? If yes can you provide examples of the Apache and Haproxy config please?
Yes I have please see the configuration here link text
I use nginx, here is an example nginx.conf:
server {
listen 443;
server_name localhost;
ssl on;
ssl_certificate /etc/pki/tls/certs/localhost.crt;
ssl_certificate_key /etc/pki/tls/private/localhost.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_max_temp_file_size 0;
proxy_pass http://127.0.0.1:8000;
break;
}
}
In haproxy.cfg, set:
listen http_proxy 127.0.0.1:8000