My nodejs app is deployed on AWS EB. I already configured the https server and it is working fine. Now I need to redirect every non-https request to https with the www. as prefix, like this:
GET example.com => https://www.example.com
I'm using nginx and my EB instance is a single instance without load balancer in front of it.
I have created a config file in the .ebextensions folder with this code
Resources:
sslSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
CidrIp: 0.0.0.0/0
files:
/etc/nginx/conf.d/999_nginx.conf:
mode: "000644"
owner: root
group: root
content: |
upstream nodejsserver {
server 127.0.0.1:8081;
keepalive 256;
}
# HTTP server
server {
listen 8080;
server_name localhost;
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443;
server_name localhost;
ssl on;
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_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://nodejsserver;
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;
}
}
/etc/pki/tls/certs/server.crt:
mode: "000400"
owner: root
group: root
content: |
-----BEGIN CERTIFICATE-----
my crt
-----END CERTIFICATE-----
/etc/pki/tls/certs/server.key:
mode: "000400"
owner: root
group: root
content: |
-----BEGIN RSA PRIVATE KEY-----
my key
-----END RSA PRIVATE KEY-----
/etc/nginx/conf.d/gzip.conf:
content: |
gzip on;
gzip_comp_level 9;
gzip_http_version 1.0;
gzip_types text/plain text/css image/png image/gif image/jpeg application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;
gzip_proxied any;
gzip_disable "msie6";
commands:
00_enable_site:
command: 'rm -f /etc/nginx/sites-enabled/*'
I'm sure aws is taking in account my config because de ssl is working fine. But the http block does not work.. There is no redirect.
Maybe my problem is about rewriting the original nginx config of EB, do you know how to achieve this ?
Can you help me with that please ? I've tried a lot of things..
Thank you
OK, found the issue, EB creates a default config file /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf which is listening to 8080. So your re-direct isn't being picked up as Nginx is using the earlier defined rule for 8080.
Here's a config file that I use that works. The file it generates will precede the default rule.
https://github.com/jozzhart/beanstalk-single-forced-ssl-nodejs-pm2/blob/master/.ebextensions/https-redirect.config
Related
I built a react app using the create-react-app and npm run buildcommands and connected it to node with server.jsfile in the directory created by create-react-app.
When running the command node server locally it works perfectly fine however when I pushed the changes to my nginx server I started to get a 502 bad gateway status. Why is this happening? Node is running when I get this error.
Here is the server.js code
onst express = require('express');
const path = require('path');
const app = express();
app.use('/js', express.static(path.join(__dirname, 'src/')));
app.use('/css', express.static(path.join(__dirname, 'src/')));
app.use(express.static(path.join(__dirname , '/public/build')));
// Handles any requests that don't match the ones above
app.get('/', (req,res) =>{
res.sendFile(path.join(__dirname , "/public/build/index.html"));
});
const port = process.env.PORT || 5000;
app.listen(port);
console.log('App is listening on port ' + port);
the error log
[error] 7422#7422: *4477 connect() failed (111: Connection refused) while connecting to upstream, client: 162.84.158.175, server: anthonyjimenez.me, request: "GET / HTTP/2.0", upstream: "http://127.0.0.1:3000/", host: "anthonyjimenez.me"
and the config file
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;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
go to /nginx/sites-enabled/default and add the following blocks. You will have to tell Nginx and forward this request this way
server {
listen 443 ssl ;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; //ssl
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; //ssl
index index.html index.htm index.nginx-debian.html;
server_name example.com;
location / {
proxy_pass http://localhost:3001; //Your port goes here
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I am following the AWS documentation to configure HTTPS for a single instance eb application.
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-nodejs.html
Below is my configuration file which I amputting in .ebextensions. Please find it below (I have masked the certificate and Key for security purposes.
files:
/etc/nginx/conf.d/https.conf:
mode: "000644"
owner: root
group: root
content: |
# HTTPS server
server {
listen 443;
server_name localhost;
ssl on;
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;
}
}
/etc/pki/tls/certs/server.crt:
mode: "000400"
owner: root
group: root
content: |
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
/etc/pki/tls/certs/server.key:
mode: "000400"
owner: root
group: root
content: |
-----BEGIN RSA PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END RSA PRIVATE KEY-----
But when I redeploy the application I am able to access the beanstalk URL via http the moment I try with HTTPs I get "503 Service Temporarily Unavailable" error. Can anyone help me out here.
I create droplet on DigitalOcean, setup my nodeJS app on it, connected my domain and everything works ok, but I wanted to setup https andI installed all certificates etc. I run it on CentOS 7.5, my nodeJS app is in this directory:
/home/mdurakovic/mensurdurakovic.com
HTTP works fine, but I when I try to open my website with HTTPS I get error message in browser
403 Forbidden nginx/1.12.2
So I looked up in nginx logs and I see this error:
2019/01/02 23:03:39 [error] 11014#0: *1 directory index of "/home/mdurakovic/mensurdurakovic.com/public/" is forbidden, client: 213.149.62.113, server: mensurdurakovic.com, request: "GET / HTTP/2.0", host: "mensurdurakovic.com"
I changed group permissions so when I execute this command:
f: /home/mdurakovic/mensurdurakovic.com/public/
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwx--x--- mdurakovic nginx mdurakovic
drwxrwxrwx nginx nginx mensurdurakovic.com
drwxrwxrwx nginx nginx public
As you can clearly see, nginx has rights to execute user's home dir, but it still doesn't work. Any help will be appreciated.
EDIT:
Here is my /etc/nginx/conf.d/mensurdurakovic.com.conf file:
server {
listen 80;
server_name mensurdurakovic.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://68.183.69.186:8080;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mensurdurakovic.com;
root /home/mdurakovic/mensurdurakovic.com/public;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/mensurdurakovic.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mensurdurakovic.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-$
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
resolver 8.8.8.8;
}
You are having your http connection proxy the request, but not https. If you add a block in your ssl config (and remove root and resolver) it should work as expected:
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://68.183.69.186:8080;
}
I´m trying to add a .htaccess to my ghost project to enable the gzip compression, Im serving my project in Nginx Ubuntu 16 and Ghost-cli, i see that sites-avalable generates a proxy that redirects to the node that runs on localhost:2368, this is the configutation
server {
server_name latribu.mx www.latribu.mx;
root /var/www/latribu.mx/html/system/nginx-root;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
location ~ /.well-known {
allow all;
}
client_max_body_size 50m;
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/latribu.mx/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/latribu.mx/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = latribu.mx) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = www.latribu.mx) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name latribu.mx www.latribu.mx;
return 404; # managed by Certbot
}
How can i add .htaccess file to my project
Nginx does not support .htaccess file like Apache. If you want to enable GZip with Nginx, open /etc/nginx/nginx.conf. Scroll down to the GZip settings section and add these lines.
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
Then restart Nginx with service nginx restart.
First of all, add your .htaccess where you want. Let's say it's in /var/projects/projectName/.htaccess
In location / { => you have to add
auth_basic "Restricted Content";
auth_basic_user_file /var/projects/projectName/.htaccess;
Hope this was helpful
I got the following nginx config:
server {
listen 80;
server_name domainName.com;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/rss+xml text/javascript image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype;
access_log /var/log/nginx/logName.access.log;
location / {
proxy_pass http://127.0.0.1:9000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ ^/(min/|images/|ckeditor/|img/|javascripts/|apple-touch-icon-ipad.png|apple-touch-icon-ipad3.png|apple-touch-icon-iphone.png|apple-touch-icon-iphone4.png|generated/|js/|css/|stylesheets/|robots.txt|humans.txt|favicon.ico) {
root /root/Dropbox/nodeApps/nodeJsProject/port/public;
access_log off;
expires max;
}
}
It is proxy for node.js application on port 9000.
Is it possible to change this config to let nginx use another proxy url (on port 9001 for example) in case nginx got 504 error.
I need this in case when node.js server is down on port 9000 and need several seconds to restart automatically and several seconds nginx gives 504 error for every request. I want nginx to "guess" that node.js site on port 9000 is down and use reserve node.js site on port 9001
Use upstream module.
upstream node {
server 127.0.0.1:9000;
server 127.0.0.1:9001 backup;
}
server {
...
proxy_pass http://node/;
...
}