[erlang-questions] SSL hostname verification
Raimo Niskanen
raimo+erlang-questions@REDACTED
Thu Jan 25 10:40:30 CET 2018
On Tue, Jan 23, 2018 at 06:04:53PM +0100, San Gillis wrote:
> > So you need to have a module implementing the function that you want to
> > use as a fun.
> >
>
> I tried this, and I start my remote shell using
> `erl -remsh nodename@REDACTED -pa ./ebin -setcookie cookie -name node@REDACTED
> -ssl_dist_optfile ./sslopts.conf -proto_dist inet_tls`
> where ./ebin contains the module beam.
>
> In this case the shell process just terminates without giving me any error
> messages.
>
>
> This is a limitation for distribution over TLS as unamed funs can not be
> > handled in files.
> >
>
> When I put some `io:format` statements in my unnamed function they did get
> printed to console, so it seems this does work?
>
> Regards,
> San
Well, I'll be darned, but that acually seems to work!
The file parsing results in an erl_eval internal fun with the parsed
abstract form in its environment, so when that fun is called it is
interpreted by erl_eval. Interpretation is _much_ slower then execution,
but I do not know when that would be a real problem...
Here is an example that works, I ripped out pieces from after running
the test suite ssl_dist_bench_SUITE:setup/1:
To start one node:
erl -run application start crypto -run application start public_key
-eval 'net_kernel:verbose(1)'
-sname ssl_dist_bench_SUITE_node_a
-proto_dist inet_tls
-ssl_dist_optfile ~/tmp/ssl_dist_bench_SUITE_node_a@REDACTED
To start the other node:
erl -run application start crypto -run application start public_key
-eval 'net_kernel:verbose(1)'
-sname ssl_dist_bench_SUITE_node_b
-proto_dist inet_tls
-ssl_dist_optfile ~/tmp/ssl_dist_bench_SUITE_node_b@REDACTED
My host's short name is elxd1243rl3.
The "-eval 'net_kernel:verbose(1)' increases verbosity for testing.
The applications 'crypto' and 'public_key' has to be started, either from
the command line like this, or from a dedicated boot script. See:
http://erlang.org/doc/apps/ssl/ssl_distribution.html Section 4.1
The test framework generates the .conf files containing certificates for
the short node names so these nodes actually pass hostname verification.
In these .conf files I have added an inline verify_fun in the client
section.
Excerpt from ~/tmp/ssl_dist_bench_SUITE_node_b@REDACTED:
[{server,
[{fail_if_no_peer_cert,true},
{verify,verify_peer},
{versions,['tlsv1.2']},
{ciphers,[{ecdhe_ecdsa,aes_128_cbc,sha256,sha256}]},
{cert,<<48,130,2,237,48,130,2,72,160,3,2,1,2,2,1,4,48,16,6,7,42,134,
...,235,67,74,159,21,16,15>>},
{key,{'ECPrivateKey',<<48,129,220,2,1,1,4,66,1,177,250,81,233,146,
...,60,213,172>>}},
{cacerts,[<<48,130,2,213,48,130,2,48,160,3,2,1,2,2,1,2,48,16,6,7,42,
...,141,240,231,115,166,243>>,
<<48,130,2,213,48,130,2,48,160,3,2,1,2,2,1,2,48,16,6,7,
...,237,32,9,141,240,231,115,166,243>>]}]},
{client,
[{verify,verify_peer},
{verify_fun,
{fun (_, Event, UserState) ->
io:format("~p.~n", [Event]),
case Event of
{bad_cert, hostname_check_failed} ->
%%% Preform own check ...
{valid, UserState};
{extension, _} ->
{unknown, UserState};
valid ->
{valid, UserState};
valid_peer ->
{valid, UserState}
end
end, []}},
{versions,['tlsv1.2']},
{ciphers,[{ecdhe_ecdsa,aes_128_cbc,sha256,sha256}]},
{cert,<<48,130,2,237,48,130,2,72,160,3,2,1,2,2,1,4,48,16,6,7,42,134,
...,235,67,74,159,21,16,15>>},
{key,{'ECPrivateKey',<<48,129,220,2,1,1,4,66,1,177,250,81,233,146,
...,60,213,172>>}},
{cacerts,[<<48,130,2,213,48,130,2,48,160,3,2,1,2,2,1,2,48,16,6,7,42,
...,141,240,231,115,166,243>>,
<<48,130,2,213,48,130,2,48,160,3,2,1,2,2,1,2,48,16,6,
...,206,74,237,32,9,141,240,231,115,166,243>>]}
]
}].
This is node a that gets connected to, I am sorry I connected from node b
to node a, that is not according to telco tradition :-(
erl -run application start crypto -run application start public_key
-eval 'net_kernel:verbose(1)' -sname ssl_dist_bench_SUITE_node_a
-proto_dist inet_tls
-ssl_dist_optfile ~/tmp/ssl_dist_bench_SUITE_node_a@REDACTED
Erlang/OTP 21 [DEVELOPMENT] [erts-9.2] [source-8e66754] [64-bit] [smp:8:8]
[ds:8:8:10] [async-threads:10] [hipe]
Eshell V9.2 (abort with ^G)
(ssl_dist_bench_SUITE_node_a@REDACTED)1>
=ERROR REPORT==== 25-Jan-2018::09:53:37 ===
Net kernel got ping
And this is node b that connects:
erl -run application start crypto -run application start public_key
-eval 'net_kernel:verbose(1)' -sname ssl_dist_bench_SUITE_node_b
-proto_dist inet_tls
-ssl_dist_optfile ~/tmp/ssl_dist_bench_SUITE_node_b@REDACTED
Erlang/OTP 21 [DEVELOPMENT] [erts-9.2] [source-8e66754] [64-bit] [smp:8:8]
[ds:8:8:10] [async-threads:10] [hipe]
Eshell V9.2 (abort with ^G)
(ssl_dist_bench_SUITE_node_b@REDACTED)1>
{net_kernel,ssl_dist_bench_SUITE_node_a@REDACTED} ! ping.
ping
=INFO REPORT==== 25-Jan-2018::09:53:37 ===
{net_kernel,{auto_connect,ssl_dist_bench_SUITE_node_a@REDACTED,1,
#Ref<0.1220262086.1603141640.225564>}}
{extension,
{'Extension',{2,5,29,17},false,
[{dNSName,"ssl_dist_bench_SUITE_node_a@REDACTED"}]}}.
valid_peer.
(ssl_dist_bench_SUITE_node_b@REDACTED)2>
So we got two printouts from the verify_fun on node b, one for the
subject altnames extension, and one from the succesful validation.
I hope this information was useful.
--
/ Raimo Niskanen, Erlang/OTP, Ericsson AB
More information about the erlang-questions
mailing list