Forked from ferd/gist:af9abf6b3600d2d7f08dba58fdfb514a
Created
April 20, 2021 17:32
-
-
Save nirev/6824ed45386794a519b8384a70c51606 to your computer and use it in GitHub Desktop.
This file contains 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 characters
Originally from: http://erlang.org/pipermail/erlang-questions/2017-August/093170.html | |
For a safe and fast Erlang SSL server, there's a few | |
configuration values you might want by default: | |
[{ciphers, CipherList}, % see below | |
{honor_cipher_order, true}, % pick the server-defined order of ciphers | |
{secure_renegotiate, true}, % prevent renegotiation hijacks | |
{client_renegotiation, false}, % prevent clients DoSing w/ renegs | |
{versions, ['tlsv1.2', 'tlsv1.1']}, % add tlsv1 if you must | |
{reuse_sessions, false}, % drop session cache for perf | |
{ecc, EllipticCurves}, % see below | |
{honor_ecc_order, true} | |
]. | |
A safe CipherList can be those enumerated in | |
https://github.com/heroku/snit/blob/master/src/snit.app.src#L45-L83 for | |
example, though the format in that config is meant to contain both the | |
OpenSSL-readable format and the Erlang-accepted one. | |
The order of elliptic curves I like is the one at | |
https://github.com/heroku/snit/blob/master/src/snit.app.src#L116-L121 -- | |
it is not the strongest, but aligns with what AWS ELBs prefer (secp256r1 | |
first) which gives a decent compromise between performance and safety. | |
Stronger curves at 512b roughly double the time a handshake takes, but | |
if you prefer the safety to the perf, reorder them to be first. | |
Furthermore, the following values can go in your sys.config file to | |
further modify the SSL behaviour: | |
{ssl, [ | |
{bypass_pem_cache, true}, % bypass PEM cache (see below) | |
{session_cb, ssl_cache_null}, % see below | |
{session_cb_init_args, []} % (cont) | |
]} | |
The PEM cache is a cache used whenever you have disk-based certificates. | |
In cases where you use in-memory certificates, it can act as a | |
bottleneck. See | |
https://blog.heroku.com/how-we-sped-up-sni-tls-handshakes-by-5x for my | |
writeup on the topic. | |
The last one about the session callback is a further cache that you may | |
disable if you hit performance issues. It uses the callback at | |
http://erlang.org/doc/man/ssl_session_cache_api.html to configure how to | |
store session data. A gotcha is that this table still sees some use even | |
if you disable the session cache (or at least it did last time I | |
looked). As such, you can provide an empty module like the following one | |
to fully bypass it: | |
-module(ssl_cache_null). | |
-behaviour(ssl_session_cache_api). | |
-export([init/1, terminate/1, lookup/2, update/3, delete/2, | |
foldl/3, select_session/2, size/1]). | |
init(_) -> disabled. | |
terminate(_) -> disabled. | |
lookup(_,_) -> undefined. | |
update(_,_,_) -> disabled. | |
delete(_,_) -> disabled. | |
foldl(_,Acc,_) -> Acc. | |
select_session(_,_) -> []. | |
size(_) -> 0. | |
With this module part of your project along with the config above, you | |
should get quite decent performance with it. Back in the days I was at | |
heroku, we went close to what Amazon ELBs could do in terms of | |
performance. Maybe a few milliseconds slower on average, but nearly an | |
order of magnitude faster on 99th percentiles. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment