ninenines / cowboy

Small, fast, modern HTTP server for Erlang/OTP.

Home Page:https://ninenines.eu

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cowboy 2.9.0 with Ranch 1.8.0 fails when use TLS 1.3

shapovalovts opened this issue · 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}),   

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">>]},?

Yes this is the option for the NPN extension.

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.

Please open a ticket in Gun.

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