Nginx Config for IP Address URL - ruby-on-rails

I wish to setup my URL like this https://IP_ADDRESS/. I have already setup rails and puma and I'm struggling with the Nginx config. My server is on Ubuntu 16.04.
/etc/nginx/sites-available/default :
upstream app-name-production-backend {
server unix:///home/rails/apps/app-name/production/shared/sockets/puma.sock;
}
server {
listen 80;
listen [::]:80 ipv6only=on;
root /home/rails/apps/app-name/production/current/public/;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
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;
if (!-f $request_filename) {
proxy_pass http://app-name-production-backend;
break;
}
}
}
Is my Nginx config correct?

So, the issue I was having is that I had the force_ssl statement in the application_controller.rb, this was forcing everything through https (port 443) and not serving anything through http (port 80) and because port 443 was not configured and I didn't have any SSL certificates in place it was displaying the This site can’t be reached (on chrome) message.

Related

Setup nginx in docker. Want to send request from docker backend container to internet

I have a backend container in internal docker network, which is not accessible to the internet.
Through nginx proxy i want to send request (webhook to slack) from backend server to outside world. Is it possible at all?
I have this config for nginx:
server {
listen 80 default_server;
server_name localhost;
client_max_body_size 100M;
charset utf-8;
... # setup for server containers
}
server{
listen 443;
server_name hooks.slack.com;
location / {
proxy_pass https://hooks.slack.com/;
proxy_redirect off;
proxy_set_header Host $http_host;
#proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #Gets CSS working
#proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

NGINX Reverse Proxy Configuration Structure

Is there a "proper" structure for the directives of an NGINX Reverse Proxy? I have seen 2 main differences when looking for examples of an NGINX reverse proxy.
http directive is used to house all server directives. Servers with data are listed in a pool within the upstream directive.
server directives are listed directly within the main directive.
Is there any reason for this or is this just a syntactical sugar difference?
Example of #1 within ./nginx.conf file:
upstream docker-registry {
server registry:5000;
}
http {
server {
listen 80;
listen [::]:80;
return 301 https://$host#request_uri;
}
server {
listen 443 default_server;
ssl on;
ssl_certificate external/cert.pem;
ssl_certificate_key external/key.pem;
# set HSTS-Header because we only allow https traffic
add_header Strict-Transport-Security "max-age=31536000;";
proxy_set_header Host $http_host; # required for Docker client sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
location / {
auth_basic "Restricted"
auth_basic_user_file external/docker-registry.htpasswd;
proxy_pass http://docker-registry; # the docker container is the domain name
}
location /v1/_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
}
}
Example of #2 within ./nginx.conf file:
server {
listen 80;
listen [::]:80;
return 301 https://$host#request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
error_log /var/log/nginx/error.log info;
access_log /var/log/nginx/access.log main;
ssl_certificate /etc/ssl/private/{SSL_CERT_FILENAME};
ssl_certificate_key /etc/ssl/private/{SSL_CERT_KEY_FILENAME};
location / {
proxy_pass http://app1
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-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr; # could also be `$proxy_add_x_forwarded_for`
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
}
I dont quite understand your question, but it seems to me that the second example is missing the http {}, I dont think that nginx will start without it.
unless your example2 file is included somehow in the nginx.conf that has the http{}

How to remove /SOGo from Zentyal 6.1 Webmail Login

Working with a fresh install of Zentyal 6.1, how do I remove /SOGo from the default webmail login. Currently users need to access https://mail.mydomain.com/SOGo (Case sensitive) when I would like them to be able to access at https://mail.mydomain.com/.
I have tried adding the below to /etc/apache2/sites-enabled/default-ssl.conf. Result of that is the text on the page loading but all includes such as css and just return net::ERR_ABORTED 403 (Forbidden).
ServerName mail.domain.com
ProxyPass / http://127.0.0.1/SOGo/ retry=0
ProxyPassReverse / http://127.0.0.1/SOGo/
Ideally I would like all users to access mail.domain.com to access webmail. Also, I would like Outlook clients to use mail.domain.com for the server. This will be setup with multiple virtual mail domains for end users, such as joe#domain1.com or jane#domain2.com.
You should try using the Apache rewrite mod in order to redirect the url you like to the SOGo url. See this:
https://httpd.apache.org/docs/2.4/rewrite/remapping.html
BR.
I ended up scrapping Zentyal and switched to MailCow in Docker. Access SoGo via mail.domain.com. Below is the Reverse-Proxy for NGINX outside of Docker.
#######
### NGINX Reverse-Proxy to mailcow and SOGo
### Redirects root to SOGo and /setup to mailcow control panel
### Handles all SSL security
#######
## HTTP catch-all for invalid domain names (e.g. root domain "example.com")
server {
listen 80 default_server;
listen [::]:80 default_server;
# Have NGINX drop the connection (return no-data)
return 444;
}
## Redirect HTTP to HTTPS for valid domain names on this server
## (e.g. mail.example.com, webmail.example.com)
server {
listen 80;
listen [::]:80;
server_name mail.domain-name.com
autodiscover.domain-name.com
autoconfig.domain-name.com;
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
# Path can be used for cert-validation on all domains
root /var/www/html/;
break;
}
# Redirect to properly formed HTTPS request
return 301 https://$host$request_uri;
}
## HTTPS catch-all site for invalid domains that generate a certificate
## mismatch but the user proceeds anyways
server {
listen 443 default_server ssl http2;
listen [::]:443 default_server ssl http2;
# SSL settings in another file (see my 'mozModern_ssl' file as an example)
# include /etc/nginx/mozModern_ssl.conf
# SSL certificates for this connection
ssl_certificate /etc/letsencrypt/live/mail.domain-name.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mail.domain-name.com/privkey.pem;
# Have NGINX drop the connection (return no-data)
return 444;
}
## Proxy primary server and webmail subdomain to mailcow
## Go to SOGo after typing root address only (default browsing action)
## Go to mailcow admin panel after typing /admin subdirectory
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mail.domain-name.com
autodiscover.domain-name.com;
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
# Path can be used for cert-validation on all domains
root /var/www/html/;
break;
}
# SSL settings in another file (see my 'mozModern_ssl' file as an example)
#include /etc/nginx/mozModern_ssl.conf
# SSL certificates for this connection
ssl_certificate /etc/letsencrypt/live/mail.domain-name.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mail.domain-name.com/privkey.pem;
location /Microsoft-Server-ActiveSync {
proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync;
proxy_set_header Host $http_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_connect_timeout 75;
proxy_send_timeout 3650;
proxy_read_timeout 3650;
proxy_buffers 64 256k;
client_body_buffer_size 512k;
client_max_body_size 0;
}
# Redirect root to SOGo. Rewrite rule changes / to /SOGo
location / {
rewrite ^/$ /SOGo;
proxy_pass https://127.0.0.1:8443;
proxy_set_header Host $http_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;
client_max_body_size 100m;
}
# Redirect /setup to mailcow admin panel
# Note the trailing / after setup and the trailing / after proxy URL
# This makes sure that NGINX doesn't try to go to proxyURL/setup which
# would result in a 404.
# Recent updates result in loops if you try to use 'admin' here
location ^~ /setup/ {
proxy_pass https://127.0.0.1:8443/;
proxy_set_header Host $http_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;
client_max_body_size 100m;
}
}

Nginx redirect https->http(reverse proxy)->port(docker container)

Context
Simple setup
A docker container exposing 8090 as a website (node, express)
A nginx conf exposing 80 and mapping it to localhost 8090
Issue
I don't have paid SSL certificate, I want end users that try to reach https to be redirected to http.
I have tried redirects, rewrite, and here below a simple listen.. without success. Browser would return 'ERR_SSL_PROTOCOL_ERROR'.
server {
listen 80;
listen 443;
ssl off;
server_name xxxx.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://0.0.0.0:8090";
}
}
Question
Could you please advise on the cleanest way to redirect https->http(reverse proxy) ? Regards
Edit 1
The following config results in a browser "ERR_SSL_PROTOCOL_ERROR".
server {
listen 80;
server_name xxxx.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://0.0.0.0:8090";
}
}
server {
listen 443;
server_name xxxx.com;
rewrite ^(.*) http://$host$1 permanent;
}
Using letsencrypt to get a free certificate and then either use https or redirect to http was the solution for me.
Credits to #RichardSmith
You can try to use TCP restreaming by ngx_stream_core_module
http://nginx.org/en/docs/stream/ngx_stream_core_module.html
stream {
server {
listen 443;
proxy_pass 127.0.0.1:80;
}
}

Rails' *_url helpers with custom (not 80) port in production. (Nginx, Unicorn)

I'm noob in rails production environment.
Can I configure nginx and unicorn to response on other (not 80) port? I don't need any domains, i need only ip and port.
Here is nginx config to my application (80 port):
server {
listen 80;
server_name localhost;
root /home/my_app_folder/web-app/public;
client_max_body_size 32m;
location / {
try_files $uri #unicorn;
}
location #unicorn {
proxy_set_header Client-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://unix:/home/my_app_folder/web-app/tmp/sockets/unicorn.sock;
}
}
My application work fine with 80 port.
If I change 80 to 3000 for example, like here:
server {
listen 3000;
server_name localhost;
root /home/my_app_folder/web-app/public;
client_max_body_size 32m;
location / {
try_files $uri #unicorn;
}
location #unicorn {
proxy_set_header Client-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://unix:/home/my_app_folder/web-app/tmp/sockets/unicorn.sock;
}
}
I get a problem. Everything work fine, I can go to http://my_ip:3000 but Rails' url helpers (for example root_url, ect.) are without port (http://my_ip).
What can I do to see url helpers with port? Is there a way to do this in the configuration files of Nginx or maybe Unicorn? After all, when I run locally Webrick, it has the form of URL http://localhost:3000 and every *_url helper return url with the port 3000. I need to could change a few config files, and transfer the application to another port.
Thanks.
Try putting something like this in your application controller:
default_url_options[:port] = 3000 if Rails.env.production?
or, depending on what version of Rails you are using:
Rails.application.routes.default_url_options[:port]= 3000 if Rails.env.production?
Credit - Dylan's answer at:
default_url_options and rails 3

Resources