Nginx proxy while reserving path - nginx

http {
server {
listen 4443 ssl;
server_name {{hostname}};
port_in_redirect off;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
# https://stackoverflow.com/questions/32845674/setup-nginx-not-to-crash-if-host-in-upstream-is-not-found/32846603#32846603
resolver 127.0.0.1 valid=30s;
proxy_pass http://app1:8080;
}
}
server {
listen 4444 ssl;
server_name X.{{hostname}};
port_in_redirect off;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
resolver 127.0.0.1 valid=30s;
proxy_pass http://app1:8080/my/path/;
}
}
}
# http://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html
# https://stackoverflow.com/questions/34741571/nginx-tcp-forwarding-based-on-hostname/40135151#40135151
stream {
upstream app1 {
server 127.0.0.1:4443;
}
server {
listen 0.0.0.0:443;
proxy_connect_timeout 10s;
proxy_timeout 5m;
proxy_pass $target;
ssl_preread on;
}
access_log /var/log/nginx/access.log basic;
error_log /var/log/nginx/error.log error;
}
This is my nginx configuration.
This is part of a docker-compose setup. I proxy requests sent to https://hostname to the app1 container successfully.
Now my goal is to send requests sent to https://X.hostname to the app1 container, however to a different path.
For example:
Client sends request to https://A.hostname
Nginx forwards it to https://app1/my/path/
However the path is not being preserved, it's just forwarding it to https://app1
Tried many different solutions available online, and none worked.

Related

nginx proxy_pass shows different app and crosses out https

When I try to visit app2, this happens:
It works with http://123.456.789.255:8081
It doesn't work with https://app2.example.com, it goes to https://app2.example.com with https crossed out, but shows app1.
Why does this happen?
Here's the nginx configuration.
There are also A records for both subdomains.
events {}
http {
include mime.types;
proxy_connect_timeout 999;
proxy_send_timeout 999;
proxy_read_timeout 999;
send_timeout 999;
# APP 1 =============================================================
server {
listen 80;
server_name app1.example.com;
return 301 https://app1.example.com$request_uri;
}
server {
listen 443 ssl;
server_name app1.example.com;
ssl_certificate /etc/letsencrypt/live/app1.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app1.example.com/privkey.pem;
location / {
proxy_pass 'http://localhost:3000/';
}
}
# APP 2 ============================================================
server {
listen 80;
server_name app2.example.com;
return 301 https://app2.example.com$request_uri;
}
server {
listen 443 ssl;
server_name app2.example.com;
ssl_certificate /etc/letsencrypt/live/app2.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app2.example.com/privkey.pem;
location / {
proxy_pass 'http://127.0.0.1:8081';
}
}
}

Nginx is showing 400 Bad Request No required SSL certificate was sent

I'm trying to establish SSL connection, and I'm getting 400 No required SSL certificate was sent response from the server.
I used this tutorial for it
I tried everything to solve this issue, but it seems that there is something wrong with the Cloudflare certificate because when I disable ssl_verify_client it is working (with security alert).
Here is my nginx configuration:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
ssl_client_certificate /etc/ssl/cloudflare.crt;
ssl_verify_client on;
server_name example.com www.example.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/username/www/exampleproject;
}
location /media/ {
root /home/username/www/exampleproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/username/www/exampleproject/exampleproject.sock;
}
}

Why does nginx proxy_pass to a variable only pass the root url

I'm trying to implement this suggestion to make my nginx service start even if the upstream service isn't there https://sandro-keil.de/blog/let-nginx-start-if-upstream-host-is-unavailable-or-down/
I've removed other locations for simplicity
gitea is the name of the service on the stack i am proxying to
So with this configuration everything works ok
server {
# resolver 127.0.0.11 valid=30s; ## internal docker dns
#listen [::]:3011 default ipv6only=on; ## listen for ipv6
listen 80;
client_header_timeout 120s;
client_body_timeout 120s;
client_max_body_size 200m;
# save logs here
server_name sigyl.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
resolver 127.0.0.11 ipv6=off valid=30s; ## internal docker dns
#listen [::]:3011 default ipv6only=on; ## listen for ipv6
# listen 444
listen 443 ssl;
# this should allow large docs
client_header_timeout 120s;
client_body_timeout 120s;
client_max_body_size 0;
ssl_certificate /etc/letsencrypt/live/sigyl.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sigyl.com/privkey.pem;
# save logs here
#access_log /var/log/nginx/access.log compression;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on;
server_name sigyl.com;
location /git/ {
proxy_pass http://gitea:3000/;
}
}
however if I set a variable like this:
.....
location /git/ {
set $upstream http://gitea:3000/;
proxy_pass $upstream;
}
}
all the requests just return the root url
ie
https://example.com/git/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js
just returns what's at https://example.com/git/
how can I fix this?
Sam's comment here explains the problem
https://serverfault.com/questions/240476/how-to-force-nginx-to-resolve-dns-of-a-dynamic-hostname-everytime-when-doing-p/973311#comment1306507_593003
so I ended up with:
location ~ /git/(.*) {
resolver 127.0.0.11 ipv6=off valid=30s; ## internal docker dns set
$upstream http://gitea:3000/$1$is_args$args;
proxy_pass $upstream;
}

Nginx websockets + SSL not working (net::ERR_CERT_COMMON_NAME_INVALID)

I have a problem with running a websocket server on Nginx. This is my Nginx default.conf:
upstream websocket {
server xx.xx.xx.xx:8080;
}
server {
listen 80;
listen [::]:80;
server_name domain.com *.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name domain.com *.domain.com;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
location /ws {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
I get the following error in chrome:
(index):2 WebSocket connection to 'wss://xx.xx.xx.xx/ws:8080' failed: Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID
I think it has something to do with certificates (SSL) but I really have no idea to fix this!
Thanks in advance!
Edit:
My index.php file is
<script>
var conn = new WebSocket('wss://xx.xx.xx.xx/ws');
conn.onopen = function(e) {
console.log("Connection established!");
};
</script>
When I change xx.xx.xx.xx to domain.com I get a handshake error code 504.
Btw I'm running a websocket server via php (php server.php) with ratchet following this example: http://socketo.me/docs/hello-world
Configure SSL for upstream - Nginx
Prerequisites
NGINX Plus R6 and later or the latest NGINX Open Source compiled with the --with-stream and with-stream_ssl_module configuration parameters
A proxied TCP server or an upstream group of TCP servers
SSL certificates and a private key
Sample configuration:
stream {
upstream websocket {
server backend1.example.com:8080;
}
server {
listen 8080 ssl;
proxy_pass websocket;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 4h;
ssl_handshake_timeout 30s;
…
}
}
For more detail please follow this link https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-tcp/
No mention of the port in your supplied code, but you are attempting to make a secure websocket connection directly from the browser to your websocket server, which is running on port 8080. Hence this message:
(index):2 WebSocket connection to 'wss://xx.xx.xx.xx/ws:8080' failed:
Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID
What you should be doing is connecting to Nginx, which is listening on port 443 and then let Nginx proxy the request. There must be some code on your page somewhere which is specifying port 8080.
Get rid of it.

Nginx Webdav, client certificate

I am trying to create my private webdav server using nginx.
I set up the server to require a client certificate.
When visiting the site with the browser, the client certificate is requested.
However when I added a windows network location pointing to my server, it worked out of the box. It did not forward me to do anything, it just connected.
Obviously I do not want unverified access to my webdav.
What went wrong and how do I set this up correctly?
My config:
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl on;
server_name XXX;
ssl_certificate /etc/letsencrypt/live/XXX/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/XXX/privkey.pem;
ssl_client_certificate /etc/nginx/ca/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
access_log /var/log/nginx/XXX.access;
error_log /var/log/nginx/XXX.error;
location /data {
#Webdav
alias /media/webdav;
autoindex on;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
dav_access user:rw group:r all:r;
client_body_temp_path /tmp/nginx/client-bodies;
client_max_body_size 0;
create_full_put_path on;
}
location / {
return 404;
}
}

Resources