What I am trying do is to configure NGINX to forward https requests to corresponding containers (by hostnames) running on the same machine with TLS passthrough so TLS termination will be done at the containers. As right now, I only have bw.domain.com
Here is my nginx config that I try to config:
stream {
map $ssl_preread_server_name $name {
bw.domain.com bw;
}
upstream bw {
server 127.0.0.1:4443;
}
server {
listen 443;
proxy_pass $name;
ssl_preread on;
}
}
Here is the nginx config generated by self-host bitwarden (upstream):
#######################################################################
# WARNING: This file is generated. Do not make changes to this file. #
# They will be overwritten on update. You can manage various settings #
# used in this file from the ./bwdata/config.yml file for your #
# installation. #
#######################################################################
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name bw.domain.com;
return 301 https://bw.domain.com$request_uri;
}
server {
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
server_name bw.domain.com;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_session_timeout 30m;
ssl_session_cache shared:SSL:20m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_protocols TLSv1.2;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
# Enables server-side protection from BEAST attacks
ssl_prefer_server_ciphers on;
# OCSP Stapling ---
# Fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
# Verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/ssl/fullchain.pem;
resolver 1.1.1.1 1.0.0.1 9.9.9.9 149.112.112.112 valid=300s;
include /etc/nginx/security-headers-ssl.conf;
include /etc/nginx/security-headers.conf;
location / {
proxy_pass http://web:5000/;
include /etc/nginx/security-headers-ssl.conf;
include /etc/nginx/security-headers.conf;
add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://haveibeenpwned.com https://www.gravatar.com; child-src 'self' https://*.duosecurity.com https://*.duofederal.com; frame-src 'self' https://*.duosecurity.com https://*.duofederal.com; connect-src 'self' wss://bw.domain.com https://api.pwnedpasswords.com https://2fa.directory; object-src 'self' blob:;";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Robots-Tag "noindex, nofollow";
}
location /alive {
return 200 'alive';
add_header Content-Type text/plain;
}
location = /app-id.json {
proxy_pass http://web:5000/app-id.json;
include /etc/nginx/security-headers-ssl.conf;
include /etc/nginx/security-headers.conf;
proxy_hide_header Content-Type;
add_header Content-Type $fido_content_type;
}
location = /duo-connector.html {
proxy_pass http://web:5000/duo-connector.html;
}
location = /webauthn-connector.html {
proxy_pass http://web:5000/webauthn-connector.html;
}
location = /webauthn-fallback-connector.html {
proxy_pass http://web:5000/webauthn-fallback-connector.html;
}
location = /sso-connector.html {
proxy_pass http://web:5000/sso-connector.html;
}
location /attachments/ {
proxy_pass http://attachments:5000/;
}
location /api/ {
proxy_pass http://api:5000/;
}
location /icons/ {
proxy_pass http://icons:5000/;
}
location /notifications/ {
proxy_pass http://notifications:5000/;
}
location /notifications/hub {
proxy_pass http://notifications:5000/hub;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
location /events/ {
proxy_pass http://events:5000/;
}
location /sso {
proxy_pass http://sso:5000;
include /etc/nginx/security-headers-ssl.conf;
include /etc/nginx/security-headers.conf;
add_header X-Frame-Options SAMEORIGIN;
}
location /identity {
proxy_pass http://identity:5000;
include /etc/nginx/security-headers-ssl.conf;
include /etc/nginx/security-headers.conf;
add_header X-Frame-Options SAMEORIGIN;
}
location /admin {
proxy_pass http://admin:5000;
include /etc/nginx/security-headers-ssl.conf;
include /etc/nginx/security-headers.conf;
add_header X-Frame-Options SAMEORIGIN;
}
}
Right now, it throws this error when I use Firefox:
Secure Connection Failed
An error occurred during a connection to bw.domain.com.
PR_END_OF_FILE_ERROR
Error code: PR_END_OF_FILE_ERROR
Here is the logs of the NGINX
2023/01/07 23:09:37 [error] 28#28: *1 connect() failed (111:
Connection refused) while connecting to upstream, client: 172.16.1.1,
server: 0.0.0.0:443, upstream: "127.0.0.1:4443", bytes from/to
client:0/0, bytes from/to upstream:0/0
Related
This is nginx conf for Kuzzle console:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/ *****;
ssl_certificate_key /etc/nginx/ssl *****
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;
server_name *****
root /home/ubuntu/kuzzle-compose/kuzzle-admin-console/dist/;
index index.html;
location / {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache';
if_modified_since off;
expires off;
etag off;
#try_files $uri $uri/ =404;
try_files $uri$args $uri$args/ /index.html;
}
}
This is Socket connection Nginx Conf which is not establishing the connection:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream kuzzle {
server localhost:7512;
}
server {
listen 443 ssl;
proxy_read_timeout 3600s;
ssl_certificate /etc/nginx/ssl/***;
ssl_certificate_key /etc/nginx/ssl/****;
# error_page 497 https://$host:17512$request_uri;
location / {
proxy_pass http://kuzzle;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
On IP it is connecting and establishing connection over http and in case if socket connection after adding ip and port in Kuzzle Console it doesn't connecting with kuzzle backend.
note: Kuzzle console (nginx conf) is working fine and connection with SSL too.
I currently have a deployed application. https://dostoevsky.rest/
It works well with Nginx and Docker.
However, I want to get a JSON response when I hit the endpoint https://dostoevsky.rest/api/rand with a subdomain.
So, I want the subdomain api.dostoevsky.rest to give the response https://dostoevsky.rest/api/rand would give.
I thought I could configure Nginx with proxy_pass, so I did the following:
server {
server_name api.dostoevsky.rest www.api.dostoevsky.rest;
location / {
default_type application/json;
proxy_pass http://<IP>:80/api/rand/;
}
}
However, when I do curl api.dostoevsky.rest I get this timeout message:
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.21.3</center>
</body>
</html>
Nginx Logs:
*1 upstream timed out (110: Operation timed out) while connecting to upstream, client:
I'm assuming the resource isn't found?
If I do curl https://dostoevsky.rest/api/rand it works fine. So, I think I'm making a mistake with the proxy or how the server is configured. Any help would be appreciated. Sorry if this is a low-quality question; I'm new to using Nginx.
Deployed on a DigitalOcean droplet.
I've also configured the DNS for the IP to point to api.dostoevsky.rest, by the way.
Following is my complete nginx.conf file:
server {
listen 80;
listen [::]:80;
server_name dostoevsky.rest www.dostoevsky.rest;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name dostoevsky.rest www.dostoevsky.rest;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/dostoevsky.rest/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dostoevsky.rest/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
try_files $uri #nodejs;
}
location #nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
server {
server_name api.dostoevsky.rest www.api.dostoevsky.rest;
location / {
default_type application/json;
proxy_pass http://<IP>:80/api/rand/;
}
}
I watn to use Nginx as load balancer for Consul cluster. The Consul cluster is reachable only with TLS.
Here I've tried to reverse proxy a single Consul server to check if the TLS certificates are working
server {
listen 80;
listen [::]:80;
location /consul/ {
resolver 127.0.0.1;
proxy_pass https://core-consul-server-1-dev.company.io:8500;
sub_filter_types text/css application/javascript;
sub_filter_once off;
sub_filter /v1/ /consul_v1/;
proxy_ssl_certificate /etc/nginx/certs/agent.crt;
proxy_ssl_certificate_key /etc/nginx/certs/agent.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 4;
}
}
this configuration working fine and I can call it with
curl http://core-proxy-server-1-dev.company.io/consul/consul_v1/agent/members
Now I've tried to do an upstream like this:
upstream consul {
server core-consul-server-1-dev.company.io:8500;
server core-consul-server-2-dev.company.io:8500;
}
server {
listen 80;
listen [::]:80;
location /consul/ {
resolver 127.0.0.1;
proxy_pass https://consul;
sub_filter_types text/css application/javascript;
sub_filter_once off;
sub_filter /v1/ /consul_v1/;
proxy_ssl_certificate /etc/nginx/certs/agent.crt;
proxy_ssl_certificate_key /etc/nginx/certs/agent.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 4;
}
}
when calling the same curl command as before, I get the following error:
2021/04/20 08:38:59 [debug] 3364#3364: *1 X509_check_host(): no match
2021/04/20 08:38:59 [error] 3364#3364: *1 upstream SSL certificate does not match "consul" while SSL handshaking to upstream, client: 10.10.xx.xxx, server: , request: "GET /consul/consul_v1/agent/members HTTP/1.1", upstream: "https://10.10.yy.yyy:8500/consul/consul_v1/agent/members", host: "core-proxy-server-1-dev.company.io"
Then I've tried like this:
upstream consul_1 {
server core-consul-server-1-dev.company.io:8500;
}
upstream consul_2 {
server core-consul-server-2-dev.company.io:8500;
}
map $http_host $backend {
core-consul-server-1-dev.company.io consul_1;
core-consul-server-2-dev.company.io consul_2;
}
server {
listen 80;
listen [::]:80;
location /consul/ {
resolver 127.0.0.1;
proxy_pass https://$backend;
sub_filter_types text/css application/javascript;
sub_filter_once off;
sub_filter /v1/ /consul_v1/;
proxy_ssl_certificate /etc/nginx/certs/agent.crt;
proxy_ssl_certificate_key /etc/nginx/certs/agent.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 4;
}
}
but also no luck;
2021/04/20 08:45:05 [error] 3588#3588: *1 invalid URL prefix in "https://", client: 10.10.xx.xxx, server: , request: "GET /consul/consul_v1/agent/members HTTP/1.1", host: "core-proxy-server-1-dev.company.io"
any ideas? can someone please help me with one?
I figured it out.
in this variation:
upstream consul {
server core-consul-server-1-dev.company.io:8500;
server core-consul-server-2-dev.company.io:8500;
}
server {
listen 80;
listen [::]:80;
location /consul/ {
resolver 127.0.0.1;
proxy_pass https://consul;
sub_filter_types text/css application/javascript;
sub_filter_once off;
sub_filter /v1/ /consul_v1/;
proxy_ssl_certificate /etc/nginx/certs/agent.crt;
proxy_ssl_certificate_key /etc/nginx/certs/agent.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 4;
}
}
the upstream name consul should also match the alt_names I defined in my certificate. so changing the configuration to the one below did the trick:
upstream core-consul-server-1-dev.company.io{
server core-consul-server-1-dev.company.io:8500;
server core-consul-server-2-dev.company.io:8500;
}
server {
listen 80;
listen [::]:80;
location /consul/ {
resolver 127.0.0.1;
proxy_pass https://core-consul-server-1-dev.company.io;
sub_filter_types text/css application/javascript;
sub_filter_once off;
sub_filter /v1/ /consul_v1/;
proxy_ssl_certificate /etc/nginx/certs/agent.crt;
proxy_ssl_certificate_key /etc/nginx/certs/agent.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 4;
}
}
I should just later add a general name in alt_names so I can reference the stream as
core-consul-server-dev.company.io
Below is my nginx conf, how to remove www. from redirect url.
right now when i am entering url www.platform.iamwoken.com/ its redirecting to https://www.platform.iamwoken.com/ which is wrong
i need to redirect it to https://platform.iamwoken.com/
server_tokens off;
server {
if ($host ~ (platform.iamwoken.com|www.platform.iamwoken.com)) {
return 301 https://platform.iamwoken.com;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name platform.iamwoken.com www.platform.iamwoken.com;
return 301 https://platform.iamwoken.com;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name platform.iamwoken.com www.platform.iamwoken.com;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# Disable SSL
ssl_protocols TLSv1 TLSv1.1;
# Optimise cipher suites
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# Enable HSTS
add_header Strict-Transaport-Security "max-age=31536000" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
# SSL sessions
#ssl_session_cache shared:devplatform.iamwoken.com:40m;
# ssl_session_tickets on;
# Skip buffering for static files
sendfile on;
location /static/ {
access_log off;
add_header Cache-Control public;
add_header Pragma public;
add_header Vary Accept-Encoding;
expires 1m;
root /home/ubuntu/wokencrm;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
how to resolve this issue
use below NGiNX block to redirect www to non-www
server {
server_name www.platform.iamwoken.com;
return 301 $scheme://platform.iamwoken.com$request_uri;
}
Restart the nginx web-server and test the URL in browser. It will work as expected.
I want to configure two reverse proxies with ssl that proxy pass to different applications
https://api.example.com --> http://app:8080
https://pg.example.com --> http://pgadmin:80
Given the following nginx configuration, both sub-domains redirect to the first 443-server config (app). The problem occurs when hitting the 443 port. The redirect from 80 to 433 works fine for both. But when I browse https://pg.example.com it passes to app instead of pgadmin.
server {
listen 80;
listen [::]:80;
server_name api.example.com pg.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.example.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://app:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name pg.example.com;
server_tokens off;
# note that api.example.com certificate has pg.example.com as alias
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_set_header X-Scheme $scheme;
proxy_set_header Host $host;
proxy_pass http://pgadmin:80;
proxy_redirect off;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
}
Feels like the SNI is not working or so..?! But it is enabled in nginx:
nginx -V
nginx version: nginx/1.17.10
built by gcc 9.2.0 (Alpine 9.2.0)
built with OpenSSL 1.1.1d 10 Sep 2019 (running with OpenSSL 1.1.1g 21 Apr 2020)
TLS SNI support enabled
What am I missing to make both reverse proxies work?
Edit:
When I remove the server block for server_name api.example.com; (on 443) then the other (pg.example.com:443) does work as expected. The api.example.com:443 then shows the same pgadmin upstream).
I think the easiest way is to split up the first server block into two server-blocks.
For example:
server {
listen 80;
listen [::]:80;
server_name api.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
and
server {
listen 80;
listen [::]:80;
server_name pg.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
I hope this helps, but I can't guarantee, that this config is working properly with certbot.
Turns out the reason is a misspelled domain for the sever_name of the
pg.example.com:433. Hence, not sever_name would match and nginx would then use the best match - which is the api.example.com:433.
I found out by adding a default (by making them the first in the conf file and both using sever_name _) server config for both 80 and 443 so I could ensure that the specific server configs are only used if the server_name matches. The result was that api.example.com:433 showed the same behavior as before (indicating that it works) while the pg.example.com:433 would show the newly configured default server - so it must be something that prevents the proper match on the server_name in the config. I triple checked the sever_name and finally saw the typo.