Giter Site home page Giter Site logo

fromxt / heroku-tls-auth-nginx-sample Goto Github PK

View Code? Open in Web Editor NEW

This project forked from gregburek/heroku-tls-auth-nginx-sample

0.0 1.0 0.0 152 KB

A sample Heroku app that shows how to use the nginx buildpack to require SSL for some connections

License: MIT License

Ruby 67.79% Shell 32.21%

heroku-tls-auth-nginx-sample's Introduction

heroku-tls-auth-nginx-sample

This repo shows several ways that you may use the nginx buildpack to add TLS and basic authentication to your Heroku app.

HTTPS Redirects

Configuring your Heroku app so that it will redirect insecure HTTP traffic to an HTTPS endpoint can be finicky and is language/framework specific.

The nginx buildpack gives us a broadly applicable and language angnostic way to redirect HTTP app traffic to a secure HTTPS address.

By adding:

if ($http_x_forwarded_proto != 'https') {
  rewrite ^ https://$host$request_uri? permanent;
}

to the location section of your app's nginx config file template, any access to that location will be met with a 301 Moved Permanently redirect to the https version of that site and path.

As all apps are accessible at https://<app-name>.herokuapp.com/ by using Heroku's herokuapp.com SSL cert, this provides a free and easy way to secure your apps. Custom domain names require custom SSL certs, which are available from traditional SSL vendors or from Heroku addon Expedited SSL

HSTS Headers

By adding a HTTP Strict Transport Security (HSTS) header to your app's HTTP response, modern clients will remember that your site should only be accessed via HTTPS.

Add this line to your nginx.conf.erb:

add_header Strict-Transport-Security max-age=31536000;

HTTP Basic Authentication

With a .profile.d script, it is possible to generate an .htpasswd file on dyno boot that contains a username and password in config vars. This file can then be used by nginx for basic authentication.

In .profile.d/gen-htpasswd.sh:

#!/usr/bin/env bash
set -ex

echo -e "${USERNAME}:$(perl -le 'print crypt($ENV{"PASSWORD"}, rand(0xffffffff));')" > /app/config/basic.htpasswd

In nginx.conf.erb location section:

auth_basic              "Restricted";
auth_basic_user_file    basic.htpasswd;

Try it out on Heroku

Deploy

Manual set up

> git clone https://github.com/gregburek/heroku-tls-auth-nginx-sample
> cd heroku-tls-auth-nginx-sample
> heroku create
Creating frozen-fortress-6701... done, stack is cedar
https://frozen-fortress-6701.herokuapp.com/ | [email protected]:frozen-fortress-6701.git
Git remote heroku added

> heroku config:set BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git
Setting config vars and restarting frozen-fortress-6701... done, v5
BUILDPACK_URL: https://github.com/ddollar/heroku-buildpack-multi.git

> git push heroku master
Fetching repository, done.
Counting objects: 1, done.
Writing objects: 100% (1/1), 197 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)

-----> Fetching custom git buildpack... done
-----> Multipack app detected
=====> Downloading Buildpack: https://github.com/ryandotsmith/nginx-buildpack.git
=====> Detected Framework: nginx-buildpack
-----> nginx-buildpack: Installed nginx/1.5.7 to app/bin
-----> nginx-buildpack: Added start-nginx to app/bin
-----> nginx-buildpack: Default mime.types copied to app/config/
-----> nginx-buildpack: Custom config found in app/config.
=====> Downloading Buildpack: https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz
=====> Detected Framework: Ruby
-----> Compiling Ruby/Rack
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using 1.6.3
       Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
       Using kgio 2.9.2
       Using rack 1.5.2
       Using raindrops 0.13.0
       Using bundler 1.6.3
       Using unicorn 4.8.3
       Your bundle is complete!
       Gems in the groups development and test were not installed.
       It was installed into ./vendor/bundle
       Bundle completed (0.74s)
       Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL

###### WARNING:
       You have not declared a Ruby version in your Gemfile.
       To set your Ruby version add this line to your Gemfile:
       ruby '2.0.0'
       # See https://devcenter.heroku.com/articles/ruby-versions for more information.

Using release configuration from last framework (Ruby).
-----> Discovering process types
       Procfile declares types     -> web
       Default types for Multipack -> console, rake

-----> Compressing... done, 13.8MB
-----> Launching... done, v6
       https://frozen-fortress-6701.herokuapp.com/ deployed to Heroku

To [email protected]:frozen-fortress-6701.git
 + d213969...cd72c1a master -> master (forced update)

> curl -Lv http://frozen-fortress-6701.herokuapp.com/
* Adding handle: conn: 0x7f8c38804000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f8c38804000) send_pipe: 1, recv_pipe: 0
* About to connect() to frozen-fortress-6701.herokuapp.com port 80 (#0)
*   Trying 54.235.151.26...
* Connected to frozen-fortress-6701.herokuapp.com (54.235.151.26) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: frozen-fortress-6701.herokuapp.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Connection: keep-alive
* Server nginx is not blacklisted
< Server: nginx
< Date: Sun, 26 Oct 2014 22:13:35 GMT
< Content-Type: text/html
< Content-Length: 178
< Location: https://frozen-fortress-6701.herokuapp.com/
< Strict-Transport-Security: max-age=31536000
< Via: 1.1 vegur
<
* Ignoring the response-body
* Connection #0 to host frozen-fortress-6701.herokuapp.com left intact
* Issue another request to this URL: 'https://frozen-fortress-6701.herokuapp.com/'
* Found bundle for host frozen-fortress-6701.herokuapp.com: 0x7f8c38415200
* Adding handle: conn: 0x7f8c3a000000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f8c38804000) send_pipe: 0, recv_pipe: 0
* - Conn 1 (0x7f8c3a000000) send_pipe: 1, recv_pipe: 0
* About to connect() to frozen-fortress-6701.herokuapp.com port 443 (#1)
*   Trying 54.235.151.26...
* Connected to frozen-fortress-6701.herokuapp.com (54.235.151.26) port 443 (#1)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.herokuapp.com
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: frozen-fortress-6701.herokuapp.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
* Server nginx is not blacklisted
< Server: nginx
< Date: Sun, 26 Oct 2014 22:13:35 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Status: 200 OK
< Strict-Transport-Security: max-age=31536000
< Via: 1.1 vegur
<
* Connection #1 to host frozen-fortress-6701.herokuapp.com left intact
hello world%

> curl -Lv http://frozen-fortress-6701.herokuapp.com/insecure
* Adding handle: conn: 0x7f8adb004000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f8adb004000) send_pipe: 1, recv_pipe: 0
* About to connect() to frozen-fortress-6701.herokuapp.com port 80 (#0)
*   Trying 54.235.137.114...
* Connected to frozen-fortress-6701.herokuapp.com (54.235.137.114) port 80 (#0)
> GET /insecure HTTP/1.1
> User-Agent: curl/7.30.0
> Host: frozen-fortress-6701.herokuapp.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
* Server nginx is not blacklisted
< Server: nginx
< Date: Sun, 26 Oct 2014 22:14:35 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Status: 200 OK
< Strict-Transport-Security: max-age=31536000
< Via: 1.1 vegur
<
* Connection #0 to host frozen-fortress-6701.herokuapp.com left intact
hello world%

heroku-tls-auth-nginx-sample's People

Contributors

gregburek avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.