-
-
Notifications
You must be signed in to change notification settings - Fork 337
strip out options unsupported in TLS1.3 before listening on socket #313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Fixes also submitted for Plug and Plug Cowboy: |
|
I don't know if this is something we want, but that's definitely not the right place, TLS related code should only be in |
I'll take a look into moving it then. thank you. |
…ocket" This reverts commit dc8ba08.
…oved from acceptors)
I've moved it to |
|
This is not pretty but I personally think it's the right thing to do. For example, we had to document these limitations for RabbitMQ but many users don't read any docs until things fail, often too late in the process (e.g. at deployment time). |
Maria-12648430
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments inline :)
src/ranch_ssl.erl
Outdated
| ok. | ||
|
|
||
| -spec strip_usupported_options(opts()) -> opts(). | ||
| strip_usupported_options(SocketOpts) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo? usupported --> unsupported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed, thank you for spotting that. The downside of autocomplete once it was written wrong.
src/ranch_ssl.erl
Outdated
|
|
||
| -spec strip_usupported_options(opts()) -> opts(). | ||
| strip_usupported_options(SocketOpts) -> | ||
| case lists:keyfind(versions, 1, SocketOpts) of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is only part of it, ie the versions key in the socket options is not the only place influencing it. According to the ssl docs here, if absent it can also be set by an environment option for the ssl application, and if absent there it defaults to all versions that are supported (which can probably be found out by examining the supported key in the return from ssl:versions()).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if you mean that other options could give a value of 'tlsv1.3' for a version number, not only {versions, ['tlsv1.3']}; however, just to clarify, we found that as long as other options are specified in addition to 'tlsv1.3', .e.g. {versions, ['tlsv1.2', 'tlsv1.3']}, then the SSL error does not occur.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We mean that the versions could be implicitly ['tlsv1.3'] even if you don't specify them at all in the socket options, namely if they are specified in the ssl application environment. Like, try starting your node with erl -ssl protocol_versions "['tlsv1.3']". If you later give other versions in the socket options, that overrides those environment settings, but if you leave them out, the ssl application environment protocol_versions is taken for versions. If that is not defined either, versions default to all supported versions, which is probably more than only ['tlsv1.3'].
So, I guess what I mean is, if you don't find versions in the socket options, see if there is a protocol_versions key in the application environment of ssl, and if that is set to ['tlsv1.3].
src/ranch_ssl.erl
Outdated
| _ -> | ||
| SocketOpts | ||
| end; | ||
| strip_usupported_options(SocketOpts) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This clause is pointless, it will never be reached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove this. It was inherited from the code, which I'd moved from the acceptors file.
src/ranch_ssl.erl
Outdated
| Intermediate1 = lists:keydelete(secure_renegotiate, 1, SocketOpts), | ||
| Intermediate2 = lists:keydelete(reuse_sessions, 1, Intermediate1), | ||
| Intermediate3 = lists:keydelete(next_protocols_advertised, 1, Intermediate2), | ||
| lists:keydelete(alpn_preferred_protocols, 1, Intermediate3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor detail probably, but this is not exhaustive either. lists:keydelete only removes the first occurrence, but in reality the same option may be given multiple times, pointless as that may be (if it follows the practice used in gen_tcp, not 100% sure for ssl). To be on the safe side, you'll have to lists:filter/2 the socket options.
|
Please do not silently drop the values, instead we should call /cc @lhoguin |
|
I hope I resolved the above suggestions:
The only thing I wasn't quite sure of was, can if
(Versions1 == {versions, ['tlsv1.3']}) or ((Versions1 == false) and (Versions2 == {protocol_versions, ['tlsv1.3']})) -> |
| -spec strip_unsupported_options(opts()) -> opts(). | ||
| strip_unsupported_options(SocketOpts) -> | ||
| Versions1 = lists:keyfind(versions, 1, SocketOpts), | ||
| Versions2 = lists:keyfind(protocol_versions, 1, SocketOpts), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protocol_versions is not in SocketOpts but in the environment of the ssl application
application:get_env(ssl, protocol_versions)
If versions is given in SocketOpts, it overrides protocol_versions from the application environment.
| if | ||
| NewSocketOpts /= SocketOpts -> | ||
| error_logger:warning_msg("~p~n dropping options unsupported by TLS1.3-only ssl sockets: " ++ | ||
| "secure_renegotiate, reuse_sessions, next_protocols_advertised and/or alpn_preferred_protocols from ~p~n", [?MODULE, SocketOpts]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not use error_logger directly here (or logger, for that matter), but ranch:log/3 with the value from the logger key in TransOpts (as given to ranch_ssl: listen).
Also, the message is at the same time very verbose and doesn't tell very much, ie which options were actually dropped.
| if | ||
| (Versions1 == {versions, ['tlsv1.3']}) or (Versions2 == {protocol_versions, ['tlsv1.3']}) -> | ||
| NewSocketOpts = lists:filter(fun({X, _}) -> | ||
| (X /= secure_renegotiate) and (X /= reuse_sessions) and (X /= next_protocols_advertised) and (X /= alpn_preferred_protocols); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to do it this way (and I'm pretty sure that @essen will object 😅), you should use andalso. But it may be better to have individual clauses for each, so you could log what you found and dropped along the way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to log what is dropped indeed.
|
This PR seems to have dried up. I can take it on if you want? |
Hi, I believe you had a PR se-apc#3 for this. It's probably in more correct format as I'm not an Erlang programmer. It's ok if you want to go ahead and merge it in. The fix is working for us on a local branch, so I've not had to go back and touch it again (if it ain't broke, etc.... ) |
|
@Maria-12648430 Please take over the PR then. I think it would be good to release it in Ranch 2.1 along with the other ones. |
|
|
Closed in favor of #324. |
These four options to secure earlier TLS versions are actually unsupported by TLS1.3 and are sometimes added by default (e.g. in Plug and Plug Cowboy):
When earlier versions aren't being enabled, this gives an error from OTP SSL module. Remove these options if TLS1.3 is the only enabled protocol, to get around this error.