Gnosis is configured for end-to-end SSL encryption. This is due to our LDAP Integration.

Our SSL Domains:
- smoca.internal.justin.tv
- smoca-dev.internal.justin.tv

We are using [ACM](https://aws.amazon.com/certificate-manager/) for our Loadbalancer SSL Configuration, 
and System's `*.internal.justin.tv` SSL certificate for end-to-end encryption.

External resources can be found below.

There are various pieces to this.

## ACM
Our ACM configuration lives within twitch-web-dev.

AWS Certificates are viewable by running:
`aws acm list-certificates`

We've created a certificate as smoca.internal.justin.tv, with an alternate name of smoca-dev.internal.justin.tv.
This allows one certificate for both staging and production.

Both domains require a CNAME Record. These exist at:
- https://dashboard.internal.justin.tv/dns/?entry=_9813fa24f777e552ec7b614a05c18dd0.smoca.internal.justin.tv.
- https://dashboard.internal.justin.tv/dns/?entry=_63b40e345093bca01ced4774b082e7ad.smoca-dev.internal.justin.tv.

The actual domains exist at:
- https://dashboard.internal.justin.tv/dns/?entry=smoca.internal.justin.tv
- https://dashboard.internal.justin.tv/dns/?entry=smoca-dev.internal.justin.tv

## Load Balancer Termination

![Load Balancer Termination](images/ssl/gnosis_lb_termination_only.png)

**Configuration: [.ebextensions/https-lbterminate.config](../.ebextensions/https-lbterminate.config)**

The first step to the SSL integration was assigning the certificate to the Load Balancer.

At this stage, connections would come either over http or https.
The load balancer would then de-crypt and pass to the instance on Port 80.

## Load Balancer -> Instance Reencryption

![End To End](images/ssl/ssl_end_to_end.png)

With end-to-end encryption, this prevents a man-in-the-middle attack.

When a connection is made to the load balancer, it re-encrypts and sends that data over 443 SSL.

If the app server receives a request on port 80, it will issue a 301 Redirect.

Below, each part is documented.

### Security Groups

**Configuration: [terraform/sgs/main.tf](../terraform/sgs/main.tf)**

An ELB Security Group is defined to allow ingress from port 443 and 80 from all twitch subnets.

EC2 Security Groups and designed to accept port 443 and port 80 from only the ELB.

### Sandstorm

The SSL Certificates are loaded onto Gnosis' app boxes via sandstorm.

Templates are designed for the SSL Cert and Key, stored in systems. Systems allowed Gnosis' instance role to access this.

Cert: `syseng/ssl_certs/production/wildcard.internal.justin.tv.cert`
Key:  `syseng/ssl_keys/production/wildcard.internal.justin.tv.key`

The template will reload nginx whenever keys are updated. However, it will **not** reload on initialization.

Due to this, we run sandstorm separate on as a one time basis, and then after that command completes, we reload nginx.

### Nginx Https

**Configuration: [.ebextensions/03_nginx.conf](../.ebextensions/02_https_nginx.config)**

The nginx server is designed to listen to https, and use the certs imported from sandstorm.

The configuration is slightly modified from AWS' example to pass the scheme(port) to the proxy, so that Rails knows when a request was initiated via SSL.
Without this, the health check will receive 301 redirects from Rails.

`proxy_set_header X-Forwarded-Proto $scheme;`

### Reencryption

**Configuration: [.ebextensions/https-reencrypt.config](../.ebextensions/https-reencrypt.config)**

For end-to-end, we had to re-encrypt when talking to the app boxes.

The health check is also informed to use https.

### Ldap Encryption

Using Omniauth, the app talks to our ldap-vip server via SSL on port 696 (LDAPS).

### Resources

- [Configuring HTTPS for your Elastic Beanstalk Environment](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https.html)
- [Add Production SSL Cert to AWS account](https://wiki.twitch.com/display/ENG/Add+Production+SSL+Cert+to+AWS+account)
- [Configuring End-to-End Encryption in a Load Balanced Elastic Beanstalk Environment](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-endtoend.html)
