zmoog / public-notes

Apache License 2.0
0 stars 1 forks source link

Figure out how to set up ESF to use `ssl_assert_fingerprint` option with Elasticsearch #45

Closed zmoog closed 1 year ago

zmoog commented 1 year ago

In v1.5.0, the pull request https://github.com/elastic/elastic-serverless-forwarder/pull/173 introduces the SSL fingerprint option to access Elasticsearch clusters using self-signed certificates.

I want to test it and add step-by-step instructions on how to set it up.

zmoog commented 1 year ago

To set the ssl_assert_fingerprint option, you must edit the config file stored in the S3 bucket.

Suppose you have a config.yml file stored in the bucket with the following content:

inputs:
  - type: "s3-sqs"
    id: "arn:aws:sqs:eu-west-1:<REDACTED>:zmoog-dev-access-logs"
    outputs:
      - type: "elasticsearch"
        args:
          api_key: "<REDACTED>"
          es_datastream_name: "logs-aws.s3access-default"
          batch_max_actions: 500
          batch_max_bytes: 10485760
          ssl_assert_fingerprint: ""

In this example, the ssl_assert_fingerprint is blank, the default option. With this value, the ssl_assert_fingerprint is ignored, and ESF will validate the HTTPS certificate.

zmoog commented 1 year ago

The next step is to get the fingerprint of the HTTPS certificate your Elasticsearch cluster is using now.

You can use OpenSSL to get the fingerprint for your certificate. Here's an example using an Elasticsearch cluster hosted on Elastic Cloud:

$ openssl s_client \
    -connect my-deployment.es.eastus2.azure.elastic-cloud.com:443 \
    -showcerts </dev/null 2>/dev/null | openssl x509 -noout -fingerprint

SHA1 Fingerprint=1C:46:32:75:AA:D6:F1:E2:8E:10:A3:64:44:B1:36:C9:7D:44:35:B4

You can use your DNS name, IP address, and port number instead of my-deployment.es.eastus2.azure.elastic-cloud.com:443 from the above example.

Copy your fingerprint value for the next step.

zmoog commented 1 year ago

As a final step, edit your config.yml file to use the SSL fingerprint:

inputs:
  - type: "s3-sqs"
    id: "arn:aws:sqs:eu-west-1:<REDACTED>:zmoog-dev-access-logs"
    outputs:
      - type: "elasticsearch"
        args:
          api_key: "<REDACTED>"
          es_datastream_name: "logs-aws.s3access-default"
          batch_max_actions: 500
          batch_max_bytes: 10485760
          ssl_assert_fingerprint: "1C:46:32:75:AA:D6:F1:E2:8E:10:A3:64:44:B1:36:C9:7D:44:35:B4"
zmoog commented 1 year ago

To double-check the mechanism is working, your can modify the fingerprint.

For this test, I am replacing B4 with B0 in the above fingerprint.

With the wrong fingerprint, ESF with log a message like this one:

{
    "@timestamp": "2023-08-07T11:12:46.785Z",
    "log.level": "warning",
    "message": "GET https://my-deployment.es.eastus2.azure.elastic-cloud.com:443/ [status:N/A request:0.233s]",
    "ecs": {
        "version": "1.6.0"
    },
    "error": {
        "message": "Fingerprints did not match. Expected \"1c463275aad6f1e28e10a36444b136c97d4435b0\", got \"b'1c463275aad6f1e28e10a36444b136c97d4435b4'\".",
        "stack_trace": "  File \"/var/task/elasticsearch/connection/http_urllib3.py\", line 255, in perform_request\n    response = self.pool.urlopen(\n  File \"/var/task/elasticapm/instrumentation/packages/base.py\", line 211, in call_if_sampling\n    return self.call(module, method, wrapped, instance, args, kwargs)\n  File \"/var/task/elasticapm/instrumentation/packages/urllib3.py\", line 132, in call\n    response = wrapped(*args, **kwargs)\n  File \"/var/task/urllib3/connectionpool.py\", line 787, in urlopen\n    retries = retries.increment(\n  File \"/var/task/urllib3/util/retry.py\", line 525, in increment\n    raise six.reraise(type(error), error, _stacktrace)\n  File \"/var/task/urllib3/packages/six.py\", line 770, in reraise\n    raise value\n  File \"/var/task/urllib3/connectionpool.py\", line 703, in urlopen\n    httplib_response = self._make_request(\n  File \"/var/task/urllib3/connectionpool.py\", line 386, in _make_request\n    self._validate_conn(conn)\n  File \"/var/task/urllib3/connectionpool.py\", line 1042, in _validate_conn\n    conn.connect()\n  File \"/var/task/urllib3/connection.py\", line 450, in connect\n    assert_fingerprint(\n  File \"/var/task/urllib3/util/ssl_.py\", line 204, in assert_fingerprint\n    raise SSLError(\n",
        "type": "SSLError"
    },
    "log": {
        "logger": "elasticsearch",
        "origin": {
            "file": {
                "line": 288,
                "name": "base.py"
            },
            "function": "log_request_fail"
        },
        "original": "GET https://my-deployment.es.eastus2.azure.elastic-cloud.com:443/ [status:N/A request:0.233s]"
    },
    "process": {
        "name": "MainProcess",
        "pid": 8,
        "thread": {
            "id": 140422914877248,
            "name": "MainThread"
        }
    },
    "service": {
        "name": "forwarder-lambda-ApplicationElasticServerlessForwa-E3uBQcSDRFwm"
    },
    "span": {
        "id": "13370a075b108858"
    },
    "trace": {
        "id": "82f3c38384713b567b01f80c76820d67"
    },
    "transaction": {
        "id": "053c32e093d2d473"
    }
}
zmoog commented 1 year ago

Closing as completed.