Deploying actix Application with nginx - 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;
....

Related

Nginx only responding to 1 of multiple https servers

The problem I'm facing is that I have nginx configured for 2 HTTPS servers and 1 is responding and working correctly but the other one with a near identical server config is showing "connection refused".
System:
Description: Ubuntu 22.04 LTS
nginx version: nginx/1.18.0 (Ubuntu)
I am working with a default nginx.conf file and have unlinked the default sites-available entry and each server_name is a subdomain with its own SSL cert & key. When I check the access and error logs there are no entries describing why subdomain2 connection is refused, or even log entries showing a connection attempt was made. Both cert/key pairs were generated by the IT dept at a university and since 1 is working fine I have good reason to think both pairs are valid.
I'm no nginx expert but I've setup multiple subdomains like this on different systems with success and am not sure what's going on. I've double & triple checked the basic stuff like making sure a valid sym-link exists in sites-enabled, no errors show up on nginx restart or systemctl status, and obviously the machine itself is listening on 0.0.0.0:https per netstat output as well as subdomain1 working correctly. I've also verified that the proxy_pass destination works when I use subdomain1 to point to it (also verified with curl on the nginx host).
Let me know if there is any other information I can provide.
Any help is appreciated.
Thanks
/etc/nginx/sites-available/subdomain1:
server {
listen 443 ssl;
server_name subdomain1.base.edu;
ssl_certificate /path/server.crt;
ssl_certificate_key /path/server.key;
client_max_body_size 0;
add_header Strict-Transport-Security max-age=15768000;
location / {
proxy_pass http://127.0.0.1:8000;
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 $connection_upgrade;
proxy_set_header X-Scheme $scheme;
proxy_buffering off;
}
}
/etc/nginx/sites-available/subdomain2:
server {
listen 443 ssl;
server_name subdomain2.base.edu;
ssl_certificate /path/server.crt;
ssl_certificate_key /path/server.key;
location / {
proxy_pass http://127.0.0.1:10123;
}
}
UPDATE (nginx -T output)
user#host:/etc/nginx/sites-available$ sudo nginx -T
[sudo] password:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
.....
# configuration file /etc/nginx/sites-enabled/subdomain1.base.edu:
# top-level http config for websocket headers
# If Upgrade is defined, Connection = upgrade
# If Upgrade is empty, Connection = close
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name subdomain1.base.edu;
return 302 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name subdomain1.base.edu;
ssl_certificate /path/.ssl/server.crt;
ssl_certificate_key /path/.ssl/server.key;
client_max_body_size 0;
add_header Strict-Transport-Security max-age=15768000;
include /etc/nginx/sites-available/shinyapps;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# websocket headers
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Scheme $scheme;
proxy_buffering off;
}
}
# configuration file /etc/nginx/sites-available/shinyapps:
location /5627 {
proxy_pass http://localhost:5627/;
proxy_redirect / $scheme://$http_host/;
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 $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
# configuration file /etc/nginx/sites-enabled/subdomain2.base.edu:
#
# bustalab1 domain to proxy localhost shiny apps
server {
listen 80;
server_name subdomain2.base.edu;
# Tell all requests to port 80 to be 302 redirected to HTTPS
return 302 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name subdomain2.base.edu;
ssl_certificate /path/.ssl/subdomain2.crt;
ssl_certificate_key /path/.ssl/subdomain2.key;
error_log /var/log/nginx/subdomain2_err.log debug;
access_log /var/log/nginx/subdomain2_acc.log;
location / {
proxy_pass http://127.0.0.1:10123;
}
}

How to remove port number in nginx when redirecting

This is my domain.conf file in nginx:
server {
listen 80;
listen 8080;
server_name EXAMPLE.COM www.EXAMPLE.COM;
return 301 https://EXAMPLE.COM$request_uri;
}
server {
listen 443 ssl;
root /home/path;
ssl_certificate /etc/letsencrypt/live/EXAMPLE.COM/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/EXAMPLE.COM/privkey.pem;
location / {
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 $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
# Socket.IO Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Now when I type http://EXAMPLE.COM:8080 or http://EXAMPLE.COM:8080/some_folder/, my website over the port number 8080 works, but I want to remove this port number.
But what I want is:
--> Whenever I type http://EXAMPLE.COM:8080/folder, it redirects to https://EXAMPLE.COM/folder
I think the answer of what you are looking for is in proxy_redirect option, after proxy_pass.
This nginx configuration sample can be useful: (Take a look on proxy redirect line)
location /one/ {
proxy_pass http://upstream:port/two/;
proxy_redirect http://upstream:port/two/ /one/;
I think adding this should do the trick:
proxy_redirect http://127.0.0.1:8000 /blog;
You can find full documentation and examples in the nginx documentation.
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Keycloak Admin Console behind Nginx configured to use HTTPS

I'm trying to set up Keycloak, however the tutorials expect me to visit http://localhost:8080, but I'm setting it up on a remote host and need to access the admin console externally. I've tried to expose it via Nginx. Keycloak Administration Console seems to work with the new domain name and port seamlessly, but it still tries to use the "http" urls instead of the "https" ones (I've the Nginx configured to redirect HTTP to HTTPS and I want to keep it that way for security reasons). I have found the problem is that it internally sets a variable:
var authServerUrl = 'http://example.com/auth';
While the correct url would be https://example.com/auth.
As a result, when I open https://example.com/auth/admin/master/console/ in the browser, I get the error:
Refused to frame 'http://example.com/' because it violates the following Content Security Policy directive: "frame-src 'self'".
How to fix that? The Nginx config I use is:
server {
server_name example.com;
listen 80;
listen [::]:80;
location / {
return 301 https://$server_name$request_uri;
}
}
ssl_session_cache shared:ssl_session_cache:10m;
server {
server_name example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
# ... <SSL and Gzip config goes here> ...
location / {
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-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
client_max_body_size 16m;
}
}
You are doing SSL offloading in the nginx, but you need to forward information that https schema was used also to the Keycloak (X-Forwarded-Proto header). Try this:
server {
server_name example.com;
listen 80;
listen [::]:80;
location / {
return 301 https://$server_name$request_uri;
}
}
ssl_session_cache shared:ssl_session_cache:10m;
server {
server_name example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
# ... <SSL and Gzip config goes here> ...
location / {
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-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
client_max_body_size 16m;
}
}

Multiple nginx subdomains leads to a single jetty instance

I have added multiple subdomains on nginx and now I would like to proxy pass all subdomains to a single jetty instance.
Let´s say
subdomain1.blog.com -> localhost:8080/subdomain1
jenkins.blog.com -> localhost:8080/jenkins
I tested a lot of examples and in the end I struggled with the url.
If I open http://jenkins.blog.com I will redirect to https://jenkins.blog.com/jenkins/login?from=%2Fjenkins%2F
How can I get rid of this /jenkins/ in my url?
Is it possible to achieve it without using multiple jetty instances and deploying apps on webroot?
upstream jetty {
server 127.0.0.1:8080 fail_timeout=0;
}
server {
listen 80;
server_name jenkins.blog.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name jenkins.blog.com;
ssl_certificate /etc/letsencrypt/live/blog.com-0002/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.com-0002/privkey.pem;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /jenkins {
rewrite ^/jenkins(/.*)$ $1 last;
}
location / {
proxy_set_header Host $http_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;
# Fix the "It appears that your reverse proxy set up is broken" error.
proxy_pass http://jetty/jenkins/;
proxy_read_timeout 90;
#proxy_redirect http://localhost:8080/jenkins https://jenkins.blog.com;
#proxy_redirect http:// https://;
proxy_redirect off;
proxy_buffering off;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
# workaround for https://issues.jenkins-ci.org/browse/JENKINS-45651
add_header 'X-SSH-Endpoint' 'jenkins.blog.com:50022' always;
}
}
}

How to redirect NGINX to a websocket

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/;

Resources