vectordotdev / vector

A high-performance observability data pipeline.
https://vector.dev
Mozilla Public License 2.0
17.72k stars 1.57k forks source link

`verify_certificate` in TLS settings is not about the verification of server certificate #20152

Closed arslanm-mollie closed 7 months ago

arslanm-mollie commented 7 months ago

A note for the community

No response

Problem

Hello all,

If you want to secure your source, in my case Datadog Agent, with TLS you'd get below config:

sources:
  datadog_metrics:
    address: 0.0.0.0:8282
    tls:
      enabled: true
      ca_file: ./some_ca
      crt_file: ./some_crt
      key_file: ./some_key
      verify_certificate: true

Vector documentation provides following information for the parameter verify_certificate:

If enabled, certificates must not be expired and must be issued by a trusted issuer.  
This verification operates in a hierarchical manner, checking that the leaf certificate. 
(the certificate presented by the client/server) is not only valid, but that the issuer of  
that certificate is also valid, and so on until the verification process reaches a root certificate.

Relevant for both incoming and outgoing connections.

Do NOT set this to false unless you understand the risks of not verifying the validity of certificates.

But this is not entirely true. If we look at lib/vector-core/src/tls/settings.rs we'll see below code:

        context.set_verify(if self.verify_certificate {
            SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT
        } else {
            SslVerifyMode::NONE
        });

and the documentation for SslVerifyMode tells us that SslVerifyMode::PEER:

Verifies that the peer’s certificate is trusted.

On the server side, this will cause OpenSSL to request a certificate from the client.

and SslVerifyMode::FAIL_IF_NO_PEER_CERT:

On the server side, abort the handshake if the client did not send a certificate.

This should be paired with SSL_VERIFY_PEER. It has no effect on the client side.

So verify_certificate not only does not verify the certificate that we provide to Vector to secure an endpoint for inbound connections, but instead it requests a certificate from the client and attempts to verify that. If the client does not send a certificate (which is the case with the Datadog Agent's vector config) then you'd get a handshake error with SSL alert number 40 which is quite tricky to troubleshoot.

One suggestion I could make is to rename the parameter to verify_certificate_auth or something in that nature and update the documentation. It should be made clear to the user that for inbound connections this parameter requires a certificate from the client.

Configuration

No response

Version

0.36.0

Debug Output

No response

Example Data

No response

Additional Context

No response

References

No response

jszwedko commented 7 months ago

Hi @arslanm-mollie ,

Correct, verify_certificate on sources that create a server validates the client certificate. I agree that the docs could probably be a bit clearer on this front.