Skip to content

Latest commit

 

History

History
148 lines (119 loc) · 6.37 KB

fleet-server-bootstrap.asciidoc

File metadata and controls

148 lines (119 loc) · 6.37 KB

Fleet Server Bootstrap

Elastic Agent with Fleet Server has a bootstrap process that it uses to get Fleet Server up and running under Elastic Agent.

Elastic Agent will bootstrap a Fleet Server when the --fleet-server-es command-line option is provided to an install or enroll command. In this mode Elastic Agent will only communicate with its local Fleet Server and expose the Fleet Server over the :8221 port.

The :8221 port is reserved for communication between the Elastic Agent and the Fleet Server on the host. It is bound to the localhost of the machine/container and cannot be accessed remotely. This ensures that the local Elastic Agent has priority in check-ins with the Fleet Server. The :8220 port is bound on 0.0.0.0 to allow remote connections from external Elastic Agents that wish to enroll and communicate.

Operating Modes

Elastic Agent can bootstrap the Fleet Server into three different modes. The mode determines how Fleet Server exposes itself over the :8220 port, but does not change any other behaviour.

Self-signed Certificate

With the standard --fleet-server-es and --fleet-server-service-token options the Elastic Agent will generate a CA and certificate for communication with the Fleet Server that it starts. These certificates are generated by Elastic Agent and passed to the Fleet Server, with Elastic Agent using the host’s hostname in the communication URL for valid TLS verification.

HTTP Only

Using the --insecure and --fleet-server-insecure-http will bootstrap the Fleet Server without any certificates, it will be bound to localhost:8220 and Elastic Agent will communicate in clear-text.

Custom Certificates (aka. Production)

When deploying Elastic Agent in a production environment using enterprise generated certificates will ensure that Elastic Agent running locally and remote Elastic Agent will be able to connect over a verified TLS based connection. Certificates are specified with --fleet-server-cert, --fleet-server-cert-ca, and --certificate-authorities.

How Does It Bootstrap

Bootstrapping is ran during the enroll command. The install command or the container command (used by Docker container) will call the enroll command to perform the bootstrapping process.

Install Command

When the install command is executed it places the Elastic Agent in the correct file paths based on the operating system then starts the Elastic Agent service. The enroll command is then executed by the install command.

Container Command

When the container command is executed it first copies the data/downloads directory into a state path (STATE_PATH) then it executes the enroll command.

Enroll Command

This is where all the actual work of bootstrapping is performed.

  1. A new fleet.yml is written with fleet.server.* options set along with fleet.server.bootstrap: true.

  2. enroll command then either triggers a restart or spawns an Elastic Agent daemon.

    1. First it checks if there is a running Elastic Agent daemon using the control socket. In the case that there is a running Elastic Agent daemon it will trigger a restart through the control socket.

    2. In the case that there is no running Elastic Agent daemon a subprocess with the run command will be started. The enroll command will then wait for the process to be up and running by monitoring it with the control socket.

  3. The status command will then be polled through the control socket waiting for the fleet-server application to be reported as degraded. degraded is reported because the fleet-server is started without an agent.id.

  4. Once fleet-server is degraded the enroll command then uses localhost to communicate with the running fleet-server to complete enrollment. This is the same enrollment used by the Elastic Agent to a remote Fleet Server.

  5. A new fleet.yml is written with the enrollment information including its agent.id and its API key to use for communication. The new fleet.yml still includes the fleet.server.*, but this time the fleet.server.bootstrap: false is set.

  6. enroll command then either restarts the running Elatic Agent daemon if one was running from Step 2, or it stops the spawned run subprocess and returns.

Elasticsearch output

The options passed that are used to specify fleet-server initially connects to elasticsearch are:

  • --fleet-server-es

  • --fleet-server-es-ca

  • --fleet-server-es-ca-trusted-fingerprint

  • --fleet-server-es-insecure

  • --fleet-server-es-cert

  • --fleet-server-es-cert-key

  • --fleet-server-es-service-token

  • --fleet-server-es-service-token-path

  • --proxy-url

  • --proxy-disabled

  • --proxy-header

These options are always passed under a bootstrap attribute in the output when elastic-agent is passing config to fleet-server. When the fleet-server recieves an output block, it will inject any keys that are missing from the top level output but are specified in the bootstrap block After injecting the keys from bootstrap, fleet-server will test connecting the Elasticsearch with the output. If the test fails, the values under the bootstrap attribute are used as the output and fleet-server will periodically retest the output in case the error was caused by a temporary network issue. Note that if --fleet-server-es-insecure is specified, and the output in the policy contains one or more CA, or a CA fingerprint, the --fleet-server-es-insecure flag is ignored.

An example of this sequence is sequence is:

1) elastic-agent starts fleet-server and sends an output block that looks similar to:

output:
  bootstrap:
    service_token: VALUE
    hosts: ["HOST"]

2) fleet-server injects attributes into the top level from bootstrap if they are missing, resulting in

output:
  service_token: VALUE
  hosts: ["HOST"]

3) fleet-server connects to Elasticsearch with the output block 4) elastic-agent enrolls and recieves its policy 5) elastic-agent sends configuration generated from the policy to fleet-server, this may result in the output as follows:

output:
  hosts: ["HOST", "HOST2"]
  bootstrap:
    service_token: VALUE
    hosts: ["HOST"]

6) fleet-server will inject missing values resulting in:

output:
  service_token: VALUE
  hosts: ["HOST", "HOST2"]
7) fleet-server tests and uses the resulting output block.