Basic Nginx config - ssl

Background, I'd been using just Node/expressJS over https like so
const httpsOptions = {
key: fs.readFileSync('config/example_com.key'),
cert: fs.readFileSync('config/example_com.crt'),
ca: [
fs.readFileSync('config/COMODORSAAddTrustCA.crt'),
fs.readFileSync('config/COMODORSADomainValidationSecureServerCA.crt')
]
};
https.createServer(httpsOptions, app).listen(port, function () {
});
All has been working fine - https establishing fine. Now I have a goal to establish to i) help with the server load; and ii) route to a static page that says "Too many people here now, please try again later" if there is too much traffic (rather than crashing the site).
To do that, I'm just trying to migrate to nginx as reverse proxy on the same server and same everything and it just won't do at all!
Latest I tried, it's "403 Forbidden" when I go to https://www.example.com/images/picture.jpg
Can anyone please help proofread my current setup?
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 443 ssl default_server;
listen [::]:443 default_server;
server_name example.com www.example.com;
ssl on;
ssl_certificate /home/ec2-user/MIP/config/example_com.crt;
ssl_certificate_key /home/ec2-user/MIP/config/example_com.key;
if ($http_host = www.example) {
return 302 https://example.com$request_uri;
}
root /home/ec2-user/MIP/views;
include /etc/nginx/default.d/*.conf;
location / {
return 302 https://www.example.com$request_uri;
}
location /images/ {
root /home/ec2-user/MIP/public;
}
}
}
Yes, I do have a .jpg file at /home/ec2-user/MIP/public/images/picture.jpg and I've done chmod +r on this file.
Also, for the record, for now, I have sudo killall node because otherwise when I do "sudo service nginx start", it'd complain "Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details."
Many thanks in advance
[UPDATE]
For the record, I've actually got the routing to external link bit working by:
location /images/ {
return 302 https://<bucketName>.s3-us-west-2.amazonaws.com/public$request_uri;
}
Now only struggling with serving internal content from an absolute path - which's been giving me 403 Forbidden despite I've done chown -R on the public folder, and have done chmod +r on the file too
location /js/ {
root /home/ec2-user/MIP/public/;
}

Related

How to hide NGINX server information in elastic beanstalk express application?

I have been grappling with this problem for a few days now. No matter what I do my application server keeps returning the NGINX version in the HTTP response headers and it doesn't meet OWASP security recommendations:
The Dreaded Server Information Response
I have tried to manually edit the server response in express in every which way I can think of, but the server version keeps showing up despite all of this: (express function attempting to remove server response headers in the overarching app.js file)
app.use(function(req, res, next) {
res.removeHeader('server');
res.removeHeader('Server');
res.removeHeader("x-powered-by");
res.header("X-powered-by", "Blood, sweat, and tears.");
next();
});
I have tried a whole bunch of .ebextensions to modify the nginx.conf file manually on deployment but none with success... Such as that outlined here: How to hide nginx version in elastic beanstalk
Recently I have decided 'screw it, I'm just going to upload my own nginx.conf file' and have been putting that up, but still no success. Here is the nginx.conf file I'm sending to AWS EB in platform/nginx/conf.d
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 33282;
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"';
include conf.d/*.conf;
more_clear_headers Server;
server_tokens off;
more_set_headers 'Server: BLOOD_AND_SWEAT';
map $http_upgrade $connection_upgrade {
default "upgrade";
}
server {
listen 80 default_server;
root /var/app/current/public;
location / {
}
access_log /var/log/nginx/access.log main;
client_header_timeout 60;
client_body_timeout 60;
keepalive_timeout 60;
gzip off;
gzip_comp_level 4;
more_clear_headers Server;
server_tokens off;
more_set_headers 'Server: BLOOD_AND_SWEAT';
# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/01_static.conf;
include conf.d/elasticbeanstalk/healthd.conf;
}
}
I have been trying everything and anything for days.
What have I been doing wrong here? Why is this NGINX server information so hard to get rid of!!!??
I think I have made contact with the devil himself, and he cannot be slayed.
From this document
http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
You can just set server_tokens to off in http{ } section something like this:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#tcp_nodelay on;
server_tokens off;
include /etc/nginx/conf.d/*.conf;
}
Many thanks to Fahim from IntelG who found the problem here.
I had missed the dot in front of platform, As stated in the question above, I was saving the conf file in
platform/nginx/conf.d
should have been
.platform/nginx/conf.d
So much time wasted for such a stupid thing!!!

Non www version redirect to nginx default page instead of website how can i fix?

Non www version redirect to nginx default page instead of website how can i fix this?
https://www works fine
http://www works fine
https:// works fine
But http:// don't work people get to the default nginx page instead of website
Here is my nginx config file:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 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;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /var/www/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
My issue is I can't seem to make it redirect from http://example.com to https://www.example.com instead showing nginx standard page.
return 301 https://$host$request_uri; i tried this as well and still not working
P.S. Also I am using apache to with nginx in combination
How can I fix?
Thanks
The nginx redirection will looks like
server {
listen 80;
server_name yourdomain.com;
access_log off;
return 301 https://www.yourdomain.com$request_uri;
}
server {
server_name yourserveripaddress;
access_log off;
return 301 https://www.yourdomain.com$request_uri;
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/yourdomain.com.chained.crt;
ssl_certificate_key /etc/nginx/ssl/yourdomain_com.key;
access_log off;
return 301 https://www.yourdomain.com$request_uri;
}

Keep getting ERR_CONNECTION_REFUSED with NGINX conf

I keep getting ERR_CONNECTION_REFUSED
worker_processes 4;
events { worker_connections 1024; }
http {
sendfile off;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
listen 80;
listen [::]:80;
# server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
add_header Allow "GET, HEAD" always;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
if ( $request_method !~ ^(GET|HEAD)$ ) {
return 405;
}
return 200;
}
}
it successfully redirects me from http:localhost to https:localhost, but all I see is this immediately:
Does anyone know why this is happening? is it my certs?
I am just using localhost right now, so it probably isn't firewall thing. Unfortunately, nothing shows up in the access or error logs which is frankly pretty sorry.
The simple answer was I was using docker, and I needed to open up port 80 AND port 443:
docker run -d -p 80:80 -p 443:443 "$my_image"

HTTP Upgrade to TLS in Nginx Per RFC 2817

I have been looking into how I can upgrade an HTTP connection to TLS and achieve and end to end tunnel across proxy hops. I would like to use the client certificate in this tunnel to act upon it on the receiving end after a few hops.
I read RFC 2817 (HTTP Upgrade to TLS) and it seems this is possible. I just cannot figure out how to do that using Nginx being new to Nginx.
I was wondering if I am making a complete noob mistake or if this is at all possible in Nginx.
I have Nginx instance 1 with the following config for the http block:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher '
'$ssl_client_cert '
'$ssl_client_raw_cert '
'HTTP UPGRADE: $http_upgrade '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log logs/access.log;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
access_log logs/access-ssl.log main;
ssl_certificate /root/certs/server.crt;
ssl_certificate_key /root/certs/server.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /root/certs/dhparams.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass https://10.0.3.4/;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
The second Nginx instance has the following config has pretty much the same config except for one difference proxy_pass https://10.0.3.5/index.html
The last Nginx instance has the following config:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher '
'$ssl_client_cert '
'$ssl_client_raw_cert '
'HTTP UPGRADE: $http_upgrade '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log logs/access.log;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
access_log logs/access-ssl.log main;
ssl_certificate /root/certs/server.crt;
ssl_certificate_key /root/certs/server.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /root/certs/dhparams.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location / {
root html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
When I hit the URL using HTTPS, I do get the response but nothing about the client cert is printed in the logs. When I use only HTTP, I get the 301 response. These are the two calls I am making:
$ curl -k -i --cert /root/certs/client-cert.pem --key /root/certs/client-key.pem --header "Upgrade: TLS/1.2" --header "Connection: Upgrade" https://10.0.3.3/
and
$ curl -k -i --cert /root/certs/client-cert.pem --key /root/certs/client-key.pem --header "Upgrade: TLS/1.2" --header "Connection: Upgrade" http://10.0.3.3/
RFC 2817 defines two methods for TLS upgrade: CONNECT request and Connection: Upgrade.
CONNECT is a HTTP request done by the browser when using an explicitly configured HTTP proxy. It gets not used with transparent proxies or reverse proxies. Contrary to for instance squid nginx is a web server and not a HTTP proxy (from the perspective of the browser) and thus does not implement the CONNECT request.
As for the Connection Upgrade to TLS specified in RFC 2817: this was just an idea and no browser supports this. This kind of Upgrade mechanisms is actually used in browsers today but not for upgrading to TLS but only for WebSockets.

Assets not loading in production for rails app

The current app I am running is working just fine in production on its ubuntu server. But now I've had to configure a Red Hat Enterprise Linux 5.5 server to deploy the app to and I am running into some issues. First of all some specs:
rails version: 3.2.11
ruby: 1.9.3-p194
http server nginx + unicorn
managing ruby environment with rbenv
deploy method: capistrano
My nginx.conf and unicorn config file are based on Ryan Bate's videos. So I managed to get almost everything configured. I can deploy, connect to the database, etc.. However, when I visit my app's page, all of the assets fail to load. And when I go into my console it says they failed because of a 403 Forbidden error. I checked and the assets are in the correct place: apps/my_app/shared/assets. But I keep getting this 403 error.
What I've tried so far:
checked the permissions to parent folders and the actual asset files. They all had at least read permissions for everyone
changed config.assets.compile to true
Followed instructions here rails deployment using nginx & unicorn: 403 forbidden error, which recommends removing the default files in conf.d and symlinking my custom nginx config file to /etc/nginx/conf.d as opposed to .../sites-enabled
Any thoughts or ideas why I am getting a 403?
Edit 1: add /etc/nginx/nginx.conf file
Not sure if this helps but this is what the nginx.conf file (under /etc/nginx) looks like (not my custom nginx file):
events {
worker_connections 1024;
}
#----------------------------------------------------------------------
# HTTP Core Module
#
# http://wiki.nginx.org/NginxHttpCoreModule
#
#----------------------------------------------------------------------
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;
#
# The default server
#
server {
listen 80;
server_name _;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/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;
#}
}
# Load config files from the /etc/nginx/conf.d directory
include /etc/nginx/conf.d/*.conf;
}
Also, I noticed that under /etc/nginx there are nginx.conf and nginx.conf.default files, does anyone know the difference? Maybe the issue could be there?
Edit 2: Add entry from nginx log file
So I found this in the nginx log file. So maybe it is a permissions issue that could be fixed with a chmod?
2013/03/24 20:50:53 [error] 10851#0: *5 open() "/home/webapp/apps/my_app/current/public/assets/application-db22bc3811b126e586f5e82e794e7ee4.css" failed (13: Permission denied)
Edit 3: Update /etc/nginx/nginx.conf
user nginx;
worker_processes 2;
# error_log logs/error.log;
# error_log logs/error.log notice;
# error_log logs/error.log info;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include 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;
sendfile on;
#tcp_nopush on;
keepalive_timeout 60;
gzip on;
include /etc/nginx/conf.d/*.conf;
# INSIDE THE /etc/ngin/conf.d/*.conf FILE #
server {
listen 80 default deferred;
# server_name example.com;
root /home/webapp/apps/my_app/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
}
So I managed to fix this. In part to advice in this article http://nginxlibrary.com/403-forbidden-error/
for all the directories leading up to all the asset files, I set the directory permissions to chmod 775. And then for all the assets (application.js, etc...) inside apps/my_app/shared/assets I gave the files this permission chmod 775.
And that did the trick. In the article I linked to, the author mentions the need for the asset files to have both read and execute permissions, not just read.