Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save lazedo/051fb65f087983e8dac56f1edf1b0d37 to your computer and use it in GitHub Desktop.

Select an option

Save lazedo/051fb65f087983e8dac56f1edf1b0d37 to your computer and use it in GitHub Desktop.

Revisions

  1. @ferd ferd revised this gist Aug 29, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    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:

  2. @ferd ferd created this gist Aug 29, 2017.
    68 changes: 68 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    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.