ninenines/cowboy

Cowboy 2.9.0 with Ranch 1.8.0 fails when use TLS 1.3

shapovalovts opened this issue · 7 comments

I use Cowboy 2.9.0, which pulls Ranch 1.8.0. I tried to move recently from TLS 1.2 to 1.3 and the code fails here:

** {{case_clause,
     {error,
      {shutdown,
       {failed_to_start_child,wm_http,
        {{badmatch,
          {error,
           {{shutdown,
             {failed_to_start_child,ranch_acceptors_sup,
              {listen_error,https,
               {options,dependency,
                {next_protocols_advertised,
                 {versions,[tlsv1,'tlsv1.1','tlsv1.2']}}}}}},
            {child,undefined,
             {ranch_listener_sup,https},
             {ranch_listener_sup,start_link,
              [https,ranch_ssl,
               #{connection_type => supervisor,
                 socket_opts =>
                  [{next_protocols_advertised,[<<"h2">>,<<"http/1.1">>]},
                   {alpn_preferred_protocols,[<<"h2">>,<<"http/1.1">>]},
                   {port,8443},
                   {depth,99},
                   {verify,verify_peer},
                   {versions,['tlsv1.3']},
                   {fail_if_no_peer_cert,true},
                   {partial_chain,#Fun<wm_http.1.66849891>},
                   {cacertfile,"/opt/swm/spool/secure/cluster/cert.pem"},
                   {certfile,"/opt/swm/spool/secure/node/cert.pem"},
                   {keyfile,"/opt/swm/spool/secure/node/key.pem"}]},
               cowboy_tls,
               #{connection_type => supervisor,
                 env => #{dispatch => [{'_',[],[{[],[],wm_http_top,[]}]}]},
                 onresponse => #Fun<wm_http.2.66849891>}]},
             permanent,false,infinity,supervisor,
             [ranch_listener_sup]}}}},

Maybe I miss something, but it just works perfectly with TLS 1.2. The way I start Cowboy process:

      {ok, Result} =                                                                                                                      
          cowboy:start_tls(https,                                                                                                         
                           [{port, Port},                                                                                                 
                            {depth, 99},                                                                                                  
                            {verify, verify_peer},                                                                                        
                            {versions, ['tlsv1.3']},                              
                            {fail_if_no_peer_cert, true},                                                                                 
                            {partial_chain, PartChain},                                                                                   
                            {cacertfile, CaFile},                                                                                             
                            {certfile, CertFile},                                                                                             
                            {keyfile, KeyFile}],                                                                                              
                           #{env => #{dispatch => Dispatch}, onresponse => fun error_hook/4}),   
essen commented

That's because the option next_protocols_advertised does not work with TLS 1.3, it was replaced with ALPN. So Cowboy needs to filter it out if the version configured is only TLS 1.3.

For the time being you can take this function add it to your code and remove the NPN line and it should work: https://github.com/ninenines/cowboy/blob/master/src/cowboy.erl#L53-L62

I will do a maintenance release sometimes in September, when I get back from holidays.

Thank you! As a workaround I temporally added tlsv1.2 to the versions parameter and will wait for your maintenance release. But I am curios what line is NPN line there? Is it {next_protocols_advertised, [<<"h2">>, <<"http/1.1">>]},?

essen commented

Yes this is the option for the NPN extension.

essen commented

I will remove the old NPN option entirely in the next release.

Same issue exists also for client_preferred_next_protocols in Gun unless you already realized that.

essen commented

Please open a ticket in Gun.

essen commented

The option was removed in the merged PR. Gun will see the same treatment later on. Closing, thanks!