Rails app SSL is not being applied to the whole platform. - ruby-on-rails

I am running my rails app on nginx server. I am trying make the platform HTTPS secure. I purchased SSL certificate and configured it on the EC2 instance and configured the nginx.conf file accordingly too. After everything was done I entered domain.com on browser. For first time it redirected to https. But that's about it. Only home page was HTTPS the rest of the application as I went on exploring was still on HTTP
I am attaching my nginx.conf file and config/environment/production.rb files :
nginx.conf
upstream puma {
server unix:///home/deploy/apps/appname/shared/tmp/sockets/appname-puma.sock;
}
server {
#listen 80 default_server deferred;
listen 80;
listen 443 default ssl;
server_name domain.com;
ssl_certificate /etc/nginx/ssl/5532202b90020bc.crt;
ssl_certificate_key /etc/nginx/ssl/domain.key;
root /home/deploy/apps/vendaxoprod/current/public;
access_log /home/deploy/apps/appname/current/log/nginx.access.log;
error_log /home/deploy/apps/appname/current/log/nginx.error.log info;
#location ^~ /assets/ {
#gzip_static on;
#expires max;
#add_header Cache-Control public;
#}
location ^~ /(assets|fonts|swfs|images)/ {
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 $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
config/environment/production.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
Rails.application.config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = true
config.action_controller.perform_caching = true
config.action_mailer.raise_delivery_errors = true
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
# For large-scale production use, consider using a caching reverse proxy like
# NGINX, varnish or squid.
# config.action_dispatch.rack_cache = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
#config.serve_static_assets = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.serve_static_assets = false
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = true
#config.assets.precompile = ['*.js', '*.css', '*.css.erb']
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = false
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
config.action_mailer.default_url_options = { host: ENV["SMTP_HOST"] }
config.action_mailer.asset_host = ENV["SMTP_HOST"]
# config.action_mailer.delivery_method = :letter_opener
config.action_mailer.raise_delivery_errors = false
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
#Enter the smtp provider here ex: smtp.mandrillapp.com
address: ENV["SMTP_ADDRESS"],
port: ENV['SMTP_PORT'].to_i,
#Enter the smtp domain here ex: vendaxo.com
domain: ENV["SMTP_DOMAIN"],
#Enter the user name for smtp provider here
user_name: ENV["SMTP_USERNAME"],
#Enter the password for smtp provider here
password: ENV["SMTP_PASSWORD"],
authentication: 'plain',
enable_starttls_auto: true
}
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end

You should add separate server blocks for handle redirection to https.Like this:
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 default ssl;
server_name example.com;
ssl_certificate <certificate_path>;
ssl_certificate_key <certificate_key>;
}
It should work.

You should change your virtual file in Nginx as follows,
Add a separate section for requests that come in port 80 and redirect all such requests to port 443 (or HTTPS)
server {
listen 80;
server_name my.domain.com;
return 301 https://$server_name$request_uri;
}
Then, in your current configuration remove listen 80
server {
listen 443 ssl;
server_name my.domain.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000";
}
Hope this works.

Related

Apache not serving assets - Rails 5, Puma, Apache, Windows Server 2012 R2

I can't get css and js to render with Apache for my Rails 5 app running Puma. I've seen similar questions asked about this issue but none have worked for me so I think it might be specific to this stack or because I'm missing something about the location match in my httpd-vhosts.conf file. Here's what I have:
<VirtualHost *:80>
ServerName clientdb
DocumentRoot "C:/Bitnami/rubystack-2.2.7-0/projects/clientdb/public/"
<Directory "C:/Bitnami/rubystack-2.2.7-0/projects/clientdb/public/" >
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
<Proxy balancer://puma_cluster>
BalancerMember http://127.0.0.1:3003
BalancerMember http://127.0.0.1:3004
</Proxy>
ProxyPass /favicon.ico !
ProxyPass /robots.txt !
ProxyPassMatch ^/(404|422|500).html$ !
ProxyPass /assets/ !
ProxyPass / balancer://puma_cluster/
# enumerate all nodes for proxypassreverse since it adds a trailing slash :( bugid 51982
ProxyPassReverse / http://127.0.0.1:3003
ProxyPassReverse / http://127.0.0.1:3004
# ProxyPass / balancer://puma_cluster/ lbmethod=byrequests
# ProxyPass / balancer://puma_cluster/ lbmethod=bytraffic
# ProxyPass / balancer://puma_cluster/ lbmethod=bybusyness
<FilesMatch \.css\.gz$>
ForceType text/css
Header set Content-Encoding gzip
</FilesMatch>
<FilesMatch \.js\.gz$>
ForceType text/javascript
Header set Content-Encoding gzip
</FilesMatch>
<Location /assets/>
# Use of ETag is discouraged when Last-Modified is present
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</Location>
<LocationMatch "^/assets/.*\.(css|js)$">
RewriteEngine on
# Make sure the browser supports gzip encoding before we send it,
# and that we have a precompiled .gz version.
RewriteCond %{HTTP:Accept-Encoding} \b(x-)?gzip\b
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+)$ $1.gz
</LocationMatch>
# Make sure Content-Type is set for 'real' type, not gzip,
# and Content-Encoding is there to tell browser it needs to
# unzip to get real type.
# Make sure Vary header is set; while apache docs suggest it
# ought to be set automatically by our RewriteCond that uses an HTTP
# header, does not seem to be reliably working.
<LocationMatch "^/assets/.*\.css\.gz$">
ForceType text/css
Header set Content-Encoding gzip
Header add Vary Accept-Encoding
</LocationMatch>
<LocationMatch "^/assets/.*\.js\.gz$">
ForceType application/javascript
Header set Content-Encoding gzip
Header add Vary Accept-Encoding
</LocationMatch>
And this is config/environments/production.rb. (I have tried both enabling and disabling the static file server and neither works)
Rails.application.configure do
# Settings specified here will take precedence over those in
config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
config.threadsafe!
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable serving static files from the `/public` folder by default
since
# Apache or NGINX already handles this.
# config.public_file_server.enabled =
ENV['RAILS_SERVE_STATIC_FILES'].present?
config.public_file_server.enabled = false
# config.public_file_server.enabled = true
# Compress JavaScripts and CSS.
# config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# config.assets.prefix = '/clientdb/public/assets'
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# added by KO to try fix for serving assets on apache
# config.assets.digest = true
# config.assets.debug = true
# Enable serving of images, stylesheets, and JavaScripts from an asset
server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Specifies the header that your server uses for sending files.
config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
What am I missing here? I'm able to get bootstrap to render using the CDN but the rest is still missing and ideally I'd like to keep my asset pipeline intact. If I have to use CDN's then so be it, but I feel like this it probably just a tweak.
You need a "/" at the end of your ProxyPassReverse statements.
A similar question was asked here: https://stackoverflow.com/a/9929360/4038302

Assets precompiled but not showing with puma & nginx (Rails 4)

In my local machine when I do:
RAILS_ENV=production bundle exec rake assets:precompile
RAILS_ENV=production bundle exec puma -e production
Everything works fine. However I have the exact same app in a docker container for production that runs with nginx. I can see the application.css & application.js files in the assets folder with the chrome dev tools and they're not empty. But I have a page with no css/js, it should have something to do with nginx but I'm really confused.
/var/etc/nginx/nginx.conf:
user app sudo;
http{
upstream app {
server unix:/home/app/puma.sock fail_timeout=0;
}
server {
listen 80 default;
root /home/app/app/public;
try_files $uri/index.html $uri #app;
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app;
}
}
}
events {worker_connections 1024;}
config/environments/production.rb:
Rails.application.configure do
...
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_files = true
config.assets.js_compressor = :uglifier
config.assets.compile = false
config.assets.digest = true
...
end
Please do not hesitate to suggest anything. :)
update:
I've just realised that I have these 2 errors in my console:
new:11 Resource interpreted as Stylesheet but transferred with MIME type text/plain: "http://localhost/assets/application-5574b338d88d13681ef38b9b0800bc47.css".
new:12 Resource interpreted as Script but transferred with MIME type text/plain: "http://localhost/assets/application-ea59e17aff7f15a316e3e03d49f3daf4.js".
If you want nginx to serve your static assets, you'll need to set config.serve_static_files = false so Rails doesn't try to do it for you.

Rails, Nginx, Passenger, SSL - File Uploads Not Working

I am not able to get uploads to work with Passenger-Nginx and SSL. Uploads work fine if I disable SSL.
Here is my Nginx site config:
server {
listen 80;
server_name www.mysite.in;
root /home/deploy/mysite/current/public;
passenger_enabled on;
passenger_ruby /home/deploy/.rvm/gems/ruby-2.1.4/wrappers/ruby;
passenger_user deploy;
}
server {
listen 443 ssl;
server_name www.mysite.in;
root /home/deploy/mysite/current/public;
passenger_enabled on;
passenger_ruby /home/deploy/.rvm/gems/ruby-2.1.4/wrappers/ruby;
passenger_user deploy;
ssl on;
ssl_certificate /etc/nginx/ssl/www_mysite_in.crt;
ssl_certificate_key /etc/nginx/ssl/myserver.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#Disables all weak ciphers
ssl_ciphers 'AES256+EECDH:AES256+EDH';
# Specifies that server ciphers should be preferred over client (e.g. browser) ciphers when using SSL/TLS.
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;
}
Any config/environments/production.rb
Mysite::Application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
# For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
# config.action_dispatch.rack_cache = true
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_assets = false
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# Generate digests for assets URLs.
config.assets.digest = true
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.0'
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
# Set to :debug to see everything in the log.
config.log_level = :info
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# config.assets.precompile += %w( search.js )
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Disable automatic flushing of the log to improve performance.
# config.autoflush_log = false
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# config.action_mailer.delivery_method = :sendmail
end
I have tried disabling the config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' and it makes no difference under SSL or non-SSL.
I was never able to get this to work. So I just deleted the VPS image, and created a new one... and it works.
PS - I was using a setup script to install all the packages, so I am at a total loss as to why it didn't work with the original VPS image.

Rails 4 generates an empty manifest.json file when I run RAILS_ENV=production rake assets:precompile

On my staging server, I am having some troubles.
When I run
RAILS_ENV=production rake assets:precompile
Then
ls public/assets/
manifest-e694d7a3911e13a1b7c31ee3a73ccc9d.json>
Then
$ cat public/assets/manifest-e694d7a3911e13a1b7c31ee3a73ccc9d.json
{}
However, if I just run rake assets:precompile (without the RAILS_ENV=production flag), then I get a bunch of CSS and JS, as well as my images, put into the public/assets folder. Unfortunately, however, there are two problems:
1) The fingerprint (the md5 hash ) on the .js and .css files doesn't match what javascript_include_tag and stylesheet_link_tag automatically spit out
2) Inside the generated CSS file, I see references to my static asset, but they don't include the md5 hash fingerprint, even though I explicitly ask for it; e.g.
background-image: url(image-path('home/logo.png'));
It just generates
background-image: url("/assets/home/logo.png");
Even though the file that gets generated is,
logo-a412c0ad6a034e4da4324436fff2f871.png
The relevant (I think) bits of the appropriate files:
Here is my application.rb
config.assets.enabled = true
Here is my development.rb
config.assets.compress = false
config.assets.debug = true
Here is my production.rb
config.serve_static_assets = true
config.assets.compress = true
config.assets.js_compressor = :uglifier
config.assets.compile = true
config.assets.digest = true
config.assets.precompile = true
Here is my nginx conf
server {
listen 80;
server_name staging.mysite.com;
root /var/www/myuser/current/public;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location / {
proxy_pass http://appname; # match the name of upstream directive which is defined above
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ ^/(assets)/ {
root /var/www/myuser/current/public;
gzip_static on; # to serve pre-gzipped version
expires max;
add_header Cache-Control public;
}
}
Thank you for your help. I have been banging my head here for a while now. Please let me know if I should share more information.

Unicorn Rails stack + Vagrant not serving some assets

I'm using a Rails Stack with nginx + unicorn + rails meant for a production server, but I'm staging it under Vagrant for testing purposes. While doing this, I encountered a strange behavior of the rails application, where very often one or other asset wasn't being served, i.e. application.css isn't being served and therefore the whole page is displayed without any styles applied to it.
I've googled the problem and found that Vagrant's FS driver isn't completely implemented and that would bring some problems while using Apache (haven't found any mentions to nginx). The solution to this problem was to disable sendfile by adding sendfile off; to the configuration file. And... it didn't work.
Further, I went through the logs (Rails, unicorn and nginx) and found that when the file isn't served, there isn't any mention to it in any of the logs. This brought me to the question that the problem can be in the mechanism used by Vagrant to share the rails app folder through the VM. As mentioned in vagrant's website, Vagrant uses Virtual Box's Shared Folders, which is quite slow comparing to other alternatives (as shown here), and the workaround is to set up NFS Shared Folders. So, I decided to give NFS a try and the result was... the same. Unfortunately, some assets are kept from being served.
Does anyone have any ideas on this? I've searched for quite a while but haven't found any pointers additional to those I described here.
I'm using:
Mac OS X 10.6.8 + rbenv (to develop)
Vagrant + nginx + rbenv + unicorn + bundler (to stage)
unicorn.rb
rails_env = ENV['RAILS_ENV'] || 'production'
app_directory = File.expand_path(File.join(File.dirname(__FILE__), ".."))
worker_processes 4
working_directory app_directory
listen "/tmp/appname.sock", :backlog => 64
#listen "#{app_directory}/tmp/sockets/appname.sock", :backlog => 64
timeout 30
pid "#{app_directory}/tmp/pids/unicorn.pid"
stderr_path "#{app_directory}/log/unicorn.stderr.log"
stdout_path "#{app_directory}/log/unicorn.stdout.log"
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
before_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
/etc/nginx/sites-enabled/appname
upstream unicorn_server {
server unix:/tmp/appname.sock fail_timeout=0;
}
server {
listen 80;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# Location of our static files
root /home/appname/www/current/public;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://unicorn_server;
break;
}
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/hemauto/www/current/public;
}
}

Resources