Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Password protect AWS Node EB application

I've got a Node Elastic Beanstalk app up and running (though ELB). Right now it is just the AWS sample Node application on the server. Since this is a development server, before I can push my actual code up to the server I need to password protect the entire thing (this is to be used for client review, etc).

I am having a ton of trouble trying to figure out how to do this. It seems that the application code is dropped in /var/app/ and there's nothing in /var/www/html/ (no hidden files) where I would normally setup an htaccess file. It's using nginx proxy, which I have never used, and I'm not exactly sure how the files are being served.

What's the best way to lock this server down? Security groups? htaccess? Something else?

like image 924
theflowersoftime Avatar asked Jul 10 '14 17:07

theflowersoftime


3 Answers

If you are using Express.js you can add a lightweight middleware using the basic-auth package. In my case, all I needed was one username and password to lock down the site from the public. This was the easiest solution for that scenario when using a Node.js server on Elastic Beanstalk.

var auth = require('basic-auth');

app.use(function(req, res, next) {
  var credentials = auth(req);

  if (!credentials || credentials.name !== 'buster' || credentials.pass !== 'getinfree') {
    res.statusCode = 401;
    res.setHeader('WWW-Authenticate', 'Basic realm="example"');
    res.end('Access denied.');
  } else {
    next();
  }
});

Note this solution requires adding the code within your Node app, not directly interfering with nginx.

like image 85
ebuat3989 Avatar answered Oct 24 '22 02:10

ebuat3989


In your Node.js Beanstalk application your instances will have their /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf set up like this:

server {
    listen 8080;

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

What you want is for it to be set up like this:

server {
    listen 8080;

    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;
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
    gzip on;
}

With a separate password file at /etc/nginx/.htpasswd that containts your login credentials.

STEP 1: Go to your local linux environment and enter

sudo htpasswd -c .htpasswd someusernameofyourchoice

navigate into that .htpasswd file and pull out the username and password line that you generated. It will look something like this:

someusernameofyourchoice:$apr1$.1EAU7DD$rt9jdihy1U.cFuBzJTMed.

STEP 2:

Now in your root directory of your node application (where your .git/ directory is located) create a hidden directory called .ebextensions/

navigate into that .ebextensions/ directory as you will need to make 2 files.

STEP 3:

The first file will be the config file that will generate your .htpasswd file on your beanstalk application. Place the username and password hash that you generated earlier into this file and name it as follows:

00_nginx_htpasswd.config

files:
  "/etc/nginx/.htpasswd" :
    mode: "000755"
    owner: root
    group: root
    content: |
      someusernameofyourchoice:$apr1$.1EAU7DD$rt9jdihy1U.cFuBzJTMed.

STEP 4:

The second file you will create in your .ebextensions/ directory will update the 00_elastic_beanstalk_proxy.conf file on your elastic beanstalk environment. Name is as follows:

01_nginx_auth.config

files:
  /tmp/deployment/nginx_auth.sh:
    mode: "000755"
    content: |
        sed -i 's/$proxy_add_x_forwarded_for;/$proxy_add_x_forwarded_for;\n     auth_basic "Restricted";\n  auth_basic_user_file \/etc\/nginx\/.htpasswd;\n/' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf
container_commands:
  nginx_auth:
    command: "/tmp/deployment/nginx_auth.sh"

NOTE: If you only want the password protection to be on a certain environment such as your development environment. You can pass an environment variable into your environment (in the configurations > Software Configurations panel on you beanstalk dashboard) and then you can add a conditional to this file's command that checks that environment variable before it runs. This way you can password protect your development environment while leaving your production environment free for the public to access. As you are putting everything into git to push it to your beanstalk environment, this is very handy. The following is the modified file with those additions:

01_nginx_auth.config

files:
  /tmp/deployment/nginx_auth.sh:
    mode: "000755"
    content: |
      if [ "$NODE_ENV" == "development" ]; then
        sed -i 's/$proxy_add_x_forwarded_for;/$proxy_add_x_forwarded_for;\n     auth_basic "Restricted";\n  auth_basic_user_file \/etc\/nginx\/.htpasswd;\n/' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf
      fi
container_commands:
  nginx_auth:
    command: "/tmp/deployment/nginx_auth.sh"

STEP 5:

Once you have both of these files created in your .ebextensions/ directory, commit them and push them to your elastic beanstalk. You should now be prompted for that username and password combination you generated in step 1.

like image 35
August Brenner Avatar answered Oct 24 '22 02:10

August Brenner


Security groups will only block based on source IP, and htaccess is not supported by nginx. Instead they support configuration like this:

server {
    ...
    auth_basic "closed website";
    auth_basic_user_file conf/htpasswd;
}

But to achieve this you'll need to use elastic beanstalk's .ebextensions to modify the default nginx configuration. It's not easy at all.

The fastest way for you is probably to support HTTP auth within your node app itself. There are many guides to this, but here is one: http://www.sitepoint.com/http-authentication-in-node-js/

like image 23
rgareth Avatar answered Oct 24 '22 01:10

rgareth