How to redirect NGINX to a websocket - nginx

NGINX - sitting on 10.10.10.1
LAMP - sitting on 172.168.1.1 , has phpwebsockets.This listens on http://172.168.1.1:8080 and having ws folder at http://172.168.1.1:8080/ws
Nginx supposed to forward request in this fashion.
NGINX ---> LAMP Websocket
http://10.10.10.1/randomstring/ --> https://10.10.10.1/randomstring/ --> http://172.168.1.1:8080
Currect /conf.d/internal.conf nginx config file is
server {
listen 80;
server_name 172.168.1.1;
return 301 https://$host$request_uri; #redirect to self with https
}
server {
listen 443 ssl;
server_name 172.168.1.1;
root /var/www/nginx/;
index index.html;
proxy_cache one;
location /ws {
proxy_pass http://172.168.1.1:8080;
# this magic is needed for WebSocket
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;
}
location / {
proxy_pass http://172.168.1.1:8080;
}
}
I am unable to forward to /randomstring , it works for without 'randomstring'.

Please add "/" at the end of proxy_pass
proxy_pass http://172.168.1.1:8080/;

Related

Deploying actix Application with nginx

I created actix web & websocket within single application, and it works fine in localhost.
Basically, after passing a login page, it opens a dashboard and a common Javascript's WebSocket.
new WebSocket(`ws://server:8181/client?token=${TokenString}`);
And it works fine.
I don't want to expose this 8181 port on my production server, so my plan is using a sub path /ws to map to 8181 port.
So my /etc/nginx/sites-enabled/default config is:
server {
server_name my_domain.com; # managed by Certbot
....
#WebSocket part is here, under /ws path and mapped to 8181 port
location /ws {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy false;
proxy_pass http://127.0.0.1:8181;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
#Here is my web app, / mapped to 8080 port
location / {
client_max_body_size 50m;
client_body_buffer_size 50m;
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-Ip $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location ^~ /\. {
deny all;
}
#configs generated by Certbot
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl;
#...
}
#redirect http to https
server {
if ($host = my_domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name my_domain.com;
return 404; # managed by Certbot
}
My web page https://my_domain.com, works fine. But my mapped WebSocket connection doesn't.
new WebSocket(`wss://my_domain.com/ws/client?token=${TokenString}`);
With just WebSocket connection to ... failed: message, and /var/log/nginx/error.log shows nothing.
Is something wrong with my nginx config?
*Edit: it turns out showing 404 in /var/log/nginx/access.log 😪
It turns out, the /ws path should be URL rewritten since my websocket didn't map /ws to anything.
The idea was from here
So my configuration is:
location ~* ^/ws/ {
rewrite ^/ws/(.*) /$1 break;
....

How to configure nginx reverse proxy to use SECURE websockets upstream?

I want to use nginx as a reverse proxy for websocket connections.
Consider echo.websocket.org to be my backend websocket service. As a test client I use wscat from https://github.com/websockets/wscat.
What works:
client <-- ws --> backend:
wscat --connect ws://echo.websocket.org
client <-- wss -->: wscat --connect wss://echo.websocket.org
client <-- ws --> proxy <-- ws --> backend: wscat --connect ws://localhost with the following nginx configuration:
events {
}
http {
server {
listen 80;
location / {
proxy_pass http://echo.websocket.org;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
}
}
client <-- wss --> proxy <-- ws --> backend: wscat -n --connect wss://localhost with the following nginx configuration:
events {
}
http {
server {
listen 443 ssl;
ssl_certificate /pki/cert.pem;
ssl_certificate_key /pki/key.pem;
location / {
proxy_pass http://echo.websocket.org;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
}
}
What I want and what I need help with is configuring nginx to use secure websockets to connect to the backend. I want this configuration:
client <-- wss --> proxy <-- wss --> backend
I tried changing http://echo.websocket.org to https://echo.websocket.org without success. This leads to a 504 Gateway Timeout.
You need to use proxy_ssl_certificate and proxy_ssl_certificate_key as specified in Nginx Docs
This is my config upstream, server_name, ssl_certificate, HTTP 301:
server {
listen 80; # nginx 80
location / {
return 301 https://$host$request_uri;
}
location ^~ /.well-known/acme-challenge/ {
# Set correct content type. According to this:
# https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29
# Current specification requires "text/plain" or no content header at all.
# It seems that "text/plain" is a safe option.
default_type "text/plain";
# This directory must be the same as in /etc/letsencrypt/cli.ini
# as "webroot-path" parameter. Also don't forget to set "authenticator" parameter
# there to "webroot".
# Do NOT use alias, use root! Target directory is located here:
# /var/www/common/letsencrypt/.well-known/acme-challenge/
root /var/www/html;
}
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/***0***0.ru/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/***0***0.ru/privkey.pem; # managed by Certbot
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name ***0***0.ru; # server name
location /sockjs-node/ {
proxy_pass http://node; # wep application
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://node;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /smpp {
rewrite /smpp(.*) /$1 break;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
proxy_pass http://smpp;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
upstream smpp {
server localhost:5001;
}
upstream node {
server localhost:5000;
}

NGinx forward websocket from 80 to websocket port

I am using Nginx as a web host and proxy for a websocket running on the same device listening on port 8888. Trying to find a way to have nginx listen on 80 and forward the websocket requests to the internal port. Without exposing a new port to the outside. Is this even possible?
UPDATE:
This is my current configuration:
error_log /var/log/nginx/error_log.log warn;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server localhost:8888;
}
server {
listen 80;
#listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html/EncoderAdmin;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /ws {
proxy_pass http://localhost:8888;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
When I try to connect to it with ws://[address]/ws I get:
WebSocket connection to 'ws://[address]/ws' failed: Error during WebSocket handshake: Unexpected response code: 400
Yes, it's possible assuming you can distinguish the normal HTTP requests and the socket ones.
The simplest solution is to match the socket uri with location, for example all the requests to /ws will be redirected to localhost:8888, any other url to localhost:8889. Here it is an example of configuration
server {
server_name _;
location /ws {
proxy_pass http://localhost:8888;
# this magic is needed for WebSocket
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;
}
location / {
proxy_pass http://localhost:8889;
}
}
You should also remember to bind the websocket server to localhost:8888 and not to 0.0.0.0:8888. This step is not needed but with it the original port is not exposed!

nginx multiple domain configuration failed

502 bad gateway error, hmm I've no problem with my dns. I have a folder named 'app' and 'website' in my /home directory.
server {
listen 80;
server_name dashboard.abc.com;
location / {
root app;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 80;
server_name abc.com
location / {
root site;
index index.html index.htm;
}
}
Everything make sense here, not sure which part is causing the problem

Accept only subdomain in nginx

I have a reverse proxy set up in nginx for a node.js server.
server {
listen 80;
server_name sub.domain.tld;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
It works all fine and dandy, however, I only want sub.domain.tld to work. Opening up domain.tld in a browser still routes to the node.js server.
try to add this
server {
listen 80;
server_name domain.tld;
return 404;
}

Resources