Remove www subdomain in nginx and puma config - ruby-on-rails

I'm using puma and nginx to run a rails 3.2 app on AWS. I terminate my HTTPS on the loadbalancer (ELB). How can I redirect www.mydomain.com to mydomain.com? My config below does not work.
user nginx;
worker_processes auto;
worker_rlimit_nofile 100000;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
keepalive_requests 200;
reset_timedout_connection on;
types_hash_max_size 2048;
# 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;
index index.html index.htm;
upstream myapp {
# Path to Puma SOCK file
server unix:/var/www/nginx-default/myapp/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name www.my-app.com;
return 301 $scheme://my-app.com$request_uri;
}
server {
listen 80;
server_name my-app.com;
root /var/www/nginx-default/myapp/public;
#charset koi8-r;
# set client body size (upload size)
client_max_body_size 100M;
location / {
proxy_pass http://myapp; # 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;
}
# We don't need .ht files with nginx.
location ~ /\.ht {
deny all;
}
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
}
If I remove
server {
listen 80;
server_name www.my-app.com;
return 301 $scheme://my-app.com$request_uri;
}
and use
server {
listen 80;
server_name localhost;
root /var/www/nginx-default/myapp/public;
#...
}
it works but does not handle the www subdomain.

This is a speculative answer, as I do not use AWS and ELB. However, using $scheme in your redirect will result in HTTPS being redirected to HTTP:
If you do not accept HTTP at the ELB, you should redirect to HTTPS only, with:
server {
listen 80;
server_name www.my-app.com;
return 301 https://my-app.com$request_uri;
}
However, if you accept either HTTP or HTTPS at the ELB, you should be able to use the X-Forwarded-Proto header inserted by the ELB. Try this:
server {
listen 80;
server_name www.my-app.com;
return 301 $http_x_forwarded_proto://my-app.com$request_uri;
}

Related

containerized reverse proxy showing default site

No matter what I do, I keep running into the problem where my website publishes the default nginx website. I'm trying to dockerize my webserver such that it can point to home assistant running in another container. I've been able to get it to work when both were hosted on the same raspi, not running in containers, but not when both are running in containers.
I've attached my nginx.conf, Dockerfile and default.conf that I was using to start the environment up. I've spent the last 2 days looking for someone who was trying to do something similar, but I assume I'm making such a stupid mistake that most have been able to figure it out on their own..
nginx.conf:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
default.conf (/etc/nginx/conf.d/hass.conf)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
# Update this line to be your domain
server_name nekohouse.ca;
# These shouldn't need to be changed
listen [::]:80 default_server ipv6only=off;
return 301 https://$host$request_uri;
}
server {
# Update this line to be your domain
server_name nekohouse.ca;
# Ensure these lines point to your SSL certificate and key
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
# Use these lines instead if you created a self-signed certificate
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/key.pem;
# Ensure this line points to your dhparams file
ssl_dhparam /etc/nginx/dhparams.pem;
# These shouldn't need to be changed
listen [::]:443 default_server ipv6only=off; # if your nginx version is >= 1.9.5 you can also add the "http2" flag here
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
proxy_buffering off;
location / {
proxy_pass http://localhost:8123;
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
default.conf (/etc/nginx/conf.d/default.conf)
server {
listen 8100;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
The problem is because of this line
proxy_pass http://localhost:8123;
When running in containers, you should understand that localhost refers to the nginx container and not the docker host.
So, you should either change localhost to the hostname of your docker host or use docker-compose so that you can change it to the name of the container defined.
If you are just running the containers separately, you could also just use the container IP for now but note that it will change everytime the container is restarted.

Nginx permission denied while loading virtual host file - Fedora 21

So I just installed nginx and everything works well for a start and I get the default nginx welcome message on my vps running fedora 21. Then when I try adding virtual hosts for my rails application, for some reason nginx is unable to load my virtual host file. It throws a permission denied error which I can't trace why its thrown. Tried everything possible but nothing seems to change.
nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
index index.html index.htm;
# 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;
# Load virtual host conf files. (line 44 below)
include /etc/nginx/sites-enabled/*;
server {
listen 80 default_server;
server_name localhost;
root /usr/share/nginx/html;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
# redirect server error pages to the static page /40x.html
#
error_page 404 /404.html;
location = /40x.html {
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
myblog(/etc/nginx/sites-available/myblog)
upstream thin{
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
# server_name www.sitename.com;
# rewrite ^/(.*) http://sitename.com/$1 permanent;
}
server {
listen 80;
# server_name sitename.com;
access_log /home/deployer/nginx-access.log;
error_log /home/deployer/nginx-error.log;
root /home/deployer/apps/myblog/current/public/;
index index.html;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
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_redirect off;
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://thin;
break;
}
}
}
The sites-enabled folder is symliked to the sites-available folder. On restarting nginx, I get this error
nginx: [emerg] open() "/etc/nginx/sites-enabled/myblog" failed (13: Permission denied) in /etc/nginx/nginx.conf:44
Permissions of the myblog virtual host file
-rw-r--r--. 1 root root 1112 Jun 1 10:58 /etc/nginx/sites-available/myblog
Is there something i'm missing? I'm not sure why nginx cannot load my file. Thanks!

Domain name rejected by nginx

I have a server running a very simple rails app. It has nginx set up to listen on port 80, which further forwards the request to a unicorn socket file under (Rails.root)/tmp/unicorn.sock.
I bought a domain name from domain.com and pointed it to my server's address=.
e.g.
Domain: mydomain.com -> Server: 110.56.45.12
Everything works great when I hit the server directly, by either visiting 110.56.45.12 in my browser or ssh-ing into the box and running curl 127.0.0.1. I assume this is because both these actions hit port 80 and nginx serves back the correct content.
However when I try to use the public domain name domain.com or I try curl localhost I get the classic "We're sorry, but something went wrong." rails page.
I checked the rails production log and there is nothing there. I then checked nginx error log at /var/log/nginx/error.log and only got
2015/05/27 07:01:24 [error] 20041#0: *143 connect() to unix:/home/jeeves/my_app/tmp/unicorn.sock failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: mydomain.com, request: "GET / HTTP/1.1", upstream: "http://unix:/home/jeeves/my_app/tmp/unicorn.sock:/", host: "localhost"
Is there any reason my server is rejecting that connection?
Thanks!
EDIT
Here's my nginx.conf file
user jeeves;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay off;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
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;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_http_version 1.1;
gzip_proxied any;
gzip_min_length 500;
gzip_types text/plain text/xml text/css
text/comma-separated-values text/javascript
application/x-javascript application/atom+xml;
##
# Unicorn Rails
##
upstream unicorn {
server unix:/home/jeeves/my_app/tmp/unicorn.sock fail_timeout=0;
}
##
# Includes
##
include /etc/nginx/sites-enabled/*;
}
The last line includes everything in the sites-enabled directory, which is only one file - mydomain.com
server {
listen 80;
server_name mydomain.com; # Replace this with your site's domain.
keepalive_timeout 300;
client_max_body_size 4G;
# Set this to the public folder location of your Rails application.
root /home/jeeves/my_app/public;
try_files $uri/index.html $uri.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded_Proto $scheme;
proxy_redirect off;
# This passes requests to unicorn, as defined in /etc/nginx/nginx.conf
proxy_pass http://unicorn;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
# You can override error pages by redirecting the requests to a file in your
# application's public folder, if you so desire:
error_page 500 502 503 504 /500.html;
}

How to add www. to domain with NginX and SSL?

I have a VPS with a Rails 4 app running on Ubuntu with NginX and Unicorn.
Since I want all pages to be SSL secured, all requests to http:// are forwarded to https:// which is working fine.
This is my NginX configuration:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server { server 127.0.0.1:8080 fail_timeout=0; }
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name myapp.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
index index.htm index.html;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://app_server;
}
}
}
How can I make it that all requests to http://myapp.com and https://myapp.com are forwarded to https://www.myapp.com?
Thanks for any help.
You can go about this two ways:
In your Rails app, detect if the requested URI contains a www and give a 30(1|2) redirect based on that (probably easiest).
Create an additional vhost in Nginx listening on myapp.com and only have it do redirects to www.myapp.com.
server {
listen 443;
server_name myapp.com;
[add ssl config]
return 301 https://www.myapp.com$request_uri;
}

403 / Forbidden error when trying to run Rails 4 app with SSL

I am trying to get my Rails 4 working with SSL on a VPS with Ubuntu and NginX. I retrieved an SSL certificate from StartSSL.com and the installation on the server seems to have been successful.
However, I can't get my app to work with https. It only works with http at this moment.
When I try to access it in the browser through https I am getting this error:
2014/06/04 18:05:56 [error] 23306#0: *3 "/home/rails/public/index.html" is forbidden (13: Permission denied), client: 23.251.149.69, server: myapp.com, request: "GET / HTTP/1.0", host: "myapp.com"
This would be my NGINX configuration file in /etc/nginx/nginx.conf:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server { server 127.0.0.1:8080 fail_timeout=0; }
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name myapp.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
}
}
What am I missing here and how can this be fixed?
I answered this over on DigitalOcean, but I noticed it here too.
You have an upstream set but no proxy_pass. I assume you're using something like Unicorn to serve the app? You probably need to adjust the server block listening on 443 to act as a reverse proxy for what ever is acting as an upstream server. Something like:
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
index index.htm index.html;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
location / {
try_files $uri/index.html $uri.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_server;
}
}

Resources