Vector’s TLS encryption is a powerful way to secure data in transit, but understanding how to configure it correctly for both sources and sinks can be tricky.

Let’s see it in action. Imagine you have a file source sending logs to a tcp sink.

[sources.my_file]
type = "file"
include = ["/var/log/myapp/*.log"]
decryption = { tls.0 = { ca_cert = "/etc/vector/certs/ca.crt" } } # Example for source decrypting

[sinks.my_tcp]
type = "tcp"
address = "192.168.1.100:9000"
encoding.text.line_ending = "unix"
encryption = { tls.0 = { tls_key = "/etc/vector/certs/client.key", tls_cert = "/etc/vector/certs/client.crt" } } # Example for sink encrypting

In this setup, the file source is configured to decrypt data using a CA certificate, which might seem odd at first glance. This is because Vector treats the source itself as a potential client or server in a TLS handshake. If the data originating from the source needs to be decrypted before Vector processes it (e.g., it was encrypted by an upstream agent before being written to the file), you’d configure decryption here. More commonly, however, the encryption block on the sink is what ensures data is encrypted by Vector as it’s sent out.

The tcp sink, on the other hand, is configured to encrypt data before sending it. This is the more typical use case: Vector encrypts the data it’s sending to a remote endpoint.

Here’s the breakdown of how Vector handles TLS for sources and sinks:

Sources:

  • decryption block: This is where you tell Vector how to decrypt data coming into the source. This is less common for standard file or network sources but is crucial if your source is receiving data that was already encrypted by an upstream component.
    • ca_cert: The Certificate Authority certificate that signed the certificate presented by the remote peer (the entity sending data to this source). Vector uses this to verify the identity of the sender.
    • tls_key, tls_cert: If the source itself needs to present a certificate to a client connecting to it (e.g., a custom source type that acts as a server), these would be used.
  • Purpose: To ensure that data arriving at the source is legitimate and to decrypt it for further processing within Vector.

Sinks:

  • encryption block: This is where you configure Vector to encrypt data before it’s sent out by the sink. This is the most frequent TLS configuration.
    • tls_key, tls_cert: The private key and certificate Vector will use to identify itself to the remote endpoint.
    • ca_cert: The Certificate Authority certificate that signed the certificate of the remote endpoint (the server the sink is sending data to). Vector uses this to verify the identity of the server it’s connecting to.
  • Purpose: To secure data in transit from Vector to its destination, ensuring confidentiality and integrity.

The TLS Handshake Mechanics:

When a sink is configured with encryption and connects to a remote endpoint, a TLS handshake occurs. The sink (Vector) presents its tls_cert and tls_key. The remote endpoint verifies Vector’s certificate against its configured ca_cert. Simultaneously, the remote endpoint presents its own certificate, which Vector verifies against the sink’s ca_cert. If both sides successfully authenticate each other, a secure, encrypted channel is established.

For sources with decryption, the roles are reversed. If the source is acting as a server (e.g., receiving data via a network protocol that uses TLS), it would present its certificate (tls_cert, tls_key) and verify the client’s certificate using ca_cert.

Key Configuration Parameters:

  • ca_cert: Path to the Certificate Authority certificate file.
  • tls_key: Path to the private key file.
  • tls_cert: Path to the certificate file.
  • private_key_pass: Password for the private key, if encrypted.
  • alpn: Application-Layer Protocol Negotiation. Useful for protocols like HTTP/2.
  • verify_peer: Boolean, whether to verify the peer’s certificate. Defaults to true.
  • tls_version: Minimum TLS version to use (e.g., TLSv1.2, TLSv1.3).

Common Pitfalls and Solutions:

  1. Certificate File Permissions: Ensure Vector has read access to all certificate and key files.

    • Check: ls -l /etc/vector/certs/
    • Fix: chmod 400 /etc/vector/certs/client.key and chmod 644 /etc/vector/certs/client.crt (or appropriate user/group ownership).
    • Why: Vector runs as a specific user (often vector or nobody), and that user needs to be able to read these files.
  2. Incorrect ca_cert: The ca_cert specified doesn’t actually sign the certificate of the peer you’re trying to connect to or receive data from.

    • Check: Manually inspect the peer’s certificate and compare its issuer to the ca_cert you’ve provided.
    • Fix: Replace ca_cert with the correct CA certificate that issued the peer’s certificate.
    • Why: TLS relies on a chain of trust. If the CA is wrong, the trust cannot be established.
  3. Mismatched Certificates/Keys: The tls_cert and tls_key in the encryption block (for sinks) or decryption block (for sources acting as servers) do not belong to each other.

    • Check: Use openssl x509 -noout -modulus -in <cert_file> | openssl md5 and openssl rsa -noout -modulus -in <key_file> | openssl md5. The output MD5 hashes should match.
    • Fix: Ensure the tls_cert and tls_key files provided correspond to the same private key.
    • Why: The certificate is a public representation of the key; they must be mathematically linked.
  4. Expired Certificates: The certificates used by either Vector or the remote peer have expired.

    • Check: openssl x509 -enddate -noout -in <cert_file>
    • Fix: Renew and replace the expired certificates.
    • Why: TLS requires valid, non-expired certificates for authentication.
  5. Hostnames/IP Mismatches: The hostname or IP address configured in Vector does not match any Subject Alternative Names (SANs) or Common Names (CNs) in the remote peer’s certificate.

    • Check: openssl s_client -connect <host:port> -showcerts < /dev/null and examine the certificate details.
    • Fix: Ensure the address in the sink or the hostname used by the client connecting to the source matches a name in the certificate. Alternatively, regenerate the certificate with the correct names.
    • Why: For security, the client verifies that the server it’s connecting to is actually the server it thinks it’s connecting to, based on the certificate’s identity.
  6. Missing Intermediate Certificates: The tls_cert file doesn’t include the necessary intermediate certificates to form a complete chain back to the root CA.

    • Check: Using openssl s_client as above, check if the chain is complete.
    • Fix: Concatenate the intermediate certificates into your tls_cert file, ensuring the server’s certificate is first, followed by intermediates, and finally the root CA (though the root is often implicit or provided via the system trust store).
    • Why: The client needs the full chain to verify the server’s certificate up to a trusted root.
  7. SNI (Server Name Indication) Issues: When connecting to a server that hosts multiple TLS-enabled sites/services on the same IP address, SNI is used to indicate which hostname the client is trying to connect to. If not configured correctly on either end, the server might present the wrong certificate.

    • Check: Vector’s tcp sink has an tls.server_name option to explicitly set the SNI.
    • Fix: Set tls.server_name in the encryption block of the sink to match the hostname you expect.
    • Why: SNI allows a single IP to serve multiple TLS certificates, but both client and server must agree on the target hostname.

Once these are all correctly configured, the next hurdle you might face is handling certificate rotation and ensuring Vector automatically picks up new certificates without a restart.

Want structured learning?

Take the full Vector course →