Ruby on rails app working on http but not on https - nginx

I have a RoR app running in Nginx. I deploy the application to server using capistrano and puma. It works well under this nginx configuration:
upstream puma {
server unix:///home/kiui/apps/kiui/shared/tmp/sockets/kiui-puma.sock;
}
server {
listen 80;
keepalive_timeout 70;
server_name kiuiapp.com;
root /home/kiui/apps/kiui/current/public;
access_log /home/kiui/apps/kiui/current/log/nginx.access.log;
error_log /home/kiui/apps/kiui/current/log/nginx.error.log info;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #puma;
location #puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_pass http://puma;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
}
But I need run the rails app with https to use a Facebook app in it. I created a auto signed ssl certificate following this tutorial create autosigned ssl certificate and changed the nginx configuration to that:
upstream puma {
server unix:///home/kiui/apps/kiui/shared/tmp/sockets/kiui-puma.sock;
}
server {
listen 443 ssl;
keepalive_timeout 70;
server_name kiuiapp.com;
ssl on;
ssl_certificate /etc/ssl/kiui.crt;
ssl_certificate_key /etc/ssl/kiui.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
root /home/kiui/apps/kiui/current/public;
access_log /home/kiui/apps/kiui/current/log/nginx.access.log;
error_log /home/kiui/apps/kiui/current/log/nginx.error.log info;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #puma;
location #puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_pass http://puma;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
}
It not work! The browser give me ERR_CONNECTION_TIMED_OUTerror. Someone could help me?

SOLUTION:
upstream puma {
server unix:///home/kiui/apps/kiui/shared/tmp/sockets/kiui-puma.sock;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
keepalive_timeout 70;
server_name kiuiapp.com;
ssl on;
ssl_certificate /root/kiuiapp.com.chain.cer;
ssl_certificate_key /root/kiuiapp.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
root /home/kiui/apps/kiui/current/public;
access_log /home/kiui/apps/kiui/current/log/nginx.access.log;
error_log /home/kiui/apps/kiui/current/log/nginx.error.log info;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #puma;
location #puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://puma;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
}
I think the problem was the ssl certificate chain. It was not well created.

Related

Getting SSL routines:ssl3_get_record:wrong version number

I am running an Nginx reverse proxy but when I am doing a curl I am getting error while running
curl https://test-website.com:444
"SSL routines:ssl3_get_record:wrong version number".
Here is my default.conf
listen 444 ssl;
server_name test-website.com;
# Path for SSL config/key/certificate
ssl_certificate /etc/ssl/certs/nginx/site1.crt;
ssl_certificate_key /etc/ssl/certs/nginx/site1.key;
include /etc/nginx/includes/ssl.conf;
location / {
include /etc/nginx/includes/proxy.conf;
proxy_pass https://IdentityApi:5501;
}
access_log off;
error_log /var/log/nginx/error.log error;
}
# Default
server {
listen 80 default_server;
server_name _;
root /var/www/html;
charset UTF-8;
error_page 404 /backend-not-found.html;
location = /backend-not-found.html {
allow all;
}
location / {
return 404;
}
access_log off;
log_not_found off;
error_log /var/log/nginx/error.log error;
}
ssl.conf
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
proxy.conf
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 X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_intercept_errors on;
Is there any issue with the conf file?
This issue helped me with the same error but a different circumstance:
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
Had to change from https to HTTP
While I don't think this solves your question, maybe thinking about where there could be a different protocol in your file might help.

Nginx redirect config issue

I have nginx bitnami container deployed in Openshift that serves my application. The issue that I am facing is that the redirect is not working. In the logs, there are no indications that the request is caught by a proxy_pass location block.
So. the idea is that a request to app.com/backend1/api/something should be forwarded to service1.com/backend1/api/something. The same goes for service2.
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream service1 {
server service1.com;
}
upstream service2 {
server service2.com;
}
server {
listen 8443 ssl;
listen [::]:8443 http2 ssl;
server_name app.com;
error_log /opt/bitnami/nginx/error.log debug;
ssl on;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
keepalive_timeout 70;
include /opt/bitnami/nginx/conf/mime.types;
root /opt/bitnami/nginx/html;
location ~ ^/backend1/api/(.*)$ {
proxy_pass https://service1/backend1/api/$1;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ ^/backend2/api/(.*)$ {
proxy_pass https://service2/backend2/api/$1;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
try_files $uri /index.html;
}
}
}
I have also tried moving the order of the location blocks, as well as moving the root directive, but without success.
Any ideas on how to resolve this issue?

nginx internal reverse proxy

I want the following scenario
Client makes browser request to http://my-domain.com
Nginx A intercepts that request which then forwards it to Nginx B which is hosting my website
I have the current configuration but i am getting ERR_TOO_MANY_REDIRECTS
Nginx A (landing host proxy)
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
server_tokens off;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /my/ssl/my-domain.com.crt;
ssl_certificate_key /my/ssl/my-domain.com.key;
ssl_dhparam /my/ssl/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers
'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
return 404;
}
upstream client_proxy {
server my_internal_server:80;
}
server {
server_name my-domain.com;
listen 443 ssl;
ssl_certificate /my/ssl/my-domain.com.crt;
ssl_certificate_key /my/ssl/my-domain.com.key;
ssl_dhparam /my/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
location / {
rewrite ^ http://my-domain.com/;
index index.html index.htm;
charset utf-8;
auth_basic off;
allow all;
proxy_pass http://client_proxy/;
proxy_ignore_headers Set-Cookie Cache-Control Expires;
proxy_hide_header "Set-Cookie";
proxy_redirect off;
proxy_set_header Host my-domain.com;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_For;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
send_timeout 90s;
}
}
Nginx B (Web server)
server {
listen 80;
root /my/www;
index index.html;
try_files $uri $uri/ /index.html;
# ... other location blocks which are irrelevant here
}
As stated by Richard Smith in the comment,
remove the rewrite rule and it fixed it

Nginx ssl connection

I am trying to server secure site using nginx ssl connection.I am not able to load third party http css and js file. It is giving error.
This request has been blocked; the content must be served over HTTPS.
here is the my nginx conf
server {
listen 443 ssl;
server_name api-test.vendorver.com;
ssl_certificate /etc/nginx/ssl/vv_key/cert_chain.crt;
ssl_certificate_key /etc/nginx/ssl/vv_key/vendorver.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
location / {
proxy_pass http://0.0.0.0:8000;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect off;
}
#if ($host !~* ^(vendorver.com|www.vendorver.com)$ ) {
# return 444;
#}
location /static/ {
autoindex on;
alias /home/ec2-user/vendorver.backend/static/;
}
}
That file is not available on https request. How can i include that file in page?
You have to configure your static directory and your media (images) directory
To run all this over ssl the config should be something like:
server {
listen 80;
charset utf-8;
client_max_body_size 100M;
ssl on;
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/yoursite_com/ssl-bundle.crt;
ssl_certificate_key /etc/nginx/ssl/yoursite_com/cert.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
access_log /var/www/vhosts/yoursite.com/logs/access_log;
error_log /var/www/vhosts/yoursite.com/logs/error_log;
server_name yousite.com www.yoursite.com;
root /var/www/vhosts/yoursite.com/yourapp/;
add_header Strict-Transport-Security max-age=31536000;
location / {
.... your settings here
}
location /media {
alias /var/www/vhosts/yoursite.com/yourapp/media;
}
location /static {
alias /var/www/vhosts/yoursite.com/yourapp/static;
}
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
}
Rather than listening to both ports 80 and 443 in the same config. I suggest setting up server redirects, e.g.
server {
listen 80;
server_name endyourif.com www.endyourif.com;
return 301 https://www.endyourif.com$request_uri;
}
Setting up SSL with nginx including redirects from non HTTPS traffic

How to DRY nginx configuration

I have nginx config for the current and legacy application where the only difference between the two blocks is DNS-specific entries and root path. How can I put specific parts of the config in a variable or something and then call that variable in both server config blocks?
server {
listen 0.0.0.0:443 ssl;
server_name mysite.com;
ssl_certificate /etc/ssl/server.crt;
ssl_certificate_key /etc/ssl/server.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:15m;
ssl_session_timeout 15m;
root /home/deployer/apps/myapp/current/public;
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
return 403;
}
if ($http_user_agent ~* (spider|AcoiRobot|msnbot|scrapbot|catall|wget) ) {
return 403;
}
location ^~ /assets/ {
gzip_static on;
gzip_vary on;
expires max;
add_header Cache-Control public;
}
location ~ \.(gif|png|jpe?g|JPE?G|GIF|PNG {
valid_referers none blocked mysite.com *.mysite.com;
if ($invalid_referer) {
return 403;
}
}
location /evil/ {
valid_referers none blocked mysite.com *.mysite.com;
if ($invalid_referer) {
return 403;
}
}
try_files $uri/index.html $uri #puma;
location #puma {
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 https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
How can I DRY up everything below the root line?
Time has proven Alexey Ten's comment about using include to be the right way to go.
We use this in production:
File structure in /etc/nginx
nginx.conf
sites-enabled/app_config
modules/shared_serve
modules/shared_ssl_settings
In /etc/nginx/sites-enabled/app_config:
upstream puma {
server unix:/tmp/puma.socket fail_timeout=1;
}
server {
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include modules/shared_ssl_settings;
include modules/shared_serve;
}
In /etc/nginx/modules/shared_ssl_settings:
listen 443 ssl;
listen [::]:443;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers On;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:30m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
In /etc/nginx/modules/shared_serve:
location ~ \.(php|aspx|asp|myadmin)$ { return 444; log_not_found off; }
root /home/deployer/apps/example_app/current/public;
try_files $uri/index.html $uri #puma;
location #puma {
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 https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
The only gotcha is that your deploy script has to ensure the file structure in /etc/nginx. Naturally, you can name your module directory anything else. You might even keep the includable files right in /etc/nginx without a subdirectory.
You could use a map to define which app root to use based on $host:
map $host $app_root {
default /home/deployer/apps/myapp/current/public;
legacy.mysite.lv /home/deployer/apps/myapp/legacy/public;
}
Add another server_name directive to match your legacy app (use the same name in the map). Then use the variable in your root directive:
root $app_root;

Resources