How to replace http address to https for Shiny App - http

I have a Shiny app hosted in Digitalocean with Web-server as Nginx. The Web-address looks like
http://www.exacmple.com/ShinyApp
However I wish if I could change the http to https. i.e. all request to this App would be routed to https://www.exacmple.com/ShinyApp
I already have SSL certificate installed from letsencrypt, and certificate file is placed at below addresses:
/etc/letsencrypt/live/example.com/fullchain.pem;
/etc/letsencrypt/live/example.com/privkey.pem;
Currently, my Nginx Proxy file is set like below:
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
if ($http_host = example.com) {
rewrite (.*) https://www.example.com$1;
}
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /ShinyApp/ {
rewrite ^/ShinyApp/(.*)$ /$1 break;
proxy_pass http://localhost:4242;
proxy_redirect http://localhost:4242/ $scheme://$host/ShinyApp/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
}
To implement for https, I have appended this file as below (the location section)
location /ShinyApp/ {
rewrite ^/ShinyApp/(.*)$ /$1 break;
SSLEngine on
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ProxyPreserveHost On
proxy_pass http://localhost:4242;
roxyPassReverse http://localhost:4242;
proxy_redirect http://localhost:4242/ $scheme://$host/ShinyApp/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
However above change fails to implement https request.
I have gone through various suggestions available over Web (e.g. HTTPS for Shiny apps?) however failed to find any workable solution.
Any pointer towards the right direction would be very helpful.
Thanks,

Common practice for this is to use two server blocks:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
... # root, index and other top-level directives here
location /ShinyApp/ {
# your backend configuration here
}
}
Don't use ssl_certificate and ssl_certificate_key directives inside a location blocks, pay attention on a context in which nginx directives may or may not be used. SSLEngine, ProxyPreserveHost and ProxyPassReverse are apache directives, remove them! Test your configuration with nginx -t before reloading nginx with a new configuration.

Related

failed to dial to (wss://<ip>/subf1/40234): 502 Bad Gateway > websocket: bad handshake

OK, this 502 error is from something different than the other related articles here.
first i managed to setup a v2ray system using ubuntu 22.
I have a domain and a cloudflare account to set DNS for my domain and a 'sub' subdomain connected to my server ip, all set as it should be.
equipped with SSL cert & key using certbot on linux and works ok, website comes up with https just fine.
dns proxy and websocket check are both enable in CF(CloudFlare).
also im using reverse DNS like the famous tutorials saying, so i've edited the /etc/nginx/sites-available/sub.domain.com to become like this:
server {
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# 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;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name sub.domain.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /subf1 {
if ($http_upgrade != "websocket") {
return 404;
}
location ~ /subf1/\d\d\d\d\d$ {
if ($request_uri ~* "([^/]*$)" ) {
set $port $1;
}
proxy_redirect off;
proxy_pass http://127.0.0.1:$port/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
return 404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem; # mana>
ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem; # ma>
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = sub.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name sub.domain.com;
return 404; # managed by Certbot
}
also, have the x-ui v2ray panel installed and everything is setup just right here is a sample vless connection which i used to create normally and worked fine till yesterday:
the 9988 port is defined from x-ui v2ray management panel on the server.
everything was fine until i removed the x-ui panel and installed another version.
since then i cannot make the connections work, no matter what the v2ray client gives this series of errors:
app/proxyman/outbound: failed to process outbound traffic > proxy/vless/outbound: failed to find an available destination > common/retry: [transport/internet/websocket: failed to dial WebSocket > transport/internet/websocket: failed to dial to (wss://<ip>/subf1/40234): 502 Bad Gateway > websocket: bad handshake] > common/retry: all retry attempts failed
proxy/http: failed to read response from 149.xx.xx.xx:80 > io: read/write on closed pipe
some things i did to resolve this are:
restarting nginx
rebooting the server
re-installing the x-ui panel (various versions)
rebuilding the server
changing the subdomain
changing the sub domain + changing the server and gettin a different ip
and SSL is being set just fine with CF SSL selected at Full.
any kind of help and suggestion is so appreciated.

How do I configure an ssl certificate with Nginx on Ubuntu 18.04?

I am trying to install an SSL certificate on an Ubuntu server with Nginx (my project is on a Flask server). When I try to reach my domain with my current configuration, the site can't be reached and ERR_CONNECTION_TIMED_OUT appears. I'm also trying to redirect all http requests to https. This is my current .conf file:
server {
server_name backlogtracker.live www.backlogtracker.live;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
}
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/backlogtracker.live/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/backlogtracker.live/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.backlogtracker.live) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = backlogtracker.live) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name backlogtracker.live www.backlogtracker.live;
return 301 https://$server_name$request_uri;
}
Even with https, I can't reach the domain. Is there something that I'm missing?
Redirect http->https
This is a simple pattern for redirecting everything to https:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
It does not fit to all use-cases, but for most it is the simplest way without strange directives.
Order
Order does in some cases make a difference in config-files. Nginx is working top-down, so to prevent strange behaviour I'd suggest to always write your config as a story. E.g. return immediately stops execution, so stuff behind that is not processed. I would suggest the order:
connection settings (listen, server_name)
general config (ssl, headers, log, etc)
logic (if, map, ..)
locations
Headers for reverse proxy
I would suggest to always add headers (can be put in server-block to work for all locations):
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 Referer $http_referer;
proxy_set_header X-Forwarded-Proto $scheme;
SSL Protocol
Disable old TLS protocols
ssl_protocols TLSv1.2 TLSv1.3;
Further inspection
If not working then:
What is included in /etc/letsencrypt/options-ssl-nginx.conf
What are the logs of Flask and Nginx telling?
Are both running on host machine (no containers)?

nginx websocket handshake doesnt work, wrong configuration?

i have a php script which only have some function like get some content or post a file to the server.
now i am trying to open a websocket with JS. But i got everytime that the handshake wouldnt work.
new WebSocket('myDomain.com')
WebSocket connection to 'ws://mydomain.com/ws' failed: Error during WebSocket handshake: Unexpected response code: 200
I am not sure, what is going wrong.
server {
listen 80;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
# listen 80 default_server;
# listen [::]:80 default_server;
# root /var/www/html;
server_name mydomain.com;
# index index.php index.html index.htm index.nginx-debian.html;
listen 443 ssl; # managed by Certbot
# RSA certificate
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
location / {
try_files $uri $uri/ =404;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
}
}
Seems like a websocket server is missing in the setup.
It should be binding to a port somewhere independent of nginx.
The relevant nginx setting should look similar to this:
location /ws {
proxy_pass http://localhost:8123/websocket;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Your php script likely needs to be expanded into a php websocket server.
You can read up on it here:
How to create websockets server in PHP

Make it so nginx always has site using https

NOTE: example.com is just that. Per the rules of stackoverflow, I'm not using an actual domain.
I've been trying to get it so my nginx server for a single site always uses https.
I have the certificate installed and if I view the site with:
https://www.example.com it works fine.
But by default it goes to http and shows the site as insecure.
Here is the config:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/nodeapp;
index index.html index.htm;
server_name www.example.com example.com;
location / {
proxy_pass https://[IP address here]: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;
}
}
I esentially want everything to point to https://www.example.com
Because your site has both of http and https. (80 port and 443 port).
To activate the only https you have to remove the config for http.
Please remove listen 80 and use listen 443 instead.
If you want to redirect all traffics to https,
you could add redirection config as following.
server{
if ($host = your_domain) {
return 301 https://$host$request_uri;
}
server_name your_domain;
listen 80;
return 404;
}
I've assumed that your config has ssl part in your main config.
For example,
listen 443 ssl;
ssl_certificate /etc/***/fullchain.pem;
ssl_certificate_key /etc/**/privkey.pem; # managed by Certbot
ssl_dhparam /etc/**/ssl-dhparams.pem; # managed by Certbot

Why is Nginx routing all traffic to one subdomain?

I am new to nginx. I am trying to install GitLabs alongside an existing php project which is currently being served by Apache on port 80. My plan is to get them both working side by side on port 90 and then turn off Apache, switching both projects to Nginx on port 80.
Okay. The problem is that both subdomains are being captured by the server for my php project which should only be served to requests for db.mydomain.com. For the php project I have a file called: ccdb symlinked into /etc/nginx/sites-enabled. It contains:
server {
server_name db.mydomain.com;
listen 90; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
root /var/www/ccdb;
index index.html index.htm index.php;
}
However, for some reason, traffic to git.mydomain.com is being serverd from /var/www/ccdb even though I have another file symlinked alongside that one called gitlab with this content:
# GITLAB
# Maintainer: #randx
# App Version: 5.0
upstream gitlab {
server unix:/home/git/gitlab/tmp/sockets/gitlab.socket;
}
server {
listen 90; # e.g., listen 192.168.1.1:80; In most cases *:80 is a good idea
server_name git.mydomain.com; # e.g., server_name source.example.com;
server_tokens off; # don't show the version number, a security best practice
root /home/git/gitlab/public;
# individual nginx logs for this gitlab vhost
access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;
location / {
# serve static files from defined root folder;.
# #gitlab is a named location for the upstream fallback, see below
try_files $uri $uri/index.html $uri.html #gitlab;
}
# if a file, which is not found in the root folder is requested,
# then the proxy pass the request to the upsteam (gitlab unicorn)
location #gitlab {
proxy_read_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694
proxy_connect_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://gitlab;
}
}
NOTE: I am accessing the two domains from an OSX machine on the same local network which has entries in it's /etc/hosts file like so:
192.168.1.100 db.mydomain.com
192.168.1.100 git.mydomain.com
Try to use:
server_name git.mydomain.com:90;
... and:
server_name db.mydomain.com:90;

Resources