enable SSL on dynamically declared subdomains rails - ruby-on-rails

we have a website where each user will have his own subdomain, lets's call the domain example.com.
when user1 gets created, he should be able to access his page through user1.example.com
right now when the user access user1.example.com he gets
"Your connection is not private" error message.
We are using rails 7 and we are hosted on AWS lightsail.
the SSL certificate is created using AWS certmanager and attached to the loadbalancer.
our simple Nginx config
listen 80;
listen [::]:80;
server_name _;
root /home/ubuntu/link/to/application/public;
passenger_enabled on;
passenger_app_env production;
location /cable {
passenger_app_group_name myapp_websocket;
passenger_force_max_concurrent_requests_per_process 0;
}
# Allow uploads up to 100MB in size
client_max_body_size 5m;
location ~ ^/(assets|packs) {
expires max;
gzip_static on;
}
}
EDIT 1:
we got a new wildcard certificate from letsencrypt certbot and updated ngnix with the following:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /home/ubuntu/link/to/app/current/public;
server_name domain.com www.domain;
passenger_enabled on;
passenger_app_env production;
location /cable {
passenger_app_group_name myapp_websocket;
passenger_force_max_concurrent_requests_per_process 0;
}
# Allow uploads up to 100MB in size
client_max_body_size 5m;
location ~ ^/(assets|packs) {
expires max;
gzip_static on;
}
listen 443 ssl; # managed by Certbot
# RSA certificate
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# Redirect non-https traffic to https
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
now both domain.com and www.domain.com has SSL certificates, but I still can have user1.domain.com to have that certificate

Related

How to get React frontend and Django backend to run on HTTPS? ERR_SSL_PROTOCOL_ERROR

My web application is running on a Linux Ubuntu 20.04.4 VPS server and its IP is assigned to a domain name.
React frontend has an SSL certificate and is running on port 443.
API (written in Django) is running inside a Docker container on port
1414 with no SSL.
Frontend's attempts to send requests to the API result in ERR_SSL_PROTOCOL_ERROR getting thrown in the console. How can I get my backend to run on HTTPS? Do I need to create another certificate within my Docker container, or do I have to configure something in the domain?
For now, my colleague wrote a script in PHP that somehow manages to bypass the error and make the requests. However, this seems like a very insecure way of doing things and is only a temporary solution.
Below you'll find my Nginx configuration files
# etc/nginx/sites-available/default
server {
listen 80;
listen [::]:80 default_server;
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 _;
location / {
try_files $uri /index.html =404;
}
}
server {
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 www.domainname.com domainname.com; # managed by Certbot
location / {
try_files $uri /index.html =404;
}
rewrite ^/api/get/(.*)$ /api.php?method=get&url=$1 last;
rewrite ^/api/post/(.*)$ /api.php?method=post&url=$1 last;
rewrite ^/api/put/(.*)$ /api.php?method=put&url=$1 last;
rewrite ^/api/delete/(.*)$ /api.php?method=delete&url=$1 last;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domainname.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domainname.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 img.domainname.com;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
location / {
proxy_pass http://127.0.0.1:1414/static/media/uploads/meal/;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Host $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-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/img.domainname.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/img.domainname.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.domainname.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = domainname.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name www.domainname.com domainname.com;
return 404; # managed by Certbot
}
server {
if ($host = img.domainname.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name img.domainname.com;
listen [::]:80;
return 404; # managed by Certbot
}
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
# Basic Settings
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;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POOD LE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
And this is my Nginx config file inside my Docker container (for the backend)
server {
listen ${LISTEN_PORT};
location /static {
alias /vol/static;
}
location / {
uwsgi_pass ${APP_HOST}:${APP_PORT};
include /etc/nginx/uwsgi_params;
client_max_body_size 10M;
}
}

example.com redirected you too many times. ERR_TOO_MANY_REDIRECTS

I was trying to Secure Nginx with Let's Encrypt on Ubuntu 16.04.
example.conf file before obtaining an SSL Certificate
server {
server_name example.com www.example.com ;
# Tell Nginx and Passenger where your app's 'public' directory is
root /var/www/backup/mycode/public;
# Turn on Passenger
passenger_enabled on;
rails_env development;
passenger_ruby /usr/local/rvm/gems/ruby-2.5.6/wrappers/ruby;
}
http://example.com/ is working fine.
I try to Obtain an SSL Certificate by
sudo certbot --nginx -d example.com -d www.example.com
the result was
Your existing certificate has been successfully renewed, and the new certificate
has been installed.
The new certificate covers the following domains: https://example.com and
https://www.example.com
example.conf file after obtaining an SSL Certificate
server {
server_name example.com www.example.com ;
# Tell Nginx and Passenger where your app's 'public' directory is
root /var/www/backup/example.com/public;
# Turn on Passenger
passenger_enabled on;
rails_env development;
passenger_ruby /usr/local/rvm/gems/ruby-2.5.6/wrappers/ruby;
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
server_name example.com www.example.com ;
listen 80;
return 404; # managed by Certbot
}
http://example.com/ is redirecting to https://example.com/ too many times
example.com redirected you too many times.
ERR_TOO_MANY_REDIRECTS
Why is it redirecting too many times?
what is the purpose of the second server block?
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
server_name example.com www.example.com ;
listen 80;
return 404; # managed by Certbot
}
How to make all redirects to https://www.example.com/ ?
EDIT1
Moving the certibot managed code to second server block has stopped the too many redirects problem. But my website is back again directing to HTTP instead of https.
server {
server_name example.com www.example.com ;
# Tell Nginx and Passenger where your app's 'public' directory is
root /var/www/backup/example.com/public;
# Turn on Passenger
passenger_enabled on;
rails_env development;
passenger_ruby /usr/local/rvm/gems/ruby-2.5.6/wrappers/ruby;
}
server {
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
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
server_name example.com www.example.com ;
listen 80;
return 404; # managed by Certbot
}
Try this:
server {
server_name example.com www.example.com ;
listen 80;
listen 443 ssl;
if ($scheme != "https") {
return 301 https://www.example.com$request_uri;
}
if ($host = example.com) {
return 301 https://www.example.com$request_uri;
}
# Tell Nginx and Passenger where your app's 'public' directory is
root /var/www/backup/example.com/public;
# Turn on Passenger
passenger_enabled on;
rails_env development;
passenger_ruby /usr/local/rvm/gems/ruby-2.5.6/wrappers/ruby;
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
}
This should redirect to www.example.com if used HTTP instead of HTTPS or host is example.com
regarding your questions:
I am not sure, maybe you also redirect in your ruby code. Your EDIT1 code example will redirect forever, since it redirects using the $host
weird way to redirect traffic on port 80 (used for HTTP)
In my example I fixed the redirect to www.example.com instead of $host

nginx configuration for ssl certificate installation with rails application

I have a site that I built using ruby on rails on nginx server with passenger. My client decided to install ssl certificate.I am a newbie to that kind of issues and I have never did it before and I need to confirm that my sites-enabled/default file is configured properly.
My current configuration is :
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name www.mysite.com;
passenger_enabled on;
rails_env production;
root /home/directory;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
and for adding ssl certificate, I will add another server block like below:
server {
listen 443;
server_name www.mysite.com;
passenger_enabled on;
rails_env production;
root /home/directory;
ssl on;
ssl_certificate /etc/ssl/my_certificate;
ssl_certificate_key /etc/ssl/my_private_key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_stapling on
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
is that a right way and parameters to configure nginx or I need to combine them in one server block ?
is there any thing missing should I add to the previous config ?
in the :server_name www.mysite.com;
can I replace it with my IP address instead of the domain name ?
Thanks for your time in advance
You can have HTTP and HTTPS servers in the same server section
server {
listen 80;
listen [::]:80 ipv6only=on;
listen 443 ssl;
...
}
For complete SSL related configuration I would recommend to use Mozilla generator
Yes, but you shouldn't. Nginx will match your first server section even if you haven't set server_name properly, but such configuration is hard to support and troubleshoot

rails application on nginx http and https access denied

I'm deploying a Rails application on personal server using Nginx, phusion_passenger. I've site configuration file with following server blocks. With this configuration my http://192.168.1.121 service doesn't work while https://192.168.1.121 fails with forbidden (access denied) error.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
# Make site accessible from http://192.168.1.121/
server_name 192.168.1.121;
passenger_enabled on;
rails_env production;
root /home/deploy/www/myrailsapp/current/public;
index index.html index.htm;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 443;
server_name 192.168.1.121;
passenger_enabled on;
rails_env production;
root /home/deploy/www/myrailsapp/current/public;
index index.html index.htm;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
error_page 500 502 503 504 /50x.html;
location / {
try_files $uri $uri/ =404;
}
}
production.rb has force_ssl: true
Also, If I remove server {} block with https entry, application works on http just fine (of course I've to comment out force_ssl: true from production.rb). I'm very puzzled by the access denied error if the same directory is accessed from https.
- nginx version: nginx/1.6.2
- Rails 4.0
- Ruby 2.1.3
Any help is appreciated.
Try configuring the SSL on the same server block as your port 80 configuration.
Also, it's recommended to use the ssl parameter of the listen directive for port 443, instead of the ssl on directive.
So something like this:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
# Use ssl parameter on the listening socket instead of the 'ssl on' directive
listen 443 ssl;
server_name 192.168.1.121;
# Rest of your ssl configuration here
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
passenger_enabled on;
rails_env production;
root /home/deploy/www/myrailsapp/current/public;
index index.html index.htm;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Sources and Recommended Reading:
Official nginx docs - A single HTTP/HTTPS server
Digital Ocean tutorial (may or may not be helpful for your case)

nginx subdomain failure with Rails app and passenger

I am totally new to nginx deployment and having problem setting up the subdomain for rails app which is running in passenger. My app structure is like this
-- sss.com (parent domain)
-- sub.sss.com (subdomain)
-- zzz.com (which will be redirected to sub.sss.com)
For more clear perspective, think of the gmail structure
-- google.com (parent domain)
- mail.google.com (subdomain)
-- gmail.com (which will be redirected to mail.google.com)
And remember sub.sss.com is not just a directory under sss, its completely a different rails app.
To setup a similar structure i have configured nginx like this
server {
listen 80;
server_name sss.com *.sss.com;
rewrite ^(.*) http://sss.com$1 permanent;
}
server {
listen 80;
server_name sss.com;
passenger_enabled on;
access_log logs/sss.log;
error_log logs/sss_error.log;
root /var/www/sss/public;
}
server {
listen 80;
server_name sub.sss.com;
passenger_enabled on;
access_log logs/sub.log;
error_log logs/sub_error.log;
root /var/www/sub/public;
}
server {
listen 80;
server_name zzz.com;
rewrite ^(.*) http://sub.sss.com$1 permanent;
}
When i start nginx i got this warning message
nginx: [warn] conflicting server name "sss.com" on 0.0.0.0:80, ignored
And got this message when tried to access the url www.sss.com
Chrome - Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many redirects.
FF - Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
But when i access zzz.com, it successfully redirects to sub.sss.com with a same error.
Seems its messed up in some kind of loop. anybody got a idea how to solve this?
In your first server you define the sss.com like server in the second too. You just need delete from first. like that :
server {
listen 80;
server_name *.sss.com;
rewrite ^(.*) http://sss.com$1 permanent;
}
server {
listen 80;
server_name sss.com;
passenger_enabled on;
access_log logs/sss.log;
error_log logs/sss_error.log;
root /var/www/sss/public;
}
server {
listen 80;
server_name sub.sss.com;
passenger_enabled on;
access_log logs/sub.log;
error_log logs/sub_error.log;
root /var/www/sub/public;
}
server {
listen 80;
server_name zzz.com;
rewrite ^(.*) http://sub.sss.com$1 permanent;
}
You have 3 domains/subdamians and there should be only 3 server blocks instead of the four you had.
Try ...
server {
# This server block serves sss.com
listen 80;
server_name sss.com;
passenger_enabled on;
access_log logs/sss.log;
error_log logs/sss_error.log;
root /var/www/sss/public;
}
server {
# This server block serves sub.sss.com
listen 80;
server_name sub.sss.com;
passenger_enabled on;
access_log logs/sub.log;
error_log logs/sub_error.log;
root /var/www/sub/public;
}
server {
# This server block redirects zzz.com to sub.sss.com
listen 80;
server_name zzz.com;
rewrite ^ http://sub.sss.com$request_uri? permanent;
}

Resources