I'm trying to get websockets (socket.io) to work through 2 proxy_pass and 2 different servers (one is a server loadbalancer, the another one is the actual server). I get an 400 when the socket.io is trying
In this case, I have two servers, 1 domainName :
domainName : dev-socket.domain.com -> cname to lb.domain.com
Server 1 : lb.domain.com
- handling all the certifications
- handling all our {subdomain}.domain.com requests, proxy_pass them to the rightfull servers
- everything works fine, except websockets
Server 2 : dev.domain.com
- host the actual api handling all the websockets
- nginx proxyPass to rightfull :port application
What should work, and doesn't :
dev-socket.domain.com (domainName) -> lb.domain.com (Server1, ssl) -> dev.domain.com (server2) -> nodeJsApp
This is getting an 400.
WHAT WORKS : this works, if I bypass the lb.domain.com and directly do this :
dev-socket.domain.com (domainName) -> dev.domain.com (server2, ssl) -> nodeJsApp
server 1 : lb.domain.com :
map $http_connection $upgrade_requested {
default upgrade;
'' close;
}
server {
listen 80;
listen 443 ssl http2;
server_name dev-socket.domain.com;
access_log /var/log/nginx/dev-socket.domain.com-access.log;
error_log /var/log/nginx/dev-socket.domain.com-error.log error;
client_max_body_size 256M;
ssl_certificate /etc/letsencrypt/live/dev-
socket.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev-
socket.domain.com/privkey.pem;
includeSubDomains; preload";
location /socket/live {
proxy_read_timeout 120;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://91.121.117.17/socket/live;
}
location / {
proxy_pass http://server_dev;
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;
proxy_set_header X-Forwarded-Port 443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location ~ ^/.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
root /usr/share/nginx/html/;
}
}
server 2 : dev.domain.com
map $http_connection $upgrade_requested {
default upgrade;
'' close;
}
server {
listen *:443;
server_name dev-socket.domain.com;
#ssl_certificate /etc/letsencrypt/live/dev-socket.domain.com/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/dev-socket.domain.com/privkey.pem;
#ssl on;
client_max_body_size 5M;
access_log /var/log/nginx/dev-socket.domain.com;
error_log /var/log/nginx/dev-socket.error;
location /socket/live {
proxy_pass http://localhost:3000;
proxy_read_timeout 120;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location / {
proxy_pass http://localhost:3000;
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;
}
}
server {
listen *:80;
server_name dev-socket.domain.com;
if ($http_x_forwarded_proto != "https") {
return 301 https://$server_name$request_uri;
}
access_log /var/log/nginx/dev-socket.domain.com;
error_log /var/log/nginx/dev-socket.error;
location / {
proxy_pass http://localhost:3000;
}
}
the above configuration gets a simple 400 error during the handshake instead of succeeding.
WebSocket connection to 'wss://dev-socket.domain.com/socket/live/?Auth=e02b7a2ab5c158d7f46c18d36f45955bf3769716&sessionId=5a38e191fc6bf8602001b237&EIO=3&transport=websocket&sid=Fu6M2b1I9sh9stLFAANX' failed: Error during WebSocket handshake: Unexpected response code: 400
I can confirm by checking the activty logs of both nginx (server1, server2) that the request is getting to server2. So my guess for the moment is something about a malformed header..
As a said, if I bypass lb.domain.com, and activate ssl on the dev.domain.com direclty, it is working
Related
I run my server app with command: ng serve and get error in browser console:
Firefox cannot connect to the wss://dev.domain.com/ws server.
[webpack-dev-server] Trying to reconnect...
or on chrome:
WebSocket connection to 'wss://dev.domain.com/ws' failed
[webpack-dev-server] Disconnected!
[webpack-dev-server] Trying to reconnect...
My config nginx is:
location ^~ / {
proxy_pass http://localhost:4200;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
}
location ^~ /sockjs-node/ {
proxy_pass http://localhost:4200;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
}
location ^~ /ws/ {
proxy_pass http://localhost:4200;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
}
This should work, but it doesn't. my configuration is wrong?
That works for me for Angular 14 :
location /ng-cli-ws {
proxy_pass http://host-gateway:4200;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
If your app is using /ws, try to remove ending slash, else nginx responds with 301 to /ws/...
I second Vlad's answer, but I would like to elaborate on the solution.
I wanted my Angular application to be able to reload any changes at development time and be able to display them through HTTPS. So the following is what is working fine for me. It includes configuration managed by Certbot; and omits an additional default server block.
upstream frontend {
server 0.0.0.0:4200 fail_timeout=3s max_fails=3;
server 0.0.0.0:80 backup;
}
upstream wsfront {
ip_hash;
server 0.0.0.0:4200;
}
server {
server_name my.domain.net;
location ~ ^/ng-cli-w(s|s/)$ {
proxy_pass http://wsfront;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
proxy_pass http://frontend;
}
listen [::]:443 ssl;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/my.domain.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.domain.net/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
if ($host = my.domain.net) {
return 301 https://$host$request_uri;
}
listen 80 ;
listen [::]:80 ;
server_name my.domain.net;
return 404;
}
I was trying to host flask application in NGINX which uses websockets.
It is working fine with the servers which do not use any proxy servers.
When it is hosted in a server that passes requests to proxy servers, client does not receive any message sent via websocket.
Initially none of the external API calls were working which started working when I added environ variable http_proxy and https_proxy for the service.
But the socket is still not working.
Got error: "no pong received in 3 seconds" in the server when trying to connect to websocket
This is what I get in browser
The following is the nginx configuration.
log_format upstreamlog '$server_name to: $upstream_addr [$request] '
'upstream_response_time $upstream_response_time '
'msec $msec request_time $request_time';
upstream socket_nodes {
ip_hash;
server 127.0.0.1:4000;
server 127.0.0.1:4001;
server 127.0.0.1:4002;
}
server {
listen 80;
listen [::]:80;
access_log /var/log/nginx/access.log upstreamlog;
add_header Strict-Transport-Security max-age=15768000;
location /static/* {
alias /file_path;
}
location / {
include uwsgi_params;
proxy_pass http://socket_nodes;
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_set_header X-Forwarded-Proto $scheme;
add_header Front-End-Https on;
proxy_buffer_size 16k;
proxy_busy_buffers_size 16k;
}
location /socket.io {
proxy_pass http://socket_nodes/socket.io;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering 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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Try changing the socket configuration as below,
location /socket.io {
proxy_pass http://socket_nodes/socket.io;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
I am having multiple apps each listening on different ports and i am trying to configure nginx so i can proxy pass to each of them separately.
I am able to configure the root location of my domain to proxy pass to a bokeh app which is listening on port 5006 using this config:
server {
listen 80 default_server;
listen 443 ssl;
root /var/www/mydomain/html;
index index.html index.htm index.nginx-debian.html;
server_name mydomain www.mydomain;
ssl_certificate /etc/letsencrypt/live/mydomain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5006;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
proxy_buffering off;
}
The above part works. However, when i try to create an additional location so that i can have the location / serving a landing page (from root) and then location /env to proxy to localhost:5006 it shows empty page at mydomain/env. Here is the config i am trying with:
server {
listen 80 default_server;
listen 443 ssl;
root /var/www/mydomain/html;
index index.html index.htm index.nginx-debian.html;
server_name mydomain www.mydomain;
ssl_certificate /etc/letsencrypt/live/mydomain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain/privkey.pem;
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
proxy_buffering off;
}
location /env/ {
rewrite ^/env/(.*)$ /$1 break;
proxy_cache_bypass $http_upgrade
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
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_set_header Host $host:$server_port;
proxy_buffering off;
proxy_pass http://127.0.0.1:5006;
}
}
It would be great if someone could point out on where i am making the mistake.
Thanks.
I've got a pretty basic nginx/nginx.conf but unfortunately I can't get 1 of the servers to match properly, I'm pretty sure it's because they use some text which is exactly the same as another domain
I've tested the regex's on regex101.com and they seem to be matching the way they should be, but nginx is doing something else with them
this is what my whole nginx conf looks like
https://pastebin.com/E3N8awGk
key area:
# lopudesigns
server {
listen 80;
server_name ~^(.*|)(\.|)lopudesigns\.dev$;
keepalive_timeout 70;
location / {
proxy_set_header x-real-IP $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
proxy_set_header host $host;
proxy_pass http://127.0.0.1:7777;
}
}
# lopudesigns example sites
server {
listen 80;
server_name ~^ozledgrowlights\.lopudesigns\.dev$;
keepalive_timeout 70;
location / {
proxy_set_header x-real-IP $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
proxy_set_header host $host;
proxy_pass http://127.0.0.1:1337;
}
}
# ozledgrowlights
server {
listen 80;
server_name ~^(.*|)(\.|)ozledgrowlights\.dev\.au$;
keepalive_timeout 70;
location / {
proxy_set_header x-real-IP $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
proxy_set_header host $host;
proxy_pass http://127.0.0.1:1337;
}
}
# a lopu client
server {
listen 80;
server_name ~^(.*|)(\.|)alopu\.com$;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name ~^(.*|)(\.|)alopu\.com$;
keepalive_timeout 70;
location / {
proxy_set_header x-real-IP $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header host $host;
proxy_pass http://127.0.0.1:8888;
}
ssl_certificate /usr/local/etc/nginx/certs/alopu/server.crt.pem;
ssl_certificate_key /usr/local/etc/nginx/certs/alopu/server.key.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}
ozledgrowlights.dev.au matches correctly
alopu.com matches correctly
but lopudesigns.dev gets proxied to http://127.0.0.1:8888 instead of http://127.0.0.1:7777
which is evident because the url doesn't change, so it doesn't actually get redirected to alopu.com, which means that the alopu.com regex/server block is capturing those http requests, which is pretty weird since the regex
~^(.*|)(\.|)lopudesigns\.dev$; captures lopudesigns.dev perfectly and ~^(.*|)(\.|)alopu\.com$; doesn't capture lopudesigns.dev at all
I should also note that ~^(.*|)(\.|)ozledgrowlights\.dev\.au$; doesn't capture anything at all, so ozledgrowlights.lopudesigns.dev doesn't load anything at all
so I'm a bit confused? :O
Sorry but it was some local issue with the .dev domain, not sure what it was but changing .dev to .ved made it work... odd
I'm having trouble addressing Neo4j via a reverse proxy with NGINX.
The web client works without problems, but I have no idea about the Bolt protocol.
Here's how the web client works:
server {
listen 80;
server_name XXX;
location / {
proxy_pass http://YYY:7474/;
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_buffering off;
}
}
But how does the Bolt protocol over port 7687 work?
Thanks.
PS: Google translator ftw.
You need to use nginx compiled with --with-stream. Then you can add below section to your nginx config
stream {
server {
listen 7687;
proxy_pass neo4j:7687;
}
}
Basically you need to use tcp reverse proxy and not http proxy. The above configuration section will be at top level and not inside http or server block
You will need to open port 7687 between your laptop and the server hsoting neo4j.
If you are using let's encrypt and try to connect though SSL. neo4j embedded certificate were not signed by an Authority which was generating the error in my chrome browser.
To make it works, I had to copy my certs in neo4j certificates :
sudo su
cp /etc/letsencrypt/live/MYDOMAIN/fullchain.pem /var/lib/neo4j/certificates/neo4j.cert
cp /etc/letsencrypt/live/MYDOMAIN/privkey.pem /var/lib/neo4j/certificates/neo4j.key
service neo4j restart
Here is what works:
worker_processes auto;
events {
worker_connections 1024;
}
http {
map $http_upgrade $connection_upgrade {
"" close;
default upgrade;
}
upstream neo4j_bolt {
server neo4j:7687;
}
upstream neo4j_insecure {
server neo4j:7474;
}
upstream neo4j_secure {
server neo4j:7473;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://neo4j_insecure;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
}
}
server {
listen 443 ssl;
server_name localhost;
#SSL/https
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ecdh_curve secp384r1;
ssl_certificate /etc/nginx/conf.d/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/nginx.key;
ssl_dhparam /etc/nginx/conf.d/ssl/dhparam.pem;
location / {
proxy_pass https://neo4j_secure;
proxy_http_version 1.1;
proxy_set_header Connection "";
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;
}
}
server {
listen 7687 ssl;
server_name localhost;
#SSL/https
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ecdh_curve secp384r1;
ssl_certificate /etc/nginx/conf.d/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/nginx.key;
ssl_dhparam /etc/nginx/conf.d/ssl/dhparam.pem;
location / {
proxy_pass https://neo4j_bolt;
proxy_http_version 1.1;
proxy_set_header Connection Upgrade;
proxy_set_header Host $host;
proxy_set_header Upgrade $connection_upgrade;
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;
}
}
server {
listen 7688;
server_name localhost;
location / {
proxy_pass http://neo4j_bolt;
proxy_http_version 1.1;
proxy_set_header Connection Upgrade;
proxy_set_header Host $host;
proxy_set_header Upgrade $connection_upgrade;
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;
}
}
}
Dockerized solution here: https://github.com/joehoeller/nginx-server-neo4j-graph-db