fluent / fluentd

Fluentd: Unified Logging Layer (project under CNCF)
https://www.fluentd.org
Apache License 2.0
12.85k stars 1.34k forks source link

TLS 1.3 support in http output plugin #4332

Open ashie opened 11 months ago

ashie commented 11 months ago

Discussed in https://github.com/fluent/fluentd/discussions/4329

Originally posted by **mikakatua** October 22, 2023 I'm trying to use fluentd to send logs to a http endpoint. This endpoint only supports TLS 1.3 My configuration is as follows: ``` @type forward @label @mainstream port 24224 bind 0.0.0.0 ``` This does not work. I get the error: > [warn]: #0 got unrecoverable error in primary and no secondary error_class=ArgumentError error="unknown SSL method `TLSv1_3'" Looking at the [http output documentation](https://docs.fluentd.org/output/http#tls_version) it looks like the max version is TLS 1.2. I have verified that it works removing the `tls_version` parameter and downgrading the ssl configuration of the endpoint to support TLS 1.2. If I remove the `tls_version` parameter without downgrading the endpoint, the error is: > [warn]: #0 failed to flush the buffer. retry_times=0 next_retry_time=2023-10-21 15:55:12 +0000 chunk="6083c037d2f85b70a8f464156a75b22d" error_class=OpenSSL::SSL::SSLError error="SSL_connect returned=1 errno=0 peeraddr=172.18.0.4:8443 state=error: tlsv1 alert protocol version" Is there any way to get it working with TLS 1.3? I'm using Fluentd v1.16.2-1.0 docker image
ashie commented 11 months ago

Hmm, current out_http implementation doesn't seem able to set TLSv1.3 because it doesn't use Fluent::TLS:#set_version_to_context, it passes the version string directly to Net::HTTP#start:

https://github.com/fluent/fluentd/blob/dd1a6e59b059af3d2e84a1c10be7a2baf637a748/lib/fluent/plugin/out_http.rb#L207 https://github.com/fluent/fluentd/blob/dd1a6e59b059af3d2e84a1c10be7a2baf637a748/lib/fluent/plugin/out_http.rb#L248-L256

and it still uses deprecated method ssl_version: https://github.com/ruby/openssl/blob/f948e6bbd371046b880be50b9613fca110dbd27a/lib/openssl/ssl.rb#L209-L231

      def ssl_version=(meth)
        meth = meth.to_s if meth.is_a?(Symbol)
        if /(?<type>_client|_server)\z/ =~ meth
          meth = $`
          if $VERBOSE
            warn "#{caller(1, 1)[0]}: method type #{type.inspect} is ignored"
          end
        end
        version = METHODS_MAP[meth.intern] or
          raise ArgumentError, "unknown SSL method `%s'" % meth
        set_minmax_proto_version(version, version)
        @min_proto_version = @max_proto_version = version
      end

      METHODS_MAP = {
        SSLv23: 0,
        SSLv2: OpenSSL::SSL::SSL2_VERSION,
        SSLv3: OpenSSL::SSL::SSL3_VERSION,
        TLSv1: OpenSSL::SSL::TLS1_VERSION,
        TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
        TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION,
      }.freeze
      private_constant :METHODS_MAP

We should fix this.