Using WebSocket Secure with Nginx and Daphne - ssl

I've been struggling to figure it all out, but I finally have something working with the following:
nginx:
server {
server_name example.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/example/example;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
include proxy_params;
proxy_pass http://unix:/tmp/daphne.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name example.com;
return 404; # managed by Certbot
}
daphne.service:
[Unit]
Description=daphne daemon
After=network.target
[Service]
User=example
Group=www-data
WorkingDirectory=/home/example/example
StandardOutput=file:/var/example.log
StandardError=file:/var/example.log
ExecStart=/home/example/example/venv/bin/daphne \
-u /tmp/daphne.sock \
project.asgi:application
[Install]
WantedBy=multi-user.target
I'm constrained to using https. The page does load with that. However, if I try and make a websocket connection it fails with something about mixed protocols. So I change 'ws://' to 'wss://' and now I get The URL 'wss://' is invalid. How can I get this to work?

The problem was quite simple to resolve. In my JavaScript I had
new WebSocket(
window.location.protocol == 'https:' ? 'wss://' : 'ws://'
+ window.location.host
+ '/ws/'
);
when I should have had
new WebSocket(
(window.location.protocol == 'https:' ? 'wss://' : 'ws://')
+ window.location.host
+ '/ws/'
);
Note the parentheses.

Related

Nginx Whitelist IP, use certificate otherwise

I am setting up a server for my university which has to be only accessible from inside their network.
This I can easily do with nginx. Unfortunatley there are some people that do not have access to this network/IP range. I could use Basic Authentication With Source IP Whitelisting but I would prefer to use a certificate.
Is there a way to first check, if the access is from within the allowed IP Range and if not asking for a certificate?
I tried something like:
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/test.de/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/test.de/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# server_name _;
server_name test.de;
ssl_client_certificate /etc/nginx/client_certs/ca.crt;
ssl_verify_client optional;
error_log /var/log/nginx/errors.log debug;
location / {
satisfy any;
allow 123.0.0.0/16;
allow 456.0.0.0/16;
deny all;
if ($ssl_client_verify != SUCCESS) {
return 403;
}
try_files $uri $uri/ =403;
}
}
server {
if ($host = test.de) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name test.de;
return 404; # managed by Certbot
}
which is not working.
I could use a check for the IP before checking the ssl_client_verify like
if ($remote_addr = 1.2.3.4 )
{
proxy_pass http://10.10.10.1;
break;
}
if ($ssl_client_verify != "SUCCESS")
{ return 403; }
but this would not be feasible for every single ip adress.
How could I handle this efficiently?
Thank you in advance
~Fabian
You may be able to use a geo block instead of the allow/deny statements and use $ssl_client_verify as the default value.
For example:
geo $verify {
123.0.0.0/16 "SUCCESS";
456.0.0.0/16 "SUCCESS";
default $ssl_client_verify;
}
server {
if ($verify != "SUCCESS") { return 403; }
...
}
See this document for details.

Redirect non-http link to HTTPS link using LetsEncrypt in nginx

I'm using Nginx and LetsEncrypt for the SSL certificate.
I have this nginx.conf file which isn't redirecting non-http links to https. how can I go about redirecting all links to https?
user root;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
#include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name api.example.com www.api.example.com;
proxy_read_timeout 600s;
location /apis/media/images {
#add_header Access-Control-Allow-Origin *;
alias /home/example_PROD/Images/;
}
location / {
proxy_pass http://127.0.0.1:10000/;
}
}
server {
server_name example.com;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri /index.html;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name www.example.com; # managed by Certbot
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri /index.html;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
listen [::]:443 ssl ; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
return 404; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name www.example.com;
return 404; # managed by Certbot
}}
Delete this part:
server {
listen 80;
listen [::]:80;
server_name api.example.com www.api.example.com;
proxy_read_timeout 600s;
location /apis/media/images {
#add_header Access-Control-Allow-Origin *;
alias /home/example_PROD/Images/;
}
location / {
proxy_pass http://127.0.0.1:10000/;
}
}

NGINX reverse proxy for port 8765 with SSL is not working

I have an Nginx server with SSL. And when I use proxy_pass to http://127.0.0.1:8765 with ssl added its giving "This site can’t be reached". Without SSL it was working correctly. If I send a request as http://domain-name:8765 in a web browser it gave the output correctly. Below is my configuration :
server {
server_name domain-name.in;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
location / {
proxy_pass http://127.0.0.1:8765;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain-name.in/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain-name.in/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = domain-name.in) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name domain-name.in;
return 404; # managed by Certbot
}

Certbot Redirection of HTTP to HTTPS from Nginx is not working

I'm setting ssl server on Nginx with proxy_pass to apache.
The code was recreated by certbot and is not working. I can't find out what's wrong.
I've also tried to replace $host by $server_name and other suggestions from forum with no success.
server {
server_name biofit.blog www.biofit.blog;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/gekko.winsum.ws/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/gekko.winsum.ws/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
proxy_buffers 8 32k;
proxy_buffer_size 64k;
proxy_pass http://biofit.blog:81;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
server {
if ($host = www.biofit.blog) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = biofit.blog) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name biofit.blog www.biofit.blog;
return 404; # managed by Certbot
}
The expected output of ssl should pass to apache running on port 81, but not:
ERR_TOO_MANY_REDIRECTS
it's not recommended to use if statement
try this:
server {
listen 80;
listen [::]:80;
server_name biofit.blog www.biofit.blog;
rewrite ^ https://$server_name$request_uri? permanent;
return 404; # managed by Certbot
}

Keep getting ERR_CONNECTION_REFUSED with NGINX conf

I keep getting ERR_CONNECTION_REFUSED
worker_processes 4;
events { worker_connections 1024; }
http {
sendfile off;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
listen 80;
listen [::]:80;
# server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
add_header Allow "GET, HEAD" always;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
if ( $request_method !~ ^(GET|HEAD)$ ) {
return 405;
}
return 200;
}
}
it successfully redirects me from http:localhost to https:localhost, but all I see is this immediately:
Does anyone know why this is happening? is it my certs?
I am just using localhost right now, so it probably isn't firewall thing. Unfortunately, nothing shows up in the access or error logs which is frankly pretty sorry.
The simple answer was I was using docker, and I needed to open up port 80 AND port 443:
docker run -d -p 80:80 -p 443:443 "$my_image"