# TLS

Fluent Bit provides integrated support for Transport Layer Security (TLS) and its predecessor Secure Sockets Layer (SSL). This section refers only to TLS for both implementations.

{% hint style="info" %}
Fluent Bit 4.1.0 introduced the replacement of Next Protocol Negotiation (NPN) with Application Layer Protocol Negotiation (ALPN) as its implementation for TLS. Both NPN and ALPN are used when client and server are establishing SSL/TLS connections. ALPN avoids an additional round trip because the client list the application layer protocols supported by the client in the client hello message.
{% endhint %}

Both input and output plugins that perform Network I/O can optionally enable TLS and configure the behavior. The following table describes the properties available:

| Property              | Description                                                                                                                             | Default |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `tls`                 | Enable or disable TLS support.                                                                                                          | `off`   |
| `tls.debug`           | Set TLS debug verbosity level. Accepted values: `0` (No debug), `1` (Error), `2` (State change), `3` (Informational) and `4` (Verbose). | `1`     |
| `tls.ca_file`         | Absolute path to CA certificate file.                                                                                                   | *none*  |
| `tls.ca_path`         | Absolute path to scan for certificate files.                                                                                            | *none*  |
| `tls.ciphers`         | Specify TLS ciphers up to TLSv1.2.                                                                                                      | *none*  |
| `tls.crt_file`        | Absolute path to Certificate file.                                                                                                      | *none*  |
| `tls.key_file`        | Absolute path to private Key file.                                                                                                      | *none*  |
| `tls.key_passwd`      | Optional password for `tls.key_file` file.                                                                                              | *none*  |
| `tls.max_version`     | Specify the maximum version of TLS.                                                                                                     | *none*  |
| `tls.min_version`     | Specify the minimum version of TLS.                                                                                                     | *none*  |
| `tls.verify`          | Force certificate validation.                                                                                                           | `on`    |
| `tls.vhost`           | Hostname to be used for TLS SNI extension.                                                                                              | *none*  |
| `tls.verify_hostname` | Force TLS verification of host names.                                                                                                   | `off`   |

To use TLS on input plugins, you must provide both a certificate and a private key.

The listed properties can be enabled in the configuration file, specifically in each output plugin section or directly through the command line.

The following output plugins can take advantage of the TLS feature:

* [Amazon S3](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/s3)
* [Apache SkyWalking](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/skywalking)
* [Azure](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/azure)
* [Azure Blob](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/azure_blob)
* [Azure Data Explorer (Kusto)](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/azure_kusto)
* [Azure Logs Ingestion API](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/azure_logs_ingestion)
* [BigQuery](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/bigquery)
* [Dash0](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/dash0)
* [Datadog](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/datadog)
* [Elasticsearch](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/elasticsearch)
* [Forward](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/forward)
* [GELF](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/gelf)
* [Google Chronicle](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/chronicle)
* [HTTP](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/http)
* [InfluxDB](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/influxdb)
* [Kafka REST Proxy](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/kafka-rest-proxy)
* [LogDNA](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/logdna)
* [Loki](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/loki)
* [New Relic](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/new-relic)
* [OpenSearch](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/opensearch)
* [OpenTelemetry](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/opentelemetry)
* [Oracle Cloud Infrastructure Logging Analytics](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/oci-logging-analytics)
* [Prometheus Remote Write](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/prometheus-remote-write)
* [Slack](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/slack)
* [Splunk](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/splunk)
* [Stackdriver](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/stackdriver)
* [Syslog](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/syslog)
* [TCP and TLS](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/tcp-and-tls)
* [Treasure Data](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/treasure-data)
* [WebSocket](https://docs.fluentbit.io/manual/4.1/data-pipeline/outputs/websocket)

The following input plugins can take advantage of the TLS feature:

* [Docker Events](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/docker-events)
* [Elasticsearch (Bulk API)](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/elasticsearch)
* [Forward](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/forward)
* [Health](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/health)
* [HTTP](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/http)
* [Kubernetes Events](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/kubernetes-events)
* [MQTT](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/mqtt)
* [NGINX Exporter Metrics](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/nginx)
* [OpenTelemetry](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/opentelemetry)
* [Prometheus Scrape Metrics](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/prometheus-scrape-metrics)
* [Prometheus Remote Write](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/prometheus-remote-write)
* [Splunk (HTTP HEC)](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/splunk)
* [Syslog](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/syslog)
* [TCP](https://docs.fluentbit.io/manual/4.1/data-pipeline/inputs/tcp)

In addition, other plugins implement a subset of TLS support, with restricted configuration:

* [Kubernetes Filter](https://docs.fluentbit.io/manual/4.1/data-pipeline/filters/kubernetes)

## Example: enable TLS on HTTP input

By default, the HTTP input plugin uses plain TCP. Run the following command to enable TLS:

```shell
fluent-bit -i http \
           -p port=9999 \
           -p tls=on \
           -p tls.verify=off \
           -p tls.crt_file=self_signed.crt \
           -p tls.key_file=self_signed.key \
           -o stdout \
           -m '*'
```

{% hint style="info" %}
See the Tips and Tricks section for details on generating `self_signed.crt` and `self_signed.key` files shown in these examples.
{% endhint %}

In the previous command, the two properties `tls` and `tls.verify` are set for demonstration purposes. Always enable verification in production environments.

The same behavior can be accomplished using a configuration file:

{% tabs %}
{% tab title="fluent-bit.yaml" %}

```yaml
pipeline:
  inputs:
    - name: http
      port: 9999
      tls: on
      tls.verify: off
      tls.crt_file: self_signed.crt
      tls.key_file: self_signed.key

  outputs:
    - name: stdout
      match: '*'
```

{% endtab %}

{% tab title="fluent-bit.conf" %}

```
[INPUT]
  name http
  port 9999
  tls on
  tls.verify off
  tls.crt_file self_signed.crt
  tls.key_file self_signed.key

[OUTPUT]
  Name       stdout
  Match      *
```

{% endtab %}
{% endtabs %}

## Example: enable TLS on HTTP output

By default, the HTTP output plugin uses plain TCP. Run the following command to enable TLS:

```shell
fluent-bit -i cpu -t cpu -o http://192.168.2.3:80/something \
           -p tls=on         \
           -p tls.verify=off \
           -m '*'
```

In the previous command, the properties `tls` and `tls.verify` are enabled for demonstration purposes. Always enable verification in production environments.

The same behavior can be accomplished using a configuration file:

{% tabs %}
{% tab title="fluent-bit.yaml" %}

```yaml
pipeline:
  inputs:
    - name: cpu
      tag: cpu

  outputs:
    - name: http
      match: '*'
      host: 192.168.2.3
      port: 80
      uri: /something
      tls: on
      tls.verify: off
```

{% endtab %}

{% tab title="fluent-bit.conf" %}

```
[INPUT]
  Name  cpu
  Tag   cpu

[OUTPUT]
  Name       http
  Match      *
  Host       192.168.2.3
  Port       80
  URI        /something
  tls        on
  tls.verify off
```

{% endtab %}
{% endtabs %}

## Tips and tricks

### Generate a self-signed certificates for testing purposes

The following command generates a 4096-bit RSA key pair and a certificate that's signed using `SHA-256` with the expiration date set to 30 days in the future. In this example, `test.host.net` is set as the common name. This example opts out of `DES`, so the private key is stored in plain text.

```shell
openssl req -x509 \
            -newkey rsa:4096 \
            -sha256 \
            -nodes \
            -keyout self_signed.key \
            -out self_signed.crt \
            -subj "/CN=test.host.net"
```

### Connect to virtual servers using TLS

Fluent Bit supports [TLS server name indication](https://en.wikipedia.org/wiki/Server_Name_Indication). If you are serving multiple host names on a single IP address (for example, using virtual hosting), you can make use of `tls.vhost` to connect to a specific hostname.

{% tabs %}
{% tab title="fluent-bit.yaml" %}

```yaml
pipeline:
  inputs:
    - name: cpu
      tag: cpu

  outputs:
    - name: forward
      match: '*'
      host: 192.168.10.100
      port: 24224
      tls: on
      tls.verify: off
      tls.ca_file: '/etc/certs/fluent.crt'
      tls.vhost: 'fluent.example.com'
```

{% endtab %}

{% tab title="fluent-bit.conf" %}

```
[INPUT]
  Name  cpu
  Tag   cpu

[OUTPUT]
  Name        forward
  Match       *
  Host        192.168.10.100
  Port        24224
  tls         on
  tls.verify  on
  tls.ca_file /etc/certs/fluent.crt
  tls.vhost   fluent.example.com
```

{% endtab %}
{% endtabs %}

### Verify `subjectAltName`

By default, TLS verification of host names isn't done automatically. As an example, you can extract the X509v3 Subject Alternative Name from a certificate:

```
X509v3 Subject Alternative Name:
    DNS:my.fluent-aggregator.net
```

This certificate covers only `my.fluent-aggregator.net` so if you use a different hostname it should fail.

To fully verify the alternative name and demonstrate the failure, enable `tls.verify_hostname`:

{% tabs %}
{% tab title="fluent-bit.yaml" %}

```yaml
pipeline:
  inputs:
    - name: cpu
      tag: cpu

  outputs:
    - name: forward
      match: '*'
      host: other.fluent-aggregator.net
      port: 24224
      tls: on
      tls.verify: on
      tls.verify_hostname: on
      tls.ca_file: '/path/to/fluent-x509v3-alt-name.crt'
```

{% endtab %}

{% tab title="fluent-bit.conf" %}

```
[INPUT]
  Name  cpu
  Tag   cpu

[OUTPUT]
  Name                forward
  Match               *
  Host                other.fluent-aggregator.net
  Port                24224
  tls                 on
  tls.verify          on
  tls.verify_hostname on
  tls.ca_file         /path/to/fluent-x509v3-alt-name.crt
```

{% endtab %}
{% endtabs %}

This outgoing connect will fail and disconnect:

```
[2024/06/17 16:51:31] [error] [tls] error: unexpected EOF with reason: certificate verify failed
[2024/06/17 16:51:31] [debug] [upstream] connection #50 failed to other.fluent-aggregator.net:24224
[2024/06/17 16:51:31] [error] [output:forward:forward.0] no upstream connections available
```
