github.com/google/fleetspeak@v0.1.15-0.20240426164851-4f31f62c1aea/DESIGN.md (about) 1 # Fleetspeak Design 2 3 Fleetspeak is a client-server framework for communicating with a fleet of 4 machines. This document summarizes the various components, providing an overview 5 of what bits serve what purpose. 6 7 ## Identity 8 9 Fleetspeak identifies clients using a fingerprint of a public key, much like 10 openssl keys. Specifically, client creates a keypair on startup, or when asked 11 to rekey. The Fleetspeak 12 [`common.ClientID`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/common#ClientID) 13 is the first 8 bytes of a sha256 hash of the public part of this key. It is the 14 [Server Communicator's](#server-communicator) responsibility to verify the 15 identity of clients. The recommended approach is to communicate over TLS using 16 the client's Fleetspeak key as TLS client identification. The 17 [`https.Communicator` source](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/server/https/https.go) 18 has an example of this. 19 20 ## Messages 21 22 At its core, Fleetspeak forwards 23 [`fleetspeak.Message`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/common/proto/fleetspeak/common.proto) 24 protocol buffers. The comments in the `.proto` file should be considered 25 definitive, but the most important fields to understand are `destination`, 26 `message_type` and `data`. Essentially, `destination` field tells Fleetspeak 27 where to forward the message to. The `message_type` and `data` fields are 28 forwarded verbatim, and when integrating a service a developer should set these 29 fields according to their needs. 30 31 The `message_type` is meant to be used both for dispatching within a service, 32 and for reporting. So for example if your integration has three basic types of 33 messages to pass, you might indicate them with three different message type 34 strings. By doing this you make it possible to query Fleetspeak for the number 35 of messages of each type. 36 37 # Server 38 39 A Fleetspeak Server middleware process written in go. To start a server, you 40 instantiate a 41 [`server.Server`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server#Server), 42 providing the components needed for your particular installation. 43 44 ## Miniserver: An Example 45 46 The 47 [`miniserver`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/demo/miniserver/miniserver.go) 48 binary from the demo directory defines a Fleetspeak Server in a way suitable for 49 demonstrations and small installations. 50 51 When run, the miniserver binary binds two ports, and accepts bind addresses for 52 each from the command line. The `--https_addr` flag determines the interface and 53 port that clients will connect to. It needs to be open to the internet, or at 54 least to all Fleetspeak client machines. See 55 [Server Communicator](#server-communicator), below. 56 57 The `--admin_addr` flag determines the interface and port that the 58 [Administrative Interface](#administrative-interface) listens on. The miniserver 59 binary does not perform any authentication of administrative requests. Therefore 60 access to this port needs to be limited to trusted processes. 61 62 The miniserver process stores all of its state in an SQLite version 3 database. 63 The location of this database file is set by the flag `--database_path`. This 64 file will be created if missing. After running miniserver, you can examine the 65 system state using, e.g., the `sqlite3` command and package on Debian systems. 66 See [Datastore](#datastore) below. 67 68 ## Administrative Interface 69 70 The Administrative Interface is a [GRPC](https://grpc.io/) server which provides 71 access to Fleetspeak state for administrative and integration purposes. It is 72 implemented separately from the Fleetspeak Server and can be run from the same 73 or a different process, so long as it is connected to the same 74 [Datastore](#datastore) 75 76 ## Datastore 77 78 The 79 [`db.Store`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/db#Store) 80 interface defines the persistent state held by a Fleetspeak Server. If a 81 Fleetspeak installation has multiple server processes, they should run the same 82 Datastore implementation providing a view of the same database. Currently we 83 provide two Datastore implementations. 84 85 At a minimum, any Datastore implementation should pass the tests implemented by 86 the 87 [`dbtesting`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/dbtesting) 88 package. 89 90 ### SQLite 91 92 The 93 [`sqlite.Datastore`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/sqlite#Datastore) 94 implements 95 [`db.Store`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/db#Store) 96 backed by an SQLite version 3 database. This implementation is used extensively 97 in our unit tests, and its design choices focus on simplicity, safety and 98 ease-of-use rather than performance. It is meant for testing, local 99 demonstrations, and single server installations with a small number of clients. 100 101 It does not support multiple servers processes - the SQLite database file should 102 only be opened by one instance of `sqlite.Datastore` at a time. 103 104 ### Mysql 105 106 The 107 [`mysql.Datastore`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/mysql#Datastore) 108 implements 109 [`db.Store`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/db#Store) 110 backed by a mysql database. Using recent versions of the 111 [`go-sql-driver/mysql`](https://github.com/go-sql-driver/mysql) driver it passes 112 [`dbtesting`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/dbtesting), 113 but performance testing and database optimization is still in progress. 114 115 ## Server Communicator 116 117 Every server requires a 118 [`Communicator`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/comms#Communicator) 119 component which handles communication with clients. This component defines how 120 the server communicates with fleetspeak machines and should agree on protocol 121 with a corresponding [Client Communicator](#client-communicator). 122 123 The quintessential example is 124 [`https.Communicator`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/https#Communicator) 125 and at this point it is the expected implementation for essentially all 126 installations. By adjusting the passed in `net.Listener` parameter, it should be 127 possible to include any needed additional support for load balancing or other 128 reverse proxying. 129 130 ## Server Service Factories and Configuration 131 132 When messages arrive on a Fleetspeak server, they must be addressed to a 133 particular service - the `destination` field as described in 134 [Messages](#messages). A Fleetspeak server runs one or more Services in order to 135 handle these messages. By configuring additional independent services a single 136 Fleetspeak installation can handle messages for independent purposes. 137 138 A service is configured by a 139 [`fleetspeak.server.ServiceConfig`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/server/proto/fleetspeak_server/services.proto) 140 protocol buffer. Besides the name, used to address the service, the most 141 important parameter is `factory`. This string is used to look up a 142 [`service.Factory`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/service#Factory), 143 which determines what code to use to process incoming messages. 144 145 ### Message Saver 146 147 As a particularly simple example, the fleetspeak demo directory includes a 148 [`messagesaver`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/demo/messagesaver/messagesaver.go) 149 package which defines a service which simply saves all received messages to text 150 files. 151 152 ### GRPCService 153 154 The 155 [`grpcservice`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/grpcservice) 156 package provides a `service.Factory` which makes a [GRPC](https://grpc.io/) call 157 for each delivered message, in this way handing the message off to another 158 process. 159 160 It expects configuration parameters to be provided in a 161 [`fleetspeak.grpcservice.Config`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/server/grpcservice/proto/fleetspeak_grpcservice/grpcservice.proto) 162 protocol buffer, and the target GRPC server must implement the 163 `fleetspeak.grpcservice.Processor` GRPC interface. 164 165 In addition to the factory, the grpcservice package also exports a 166 [concrete type](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/server/grpcservice#GRPCService) 167 which can be used to derive a GRPC-based service with more control over how and 168 when it dials a new GRPC target. 169 170 # Client 171 172 The Fleetspeak Client is a small process which runs on an endpoint and 173 communicates with a Fleetspeak Server. Much like the server, it consists of a 174 base 175 [`client.Client`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client#Client) 176 along with a collection of components, and individual installations may adjust 177 these components according to specific needs. 178 179 ## Miniclient: An Example 180 181 The 182 [`miniclient`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/demo/miniclient/miniclient.go) 183 binary from the demo directory defines a Fleetspeak Client in a general and 184 flexible way. Individual installations may want to define their own client 185 binary in order to hardcode security critical parameters (for example, before 186 signing it as a trusted binary) and otherwise adjust client behavior. 187 188 A Fleetspeak client must be provided with a list of TLS root certificates. The 189 client will then only communicate with a server if it presents one of these 190 certs, or a cert chaining to one of these certs. The `--trusted_cert_file` flag 191 is required by miniclient to set this list. 192 193 A Fleetspeek client must also be provided with the server (host and port) to 194 connect to. The client will require that the presented TLS server be valid for 195 this host. The `--server` flag is required by miniclient to set this server. 196 197 In addition, a Fleetspeak client needs a public key that it will use to check 198 the signature of externally provided service configurations. The implications of 199 this are discussed in more detail below. The `--deployment_key_file` flag is 200 required by miniclient to configure this. 201 202 To build a binary that can only be used by a specific Fleetspeak installation, 203 we recommend creating binary which hardcodes the configuration parameters set by 204 `--trusted_cert_file`, `--server`, and `--deployment_key_file`. Specifically, we 205 strongly recommend this if you will sign, whitelist a hash, or otherwise mark 206 the Fleetspeak client binary as trusted. 207 208 ## Configuration Path 209 210 In addition to the security critical parameters described in the previous 211 section, a Fleetspeak client normally requires a configuration directory to 212 store its private key and to look for additional configuration. See the comments 213 on 214 [`config.Configuration`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/config#Configuration) 215 for details. 216 217 ## Client Communicator 218 219 Every client requires a 220 [`Communicator`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/comms#Communicator) 221 component which handles communication with the server. This component defines 222 how the client communicates with the Fleetspeak server and should agree on 223 protocol with a corresponding [Server Communicator](#server-communicator). 224 225 The quintessential example is 226 [`https.Communicator`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/https#Communicator) 227 and at this point it is the expected implementation for essentially all 228 installations. By adjusting the `DialContext` attribute before starting the 229 Fleetspeak client, it should be possible to include any needed additional 230 support for specialized tunneling or proxying. 231 232 ## Client Service Factories and Configuration 233 234 When messages arrive on a Fleetspeak client, they must be addressed to a 235 particular service - the `destination` field as described in 236 [Messages](#messages). A Fleetspeak client runs one or more Services in order to 237 handle these messages, and create message to send to the server. By configuring 238 additional independent services a single Fleetspeak client process can handle 239 messages for independent purposes. 240 241 A service is typically configured by dropping a 242 [`fleetspeak.SignedClientServiceConfig`](https://github.com/google/fleetspeak/blob/master/fleetspeak/src/common/proto/fleetspeak/system.proto) 243 into `<config_path>/services/`. Besides the name, used to address the service, 244 the most important parameter is `factory`. This string is used to look up a 245 [`service.Factory`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/service#Factory), 246 which determines what code to use to process incoming messages. 247 248 This dropped configuration file must be signed with the deployment key. 249 Therefore by controlling access to the private part of the deployment key, and 250 hardcoding the public exponent into the client binary, allows an installation to 251 maintain strong control over what a particular client binary is capable of. 252 253 ### Stdinservice 254 255 The 256 [`stdinservice.Factory`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/stdinservice#Factory) 257 runs a binary with flags and standard input provided by a message, and returns 258 the output it produces. The service configuration determines what binary to run. 259 Every message received by the service causes and execution of the binary. The 260 configuration used in the 261 [`demo` directory](https://github.com/google/fleetspeak/tree/master/fleetspeak/src/demo) 262 sets up services based on this for the `ls` and `cat` binaries. 263 264 ### Daemonservice 265 266 The 267 [`daemonservice.Factory`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/daemonservice#Factory) 268 handles the use case in which you want Fleetspeak to run a sub-process and 269 send/receive [messages](#messages) to/from it. This gives full control over what 270 is sent to the server, but requires more integration. The sub-process should use 271 the 272 [`daemonservice` client library](https://github.com/google/fleetspeak/tree/master/fleetspeak/src/client/daemonservice/client) 273 (currently available for go and python) to communicate through Fleetspeak. 274 275 ### Socketservice 276 277 The 278 [`socketservice.Factory`](https://godoc.org/github.com/google/fleetspeak/fleetspeak/src/client/socketservice#Factory) 279 handles the use case in which you want Fleetspeak and some separately running 280 process to find each other and communicate using a local filesystem path, e.g. 281 through a UNIX domain socket. Much like [`Daemonservice`](#daemonservice) this 282 also gives full control over what is sent to the server and requires some 283 integration. The sister process should use the 284 [`socketservice` client library](https://github.com/google/fleetspeak/tree/master/fleetspeak/src/client/socketservice/client) 285 to communicate through Fleetspeak.