2016-09-03 17:25:16 +00:00
package config
import (
2021-10-20 14:09:18 +00:00
"crypto/tls"
"crypto/x509"
2021-11-22 14:13:26 +00:00
"errors"
2016-09-12 17:26:56 +00:00
"fmt"
2021-10-20 14:09:18 +00:00
"io/ioutil"
2022-05-16 13:44:50 +00:00
"net/url"
2019-04-23 22:59:02 +00:00
"os"
2021-07-22 00:49:44 +00:00
"path/filepath"
"runtime"
2022-05-16 13:44:50 +00:00
"strconv"
2016-09-03 17:25:16 +00:00
"strings"
2016-09-14 16:11:06 +00:00
"time"
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
"github.com/spf13/cast"
2016-09-03 17:25:16 +00:00
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
2016-09-12 17:26:56 +00:00
const (
2021-02-11 23:36:58 +00:00
envPrefix = "FLEET"
2016-09-04 05:13:42 +00:00
)
2016-09-12 17:26:56 +00:00
// MysqlConfig defines configs related to MySQL
type MysqlConfig struct {
2020-08-19 21:56:44 +00:00
Protocol string
Address string
Username string
Password string
2021-01-04 15:58:43 +00:00
PasswordPath string ` yaml:"password_path" `
2020-08-19 21:56:44 +00:00
Database string
TLSCert string ` yaml:"tls_cert" `
TLSKey string ` yaml:"tls_key" `
TLSCA string ` yaml:"tls_ca" `
TLSServerName string ` yaml:"tls_server_name" `
2021-10-28 04:51:17 +00:00
TLSConfig string ` yaml:"tls_config" ` // tls=customValue in DSN
2020-08-19 21:56:44 +00:00
MaxOpenConns int ` yaml:"max_open_conns" `
MaxIdleConns int ` yaml:"max_idle_conns" `
2020-07-30 16:00:42 +00:00
ConnMaxLifetime int ` yaml:"conn_max_lifetime" `
2016-09-12 17:26:56 +00:00
}
2016-12-16 00:13:23 +00:00
// RedisConfig defines configs related to Redis
type RedisConfig struct {
2021-09-15 12:50:32 +00:00
Address string
Password string
Database int
UseTLS bool ` yaml:"use_tls" `
DuplicateResults bool ` yaml:"duplicate_results" `
ConnectTimeout time . Duration ` yaml:"connect_timeout" `
KeepAlive time . Duration ` yaml:"keep_alive" `
ConnectRetryAttempts int ` yaml:"connect_retry_attempts" `
ClusterFollowRedirections bool ` yaml:"cluster_follow_redirections" `
2021-10-18 13:32:17 +00:00
ClusterReadFromReplica bool ` yaml:"cluster_read_from_replica" `
2021-10-20 14:09:18 +00:00
TLSCert string ` yaml:"tls_cert" `
TLSKey string ` yaml:"tls_key" `
TLSCA string ` yaml:"tls_ca" `
TLSServerName string ` yaml:"tls_server_name" `
TLSHandshakeTimeout time . Duration ` yaml:"tls_handshake_timeout" `
2022-01-26 16:32:42 +00:00
MaxIdleConns int ` yaml:"max_idle_conns" `
MaxOpenConns int ` yaml:"max_open_conns" `
2021-10-20 14:09:18 +00:00
// this config is an int on MysqlConfig, but it should be a time.Duration.
ConnMaxLifetime time . Duration ` yaml:"conn_max_lifetime" `
IdleTimeout time . Duration ` yaml:"idle_timeout" `
2021-11-01 18:13:16 +00:00
ConnWaitTimeout time . Duration ` yaml:"conn_wait_timeout" `
2022-01-11 22:08:39 +00:00
WriteTimeout time . Duration ` yaml:"write_timeout" `
ReadTimeout time . Duration ` yaml:"read_timeout" `
2016-12-16 00:13:23 +00:00
}
2017-03-28 04:21:48 +00:00
const (
TLSProfileKey = "server.tls_compatibility"
TLSProfileModern = "modern"
TLSProfileIntermediate = "intermediate"
)
2019-01-24 17:39:32 +00:00
// ServerConfig defines configs related to the Fleet server
2016-09-12 17:26:56 +00:00
type ServerConfig struct {
2017-03-28 04:21:48 +00:00
Address string
Cert string
Key string
TLS bool
2021-06-04 15:44:36 +00:00
TLSProfile string ` yaml:"tls_compatibility" `
2019-10-16 23:40:45 +00:00
URLPrefix string ` yaml:"url_prefix" `
2021-05-08 00:29:54 +00:00
Keepalive bool ` yaml:"keepalive" `
2016-09-12 17:26:56 +00:00
}
// AuthConfig defines configs related to user authorization
type AuthConfig struct {
2021-06-07 01:10:58 +00:00
BcryptCost int ` yaml:"bcrypt_cost" `
SaltKeySize int ` yaml:"salt_key_size" `
2016-09-12 17:26:56 +00:00
}
// AppConfig defines configs related to HTTP
type AppConfig struct {
2017-02-22 15:22:19 +00:00
TokenKeySize int ` yaml:"token_key_size" `
InviteTokenValidityPeriod time . Duration ` yaml:"invite_token_validity_period" `
2022-02-09 11:20:29 +00:00
EnableScheduledQueryStats bool ` yaml:"enable_scheduled_query_stats" `
2016-09-12 17:26:56 +00:00
}
// SessionConfig defines configs related to user sessions
type SessionConfig struct {
2017-02-22 15:22:19 +00:00
KeySize int ` yaml:"key_size" `
2016-09-14 16:11:06 +00:00
Duration time . Duration
2016-09-12 17:26:56 +00:00
}
// OsqueryConfig defines configs related to osquery
type OsqueryConfig struct {
2021-11-01 18:13:16 +00:00
NodeKeySize int ` yaml:"node_key_size" `
HostIdentifier string ` yaml:"host_identifier" `
EnrollCooldown time . Duration ` yaml:"enroll_cooldown" `
StatusLogPlugin string ` yaml:"status_log_plugin" `
ResultLogPlugin string ` yaml:"result_log_plugin" `
LabelUpdateInterval time . Duration ` yaml:"label_update_interval" `
PolicyUpdateInterval time . Duration ` yaml:"policy_update_interval" `
DetailUpdateInterval time . Duration ` yaml:"detail_update_interval" `
StatusLogFile string ` yaml:"status_log_file" `
ResultLogFile string ` yaml:"result_log_file" `
EnableLogRotation bool ` yaml:"enable_log_rotation" `
MaxJitterPercent int ` yaml:"max_jitter_percent" `
2022-05-16 13:44:50 +00:00
EnableAsyncHostProcessing string ` yaml:"enable_async_host_processing" ` // true/false or per-task
AsyncHostCollectInterval string ` yaml:"async_host_collect_interval" ` // duration or per-task
2021-11-01 18:13:16 +00:00
AsyncHostCollectMaxJitterPercent int ` yaml:"async_host_collect_max_jitter_percent" `
2022-05-16 13:44:50 +00:00
AsyncHostCollectLockTimeout string ` yaml:"async_host_collect_lock_timeout" ` // duration or per-task
2021-11-01 18:13:16 +00:00
AsyncHostCollectLogStatsInterval time . Duration ` yaml:"async_host_collect_log_stats_interval" `
AsyncHostInsertBatch int ` yaml:"async_host_insert_batch" `
AsyncHostDeleteBatch int ` yaml:"async_host_delete_batch" `
AsyncHostUpdateBatch int ` yaml:"async_host_update_batch" `
AsyncHostRedisPopCount int ` yaml:"async_host_redis_pop_count" `
AsyncHostRedisScanKeysCount int ` yaml:"async_host_redis_scan_keys_count" `
2022-04-27 13:47:09 +00:00
MinSoftwareLastOpenedAtDiff time . Duration ` yaml:"min_software_last_opened_at_diff" `
2016-09-12 17:26:56 +00:00
}
2022-05-16 13:44:50 +00:00
// AsyncTaskName is the type of names that identify tasks supporting
// asynchronous execution.
type AsyncTaskName string
// List of names for supported async tasks.
const (
AsyncTaskLabelMembership AsyncTaskName = "label_membership"
AsyncTaskPolicyMembership AsyncTaskName = "policy_membership"
AsyncTaskHostLastSeen AsyncTaskName = "host_last_seen"
)
var knownAsyncTasks = map [ AsyncTaskName ] struct { } {
AsyncTaskLabelMembership : { } ,
AsyncTaskPolicyMembership : { } ,
AsyncTaskHostLastSeen : { } ,
}
// AsyncConfigForTask returns the applicable configuration for the specified
// async task.
func ( o OsqueryConfig ) AsyncConfigForTask ( name AsyncTaskName ) AsyncProcessingConfig {
strName := string ( name )
return AsyncProcessingConfig {
Enabled : configForKeyOrBool ( "osquery.enable_async_host_processing" , strName , o . EnableAsyncHostProcessing , false ) ,
CollectInterval : configForKeyOrDuration ( "osquery.async_host_collect_interval" , strName , o . AsyncHostCollectInterval , 30 * time . Second ) ,
CollectMaxJitterPercent : o . AsyncHostCollectMaxJitterPercent ,
CollectLockTimeout : configForKeyOrDuration ( "osquery.async_host_collect_lock_timeout" , strName , o . AsyncHostCollectLockTimeout , 1 * time . Minute ) ,
CollectLogStatsInterval : o . AsyncHostCollectLogStatsInterval ,
InsertBatch : o . AsyncHostInsertBatch ,
DeleteBatch : o . AsyncHostDeleteBatch ,
UpdateBatch : o . AsyncHostUpdateBatch ,
RedisPopCount : o . AsyncHostRedisPopCount ,
RedisScanKeysCount : o . AsyncHostRedisScanKeysCount ,
}
}
// AsyncProcessingConfig is the configuration for a specific async task.
type AsyncProcessingConfig struct {
Enabled bool
CollectInterval time . Duration
CollectMaxJitterPercent int
CollectLockTimeout time . Duration
CollectLogStatsInterval time . Duration
InsertBatch int
DeleteBatch int
UpdateBatch int
RedisPopCount int
RedisScanKeysCount int
}
2016-09-12 17:26:56 +00:00
// LoggingConfig defines configs related to logging
type LoggingConfig struct {
2021-11-02 17:35:57 +00:00
Debug bool
JSON bool
DisableBanner bool ` yaml:"disable_banner" `
ErrorRetentionPeriod time . Duration ` yaml:"error_retention_period" `
2022-02-15 17:42:22 +00:00
TracingEnabled bool ` yaml:"tracing_enabled" `
// TracingType can either be opentelemetry or elasticapm for whichever type of tracing wanted
TracingType string ` yaml:"tracing_type" `
2016-09-12 17:26:56 +00:00
}
2019-04-08 18:47:15 +00:00
// FirehoseConfig defines configs for the AWS Firehose logging plugin
type FirehoseConfig struct {
2020-08-19 21:56:44 +00:00
Region string
2021-07-30 15:45:49 +00:00
EndpointURL string ` yaml:"endpoint_url" `
2020-08-19 21:56:44 +00:00
AccessKeyID string ` yaml:"access_key_id" `
SecretAccessKey string ` yaml:"secret_access_key" `
StsAssumeRoleArn string ` yaml:"sts_assume_role_arn" `
StatusStream string ` yaml:"status_stream" `
ResultStream string ` yaml:"result_stream" `
}
// KinesisConfig defines configs for the AWS Kinesis logging plugin
type KinesisConfig struct {
Region string
2021-07-30 15:45:49 +00:00
EndpointURL string ` yaml:"endpoint_url" `
2020-08-19 21:56:44 +00:00
AccessKeyID string ` yaml:"access_key_id" `
SecretAccessKey string ` yaml:"secret_access_key" `
StsAssumeRoleArn string ` yaml:"sts_assume_role_arn" `
StatusStream string ` yaml:"status_stream" `
ResultStream string ` yaml:"result_stream" `
2019-04-08 18:47:15 +00:00
}
2021-02-24 18:02:26 +00:00
// LambdaConfig defines configs for the AWS Lambda logging plugin
type LambdaConfig struct {
Region string
AccessKeyID string ` yaml:"access_key_id" `
SecretAccessKey string ` yaml:"secret_access_key" `
StsAssumeRoleArn string ` yaml:"sts_assume_role_arn" `
StatusFunction string ` yaml:"status_function" `
ResultFunction string ` yaml:"result_function" `
}
2020-12-16 17:16:55 +00:00
// S3Config defines config to enable file carving storage to an S3 bucket
type S3Config struct {
2021-10-12 19:32:06 +00:00
Bucket string ` yaml:"bucket" `
Prefix string ` yaml:"prefix" `
Region string ` yaml:"region" `
EndpointURL string ` yaml:"endpoint_url" `
2020-12-16 17:16:55 +00:00
AccessKeyID string ` yaml:"access_key_id" `
SecretAccessKey string ` yaml:"secret_access_key" `
StsAssumeRoleArn string ` yaml:"sts_assume_role_arn" `
2021-10-12 19:32:06 +00:00
DisableSSL bool ` yaml:"disable_ssl" `
ForceS3PathStyle bool ` yaml:"force_s3_path_style" `
2020-12-16 17:16:55 +00:00
}
2019-07-16 22:41:50 +00:00
// PubSubConfig defines configs the for Google PubSub logging plugin
type PubSubConfig struct {
2021-07-30 15:45:49 +00:00
Project string ` json:"project" `
StatusTopic string ` json:"status_topic" yaml:"status_topic" `
ResultTopic string ` json:"result_topic" yaml:"result_topic" `
AddAttributes bool ` json:"add_attributes" yaml:"add_attributes" `
2019-07-16 22:41:50 +00:00
}
2019-04-08 18:47:15 +00:00
// FilesystemConfig defines configs for the Filesystem logging plugin
type FilesystemConfig struct {
2021-07-30 15:45:49 +00:00
StatusLogFile string ` json:"status_log_file" yaml:"status_log_file" `
ResultLogFile string ` json:"result_log_file" yaml:"result_log_file" `
EnableLogRotation bool ` json:"enable_log_rotation" yaml:"enable_log_rotation" `
EnableLogCompression bool ` json:"enable_log_compression" yaml:"enable_log_compression" `
2019-04-08 18:47:15 +00:00
}
2021-10-28 04:51:17 +00:00
// KafkaRESTConfig defines configs for the Kafka REST Proxy logging plugin.
type KafkaRESTConfig struct {
2022-03-09 22:22:29 +00:00
StatusTopic string ` json:"status_topic" yaml:"status_topic" `
ResultTopic string ` json:"result_topic" yaml:"result_topic" `
ProxyHost string ` json:"proxyhost" yaml:"proxyhost" `
ContentTypeValue string ` json:"content_type_value" yaml:"content_type_value" `
Timeout int ` json:"timeout" yaml:"timeout" `
2021-10-28 04:51:17 +00:00
}
2021-05-20 00:29:38 +00:00
// LicenseConfig defines configs related to licensing Fleet.
type LicenseConfig struct {
2022-06-13 20:29:32 +00:00
Key string ` yaml:"key" `
EnforceHostLimit bool ` yaml:"enforce_host_limit" `
2021-05-20 00:29:38 +00:00
}
2021-08-18 20:25:14 +00:00
// VulnerabilitiesConfig defines configs related to vulnerability processing within Fleet.
type VulnerabilitiesConfig struct {
2022-04-12 18:48:15 +00:00
DatabasesPath string ` json:"databases_path" yaml:"databases_path" `
Periodicity time . Duration ` json:"periodicity" yaml:"periodicity" `
CPEDatabaseURL string ` json:"cpe_database_url" yaml:"cpe_database_url" `
CVEFeedPrefixURL string ` json:"cve_feed_prefix_url" yaml:"cve_feed_prefix_url" `
CurrentInstanceChecks string ` json:"current_instance_checks" yaml:"current_instance_checks" `
DisableDataSync bool ` json:"disable_data_sync" yaml:"disable_data_sync" `
RecentVulnerabilityMaxAge time . Duration ` json:"recent_vulnerability_max_age" yaml:"recent_vulnerability_max_age" `
2021-08-18 20:25:14 +00:00
}
2021-11-22 17:47:24 +00:00
// UpgradesConfig defines configs related to fleet server upgrades.
type UpgradesConfig struct {
AllowMissingMigrations bool ` json:"allow_missing_migrations" yaml:"allow_missing_migrations" `
}
2022-01-20 19:41:02 +00:00
type SentryConfig struct {
Dsn string ` json:"dsn" `
}
2022-03-21 16:29:52 +00:00
type GeoIPConfig struct {
DatabasePath string ` json:"database_path" yaml:"database_path" `
}
2022-04-07 12:40:53 +00:00
// PrometheusConfig holds the configuration for Fleet's prometheus metrics.
type PrometheusConfig struct {
// BasicAuth is the HTTP Basic BasicAuth configuration.
BasicAuth HTTPBasicAuthConfig ` json:"basic_auth" yaml:"basic_auth" `
}
// HTTPBasicAuthConfig holds configuration for HTTP Basic Auth.
type HTTPBasicAuthConfig struct {
// Username is the HTTP Basic Auth username.
Username string ` json:"username" yaml:"username" `
// Password is the HTTP Basic Auth password.
Password string ` json:"password" yaml:"password" `
}
2021-06-06 22:07:29 +00:00
// FleetConfig stores the application configuration. Each subcategory is
2016-09-12 17:26:56 +00:00
// broken up into it's own struct, defined above. When editing any of these
// structs, Manager.addConfigs and Manager.LoadConfig should be
// updated to set and retrieve the configurations as appropriate.
2021-06-06 22:07:29 +00:00
type FleetConfig struct {
2021-09-01 19:50:52 +00:00
Mysql MysqlConfig
MysqlReadReplica MysqlConfig ` yaml:"mysql_read_replica" `
Redis RedisConfig
Server ServerConfig
Auth AuthConfig
App AppConfig
Session SessionConfig
Osquery OsqueryConfig
Logging LoggingConfig
Firehose FirehoseConfig
Kinesis KinesisConfig
Lambda LambdaConfig
S3 S3Config
PubSub PubSubConfig
Filesystem FilesystemConfig
2021-10-28 04:51:17 +00:00
KafkaREST KafkaRESTConfig
2021-09-01 19:50:52 +00:00
License LicenseConfig
Vulnerabilities VulnerabilitiesConfig
2021-11-22 17:47:24 +00:00
Upgrades UpgradesConfig
2022-01-20 19:41:02 +00:00
Sentry SentryConfig
2022-03-21 16:29:52 +00:00
GeoIP GeoIPConfig
2022-04-07 12:40:53 +00:00
Prometheus PrometheusConfig
2016-09-12 17:26:56 +00:00
}
2021-10-20 14:09:18 +00:00
type TLS struct {
TLSCert string
TLSKey string
TLSCA string
TLSServerName string
}
func ( t * TLS ) ToTLSConfig ( ) ( * tls . Config , error ) {
2021-10-25 18:47:53 +00:00
var rootCertPool * x509 . CertPool
if t . TLSCA != "" {
rootCertPool = x509 . NewCertPool ( )
pem , err := ioutil . ReadFile ( t . TLSCA )
if err != nil {
2021-11-22 14:13:26 +00:00
return nil , fmt . Errorf ( "read server-ca pem: %w" , err )
2021-10-25 18:47:53 +00:00
}
if ok := rootCertPool . AppendCertsFromPEM ( pem ) ; ! ok {
return nil , errors . New ( "failed to append PEM." )
}
2021-10-20 14:09:18 +00:00
}
cfg := & tls . Config {
RootCAs : rootCertPool ,
}
if t . TLSCert != "" {
clientCert := make ( [ ] tls . Certificate , 0 , 1 )
certs , err := tls . LoadX509KeyPair ( t . TLSCert , t . TLSKey )
if err != nil {
2021-11-22 14:13:26 +00:00
return nil , fmt . Errorf ( "load client cert and key: %w" , err )
2021-10-20 14:09:18 +00:00
}
clientCert = append ( clientCert , certs )
cfg . Certificates = clientCert
}
if t . TLSServerName != "" {
cfg . ServerName = t . TLSServerName
}
return cfg , nil
}
2016-09-12 17:26:56 +00:00
// addConfigs adds the configuration keys and default values that will be
2021-06-06 22:07:29 +00:00
// filled into the FleetConfig struct
2016-09-12 17:26:56 +00:00
func ( man Manager ) addConfigs ( ) {
2021-09-01 19:50:52 +00:00
addMysqlConfig := func ( prefix , defaultAddr , usageSuffix string ) {
man . addConfigString ( prefix + ".protocol" , "tcp" ,
"MySQL server communication protocol (tcp,unix,...)" + usageSuffix )
man . addConfigString ( prefix + ".address" , defaultAddr ,
"MySQL server address (host:port)" + usageSuffix )
man . addConfigString ( prefix + ".username" , "fleet" ,
"MySQL server username" + usageSuffix )
man . addConfigString ( prefix + ".password" , "" ,
"MySQL server password (prefer env variable for security)" + usageSuffix )
man . addConfigString ( prefix + ".password_path" , "" ,
"Path to file containg MySQL server password" + usageSuffix )
man . addConfigString ( prefix + ".database" , "fleet" ,
"MySQL database name" + usageSuffix )
man . addConfigString ( prefix + ".tls_cert" , "" ,
"MySQL TLS client certificate path" + usageSuffix )
man . addConfigString ( prefix + ".tls_key" , "" ,
"MySQL TLS client key path" + usageSuffix )
man . addConfigString ( prefix + ".tls_ca" , "" ,
"MySQL TLS server CA" + usageSuffix )
man . addConfigString ( prefix + ".tls_server_name" , "" ,
"MySQL TLS server name" + usageSuffix )
man . addConfigString ( prefix + ".tls_config" , "" ,
"MySQL TLS config value" + usageSuffix + " Use skip-verify, true, false or custom key." )
man . addConfigInt ( prefix + ".max_open_conns" , 50 , "MySQL maximum open connection handles" + usageSuffix )
man . addConfigInt ( prefix + ".max_idle_conns" , 50 , "MySQL maximum idle connection handles" + usageSuffix )
man . addConfigInt ( prefix + ".conn_max_lifetime" , 0 , "MySQL maximum amount of time a connection may be reused" + usageSuffix )
}
2016-09-12 17:26:56 +00:00
// MySQL
2021-09-01 19:50:52 +00:00
addMysqlConfig ( "mysql" , "localhost:3306" , "." )
addMysqlConfig ( "mysql_read_replica" , "" , " for the read replica." )
2016-09-12 17:26:56 +00:00
2016-12-16 00:13:23 +00:00
// Redis
2017-01-31 18:06:30 +00:00
man . addConfigString ( "redis.address" , "localhost:6379" ,
"Redis server address (host:port)" )
man . addConfigString ( "redis.password" , "" ,
"Redis server password (prefer env variable for security)" )
2020-07-30 15:57:25 +00:00
man . addConfigInt ( "redis.database" , 0 ,
"Redis server database number" )
2020-10-01 23:25:48 +00:00
man . addConfigBool ( "redis.use_tls" , false , "Redis server enable TLS" )
2021-05-13 23:01:31 +00:00
man . addConfigBool ( "redis.duplicate_results" , false , "Duplicate Live Query results to another Redis channel" )
2021-09-08 20:55:12 +00:00
man . addConfigDuration ( "redis.connect_timeout" , 5 * time . Second , "Timeout at connection time" )
man . addConfigDuration ( "redis.keep_alive" , 10 * time . Second , "Interval between keep alive probes" )
2021-09-15 12:50:32 +00:00
man . addConfigInt ( "redis.connect_retry_attempts" , 0 , "Number of attempts to retry a failed connection" )
man . addConfigBool ( "redis.cluster_follow_redirections" , false , "Automatically follow Redis Cluster redirections" )
2021-10-18 13:32:17 +00:00
man . addConfigBool ( "redis.cluster_read_from_replica" , false , "Prefer reading from a replica when possible (for Redis Cluster)" )
2021-10-20 14:09:18 +00:00
man . addConfigString ( "redis.tls_cert" , "" , "Redis TLS client certificate path" )
man . addConfigString ( "redis.tls_key" , "" , "Redis TLS client key path" )
man . addConfigString ( "redis.tls_ca" , "" , "Redis TLS server CA" )
man . addConfigString ( "redis.tls_server_name" , "" , "Redis TLS server name" )
man . addConfigDuration ( "redis.tls_handshake_timeout" , 10 * time . Second , "Redis TLS handshake timeout" )
man . addConfigInt ( "redis.max_idle_conns" , 3 , "Redis maximum idle connections" )
man . addConfigInt ( "redis.max_open_conns" , 0 , "Redis maximum open connections, 0 means no limit" )
man . addConfigDuration ( "redis.conn_max_lifetime" , 0 , "Redis maximum amount of time a connection may be reused, 0 means no limit" )
man . addConfigDuration ( "redis.idle_timeout" , 240 * time . Second , "Redis maximum amount of time a connection may stay idle, 0 means no limit" )
2021-11-01 18:13:16 +00:00
man . addConfigDuration ( "redis.conn_wait_timeout" , 0 , "Redis maximum amount of time to wait for a connection if the maximum is reached (0 for no wait, ignored in non-cluster Redis)" )
2022-01-11 22:08:39 +00:00
man . addConfigDuration ( "redis.write_timeout" , 10 * time . Second , "Redis maximum amount of time to wait for a write (send) on a connection" )
man . addConfigDuration ( "redis.read_timeout" , 10 * time . Second , "Redis maximum amount of time to wait for a read (receive) on a connection" )
2016-12-16 00:13:23 +00:00
2016-09-12 17:26:56 +00:00
// Server
2017-01-31 18:06:30 +00:00
man . addConfigString ( "server.address" , "0.0.0.0:8080" ,
2019-01-24 17:39:32 +00:00
"Fleet server address (host:port)" )
2021-06-06 22:07:29 +00:00
man . addConfigString ( "server.cert" , "./tools/osquery/fleet.crt" ,
2019-01-24 17:39:32 +00:00
"Fleet TLS certificate path" )
2021-06-06 22:07:29 +00:00
man . addConfigString ( "server.key" , "./tools/osquery/fleet.key" ,
2019-01-24 17:39:32 +00:00
"Fleet TLS key path" )
2017-01-31 18:06:30 +00:00
man . addConfigBool ( "server.tls" , true ,
"Enable TLS (required for osqueryd communication)" )
2021-02-03 19:48:48 +00:00
man . addConfigString ( TLSProfileKey , TLSProfileIntermediate ,
2020-09-10 16:31:01 +00:00
fmt . Sprintf ( "TLS security profile choose one of %s or %s" ,
TLSProfileModern , TLSProfileIntermediate ) )
2019-10-16 23:40:45 +00:00
man . addConfigString ( "server.url_prefix" , "" ,
"URL prefix used on server and frontend endpoints" )
2021-05-08 00:29:54 +00:00
man . addConfigBool ( "server.keepalive" , true ,
"Controls wether HTTP keep-alives are enabled." )
2016-09-12 17:26:56 +00:00
// Auth
2017-01-31 18:06:30 +00:00
man . addConfigInt ( "auth.bcrypt_cost" , 12 ,
"Bcrypt iterations" )
man . addConfigInt ( "auth.salt_key_size" , 24 ,
"Size of salt for passwords" )
2016-09-12 17:26:56 +00:00
// App
2017-01-31 18:06:30 +00:00
man . addConfigString ( "app.token_key" , "CHANGEME" ,
"Secret key for generating invite and reset tokens" )
man . addConfigDuration ( "app.invite_token_validity_period" , 5 * 24 * time . Hour ,
"Duration invite tokens remain valid (i.e. 1h)" )
man . addConfigInt ( "app.token_key_size" , 24 ,
"Size of generated tokens" )
2022-02-09 11:20:29 +00:00
man . addConfigBool ( "app.enable_scheduled_query_stats" , true ,
"If true (default) it gets scheduled query stats from hosts" )
2016-09-12 17:26:56 +00:00
// Session
2017-01-31 18:06:30 +00:00
man . addConfigInt ( "session.key_size" , 64 ,
"Size of generated session keys" )
2022-03-07 22:37:54 +00:00
man . addConfigDuration ( "session.duration" , 24 * 5 * time . Hour ,
2021-12-14 04:42:30 +00:00
"Duration session keys remain valid (i.e. 4h)" )
2016-09-12 17:26:56 +00:00
// Osquery
2017-01-31 18:06:30 +00:00
man . addConfigInt ( "osquery.node_key_size" , 24 ,
"Size of generated osqueryd node keys" )
2021-03-09 02:35:17 +00:00
man . addConfigString ( "osquery.host_identifier" , "provided" ,
"Identifier used to uniquely determine osquery clients" )
2021-03-09 05:26:09 +00:00
man . addConfigDuration ( "osquery.enroll_cooldown" , 0 ,
"Cooldown period for duplicate host enrollment (default off)" )
2019-04-08 18:47:15 +00:00
man . addConfigString ( "osquery.status_log_plugin" , "filesystem" ,
"Log plugin to use for status logs" )
man . addConfigString ( "osquery.result_log_plugin" , "filesystem" ,
"Log plugin to use for result logs" )
2017-01-31 18:06:30 +00:00
man . addConfigDuration ( "osquery.label_update_interval" , 1 * time . Hour ,
"Interval to update host label membership (i.e. 1h)" )
2021-09-27 19:27:38 +00:00
man . addConfigDuration ( "osquery.policy_update_interval" , 1 * time . Hour ,
"Interval to update host policy membership (i.e. 1h)" )
2020-03-02 19:08:08 +00:00
man . addConfigDuration ( "osquery.detail_update_interval" , 1 * time . Hour ,
"Interval to update host details (i.e. 1h)" )
2019-04-08 18:47:15 +00:00
man . addConfigString ( "osquery.status_log_file" , "" ,
"(DEPRECATED: Use filesystem.status_log_file) Path for osqueryd status logs" )
man . addConfigString ( "osquery.result_log_file" , "" ,
"(DEPRECATED: Use filesystem.result_log_file) Path for osqueryd result logs" )
2017-04-03 21:48:50 +00:00
man . addConfigBool ( "osquery.enable_log_rotation" , false ,
2019-04-08 18:47:15 +00:00
"(DEPRECATED: Use filesystem.enable_log_rotation) Enable automatic rotation for osquery log files" )
2021-09-21 17:21:44 +00:00
man . addConfigInt ( "osquery.max_jitter_percent" , 10 ,
"Maximum percentage of the interval to add as jitter" )
2022-05-16 13:44:50 +00:00
man . addConfigString ( "osquery.enable_async_host_processing" , "false" ,
2022-05-20 17:07:32 +00:00
"Enable asynchronous processing of host-reported query results (either 'true'/'false' or set per task, e.g., 'label_membership=true&policy_membership=true')" )
2022-05-16 13:44:50 +00:00
man . addConfigString ( "osquery.async_host_collect_interval" , ( 30 * time . Second ) . String ( ) ,
"Interval to collect asynchronous host-reported query results (e.g. '30s' or set per task 'label_membership=10s&policy_membership=1m')" )
2021-11-01 18:13:16 +00:00
man . addConfigInt ( "osquery.async_host_collect_max_jitter_percent" , 10 ,
"Maximum percentage of the interval to collect asynchronous host results" )
2022-05-16 13:44:50 +00:00
man . addConfigString ( "osquery.async_host_collect_lock_timeout" , ( 1 * time . Minute ) . String ( ) ,
2022-05-20 17:07:32 +00:00
"Timeout of the exclusive lock held during async host collection (e.g., '30s' or set per task 'label_membership=10s&policy_membership=1m'" )
2021-11-01 18:13:16 +00:00
man . addConfigDuration ( "osquery.async_host_collect_log_stats_interval" , 1 * time . Minute ,
"Interval at which async host collection statistics are logged (0 disables logging of stats)" )
man . addConfigInt ( "osquery.async_host_insert_batch" , 2000 ,
"Batch size for async collection inserts in mysql" )
man . addConfigInt ( "osquery.async_host_delete_batch" , 2000 ,
"Batch size for async collection deletes in mysql" )
man . addConfigInt ( "osquery.async_host_update_batch" , 1000 ,
"Batch size for async collection updates in mysql" )
man . addConfigInt ( "osquery.async_host_redis_pop_count" , 1000 ,
"Batch size to pop items from redis in async collection" )
man . addConfigInt ( "osquery.async_host_redis_scan_keys_count" , 1000 ,
"Batch size to scan redis keys in async collection" )
2022-04-27 13:47:09 +00:00
man . addConfigDuration ( "osquery.min_software_last_opened_at_diff" , 1 * time . Hour ,
"Minimum time difference of the software's last opened timestamp (compared to the last one saved) to trigger an update to the database" )
2016-09-12 17:26:56 +00:00
// Logging
2017-01-31 18:06:30 +00:00
man . addConfigBool ( "logging.debug" , false ,
"Enable debug logging" )
man . addConfigBool ( "logging.json" , false ,
"Log in JSON format" )
man . addConfigBool ( "logging.disable_banner" , false ,
"Disable startup banner" )
2021-11-02 17:35:57 +00:00
man . addConfigDuration ( "logging.error_retention_period" , 24 * time . Hour ,
2021-12-14 21:30:26 +00:00
"Amount of time to keep errors, 0 means no expiration, < 0 means disable storage of errors" )
2022-02-15 17:42:22 +00:00
man . addConfigBool ( "logging.tracing_enabled" , false ,
"Enable Tracing, further configured via standard env variables" )
man . addConfigString ( "logging.tracing_type" , "opentelemetry" ,
"Select the kind of tracing, defaults to opentelemetry, can also be elasticapm" )
2019-04-08 18:47:15 +00:00
// Firehose
man . addConfigString ( "firehose.region" , "" , "AWS Region to use" )
2021-07-30 15:45:49 +00:00
man . addConfigString ( "firehose.endpoint_url" , "" ,
"AWS Service Endpoint to use (leave empty for default service endpoints)" )
2019-04-08 18:47:15 +00:00
man . addConfigString ( "firehose.access_key_id" , "" , "Access Key ID for AWS authentication" )
man . addConfigString ( "firehose.secret_access_key" , "" , "Secret Access Key for AWS authentication" )
2020-08-19 21:56:44 +00:00
man . addConfigString ( "firehose.sts_assume_role_arn" , "" ,
"ARN of role to assume for AWS" )
2019-04-08 18:47:15 +00:00
man . addConfigString ( "firehose.status_stream" , "" ,
"Firehose stream name for status logs" )
man . addConfigString ( "firehose.result_stream" , "" ,
"Firehose stream name for result logs" )
2020-08-19 21:56:44 +00:00
// Kinesis
man . addConfigString ( "kinesis.region" , "" , "AWS Region to use" )
2021-07-30 15:45:49 +00:00
man . addConfigString ( "kinesis.endpoint_url" , "" ,
"AWS Service Endpoint to use (leave empty for default service endpoints)" )
2020-08-19 21:56:44 +00:00
man . addConfigString ( "kinesis.access_key_id" , "" , "Access Key ID for AWS authentication" )
man . addConfigString ( "kinesis.secret_access_key" , "" , "Secret Access Key for AWS authentication" )
man . addConfigString ( "kinesis.sts_assume_role_arn" , "" ,
"ARN of role to assume for AWS" )
man . addConfigString ( "kinesis.status_stream" , "" ,
"Kinesis stream name for status logs" )
man . addConfigString ( "kinesis.result_stream" , "" ,
"Kinesis stream name for result logs" )
2021-02-24 18:02:26 +00:00
// Lambda
man . addConfigString ( "lambda.region" , "" , "AWS Region to use" )
man . addConfigString ( "lambda.access_key_id" , "" , "Access Key ID for AWS authentication" )
man . addConfigString ( "lambda.secret_access_key" , "" , "Secret Access Key for AWS authentication" )
man . addConfigString ( "lambda.sts_assume_role_arn" , "" ,
"ARN of role to assume for AWS" )
man . addConfigString ( "lambda.status_function" , "" ,
"Lambda function name for status logs" )
man . addConfigString ( "lambda.result_function" , "" ,
"Lambda function name for result logs" )
2020-12-16 17:16:55 +00:00
// S3 for file carving
man . addConfigString ( "s3.bucket" , "" , "Bucket where to store file carves" )
man . addConfigString ( "s3.prefix" , "" , "Prefix under which carves are stored" )
2021-10-12 19:32:06 +00:00
man . addConfigString ( "s3.region" , "" , "AWS Region (if blank region is derived)" )
man . addConfigString ( "s3.endpoint_url" , "" , "AWS Service Endpoint to use (leave blank for default service endpoints)" )
2020-12-16 17:16:55 +00:00
man . addConfigString ( "s3.access_key_id" , "" , "Access Key ID for AWS authentication" )
man . addConfigString ( "s3.secret_access_key" , "" , "Secret Access Key for AWS authentication" )
man . addConfigString ( "s3.sts_assume_role_arn" , "" , "ARN of role to assume for AWS" )
2021-10-12 19:32:06 +00:00
man . addConfigBool ( "s3.disable_ssl" , false , "Disable SSL (typically for local testing)" )
man . addConfigBool ( "s3.force_s3_path_style" , false , "Set this to true to force path-style addressing, i.e., `http://s3.amazonaws.com/BUCKET/KEY`" )
2020-12-16 17:16:55 +00:00
2019-07-16 22:41:50 +00:00
// PubSub
man . addConfigString ( "pubsub.project" , "" , "Google Cloud Project to use" )
man . addConfigString ( "pubsub.status_topic" , "" , "PubSub topic for status logs" )
man . addConfigString ( "pubsub.result_topic" , "" , "PubSub topic for result logs" )
2021-05-08 19:29:52 +00:00
man . addConfigBool ( "pubsub.add_attributes" , false , "Add PubSub attributes in addition to the message body" )
2019-07-16 22:41:50 +00:00
2019-04-08 18:47:15 +00:00
// Filesystem
2021-07-22 00:49:44 +00:00
man . addConfigString ( "filesystem.status_log_file" , filepath . Join ( os . TempDir ( ) , "osquery_status" ) ,
2019-04-08 18:47:15 +00:00
"Log file path to use for status logs" )
2021-07-22 00:49:44 +00:00
man . addConfigString ( "filesystem.result_log_file" , filepath . Join ( os . TempDir ( ) , "osquery_result" ) ,
2019-04-08 18:47:15 +00:00
"Log file path to use for result logs" )
man . addConfigBool ( "filesystem.enable_log_rotation" , false ,
"Enable automatic rotation for osquery log files" )
2020-09-09 20:33:32 +00:00
man . addConfigBool ( "filesystem.enable_log_compression" , false ,
"Enable compression for the rotated osquery log files" )
2021-05-20 00:29:38 +00:00
2021-10-28 04:51:17 +00:00
// KafkaREST
man . addConfigString ( "kafkarest.status_topic" , "" , "Kafka REST topic for status logs" )
man . addConfigString ( "kafkarest.result_topic" , "" , "Kafka REST topic for result logs" )
man . addConfigString ( "kafkarest.proxyhost" , "" , "Kafka REST proxy host url" )
2022-03-09 22:22:29 +00:00
man . addConfigString ( "kafkarest.content_type_value" , "application/vnd.kafka.json.v1+json" ,
"Kafka REST proxy content type header (defaults to \"application/vnd.kafka.json.v1+json\"" )
2021-10-28 04:51:17 +00:00
man . addConfigInt ( "kafkarest.timeout" , 5 , "Kafka REST proxy json post timeout" )
2021-05-20 00:29:38 +00:00
// License
2021-09-03 16:05:23 +00:00
man . addConfigString ( "license.key" , "" , "Fleet license key (to enable Fleet Premium features)" )
2022-06-13 20:29:32 +00:00
man . addConfigBool ( "license.enforce_host_limit" , false , "Enforce license limit of enrolled hosts" )
2021-08-18 20:25:14 +00:00
// Vulnerability processing
2021-12-03 17:44:57 +00:00
man . addConfigString ( "vulnerabilities.databases_path" , "/tmp/vulndbs" ,
2021-08-18 20:25:14 +00:00
"Path where Fleet will download the data feeds to check CVEs" )
man . addConfigDuration ( "vulnerabilities.periodicity" , 1 * time . Hour ,
"How much time to wait between processing software for vulnerabilities." )
man . addConfigString ( "vulnerabilities.cpe_database_url" , "" ,
"URL from which to get the latest CPE database. If empty, defaults to the official Github link." )
man . addConfigString ( "vulnerabilities.cve_feed_prefix_url" , "" ,
"Prefix URL for the CVE data feed. If empty, default to https://nvd.nist.gov/" )
man . addConfigString ( "vulnerabilities.current_instance_checks" , "auto" ,
"Allows to manually select an instance to do the vulnerability processing." )
2021-09-14 13:58:35 +00:00
man . addConfigBool ( "vulnerabilities.disable_data_sync" , false ,
"Skips synchronizing data streams and expects them to be available in the databases_path." )
2022-04-12 18:48:15 +00:00
man . addConfigDuration ( "vulnerabilities.recent_vulnerability_max_age" , 30 * 24 * time . Hour ,
"Maximum age of the published date of a vulnerability (CVE) to be considered 'recent'." )
2021-11-22 17:47:24 +00:00
// Upgrades
man . addConfigBool ( "upgrades.allow_missing_migrations" , false ,
"Allow serve to run even if migrations are missing." )
2022-01-20 19:41:02 +00:00
// Sentry
man . addConfigString ( "sentry.dsn" , "" , "DSN for Sentry" )
2022-03-21 16:29:52 +00:00
// GeoIP
man . addConfigString ( "geoip.database_path" , "" , "path to mmdb file" )
2022-04-07 12:40:53 +00:00
// Prometheus
man . addConfigString ( "prometheus.basic_auth.username" , "" , "Prometheus username for HTTP Basic Auth" )
man . addConfigString ( "prometheus.basic_auth.password" , "" , "Prometheus password for HTTP Basic Auth" )
2016-09-12 17:26:56 +00:00
}
// LoadConfig will load the config variables into a fully initialized
2021-06-06 22:07:29 +00:00
// FleetConfig struct
func ( man Manager ) LoadConfig ( ) FleetConfig {
2016-09-12 17:26:56 +00:00
man . loadConfigFile ( )
2021-09-01 19:50:52 +00:00
loadMysqlConfig := func ( prefix string ) MysqlConfig {
return MysqlConfig {
Protocol : man . getConfigString ( prefix + ".protocol" ) ,
Address : man . getConfigString ( prefix + ".address" ) ,
Username : man . getConfigString ( prefix + ".username" ) ,
Password : man . getConfigString ( prefix + ".password" ) ,
PasswordPath : man . getConfigString ( prefix + ".password_path" ) ,
Database : man . getConfigString ( prefix + ".database" ) ,
TLSCert : man . getConfigString ( prefix + ".tls_cert" ) ,
TLSKey : man . getConfigString ( prefix + ".tls_key" ) ,
TLSCA : man . getConfigString ( prefix + ".tls_ca" ) ,
TLSServerName : man . getConfigString ( prefix + ".tls_server_name" ) ,
TLSConfig : man . getConfigString ( prefix + ".tls_config" ) ,
MaxOpenConns : man . getConfigInt ( prefix + ".max_open_conns" ) ,
MaxIdleConns : man . getConfigInt ( prefix + ".max_idle_conns" ) ,
ConnMaxLifetime : man . getConfigInt ( prefix + ".conn_max_lifetime" ) ,
}
}
2022-05-16 13:44:50 +00:00
cfg := FleetConfig {
2021-09-01 19:50:52 +00:00
Mysql : loadMysqlConfig ( "mysql" ) ,
MysqlReadReplica : loadMysqlConfig ( "mysql_read_replica" ) ,
2016-12-16 00:13:23 +00:00
Redis : RedisConfig {
2021-09-15 12:50:32 +00:00
Address : man . getConfigString ( "redis.address" ) ,
Password : man . getConfigString ( "redis.password" ) ,
Database : man . getConfigInt ( "redis.database" ) ,
UseTLS : man . getConfigBool ( "redis.use_tls" ) ,
DuplicateResults : man . getConfigBool ( "redis.duplicate_results" ) ,
ConnectTimeout : man . getConfigDuration ( "redis.connect_timeout" ) ,
KeepAlive : man . getConfigDuration ( "redis.keep_alive" ) ,
ConnectRetryAttempts : man . getConfigInt ( "redis.connect_retry_attempts" ) ,
ClusterFollowRedirections : man . getConfigBool ( "redis.cluster_follow_redirections" ) ,
2021-10-18 13:32:17 +00:00
ClusterReadFromReplica : man . getConfigBool ( "redis.cluster_read_from_replica" ) ,
2021-10-20 14:09:18 +00:00
TLSCert : man . getConfigString ( "redis.tls_cert" ) ,
TLSKey : man . getConfigString ( "redis.tls_key" ) ,
TLSCA : man . getConfigString ( "redis.tls_ca" ) ,
TLSServerName : man . getConfigString ( "redis.tls_server_name" ) ,
TLSHandshakeTimeout : man . getConfigDuration ( "redis.tls_handshake_timeout" ) ,
MaxIdleConns : man . getConfigInt ( "redis.max_idle_conns" ) ,
MaxOpenConns : man . getConfigInt ( "redis.max_open_conns" ) ,
ConnMaxLifetime : man . getConfigDuration ( "redis.conn_max_lifetime" ) ,
IdleTimeout : man . getConfigDuration ( "redis.idle_timeout" ) ,
2021-11-01 18:13:16 +00:00
ConnWaitTimeout : man . getConfigDuration ( "redis.conn_wait_timeout" ) ,
2022-01-11 22:08:39 +00:00
WriteTimeout : man . getConfigDuration ( "redis.write_timeout" ) ,
ReadTimeout : man . getConfigDuration ( "redis.read_timeout" ) ,
2016-12-16 00:13:23 +00:00
} ,
2016-09-12 17:26:56 +00:00
Server : ServerConfig {
2017-03-28 04:21:48 +00:00
Address : man . getConfigString ( "server.address" ) ,
Cert : man . getConfigString ( "server.cert" ) ,
Key : man . getConfigString ( "server.key" ) ,
TLS : man . getConfigBool ( "server.tls" ) ,
TLSProfile : man . getConfigTLSProfile ( ) ,
2019-10-16 23:40:45 +00:00
URLPrefix : man . getConfigString ( "server.url_prefix" ) ,
2021-05-08 00:29:54 +00:00
Keepalive : man . getConfigBool ( "server.keepalive" ) ,
2016-09-12 17:26:56 +00:00
} ,
Auth : AuthConfig {
BcryptCost : man . getConfigInt ( "auth.bcrypt_cost" ) ,
SaltKeySize : man . getConfigInt ( "auth.salt_key_size" ) ,
} ,
App : AppConfig {
2016-09-29 02:44:05 +00:00
TokenKeySize : man . getConfigInt ( "app.token_key_size" ) ,
InviteTokenValidityPeriod : man . getConfigDuration ( "app.invite_token_validity_period" ) ,
2022-02-09 11:20:29 +00:00
EnableScheduledQueryStats : man . getConfigBool ( "app.enable_scheduled_query_stats" ) ,
2016-09-12 17:26:56 +00:00
} ,
Session : SessionConfig {
2016-09-14 16:11:06 +00:00
KeySize : man . getConfigInt ( "session.key_size" ) ,
Duration : man . getConfigDuration ( "session.duration" ) ,
2016-09-12 17:26:56 +00:00
} ,
Osquery : OsqueryConfig {
2021-11-01 18:13:16 +00:00
NodeKeySize : man . getConfigInt ( "osquery.node_key_size" ) ,
HostIdentifier : man . getConfigString ( "osquery.host_identifier" ) ,
EnrollCooldown : man . getConfigDuration ( "osquery.enroll_cooldown" ) ,
StatusLogPlugin : man . getConfigString ( "osquery.status_log_plugin" ) ,
ResultLogPlugin : man . getConfigString ( "osquery.result_log_plugin" ) ,
StatusLogFile : man . getConfigString ( "osquery.status_log_file" ) ,
ResultLogFile : man . getConfigString ( "osquery.result_log_file" ) ,
LabelUpdateInterval : man . getConfigDuration ( "osquery.label_update_interval" ) ,
PolicyUpdateInterval : man . getConfigDuration ( "osquery.policy_update_interval" ) ,
DetailUpdateInterval : man . getConfigDuration ( "osquery.detail_update_interval" ) ,
EnableLogRotation : man . getConfigBool ( "osquery.enable_log_rotation" ) ,
MaxJitterPercent : man . getConfigInt ( "osquery.max_jitter_percent" ) ,
2022-05-16 13:44:50 +00:00
EnableAsyncHostProcessing : man . getConfigString ( "osquery.enable_async_host_processing" ) ,
AsyncHostCollectInterval : man . getConfigString ( "osquery.async_host_collect_interval" ) ,
2021-11-01 18:13:16 +00:00
AsyncHostCollectMaxJitterPercent : man . getConfigInt ( "osquery.async_host_collect_max_jitter_percent" ) ,
2022-05-16 13:44:50 +00:00
AsyncHostCollectLockTimeout : man . getConfigString ( "osquery.async_host_collect_lock_timeout" ) ,
2021-11-01 18:13:16 +00:00
AsyncHostCollectLogStatsInterval : man . getConfigDuration ( "osquery.async_host_collect_log_stats_interval" ) ,
AsyncHostInsertBatch : man . getConfigInt ( "osquery.async_host_insert_batch" ) ,
AsyncHostDeleteBatch : man . getConfigInt ( "osquery.async_host_delete_batch" ) ,
AsyncHostUpdateBatch : man . getConfigInt ( "osquery.async_host_update_batch" ) ,
AsyncHostRedisPopCount : man . getConfigInt ( "osquery.async_host_redis_pop_count" ) ,
AsyncHostRedisScanKeysCount : man . getConfigInt ( "osquery.async_host_redis_scan_keys_count" ) ,
2022-04-27 13:47:09 +00:00
MinSoftwareLastOpenedAtDiff : man . getConfigDuration ( "osquery.min_software_last_opened_at_diff" ) ,
2016-09-12 17:26:56 +00:00
} ,
Logging : LoggingConfig {
2021-11-02 17:35:57 +00:00
Debug : man . getConfigBool ( "logging.debug" ) ,
JSON : man . getConfigBool ( "logging.json" ) ,
DisableBanner : man . getConfigBool ( "logging.disable_banner" ) ,
ErrorRetentionPeriod : man . getConfigDuration ( "logging.error_retention_period" ) ,
2022-02-15 17:42:22 +00:00
TracingEnabled : man . getConfigBool ( "logging.tracing_enabled" ) ,
TracingType : man . getConfigString ( "logging.tracing_type" ) ,
2016-09-12 17:26:56 +00:00
} ,
2019-04-08 18:47:15 +00:00
Firehose : FirehoseConfig {
2020-08-19 21:56:44 +00:00
Region : man . getConfigString ( "firehose.region" ) ,
2021-07-30 15:45:49 +00:00
EndpointURL : man . getConfigString ( "firehose.endpoint_url" ) ,
2020-08-19 21:56:44 +00:00
AccessKeyID : man . getConfigString ( "firehose.access_key_id" ) ,
SecretAccessKey : man . getConfigString ( "firehose.secret_access_key" ) ,
StsAssumeRoleArn : man . getConfigString ( "firehose.sts_assume_role_arn" ) ,
StatusStream : man . getConfigString ( "firehose.status_stream" ) ,
ResultStream : man . getConfigString ( "firehose.result_stream" ) ,
} ,
Kinesis : KinesisConfig {
Region : man . getConfigString ( "kinesis.region" ) ,
2021-07-30 15:45:49 +00:00
EndpointURL : man . getConfigString ( "kinesis.endpoint_url" ) ,
2020-08-19 21:56:44 +00:00
AccessKeyID : man . getConfigString ( "kinesis.access_key_id" ) ,
SecretAccessKey : man . getConfigString ( "kinesis.secret_access_key" ) ,
StatusStream : man . getConfigString ( "kinesis.status_stream" ) ,
ResultStream : man . getConfigString ( "kinesis.result_stream" ) ,
StsAssumeRoleArn : man . getConfigString ( "kinesis.sts_assume_role_arn" ) ,
2019-04-08 18:47:15 +00:00
} ,
2021-02-24 18:02:26 +00:00
Lambda : LambdaConfig {
Region : man . getConfigString ( "lambda.region" ) ,
AccessKeyID : man . getConfigString ( "lambda.access_key_id" ) ,
SecretAccessKey : man . getConfigString ( "lambda.secret_access_key" ) ,
StatusFunction : man . getConfigString ( "lambda.status_function" ) ,
ResultFunction : man . getConfigString ( "lambda.result_function" ) ,
StsAssumeRoleArn : man . getConfigString ( "lambda.sts_assume_role_arn" ) ,
} ,
2020-12-16 17:16:55 +00:00
S3 : S3Config {
Bucket : man . getConfigString ( "s3.bucket" ) ,
Prefix : man . getConfigString ( "s3.prefix" ) ,
2021-10-12 19:32:06 +00:00
Region : man . getConfigString ( "s3.region" ) ,
EndpointURL : man . getConfigString ( "s3.endpoint_url" ) ,
2020-12-16 17:16:55 +00:00
AccessKeyID : man . getConfigString ( "s3.access_key_id" ) ,
SecretAccessKey : man . getConfigString ( "s3.secret_access_key" ) ,
StsAssumeRoleArn : man . getConfigString ( "s3.sts_assume_role_arn" ) ,
2021-10-12 19:32:06 +00:00
DisableSSL : man . getConfigBool ( "s3.disable_ssl" ) ,
ForceS3PathStyle : man . getConfigBool ( "s3.force_s3_path_style" ) ,
2020-12-16 17:16:55 +00:00
} ,
2019-07-16 22:41:50 +00:00
PubSub : PubSubConfig {
2021-05-08 19:29:52 +00:00
Project : man . getConfigString ( "pubsub.project" ) ,
StatusTopic : man . getConfigString ( "pubsub.status_topic" ) ,
ResultTopic : man . getConfigString ( "pubsub.result_topic" ) ,
AddAttributes : man . getConfigBool ( "pubsub.add_attributes" ) ,
2019-07-16 22:41:50 +00:00
} ,
2019-04-08 18:47:15 +00:00
Filesystem : FilesystemConfig {
2020-09-09 20:33:32 +00:00
StatusLogFile : man . getConfigString ( "filesystem.status_log_file" ) ,
ResultLogFile : man . getConfigString ( "filesystem.result_log_file" ) ,
EnableLogRotation : man . getConfigBool ( "filesystem.enable_log_rotation" ) ,
EnableLogCompression : man . getConfigBool ( "filesystem.enable_log_compression" ) ,
2019-04-08 18:47:15 +00:00
} ,
2021-10-28 04:51:17 +00:00
KafkaREST : KafkaRESTConfig {
2022-03-09 22:22:29 +00:00
StatusTopic : man . getConfigString ( "kafkarest.status_topic" ) ,
ResultTopic : man . getConfigString ( "kafkarest.result_topic" ) ,
ProxyHost : man . getConfigString ( "kafkarest.proxyhost" ) ,
ContentTypeValue : man . getConfigString ( "kafkarest.content_type_value" ) ,
Timeout : man . getConfigInt ( "kafkarest.timeout" ) ,
2021-10-28 04:51:17 +00:00
} ,
2021-05-20 00:29:38 +00:00
License : LicenseConfig {
2022-06-13 20:29:32 +00:00
Key : man . getConfigString ( "license.key" ) ,
EnforceHostLimit : man . getConfigBool ( "license.enforce_host_limit" ) ,
2021-05-20 00:29:38 +00:00
} ,
2021-08-18 20:25:14 +00:00
Vulnerabilities : VulnerabilitiesConfig {
2022-04-12 18:48:15 +00:00
DatabasesPath : man . getConfigString ( "vulnerabilities.databases_path" ) ,
Periodicity : man . getConfigDuration ( "vulnerabilities.periodicity" ) ,
CPEDatabaseURL : man . getConfigString ( "vulnerabilities.cpe_database_url" ) ,
CVEFeedPrefixURL : man . getConfigString ( "vulnerabilities.cve_feed_prefix_url" ) ,
CurrentInstanceChecks : man . getConfigString ( "vulnerabilities.current_instance_checks" ) ,
DisableDataSync : man . getConfigBool ( "vulnerabilities.disable_data_sync" ) ,
RecentVulnerabilityMaxAge : man . getConfigDuration ( "vulnerabilities.recent_vulnerability_max_age" ) ,
2021-08-18 20:25:14 +00:00
} ,
2021-11-22 17:47:24 +00:00
Upgrades : UpgradesConfig {
AllowMissingMigrations : man . getConfigBool ( "upgrades.allow_missing_migrations" ) ,
} ,
2022-01-20 19:41:02 +00:00
Sentry : SentryConfig {
Dsn : man . getConfigString ( "sentry.dsn" ) ,
} ,
2022-03-21 16:29:52 +00:00
GeoIP : GeoIPConfig {
DatabasePath : man . getConfigString ( "geoip.database_path" ) ,
} ,
2022-04-07 12:40:53 +00:00
Prometheus : PrometheusConfig {
BasicAuth : HTTPBasicAuthConfig {
Username : man . getConfigString ( "prometheus.basic_auth.username" ) ,
Password : man . getConfigString ( "prometheus.basic_auth.password" ) ,
} ,
} ,
2016-09-12 17:26:56 +00:00
}
2022-05-16 13:44:50 +00:00
// ensure immediately that the async config is valid for all known tasks
for task := range knownAsyncTasks {
cfg . Osquery . AsyncConfigForTask ( task )
}
return cfg
2016-09-12 17:26:56 +00:00
}
2016-10-03 21:47:31 +00:00
// IsSet determines whether a given config key has been explicitly set by any
// of the configuration sources. If false, the default value is being used.
func ( man Manager ) IsSet ( key string ) bool {
return man . viper . IsSet ( key )
}
2016-09-12 17:26:56 +00:00
// envNameFromConfigKey converts a config key into the corresponding
// environment variable name
func envNameFromConfigKey ( key string ) string {
return envPrefix + "_" + strings . ToUpper ( strings . Replace ( key , "." , "_" , - 1 ) )
}
// flagNameFromConfigKey converts a config key into the corresponding flag name
func flagNameFromConfigKey ( key string ) string {
return strings . Replace ( key , "." , "_" , - 1 )
}
2019-01-24 17:39:32 +00:00
// Manager manages the addition and retrieval of config values for Fleet
2016-09-12 17:26:56 +00:00
// configs. It's only public API method is LoadConfig, which will return the
2021-06-06 22:07:29 +00:00
// populated FleetConfig struct.
2016-09-12 17:26:56 +00:00
type Manager struct {
viper * viper . Viper
command * cobra . Command
defaults map [ string ] interface { }
}
// NewManager initializes a Manager wrapping the provided cobra
// command. All config flags will be attached to that command (and inherited by
// the subcommands). Typically this should be called just once, with the root
// command.
func NewManager ( command * cobra . Command ) Manager {
man := Manager {
viper : viper . New ( ) ,
command : command ,
defaults : map [ string ] interface { } { } ,
2016-09-03 17:25:16 +00:00
}
2016-09-12 17:26:56 +00:00
man . addConfigs ( )
return man
2016-09-03 17:25:16 +00:00
}
2016-09-12 17:26:56 +00:00
// addDefault will check for duplication, then add a default value to the
// defaults map
func ( man Manager ) addDefault ( key string , defVal interface { } ) {
if _ , exists := man . defaults [ key ] ; exists {
panic ( "Trying to add duplicate config for key " + key )
2016-09-03 17:25:16 +00:00
}
2016-09-12 17:26:56 +00:00
man . defaults [ key ] = defVal
}
2017-01-31 18:06:30 +00:00
func getFlagUsage ( key string , usage string ) string {
return fmt . Sprintf ( "Env: %s\n\t\t%s" , envNameFromConfigKey ( key ) , usage )
}
2016-09-12 17:26:56 +00:00
// getInterfaceVal is a helper function used by the getConfig* functions to
// retrieve the config value as interface{}, which will then be cast to the
// appropriate type by the getConfig* function.
func ( man Manager ) getInterfaceVal ( key string ) interface { } {
interfaceVal := man . viper . Get ( key )
if interfaceVal == nil {
var ok bool
interfaceVal , ok = man . defaults [ key ]
if ! ok {
panic ( "Tried to look up default value for nonexistent config option: " + key )
}
}
return interfaceVal
}
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
// addConfigString adds a string config to the config options
2017-01-31 18:06:30 +00:00
func ( man Manager ) addConfigString ( key , defVal , usage string ) {
man . command . PersistentFlags ( ) . String ( flagNameFromConfigKey ( key ) , defVal , getFlagUsage ( key , usage ) )
2016-09-12 17:26:56 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) )
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) )
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
// Add default
man . addDefault ( key , defVal )
}
// getConfigString retrieves a string from the loaded config
func ( man Manager ) getConfigString ( key string ) string {
interfaceVal := man . getInterfaceVal ( key )
stringVal , err := cast . ToStringE ( interfaceVal )
2016-09-03 17:25:16 +00:00
if err != nil {
2016-09-12 17:26:56 +00:00
panic ( "Unable to cast to string for key " + key + ": " + err . Error ( ) )
2016-09-03 17:25:16 +00:00
}
2016-09-12 17:26:56 +00:00
return stringVal
}
2016-09-03 17:25:16 +00:00
2017-03-28 04:21:48 +00:00
// Custom handling for TLSProfile which can only accept specific values
// for the argument
func ( man Manager ) getConfigTLSProfile ( ) string {
ival := man . getInterfaceVal ( TLSProfileKey )
sval , err := cast . ToStringE ( ival )
if err != nil {
panic ( fmt . Sprintf ( "%s requires a string value: %s" , TLSProfileKey , err . Error ( ) ) )
}
switch sval {
2020-01-14 17:36:07 +00:00
case TLSProfileModern , TLSProfileIntermediate :
2017-03-28 04:21:48 +00:00
default :
2020-09-10 16:31:01 +00:00
panic ( fmt . Sprintf ( "%s must be one of %s or %s" , TLSProfileKey ,
TLSProfileModern , TLSProfileIntermediate ) )
2017-03-28 04:21:48 +00:00
}
return sval
}
2016-09-12 17:26:56 +00:00
// addConfigInt adds a int config to the config options
2017-01-31 18:06:30 +00:00
func ( man Manager ) addConfigInt ( key string , defVal int , usage string ) {
man . command . PersistentFlags ( ) . Int ( flagNameFromConfigKey ( key ) , defVal , getFlagUsage ( key , usage ) )
2016-09-12 17:26:56 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) )
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) )
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
// Add default
man . addDefault ( key , defVal )
}
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
// getConfigInt retrieves a int from the loaded config
func ( man Manager ) getConfigInt ( key string ) int {
interfaceVal := man . getInterfaceVal ( key )
intVal , err := cast . ToIntE ( interfaceVal )
if err != nil {
panic ( "Unable to cast to int for key " + key + ": " + err . Error ( ) )
}
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
return intVal
}
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
// addConfigBool adds a bool config to the config options
2017-01-31 18:06:30 +00:00
func ( man Manager ) addConfigBool ( key string , defVal bool , usage string ) {
man . command . PersistentFlags ( ) . Bool ( flagNameFromConfigKey ( key ) , defVal , getFlagUsage ( key , usage ) )
2016-09-12 17:26:56 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) )
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) )
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
// Add default
man . addDefault ( key , defVal )
}
// getConfigBool retrieves a bool from the loaded config
func ( man Manager ) getConfigBool ( key string ) bool {
interfaceVal := man . getInterfaceVal ( key )
boolVal , err := cast . ToBoolE ( interfaceVal )
if err != nil {
panic ( "Unable to cast to bool for key " + key + ": " + err . Error ( ) )
}
2016-09-03 17:25:16 +00:00
2016-09-12 17:26:56 +00:00
return boolVal
}
2016-09-03 17:25:16 +00:00
2016-09-14 16:11:06 +00:00
// addConfigDuration adds a duration config to the config options
2017-01-31 18:06:30 +00:00
func ( man Manager ) addConfigDuration ( key string , defVal time . Duration , usage string ) {
man . command . PersistentFlags ( ) . Duration ( flagNameFromConfigKey ( key ) , defVal , getFlagUsage ( key , usage ) )
2016-09-14 16:11:06 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) )
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) )
// Add default
man . addDefault ( key , defVal )
}
// getConfigDuration retrieves a duration from the loaded config
func ( man Manager ) getConfigDuration ( key string ) time . Duration {
interfaceVal := man . getInterfaceVal ( key )
durationVal , err := cast . ToDurationE ( interfaceVal )
if err != nil {
panic ( "Unable to cast to duration for key " + key + ": " + err . Error ( ) )
}
return durationVal
}
2022-05-16 13:44:50 +00:00
// panics if the config is invalid, this is handled by Viper (this is how all
// getConfigT helpers indicate errors). The default value is only applied if
2022-05-20 17:07:32 +00:00
// there is no task-specific config (i.e., no "task=true" config format for that
2022-05-16 13:44:50 +00:00
// task). If the configuration key was not set at all, it automatically
// inherited the general default configured for that key (via
// man.addConfigBool).
func configForKeyOrBool ( key , task , val string , def bool ) bool {
parseVal := func ( v string ) bool {
if v == "" {
return false
}
b , err := strconv . ParseBool ( v )
if err != nil {
panic ( "Unable to cast to bool for key " + key + ": " + err . Error ( ) )
}
return b
}
if ! strings . Contains ( val , "=" ) {
// simple case, val is a bool
return parseVal ( val )
}
q , err := url . ParseQuery ( val )
if err != nil {
panic ( "Invalid query format for key " + key + ": " + err . Error ( ) )
}
if v := q . Get ( task ) ; v != "" {
return parseVal ( v )
}
return def
}
// panics if the config is invalid, this is handled by Viper (this is how all
// getConfigT helpers indicate errors). The default value is only applied if
// there is no task-specific config (i.e. no "task=10s" config format for that
// task). If the configuration key was not set at all, it automatically
// inherited the general default configured for that key (via
// man.addConfigDuration).
func configForKeyOrDuration ( key , task , val string , def time . Duration ) time . Duration {
parseVal := func ( v string ) time . Duration {
if v == "" {
return 0
}
d , err := time . ParseDuration ( v )
if err != nil {
panic ( "Unable to cast to time.Duration for key " + key + ": " + err . Error ( ) )
}
return d
}
if ! strings . Contains ( val , "=" ) {
// simple case, val is a duration
return parseVal ( val )
}
q , err := url . ParseQuery ( val )
if err != nil {
panic ( "Invalid query format for key " + key + ": " + err . Error ( ) )
}
if v := q . Get ( task ) ; v != "" {
return parseVal ( v )
}
return def
}
2016-09-12 17:26:56 +00:00
// loadConfigFile handles the loading of the config file.
func ( man Manager ) loadConfigFile ( ) {
2016-09-15 15:44:05 +00:00
man . viper . SetConfigType ( "yaml" )
2016-09-12 17:26:56 +00:00
configFile := man . command . PersistentFlags ( ) . Lookup ( "config" ) . Value . String ( )
2016-09-03 17:25:16 +00:00
2016-09-15 15:44:05 +00:00
if configFile == "" {
// No config file set, only use configs from env
// vars/flags/defaults
return
}
2016-09-12 17:26:56 +00:00
2016-09-15 15:44:05 +00:00
man . viper . SetConfigFile ( configFile )
2016-09-12 17:26:56 +00:00
err := man . viper . ReadInConfig ( )
if err != nil {
2019-04-23 22:59:02 +00:00
fmt . Println ( "Error loading config file:" , err )
os . Exit ( 1 )
2016-09-03 17:25:16 +00:00
}
2019-04-23 22:59:02 +00:00
2022-04-07 12:40:53 +00:00
fmt . Println ( "Using config file:" , man . viper . ConfigFileUsed ( ) )
2016-09-03 17:25:16 +00:00
}
2016-09-14 16:11:06 +00:00
// TestConfig returns a barebones configuration suitable for use in tests.
// Individual tests may want to override some of the values provided.
2021-06-06 22:07:29 +00:00
func TestConfig ( ) FleetConfig {
2021-10-28 04:51:17 +00:00
testLogFile := "/dev/null"
2021-07-22 00:49:44 +00:00
if runtime . GOOS == "windows" {
testLogFile = "NUL"
}
2021-06-06 22:07:29 +00:00
return FleetConfig {
2016-09-29 02:44:05 +00:00
App : AppConfig {
2017-04-12 00:13:38 +00:00
TokenKeySize : 24 ,
2016-09-29 02:44:05 +00:00
InviteTokenValidityPeriod : 5 * 24 * time . Hour ,
} ,
2016-09-14 16:11:06 +00:00
Auth : AuthConfig {
BcryptCost : 6 , // Low cost keeps tests fast
SaltKeySize : 24 ,
} ,
Session : SessionConfig {
KeySize : 64 ,
2022-03-07 22:37:54 +00:00
Duration : 24 * 5 * time . Hour ,
2016-09-14 16:11:06 +00:00
} ,
Osquery : OsqueryConfig {
2020-03-02 19:08:08 +00:00
NodeKeySize : 24 ,
2021-03-09 02:35:17 +00:00
HostIdentifier : "instance" ,
2021-03-09 05:26:09 +00:00
EnrollCooldown : 42 * time . Minute ,
2020-03-02 19:08:08 +00:00
StatusLogPlugin : "filesystem" ,
ResultLogPlugin : "filesystem" ,
LabelUpdateInterval : 1 * time . Hour ,
2021-09-27 19:27:38 +00:00
PolicyUpdateInterval : 1 * time . Hour ,
2020-03-02 19:08:08 +00:00
DetailUpdateInterval : 1 * time . Hour ,
2021-09-21 17:21:44 +00:00
MaxJitterPercent : 0 ,
2016-09-14 16:11:06 +00:00
} ,
Logging : LoggingConfig {
Debug : true ,
DisableBanner : true ,
} ,
2019-04-08 18:47:15 +00:00
Filesystem : FilesystemConfig {
2021-07-22 00:49:44 +00:00
StatusLogFile : testLogFile ,
ResultLogFile : testLogFile ,
2019-04-08 18:47:15 +00:00
} ,
2016-09-14 16:11:06 +00:00
}
}