Unable to access Elastic Beanstalk (single instance) from custom domain HTTPS - node.js

Greetings SO community,
I am attempting to configure my single-instance Elastic Beanstalk application to use a custom domain and HTTPS. Both the custom domain and SSL certificate were obtained from a third-party and uses their DNS servers (rather than Route 53).
I have added the .ebextensions/https-instance-securitygroup.config per AWS documentation (https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance.html) as well as the files for Node application (https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-nodejs.html). The only difference in the last step is that I did not create a .ebextensions/https-instance.config file as I am pushing my code to GitHub and using CodePipeline to build my code. So, the https.conf and certificates were manually created and uploaded to the EC2 instance.
Also, I have checked my instance's inbound rules to ensure that 80 & 443 are open on the EB instance and for the associated security group.
proxy.conf
upstream nodejs {
server 127.0.0.1:5000;
keepalive 256;
}
server {
listen 8080;
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
}
access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
access_log /var/log/nginx/access.log main;
location / {
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
gzip on;
gzip_comp_level 4;
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location /static {
alias /var/app/current/client/build/static;
}
}
https.conf
# HTTPS server
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/pki/tls/certs/server.crt;
ssl_certificate_key /etc/pki/tls/certs/server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# For enhanced health reporting support, uncomment this block:
#if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
# set $year $1;
# set $month $2;
# set $day $3;
# set $hour $4;
#}
#access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
#access_log /var/log/nginx/access.log main;
location / {
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.1;
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 https;
}
}

So after rereading the AWS documentation for what felt like the hundredth time, I was finally able to resolve my issues. And because I wasn't strictly using the preferred method of using an .ebextensions folder, I had to fiddle with the Nginx proxy on the Elastic Beanstalk-created EC2 instance directly.
In short, I was missing the following section from my /etc/nginx/conf.d/proxy.conffile:
location / {
### START MISSING ###
set $redirect 0;
if ($http_x_forwarded_proto != "https") {
set $redirect 1;
}
if ($http_user_agent ~* "ELB-HealthChecker") {
set $redirect 0;
}
if ($redirect = 1) {
return 301 https://$host$request_uri;
}
### END OF MISSING ###
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
This documented here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html
Specifically, This is a snippet from the NodeJS, default Nginx proxy config file: https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/security-configuration/https-redirect/nodejs/https-redirect-nodejs.config

Related

How do i enable auth_basic on nginx for a domain and multiple subdomains with only one password?

I successfully added the auth_basic directive to my server block with the following config:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=proxy_cache_path_global:10m loader_threshold=300 loader_files=200 max_size=2g inactive=60m use_temp_path=off;
upstream backend {
server localhost:8080;
keepalive 128;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com app.example.com;
auth_basic "Administrator’s Area";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://backend;
proxy_cache_methods GET HEAD;
proxy_cache proxy_cache_path_global;
proxy_cache_key $host$request_uri$cookie_user$slice_range;
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
proxy_cache_min_uses 3;
proxy_cache_valid any 1m;
proxy_cache_revalidate on;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_age 10s;
proxy_cache_lock_timeout 3s;
proxy_redirect off;
proxy_http_version 1.1;
proxy_read_timeout 300;
proxy_connect_timeout 300;
slice 1m;
add_header X-Cache-Status $upstream_cache_status;
proxy_set_header Host $host;
proxy_set_header Connection "";
proxy_set_header Range $slice_range;
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
When i visit my website, 2 login prompts appear after each other; one for example.com, and another one for app.example.com.
How do i configure this, so that i only have to type in my credentials once?
I already tried looking for a solution by myself unsuccessfully. Any hints would be appreciated.

Extend nginx on elastic beanstalk with websockets

I want to set up an elastic beanstalk app to work with HTTP and Websockets. I can get the HTTP working on port 8081, but I can't access my websocket server because I get a 301 redirect error with nginx. I can tell my websocket server is running, does anyone know why I can't access it? Here is my proxy.config file:
upstream nodejs {
server 127.0.0.1:8081;
keepalive 256;
}
upstream wsserver {
server 127.0.0.1:3000;
keepalive 256;
}
server {
listen 8080;
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
}
access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
access_log /var/log/nginx/access.log main;
# prevents 502 bad gateway error
large_client_header_buffers 8 32k;
location /ws/ {
# prevents 502 bad gateway error
proxy_buffers 8 32k;
proxy_buffer_size 64k;
proxy_pass http://wsserver;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location / {
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
gzip on;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
}

Cashing packages for npm registry with NGINX

My project is javascript app.
I have lots of dependencies.
I/O for npm registry takes major portion of CI execution.
So my idea is to setup NGINX in front of npm registry and cache tgz files downloads.
Im running Ubuntu 14.04.
NGINX version is 1.4.6
This is my nginx configuration script
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
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;
##
# Logging Settings
##
# access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
# include /etc/nginx/sites-enabled/*;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
default off;
https on;
}
server {
listen 80 default_server;
location / {
access_log /var/log/nginx/root.log;
root /var/tmp/nginx/npm;
try_files $request_uri #fetch;
}
location #fetch {
internal;
proxy_pass http://nmregistry:4873$request_uri;
proxy_store /var/tmp/nginx/npm$request_uri;
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_store_access user:rw group:rw all:r;
}
}
}
It works, i can install packages but they are not cached on NGINX machine.
Cant see any tgz files in /var/tmp/nginx/npm
What am i doing wrong here?
This is final version of configuration file.
The main problem was proxy_buffering on;
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
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;
##
# Logging Settings
##
error_log /var/log/nginx/error.logi debug;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
# include /etc/nginx/sites-enabled/*;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering on;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
default off;
https on;
}
server {
listen 80 default_server;
location / {
access_log /var/log/nginx/cache_root.log;
proxy_pass http://nmregistry:4873;
}
location ~* .+/-/.+$ {
root /var/tmp/nginx/npm;
expires max;
try_files $uri #fetch;
}
location #fetch {
internal;
proxy_pass http://nmregistry:4873$request_uri;
proxy_store on;
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_store_access user:rw group:rw all:rw;
proxy_temp_path /var/tmp/nginx/npm 1 2;
root /var/tmp/nginx/npm;
}
}
}

Prerender with nginx and node.js returns 504

If I understand things correctly I can setup nginx in a way that it handles crawlers (instead of nodejs doing it). So I removed app.use(require('prerender-node').set('prerenderToken', 'token')) from express configuration and made the following nginx setup (I do not use prerender token):
# Proxy / load balance (if more than one node.js server used) traffic to our node.js instances
upstream my_server_upstream {
server 127.0.0.1:9000;
keepalive 64;
}
server {
listen 80;
server_name test.local.io;
access_log /var/log/nginx/test_access.log;
error_log /var/log/nginx/test_error.log;
root /var/www/client;
# Static content
location ~ ^/(components/|app/|bower_components/|assets/|robots.txt|humans.txt|favicon.ico) {
root /;
try_files /var/www/.tmp$uri /var/www/client$uri =404;
access_log off;
sendfile off;
}
# Route traffic to node.js for specific route: e.g. /socket.io-client
location ~ ^/(api/|user/|en/user/|ru/user/|auth/|socket.io-client/|sitemap.xml) {
proxy_redirect off;
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_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass_header X-CSRFToken;
sendfile off;
# Tells nginx to use the upstream server
proxy_pass http://my_server_upstream;
}
location / {
root /var/www/client;
index index.html;
try_files $uri #prerender;
access_log off;
sendfile off;
}
location #prerender {
set $prerender 0;
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
if ($prerender = 1) {
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $prerender "127.0.0.1:3000";
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass http://$prerender;
}
if ($prerender = 0) {
rewrite .* /index.html$is_args$args break;
}
}
}
But when I test it by curl test.local.io?_escaped_fragment_= I get got 504 in 344ms for http://test.local.io
Node version is 6.9.1. I use vagrant to setup environment.
The above configuration works fine. All it was missing is an entry in /etc/hosts : 127.0.0.1 test.local.io

Nginx - Redirect HTTPS back to HTTP when leaving a secured page

I have Nginx in front of a Node.js app. I have it set up so that if the url has /account in it, it'll redirect to HTTPS. My question is - how do I set it up so that if the user leaves the /account url (clicks a link to go to the home page), it'll get sent back to HTTP?
Here's my ngnix.conf:
worker_processes 1;
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 128;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server_tokens off;
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
gzip on;
server {
listen 80;
server_name localhost;
location / {
proxy_set_header x-path $uri;
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-NginX-Proxy true;
proxy_pass http://127.0.0.1:3000;
proxy_redirect off;
}
location /account {
rewrite ^(.*) https://$host$1 permanent; #redirect to https
}
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 html;
}
}
server {
listen 443;
ssl on;
ssl_certificate ssl/server.crt;
ssl_certificate_key ssl/server.key;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-M-Secure "true";
proxy_redirect off;
proxy_max_temp_file_size 0;
proxy_pass http://127.0.0.1:3000;
}
}
}
Thanks in advance for any assistance.
This is untested.
server {
listen 443;
ssl on;
ssl_certificate ssl/server.crt;
ssl_certificate_key ssl/server.key;
location /account/ {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-M-Secure "true";
proxy_redirect off;
proxy_max_temp_file_size 0;
proxy_pass http://127.0.0.1:3000;
}
location / {
rewrite ^(.*) http://$host$1 permanent; # redirect to http
}
}

Resources