This talk was derived from an opensource.com article I wrote in April 2017, Golang to the rescue: Saving DevOps from TLS turmoil. Presented at GopherCon 2017 as a Lightning Talk. Source for the talk is available on GitHub.
Introduction
Notes:
- Hi! I’m Chris!
- I manage do X at Y (we’re hiring)
- I work in the DevOps space
- I contribute content a few places
- I run a DevOps Newsletter called DevOps’ish if you’re into those please check it out
- This talk was derived from an opensource.com article I wrote in April 2017
But Most Importantly
I’m many things But Most Importantly, I’m a Gopher
Not Too Long Ago in a Place of Work Far, Far Away…
- My team of merry DevOps’ers inherited an application
- A third-party built the app a few years ago
- The app had long been abandoned
- Before we could do any re-engineering work, we had to resolve a critical issue.
- The certificates were about to expire!
…
- Oh!
- And the only environment this application was in was production
- And there was no time to implement a new key management system
- And it was a pet project of someone in senior leadership
Let’s Talk Certificate Chains
2 Chainz (we can talk rap music later)
- Let’s Talk Certificate Chains for a minute
- HTTPS, SSL… it’s all TLS, right?
- In my opinion, if you’re using TLS you MUST have a rock solid configuration
- This means you have to include the certificate chain in the correct order
- This is no longer optional in the post-Heartbleed world
- The Internets are watching
This is the Goal
- This is the goal
- If you are going to bother to encrypt your traffic you better do it right
- This is what we’re aiming for; an A+
- At this company, we obtained certs from a preferred vendor that our company was cool with
- I prefer Let’s Encrypt but some companies aren’t comfortable with that yet for various reasons
- The process goes like this…
- You generate your CSR and private key
- You send the CSR to the vendor
- The certificate arrives but usually doesn’t have an intermediate key in chain because… vendors be vendoring
NBD … OMG
- No big deal
- Let’s go to the vendor’s documentation…
- And OMG…
- The vendor docs are terrible
- This is when you learn…
- Cryptography is hard but implementing cryptographic best practices might be even harder
…
- What do we do?
- Look at statistical probabilities and start shuffling keys around?
- The series of games you have to play with openssl or nginx or some other method aren’t intuitive
- Do you know how hard this is to explain to people?
So What Does Any Good Engineer Do?
- We needed a tool that would fail if the certificate chain provided was incorrect
- We wanted a lightweight tool that could be publicly accessible
- Conducting a third-party analysis of the certificates and configuration was also a requirement
- There were no tools that I could find meeting these needs
- So I decided to build my own
- With Go of course!
Three Go Packages: log
-
The go
log
package is pretty self-explanatory -
Package that enables logging
-
Needed a spectacular failure at the sign of trouble
-
log
has three helper functions:print
,fatal
, andpanic
-
Output from the package goes to
stderr
-
Used a
fatal
error to get the web server to stop and log any issue -
Let me just say the Go standard library is amazing!
-
log
is designed beautifully -
Using
fatal
to break the app and log tostderr
if something isn’t right is great!
Three Go Packages: crypto/tls
- The Go
crypto/tls
package partially implements TLS 1.2, as specified in RFC 5246 - Package configures usable SSL/TLS versions
- Identifies preferred cipher suites and elliptic curves used during handshakes
- This is the package that handles connections securely
- The crypto/tls package is a splendid implementation of the RFC
- “It just works.”
Three Go Packages: net/http
- Go implementation of HTTP
net/http
has a function calledListenAndServeTLS
- ListenAndServeTLS provides the desired certificate checking functionality
- “If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server’s certificate, any intermediates, and the CA’s certificate.”
net/http
has theListenAndServeTLS
function and it’s awesome- It fails if your certs aren’t up to snuff or ordered properly
- It helps us Gophers out immensely by enforcing best practices
main: mux, cfg, srv
- Code creates a
mux
, short for HTTP request multiplexer - I ❤️ multiplexers (it’s a long story that involves analog signals)
mux
has a function that creates an HTTP server with headers and content (Hello World!)cfg
brings in all the TLS bits seen in a solid web server configsrv
puts the pieces together and defines what port to listen on
Fail Spectacularly
- I ❤️ DevOps
- I embrace failure
log.Fatal(srv.ListenAndServeTLS("/etc/ssl-tester/tls.crt",
"/etc/ssl-tester/tls.key"))
- Defines path of certificate files to use
- Also logs a fatal error if certificate is not valid
- Fails Fast
- I love DevOps and I embrace failure
- The code allows us to fail quickly if the certificates aren’t in accordance with RFC
- Stuff in the standard library JUST WORKS
It’s Open Source!
https://github.com/chris-short/ssl-tester
- The code is open-sourced
- Check it out on github.com/chris-short/ssl-tester
- Throw a star my way if you feel like it
It Works!
- Yes it Works
- Yes you can access it right now!
- https://ssl-tester.chrisshort.net redirects you to a reference implementation
No. It Really Works!
- You can even scan it with external tools!
Conclusion
- The Go code does exactly what I need it to do and nothing more
- About 40 lines of code!!! I ❤️ Go!
- Binary is a self-contained web server
- Less than 6MB!!! I ❤️ Go!
- Can be safely deployed to any public server
- External testing run against it for extra vetting
- The tool does exactly what I need it to do and nothing more
- It fails when the certificate chain provided is incorrect
- It’s lightweight and publicly accessible
- I’m able to test via third-parties
- It’s a tiny, single binary