Achieving a Perfect SSL Labs Score with Go
blog.bracelab.com
blog.bracelab.com
Why does it have to be this way?
There's no reason that 128 but cannot be used today, particularly for transport encryption.
Google has SINGLEHANDEDLY improved the security of the TLS ecosystem by light-years:
* They ship the most modern client (Chrome), and started the auto-update trend.
* They forced the move from SHA1 and RC4 by leveraging that client power (with the degraded UI messages) even if it costed them popularity.
* They are leading CT, the single next best thing to happen to the ecosystem.
* They are keeping CAs accountable like no one did before.
* They have amazing people working on security UX and even shared the messages they use for anyone else to use.
* Finally, Chrome is by far the most secure browser you can use thanks to its state-of-the-art sandbox.
And take your client side certificates grudge somewhere else.
This article in a nice exercise, but not a guide you should follow in production. The HTTP/2 ciphersuites recommendations are great, and there's no security reason to disregard them.
I even go as far to say:
> You should probably stop here. Continuing to attempt to achieve a perfect score will result in reduced client compatibility. This means that many users will not be able to access your site.
I should probably have also said that it is unlikely to be their intentions. An A+ is more than good enough.
This was just an exercise to better understand how to influence the score with a Go server as I've read a few in the past for NGINX, Apache etc.
Aiming for 100% in all ares was just a fun, but mostly pointless metric. It did, however uncover a couple of interesting things along the way.
What's going on is Chrome and Firefox don't do AES_256_GCM (but Chrome will be adding support in the next release, see [1]), which means it was picking a CBC mode cipher and HTTP/2 wouldn't allow it.
SSL Labs is, in my opinion, wrong about incentivizing AES_256_CBC over AES_128_GCM. The CBC mode ciphers in TLS are composed wrong and very very difficult to implement safely. They'll be gone in TLS 1.3.
[1] https://groups.google.com/a/chromium.org/d/msg/security-dev/...
[0]: https://mozilla.github.io/server-side-tls/ssl-config-generat...
But my question still stands - why do nginx and Apache not provide the same settings as a configuration option?
When I ran the code, the Go HTTP/2 package caused a panic with the message "http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256".
I went source diving and found the following:
https://golang.org/src/net/http/h2_bundle.go?h=TLS_ECDHE_RSA...
It even has the helpful comment:
> If they already provided a CipherSuite list, return an error if it has a bad order or is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256.
I cannot see how I would have achieved my aim without disabling HTTP/2.
The aim of the exercise was to get a perfect score using Go. I wasn't discussing HTTP/2 in general. I was referencing the Go standard library implementation.
As I say, if you still think it's not right, please let me know.
That is to say, you're correct that server configured for a 100% on SSLLabs will not support HTTP/2, but I agree with davidben that SSLLabs is incorrect here for incetivising AES-256, particularly in CBC mode, for the 100% score.
It only works with the following clients without an error.. since this is when these browsers added TLS 1.2 support (and this config requires tls 1.2):
Android 5+
Firefox 27+
IE 11, Edge
Opera 17+
Safari 7+
It might work on some versions of Chrome after v30 (when tls 1.2 was added) but before they added the obsolete crypto warning (that this config triggers).It pointlessly excludes clients since TLS 1.0, 1.1 and AES 128 are still considered secure.
According to my webserver logs, I see <5% of traffic being TLS 1.0/1.1, so going TLS 1.2 only wouldn't (in my case) exclude many people. By recently blocking only 3 IP addresses (unfriendly bots), I calculate an expected reduction in TLS 1.1 usage of about 85%. So now I expect TLS 1.1 usage to plunge from about 1% to ... less than 1%.
I encourage everyone to measure their traffic, and take some time to consider how important their TLS 1.0 and 1.1 users are. If you're a business, what percentage of sales are from TLS 1.0/1.1 clients? What's the ratio of good:bad traffic? And the same questions for 1.2. Measure!
Wrong. All AES-based ciphers in TLS 1.0/1.1 are vulnerable to the Lucky Thirteen attack. This can be avoided by careful implementation, however as far as I know the go developers don't even try to do that and say if you want something secure use gcm.
1. TLS 1.2 is also vulnerable to the lucky thirteen attack.
2. The lucky thirteen attack requires CBC-mode.. which is also what generates the obsolete crypto warning in chrome.
The solution here is clearly to disable CBC-mode.
Arguably using a higher bit cipher suite should be considered worse, since it reduces accessibility. 128 bit crypto (specifically the GCM suites) are ridiculously faster, to the point where it is practically free to enable it for all websites. Treating 256bit crypto as better feels like it is missing a key point of security: availability.
See for example this 2009 paper: https://www.schneier.com/blog/archives/2009/07/another_new_a...
Ironically just before reading this article I was reviewing a Java code change to force TLS 1.1+. The logic to set security protocols and ciphers correctly is quite tangled in part because it's not consistent across different libraries e.g., for JMX and SSL sockets. I still can't tell if the code I was reviewing will work in production.
Has anyone posted a general comparison of Java vs. Go on security? This deserves a closer look.
It's not a fair comparison: Go has a TLS stack that is shepherded by Adam Langley, who is one of the Internet's foremost experts on TLS.
Here are a couple of examples of what I mean. [2] cites use of Go in financial apps without a single mention of security.
[1] http://thenewstack.io/a-closer-look-at-golang-from-an-archit...
[2] http://www.techworld.com/apps/why-googles-go-programming-lan...
But maybe I'm missing your point.
Worst of all, Oracle refuses to propagate patches backwards, so if you are running even a mildly old (like a year) JDK, you will suffer for it. Enterprise Java doesn't move that fast, so you end up having bootclass hacks to get around these shortcomings.
And oh yeah, if you also support Android, you might as well hire someone full time to deal with this, since it is that time consuming to deal with.
I highly recommend regularly reading Mozilla's various posts on recommended security settings, especially the TLS best practises for web servers and OpenSSH.
- https://wiki.mozilla.org/Security/Server_Side_TLS
- https://mozilla.github.io/server-side-tls/ssl-config-generat...
SSLLabs evaluates the highest possible security, while Mozilla's levels compromise to implement the best possible TLS for a given population of users. "best" isn't always determined by security: speed and compatibility are taken into account as well.
That said, Mozilla's modern level ranks A+ in SSLLabs: https://www.ssllabs.com/ssltest/analyze.html?d=jve.linuxwall...
So they go for a reverse proxy, more often than not, just to get the 80/443 binding.
AES256-GCM is prioritized above its 128 bits variant,
and ChaCha20 because we assume that most modern devices
support AESNI instructions and thus benefit from fast
and constant time AES.
https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_com...obviously refering to the point that all this tight security will result in lot of issues for most users