How to DRY nginx configuration - nginx

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;

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 config static website show 404 Not found

I'm config a static website in nginx,but show 404 notfound on browser
nginx version: nginx/1.10.3 (Ubuntu)
nginx configuration:
upstream client {
server 127.0.0.1:8080;
}
upstream admin {
server 127.0.0.1:8090;
}
server {
listen 443;
server_name mp.example.com;
ssl on;
ssl_certificate /etc/nginx/conf.d/certificate/mp.example.com/1_mp.example.com_bundle.crt;
ssl_certificate_key /etc/nginx/conf.d/certificate/mp.example.com/2_mp.example.com.key;
ssl_session_timeout 4m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://client;
#Proxy Settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /admin {
proxy_pass http://admin;
#Proxy Settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /zp {
root /root/admin_ui/1.1.0;
index index.html;
}
location ^~ /assets/ {
expires 90d;
alias /root/www/assets/;
}
}
server{
listen 80;
server_name mp.example.com;
location / {
rewrite ^(.*) https://$host$1 permanent;
}
}
Broswer screehshots:
my static website path:
I want input https://xx.xxxx.com/zp show my website
I think https configuration's problem, but i not sure

Ruby on rails app working on http but not on https

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.

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 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

Resources