Forked from jed/how-to-set-up-stress-free-ssl-on-os-x.md
Last active
August 29, 2015 14:12
-
-
Save andreydelpozo2/2c991871153e1c4e528b to your computer and use it in GitHub Desktop.
Revisions
-
jed revised this gist
Aug 6, 2013 . 2 changed files with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -183,7 +183,7 @@ Note that this will satisfy Chrome and Safari, but since Firefox doesn't inherit #### How do you HTTPS? This guide is a snapshot of my thoughts on how to simplify HTTPS workflow for web development, but if you have any feedback or want to share some tips about your workflow, drop a line at [@jedschmidt](https://twitter.com/jedschmidt) or [leave a comment](https://gist.github.com/jed/6147872#comments) below. [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -126,7 +126,7 @@ There's a better way; we can tell OS X to trust the certificate we just created Since our certificate is self-signed, we'll always get a warning when using it for our HTTPS site. We need to use __Keychain Access__ to tell OS X to enhance its calm for this domain.  1. Open the certificate in __Keychain Access__. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 2 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -128,20 +128,12 @@ Since our certificate is self-signed, we'll always get a warning when using it f  1. Open the certificate in __Keychain Access__. ```bash open /Applications/Utilities/Keychain\ Access.app ssl.crt ``` 1. Click __Don't Trust__. 1. Select the newly imported certificate, which should appear at the bottom of the certificate list, and click the [i] button. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 63 additions and 51 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -32,7 +32,7 @@ With a little more work up front, we can streamline our development workflow by One tool that can help us do this is [Dnsmasq][], a lightweight DNS forwarder. Here's how we'll install it: ```bash brew install dnsmasq mkdir -pv $(brew --prefix)/etc sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons @@ -44,14 +44,18 @@ Once it's installed and running, we need to choose what TLD we'd like to resolve All of the following shell scripts assume you're cool with using your user id as your top-level domain, but feel to change them accordingly by replacing `$(whoami)` with your chosen TLD. ```bash echo "address=/.$(whoami)/127.0.0.1" | sudo tee -a $(brew --prefix)/etc/dnsmasq.conf echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/$(whoami) ``` Now we need to make sure that worked, by spinning up a server and hitting it. ```bash cd /Applications sleep 1 && open "http://some.domain.$(whoami):9520" & python -m SimpleHTTPServer 9520 ``` This should open a new browser that shows the contents of your Applications folder, like this: @@ -70,38 +74,42 @@ Now that we know our DNS works, we need to create an SSL certificate for our dev First, let's create a new directory named for our project and `cd` into it. ```bash mkdir ~/Desktop/myproject && cd $_ ``` Next, let's create a temporary configuration file, and feed it into `openssl` to create our certificate. ```bash cat > openssl.cnf <<-EOF [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] CN = *.${PWD##*/}.$(whoami) [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = *.${PWD##*/}.$(whoami) DNS.2 = ${PWD##*/}.$(whoami) EOF openssl req \ -new \ -newkey rsa:2048 \ -sha1 \ -days 3650 \ -nodes \ -x509 \ -keyout ssl.key \ -out ssl.crt \ -config openssl.cnf rm openssl.cnf ``` Now we have two files in our project directory: `ssl.key`, the private key used to sign the certificate, and `ssl.crt`, the certificate itself. @@ -122,7 +130,9 @@ Since our certificate is self-signed, we'll always get a warning when using it f 1. Open __Keychain Access__. ```bash open /Applications/Utilities/Keychain\ Access.app ``` 1. From the __Keychains__ list on the left, select __System__. @@ -149,25 +159,27 @@ Since our certificate is self-signed, we'll always get a warning when using it f Now that OS X knows that our self-signed certificate is legit, let's spin up an HTTPS server to make sure it all works. You can use Apache or Nginx or whatever you like, but here we'll use [nodejs][]: ```bash sleep 1 && open "https://myproject.$(whoami):8443" & sleep 1 && open "https://subdomain.myproject.$(whoami):8443" & node <<-EOF var https = require("https") var fs = require("fs") var options = { key: fs.readFileSync("ssl.key"), cert: fs.readFileSync("ssl.crt") } var server = https.createServer(options, function(req, res) { res.writeHead(200, {"Content-Type": "text/plain"}) res.end("It worked!\n") }) server.listen(8443, console.log) EOF ``` As you can see, the correct content is being served by both the apex domain and subdomain. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -32,7 +32,7 @@ With a little more work up front, we can streamline our development workflow by One tool that can help us do this is [Dnsmasq][], a lightweight DNS forwarder. Here's how we'll install it: ```sh brew install dnsmasq mkdir -pv $(brew --prefix)/etc sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons -
jed revised this gist
Aug 6, 2013 . 1 changed file with 7 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -32,11 +32,13 @@ With a little more work up front, we can streamline our development workflow by One tool that can help us do this is [Dnsmasq][], a lightweight DNS forwarder. Here's how we'll install it: ```bash brew install dnsmasq mkdir -pv $(brew --prefix)/etc sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist sudo mkdir -pv /etc/resolver ``` Once it's installed and running, we need to choose what TLD we'd like to resolve to our local box. OS X [reserves][] the `.local` TLD, and [many developers][] use `.dev`, but I like the idea of using names as TLDs, to make it easier to reason about my local environment within the context of other developers on the same project. So I'm going to have Dnsmasq locally resolve all hosts ending in my OS X user id (also known as a _short name_, and what you get when you type `whoami` in the terminal). Since my user id is `jed`, that means everything from `apple.jed` to `zebras.jed` to `apple.zebras.jed` will resolve to `127.0.0.1`. -
jed revised this gist
Aug 6, 2013 . 2 changed files with 1 addition and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -103,8 +103,6 @@ Next, let's create a temporary configuration file, and feed it into `openssl` to Now we have two files in our project directory: `ssl.key`, the private key used to sign the certificate, and `ssl.crt`, the certificate itself. At this point we have almost everything we need to fire up a local HTTPS server, but there's one problem.  @@ -151,6 +149,7 @@ Now that OS X knows that our self-signed certificate is legit, let's spin up an sleep 1 && open "https://myproject.$(whoami):8443" & sleep 1 && open "https://subdomain.myproject.$(whoami):8443" & node <<-EOF var https = require("https") var fs = require("fs") Binary file not shown. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -64,7 +64,7 @@ In this case, we'll need to restart the machine to make sure the setup above has <a name="step-2"></a> #### Create a wildcard SSL certificate for each project Now that we know our DNS works, we need to create an SSL certificate for our development environment. Since (for good reason) browsers [won't trust][] certificates that cover an entire TLD, we need to create a wildcard certificate for each domain we want to use. Also, since we want to cover both arbitrary subdomains (*.yourproject.tld) _and_ the domain apex (yourproject.tld), we'll need to use the [Subject Alternative Name][] X.509 extension. First, let's create a new directory named for our project and `cd` into it. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -178,7 +178,7 @@ Note that this will satisfy Chrome and Safari, but since Firefox doesn't inherit #### How do you HTTPS? This guide is a snapshot of my thoughts on how to simply the HTTPS workflow for web development, but if you have any feedback or want to share some tips about your HTTPS workflow, drop me a line at [@jedschmidt](https://twitter.com/jedschmidt) or [leave a comment](https://gist.github.com/jed/6147872#comments) below. [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -178,7 +178,7 @@ Note that this will satisfy Chrome and Safari, but since Firefox doesn't inherit #### How do you HTTPS? This guide is a snapshot of my thoughts on responsible web development, but if you have any feedback or want to share some tips about your HTTPS workflow, drop me a line at [@jedschmidt](https://twitter.com/jedschmidt) or [leave a comment](https://gist.github.com/jed/6147872#comments) below. [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html -
jed revised this gist
Aug 6, 2013 . 1 changed file with 48 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,49 +1,97 @@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yeah, so you should stop reading now, unless you want a data dump of all the images used in this missive. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 48 additions and 48 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,49 +1,49 @@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yeah, so you should stop reading now, unless you want a data dump of all the images used in this missive. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 49 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,49 @@ yeah, so you should stop reading now, unless you want a data dump of all the images used in this missive. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 5 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -174,7 +174,11 @@ As you can see, the correct content is being served by both the apex domain and  Note that this will satisfy Chrome and Safari, but since Firefox doesn't inherit the same keychain from OS X, it will tell you that the certificate is untrusted. In this case, click __I Understand the Risks__, then __Add Exception...__, and then __Confirm Security Exception___ when prompted. #### How do you HTTPS? This guide is a snapshot of my thoughts on responsible web development, but if you have any feedback or want to share some tips about your HTTPS workflow, drop me a line at [@jedschmidt](https://twitter.com/jedschmidt). [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html -
jed revised this gist
Aug 6, 2013 . 1 changed file with 187 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,187 @@ ### How to set up stress-free SSL on an OS X development machine One of the best ways to reduce complexity (read: _stress_) in web development is to minimize the differences between your development and production environments. After being frustrated by attempts to unify the approach to SSL on my local machine and in production, I searched for a workflow that would make the protocol invisible to me between all environments. Most workflows make the following compromises: - __Use HTTPS in production but HTTP locally__. This is annoying because it makes the environments inconsistent, and the protocol choices leak up into the stack. For example, your web application needs to understand the underlying protocol when using the `secure` flag for cookies. If you don't get this right, your HTTP development server won't be able to read the cookies it writes, or worse, your HTTPS production server could pass sensitive cookies over an insecure connection. - __Use production SSL certificates locally__. This is annoying because SSL credentials shouldn't be passed around lightly, and ideally should only exist on blessed machines. Plus, even with a wildcard certificate, coming up with a scheme to put development hosts and production hosts under the same namespace has some weird edge cases (if the production app is served off of `myproject.com`, where is the development app served from?) - __Give up on HTTPS entirely__. This is annoying because it's like, 2013 already, amirite. So here's my approach for a modern HTTPS workflow, in four steps: 1. [Resolve a top-level domain for all development work](#step-1), 2. [Create a wildcard SSL certificate for each project](#step-2), 3. [Avoid HTTPS warnings by telling OS X to trust the certificate](#step-3), and 4. [Bask in easy HTTPS](#step-4). Let's get started. #### Install [Homebrew][] if it's not already installed ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" <a name="step-1"></a> #### Resolve a top-level domain for all development work The most common way to get a given host to resolve to your local machine is to manually edit your `/private/etc/hosts` file, which is annoyingly _O(n<sup>2</sup>)_, since you need to add an entry for each subdomain of each project you're working on. With a little more work up front, we can streamline our development workflow by resolving a single [top-level domain][] (herein as _TLD_) to our development box and [never touch the hosts file again][]. One tool that can help us do this is [Dnsmasq][], a lightweight DNS forwarder. Here's how we'll install it: brew install dnsmasq mkdir -pv $(brew --prefix)/etc sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist sudo mkdir -pv /etc/resolver Once it's installed and running, we need to choose what TLD we'd like to resolve to our local box. OS X [reserves][] the `.local` TLD, and [many developers][] use `.dev`, but I like the idea of using names as TLDs, to make it easier to reason about my local environment within the context of other developers on the same project. So I'm going to have Dnsmasq locally resolve all hosts ending in my OS X user id (also known as a _short name_, and what you get when you type `whoami` in the terminal). Since my user id is `jed`, that means everything from `apple.jed` to `zebras.jed` to `apple.zebras.jed` will resolve to `127.0.0.1`. All of the following shell scripts assume you're cool with using your user id as your top-level domain, but feel to change them accordingly by replacing `$(whoami)` with your chosen TLD. echo "address=/.$(whoami)/127.0.0.1" | sudo tee -a $(brew --prefix)/etc/dnsmasq.conf echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/$(whoami) Now we need to make sure that worked, by spinning up a server and hitting it. cd /Applications sleep 1 && open "http://some.domain.$(whoami):9520" & python -m SimpleHTTPServer 9520 This should open a new browser that shows the contents of your Applications folder, like this:  The browser might tell us that the DNS lookup failed, like this:  In this case, we'll need to restart the machine to make sure the setup above has taken effect. <a name="step-2"></a> #### Create a wildcard SSL certificate for each project Now that we know our DNS works, we need to create an SSL certificate for our development environment. Since (for good reason) browsers [won't trust][] certificates that cover an entire TLD, we need to create a wildcard certificate for each domain we want to use. Also, since we want to cover both any subdomain (*.yourproject.tld) _and_ the domain apex (yourproject.tld), we'll need to use [Subject Alternative Name][] extension. First, let's create a new directory named for our project and `cd` into it. mkdir ~/Desktop/myproject && cd $_ Next, let's create a temporary configuration file, and feed it into `openssl` to create our certificate. cat > openssl.cnf <<-EOF [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] CN = *.${PWD##*/}.$(whoami) [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = *.${PWD##*/}.$(whoami) DNS.2 = ${PWD##*/}.$(whoami) EOF openssl req \ -new \ -newkey rsa:2048 \ -sha1 \ -days 3650 \ -nodes \ -x509 \ -keyout ssl.key \ -out ssl.crt \ -config openssl.cnf rm openssl.cnf Now we have two files in our project directory: `ssl.key`, the private key used to sign the certificate, and `ssl.crt`, the certificate itself.  At this point we have almost everything we need to fire up a local HTTPS server, but there's one problem.  Any content we try to serve over HTTPS from this domain gets [IMMA-LET-YOU-FINISH](http://knowyourmeme.com/memes/events/kanye-interrupts-imma-let-you-finish)ed by a scary message like the one above, warning us that the presented certificate is not trusted. This message differs by browser, and you might be tempted to go ahead and ignore it, but that's not a good habit to get into, and is likely to lead to development complexity down the road. There's a better way; we can tell OS X to trust the certificate we just created so that we don't have to see this screen ever again, by adding the certificate to our keychain. <a name="step-3"></a> #### Avoid HTTPS warnings by telling OS X to trust the certificate Since our certificate is self-signed, we'll always get a warning when using it for our HTTPS site. We need to use __Keychain Access__ to tell OS X to enhance its calm for this domain.  1. Open __Keychain Access__. `open /Applications/Utilities/Keychain\ Access.app` 1. From the __Keychains__ list on the left, select __System__. 1. Click the [+] button under the list of certificates. 1. Choose the `ssl.crt` file created in the previous step, make sure __System__ is selected for __Destination Keychain__, and click __Open__. 1. When prompted, enter your password and click __Modify Keychain__. 1. Click __Don't Trust__. 1. Select the newly imported certificate, which should appear at the bottom of the certificate list, and click the [i] button. 1. In the popup window, click the ▶ button to the left of __Trust__, and select __Always Trust__ for __When using this certificate:__. 1. Close the popup window. 1. When prompted, enter your password again and click __Update Settings__. 1. Close __Keychain Access__. <a name="step-4"></a> #### Bask in easy HTTPS Now that OS X knows that our self-signed certificate is legit, let's spin up an HTTPS server to make sure it all works. You can use Apache or Nginx or whatever you like, but here we'll use [nodejs][]: sleep 1 && open "https://myproject.$(whoami):8443" & sleep 1 && open "https://subdomain.myproject.$(whoami):8443" & node <<-EOF var https = require("https") var fs = require("fs") var options = { key: fs.readFileSync("ssl.key"), cert: fs.readFileSync("ssl.crt") } var server = https.createServer(options, function(req, res) { res.writeHead(200, {"Content-Type": "text/plain"}) res.end("It worked!\n") }) server.listen(8443, console.log) EOF As you can see, the correct content is being served by both the apex domain and subdomain.   This will satisfy Chrome and Safari, but since Firefox doesn't inherit the same keychain from OS X, it will tell you that the certificate is untrusted. In this case, click __I Understand the Risks__, then __Add Exception...__, and then __Confirm Security Exception___ when prompted. [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html [top-level domain]: http://en.wikipedia.org/wiki/Top-level_domain [never touch the hosts file again]: http://www.echoditto.com/blog/never-touch-your-local-etchosts-file-os-x-again [reserves]: http://en.wikipedia.org/wiki/.local#mDNS_implementations [won't trust]: http://security.stackexchange.com/questions/6873/can-a-wildcard-ssl-certificate-be-issued-for-a-second-level-domain [Subject Alternative Name]: http://en.wikipedia.org/wiki/SubjectAltName [many developers]: http://pow.cx [nodejs]: http://nodejs.org -
jed revised this gist
Aug 6, 2013 . 2 changed files with 0 additions and 374 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,187 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,187 +0,0 @@ -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -122,7 +122,7 @@ Since our certificate is self-signed, we'll always get a warning when using it f 1. Open __Keychain Access__. `open /Applications/Utilities/Keychain\ Access.app` 1. From the __Keychains__ list on the left, select __System__. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -122,7 +122,7 @@ Since our certificate is self-signed, we'll always get a warning when using it f 1. Open __Keychain Access__. open /Applications/Utilities/Keychain\ Access.app 1. From the __Keychains__ list on the left, select __System__. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -122,7 +122,7 @@ Since our certificate is self-signed, we'll always get a warning when using it f 1. Open __Keychain Access__. open /Applications/Utilities/Keychain\ Access.app 1. From the __Keychains__ list on the left, select __System__. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 187 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,187 @@ ### How to set up stress-free SSL on an OS X development machine One of the best ways to reduce complexity (read: _stress_) in web development is to minimize the differences between your development and production environments. After being frustrated by attempts to unify the approach to SSL on my local machine and in production, I searched for a workflow that would make the protocol invisible to me between all environments. Most workflows make the following compromises: - __Use HTTPS in production but HTTP locally__. This is annoying because it makes the environments inconsistent, and the protocol choices leak up into the stack. For example, your web application needs to understand the underlying protocol when using the `secure` flag for cookies. If you don't get this right, your HTTP development server won't be able to read the cookies it writes, or worse, your HTTPS production server could pass sensitive cookies over an insecure connection. - __Use production SSL certificates locally__. This is annoying because SSL credentials shouldn't be passed around lightly, and ideally should only exist on blessed machines. Plus, even with a wildcard certificate, coming up with a scheme to put development hosts and production hosts under the same namespace has some weird edge cases (if the production app is served off of `myproject.com`, where is the development app served from?) - __Give up on HTTPS entirely__. This is annoying because it's like, 2013 already, amirite. So here's my approach for a modern HTTPS workflow, in four steps: 1. [Resolve a top-level domain for all development work](#step-1), 2. [Create a wildcard SSL certificate for each project](#step-2), 3. [Avoid HTTPS warnings by telling OS X to trust the certificate](#step-3), and 4. [Bask in easy HTTPS](#step-4). Let's get started. #### Install [Homebrew][] if it's not already installed ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" <a name="step-1"></a> #### Resolve a top-level domain for all development work The most common way to get a given host to resolve to your local machine is to manually edit your `/private/etc/hosts` file, which is annoyingly _O(n<sup>2</sup>)_, since you need to add an entry for each subdomain of each project you're working on. With a little more work up front, we can streamline our development workflow by resolving a single [top-level domain][] (herein as _TLD_) to our development box and [never touch the hosts file again][]. One tool that can help us do this is [Dnsmasq][], a lightweight DNS forwarder. Here's how we'll install it: brew install dnsmasq mkdir -pv $(brew --prefix)/etc sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist sudo mkdir -pv /etc/resolver Once it's installed and running, we need to choose what TLD we'd like to resolve to our local box. OS X [reserves][] the `.local` TLD, and [many developers][] use `.dev`, but I like the idea of using names as TLDs, to make it easier to reason about my local environment within the context of other developers on the same project. So I'm going to have Dnsmasq locally resolve all hosts ending in my OS X user id (also known as a _short name_, and what you get when you type `whoami` in the terminal). Since my user id is `jed`, that means everything from `apple.jed` to `zebras.jed` to `apple.zebras.jed` will resolve to `127.0.0.1`. All of the following shell scripts assume you're cool with using your user id as your top-level domain, but feel to change them accordingly by replacing `$(whoami)` with your chosen TLD. echo "address=/.$(whoami)/127.0.0.1" | sudo tee -a $(brew --prefix)/etc/dnsmasq.conf echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/$(whoami) Now we need to make sure that worked, by spinning up a server and hitting it. cd /Applications sleep 1 && open "http://some.domain.$(whoami):9520" & python -m SimpleHTTPServer 9520 This should open a new browser that shows the contents of your Applications folder, like this:  The browser might tell us that the DNS lookup failed, like this:  In this case, we'll need to restart the machine to make sure the setup above has taken effect. <a name="step-2"></a> #### Create a wildcard SSL certificate for each project Now that we know our DNS works, we need to create an SSL certificate for our development environment. Since (for good reason) browsers [won't trust][] certificates that cover an entire TLD, we need to create a wildcard certificate for each domain we want to use. Also, since we want to cover both any subdomain (*.yourproject.tld) _and_ the domain apex (yourproject.tld), we'll need to use [Subject Alternative Name][] extension. First, let's create a new directory named for our project and `cd` into it. mkdir ~/Desktop/myproject && cd $_ Next, let's create a temporary configuration file, and feed it into `openssl` to create our certificate. cat > openssl.cnf <<-EOF [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] CN = *.${PWD##*/}.$(whoami) [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = *.${PWD##*/}.$(whoami) DNS.2 = ${PWD##*/}.$(whoami) EOF openssl req \ -new \ -newkey rsa:2048 \ -sha1 \ -days 3650 \ -nodes \ -x509 \ -keyout ssl.key \ -out ssl.crt \ -config openssl.cnf rm openssl.cnf Now we have two files in our project directory: `ssl.key`, the private key used to sign the certificate, and `ssl.crt`, the certificate itself.  At this point we have almost everything we need to fire up a local HTTPS server, but there's one problem.  Any content we try to serve over HTTPS from this domain gets [IMMA-LET-YOU-FINISH](http://knowyourmeme.com/memes/events/kanye-interrupts-imma-let-you-finish)ed by a scary message like the one above, warning us that the presented certificate is not trusted. This message differs by browser, and you might be tempted to go ahead and ignore it, but that's not a good habit to get into, and is likely to lead to development complexity down the road. There's a better way; we can tell OS X to trust the certificate we just created so that we don't have to see this screen ever again, by adding the certificate to our keychain. <a name="step-3"></a> #### Avoid HTTPS warnings by telling OS X to trust the certificate Since our certificate is self-signed, we'll always get a warning when using it for our HTTPS site. We need to use __Keychain Access__ to tell OS X to enhance its calm for this domain.  1. Open __Keychain Access__. open /Applications/Utilities/Keychain\ Access.app 1. From the __Keychains__ list on the left, select __System__. 1. Click the [+] button under the list of certificates. 1. Choose the `ssl.crt` file created in the previous step, make sure __System__ is selected for __Destination Keychain__, and click __Open__. 1. When prompted, enter your password and click __Modify Keychain__. 1. Click __Don't Trust__. 1. Select the newly imported certificate, which should appear at the bottom of the certificate list, and click the [i] button. 1. In the popup window, click the ▶ button to the left of __Trust__, and select __Always Trust__ for __When using this certificate:__. 1. Close the popup window. 1. When prompted, enter your password again and click __Update Settings__. 1. Close __Keychain Access__. <a name="step-4"></a> #### Bask in easy HTTPS Now that OS X knows that our self-signed certificate is legit, let's spin up an HTTPS server to make sure it all works. You can use Apache or Nginx or whatever you like, but here we'll use [nodejs][]: sleep 1 && open "https://myproject.$(whoami):8443" & sleep 1 && open "https://subdomain.myproject.$(whoami):8443" & node <<-EOF var https = require("https") var fs = require("fs") var options = { key: fs.readFileSync("ssl.key"), cert: fs.readFileSync("ssl.crt") } var server = https.createServer(options, function(req, res) { res.writeHead(200, {"Content-Type": "text/plain"}) res.end("It worked!\n") }) server.listen(8443, console.log) EOF As you can see, the correct content is being served by both the apex domain and subdomain.   This will satisfy Chrome and Safari, but since Firefox doesn't inherit the same keychain from OS X, it will tell you that the certificate is untrusted. In this case, click __I Understand the Risks__, then __Add Exception...__, and then __Confirm Security Exception___ when prompted. [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html [top-level domain]: http://en.wikipedia.org/wiki/Top-level_domain [never touch the hosts file again]: http://www.echoditto.com/blog/never-touch-your-local-etchosts-file-os-x-again [reserves]: http://en.wikipedia.org/wiki/.local#mDNS_implementations [won't trust]: http://security.stackexchange.com/questions/6873/can-a-wildcard-ssl-certificate-be-issued-for-a-second-level-domain [Subject Alternative Name]: http://en.wikipedia.org/wiki/SubjectAltName [many developers]: http://pow.cx [nodejs]: http://nodejs.org -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,7 +26,7 @@ Let's get started. <a name="step-1"></a> #### Resolve a top-level domain for all development work The most common way to get a given host to resolve to your local machine is to manually edit your `/private/etc/hosts` file, which is annoyingly _O_(_n_<sup>_2_</sup>), since you need to add an entry for each subdomain of each project you're working on. With a little more work up front, we can streamline our development workflow by resolving a single [top-level domain][] (herein as _TLD_) to our development box and [never touch the hosts file again][]. -
jed renamed this gist
Aug 6, 2013 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
jed renamed this gist
Aug 6, 2013 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
jed renamed this gist
Aug 6, 2013 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -126,17 +126,17 @@ Since our certificate is self-signed, we'll always get a warning when using it f 1. From the __Keychains__ list on the left, select __System__. 1. Click the [+] button under the list of certificates. 1. Choose the `ssl.crt` file created in the previous step, make sure __System__ is selected for __Destination Keychain__, and click __Open__. 1. When prompted, enter your password and click __Modify Keychain__. 1. Click __Don't Trust__. 1. Select the newly imported certificate, which should appear at the bottom of the certificate list, and click the [i] button. 1. In the popup window, click the ▶ button to the left of __Trust__, and select __Always Trust__ for __When using this certificate:__. 1. Close the popup window. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -174,7 +174,7 @@ As you can see, the correct content is being served by both the apex domain and  This will satisfy Chrome and Safari, but since Firefox doesn't inherit the same keychain from OS X, it will tell you that the certificate is untrusted. In this case, click __I Understand the Risks__, then __Add Exception...__, and then __Confirm Security Exception___ when prompted. [Homebrew]: http://brew.sh [Dnsmasq]: http://www.thekelleys.org.uk/dnsmasq/doc.html -
jed revised this gist
Aug 6, 2013 . 2 changed files with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ ### How to set up stress-free SSL on an OS X development machine One of the best ways to reduce complexity (read: _stress_) in web development is to minimize the differences between your development and production environments. After being frustrated by attempts to unify the approach to SSL on my local machine and in production, I searched for a workflow that would make the protocol invisible to me between all environments. LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -126,17 +126,17 @@ Since our certificate is self-signed, we'll always get a warning when using it f 1. From the __Keychains__ list on the left, select __System__. 1. Click the :heavy_plus_sign: button under the list of certificates. 1. Choose the `ssl.crt` file created in the previous step, make sure __System__ is selected for __Destination Keychain__, and click __Open__. 1. When prompted, enter your password and click __Modify Keychain__. 1. Click __Don't Trust__. 1. Select the newly imported certificate, which should appear at the bottom of the certificate list, and click the :information_source: button. 1. In the popup window, click the :arrow_forward: button to the left of __Trust__, and select __Always Trust__ for __When using this certificate:__. 1. Close the popup window. -
jed revised this gist
Aug 6, 2013 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -107,7 +107,7 @@ Now we have two files in our project directory: `ssl.key`, the private key used At this point we have almost everything we need to fire up a local HTTPS server, but there's one problem.  Any content we try to serve over HTTPS from this domain gets [IMMA-LET-YOU-FINISH](http://knowyourmeme.com/memes/events/kanye-interrupts-imma-let-you-finish)ed by a scary message like the one above, warning us that the presented certificate is not trusted. This message differs by browser, and you might be tempted to go ahead and ignore it, but that's not a good habit to get into, and is likely to lead to development complexity down the road. @@ -118,7 +118,7 @@ There's a better way; we can tell OS X to trust the certificate we just created Since our certificate is self-signed, we'll always get a warning when using it for our HTTPS site. We need to use __Keychain Access__ to tell OS X to enhance its calm for this domain.  1. Open __Keychain Access__. @@ -170,9 +170,9 @@ Now that OS X knows that our self-signed certificate is legit, let's spin up an As you can see, the correct content is being served by both the apex domain and subdomain.   This will satisfy Chrome and Safari, but since Firefox doesn't inherit the same keychain from OS X, it will tell you that the certificate is untrusted. In this case, click __I Understand the Risks__, then __Add Exception...___, and then __Confirm Security Exception___ when prompted.
NewerOlder