Chassis / chassis_openssl

openSSL module as extension for chassis.io
1 stars 2 forks source link

Force HTTPS #15

Open banderon opened 4 years ago

banderon commented 4 years ago

Howdy. Our prod site is only served over https so we wanted our local environment to follow suit. The easiest way we've found to accomplish this was running the following script prior to provisioning:

# While in `/content`
cd ../puppet/modules/chassis/templates/

# Strip off any trailing "\n" in `site.nginx.conf.erb` | remove last line, the closing `}` > save changes
awk '/^$/ {nls=nls "\n";next;} {printf "%s",nls; nls=""; print;}' site.nginx.conf.erb | sed '$d' > nginx-tmp && mv nginx-tmp site.nginx.conf.erb

# Add SSL redirect and replace closing `}`
echo '
\tif ($scheme = http) {
\t\treturn 301 https://$server_name$request_uri;
\t}
}
' >> site.nginx.conf.erb

Any thoughts as to a cleaner way of forcing HTTPS on created sites? Is this something that can potentially (optionally) be done via extension?

BronsonQuick commented 4 years ago

Hrmm. Good question! You can include additional nginx in a custom extension. I know that some custom rewrites have been handled in this extension.

It's probably worth us considering adding something like https: yes to a configuration and handling it automagically. What are your thoughts on the best approach for this @rmccue and @roborourke? I'm happy to write the code if we can come up with the best approach! We could possibly add https: yes upstream in Chassis and if that's set automatically clone this extension on provisioning and the initial up. I'll wait to see what the lads think as that is just me spitballing ideas without actually thinking it through properly #lazyweb 😂

roborourke commented 4 years ago

We can’t automatically add the certificate that’s generated at the moment i think, I’d start there.

Having a https config setting sounds ok but I wouldn’t do this in nginx, it’s way more flexible to just use PHP for that.

roborourke commented 4 years ago

Not sure about doing that in upstream chassis tbh, interesting idea though as a core feature. Laravel homestead has that capability on Mac for instance

rmccue commented 4 years ago

I think the web has evolved significantly since we first started Chassis, and building HTTPS in out of the box makes a lot of sense now.

With that said, I'm yet to have a good user experience setting up HTTPS locally just generally, so I actually force-disable it on any projects where we have it (both Chassis-based and Node projects). This boils down to a fundamental flaw with most of these: generating per-server self-signed certificates. Using self-signed certificates means you have to add every one individually.

mkcert has the best user experience by a country mile because it instead creates a self-signed root certificate you install, then acts as a CA and issues certificates. Unfortunately, it doesn't have an API. https://github.com/FiloSottile/mkcert/issues/154 discusses the idea of adding an ACME server to mkcert which would solve the problem, but that hasn't been done. Mentioned in that ticket though is Smallstep's step-ca, which I've not seen before, but could be a good path forward: https://smallstep.com/blog/private-acme-server/

Given that, I'd ultimately expect something like:

We could probably get away without using mkcert/etc provided we do the root cert dance at least.

mholt commented 4 years ago

@rmccue Would Caddy 2 be useful to you here? It can act as a long-running CA , and once this PR is merged (probably a week or two) it will also embed the same Smallstep ACME server you referred to.

It can install its root cert into your trust store, too (by default -- you can turn this off though).

This way you won't have to re-implement the cert generation logic, intermediate renewals (if using intermediates), etc.

banderon commented 4 years ago

Re the cert, just wanted to point out this PR that's been merged in recently that one of our devops folks whipped up. After the VM's been provisioned, we use that in combination with the following script to add the cert to our macOS keychain:

# $CONTENT_DIR=/path/to/content/folder
# success(){ color-coded success output }
# warning(){ color-coded failure output }

# Add cert to keyring to prevent browser warnings
printf "\n-------------------------------\n"
printf "Adding SSL cert to keyring"
printf "\n-------------------------------\n"
if [ -f $CONTENT_DIR/../site.domain.cert ]; then
  sudo security add-trusted-cert -k /Library/Keychains/System.keychain -d $CONTENT_DIR/../site.domain.cert
  success "Site SSL certificate added to system keyring"
else
  warning "Site SSL certificate not found!"
fi

Perhaps more of a specific and makeshift solution, but it's simple and gets the job done.