2016-09-03 17:25:16 +00:00
package config
import (
2022-10-19 10:42:21 +00:00
"context"
2021-10-20 14:09:18 +00:00
"crypto/tls"
"crypto/x509"
2022-12-06 20:50:56 +00:00
"encoding/json"
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-10-19 10:42:21 +00:00
"net"
"net/http"
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"
2023-01-16 15:22:12 +00:00
"testing"
2016-09-14 16:11:06 +00:00
"time"
2016-09-03 17:25:16 +00:00
2022-12-06 20:50:56 +00:00
nanodep_client "github.com/micromdm/nanodep/client"
"github.com/micromdm/nanodep/tokenpki"
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 {
2022-07-20 16:10:03 +00:00
Protocol string ` yaml:"protocol" `
Address string ` yaml:"address" `
Username string ` yaml:"username" `
Password string ` yaml:"password" `
2021-01-04 15:58:43 +00:00
PasswordPath string ` yaml:"password_path" `
2022-07-20 16:10:03 +00:00
Database string ` yaml:"database" `
2020-08-19 21:56:44 +00:00
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" `
2022-07-20 16:10:03 +00:00
SQLMode string ` yaml:"sql_mode" `
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
2022-12-14 13:53:38 +00:00
Username string
2021-09-15 12:50:32 +00:00
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 {
2023-03-28 05:23:29 +00:00
Address string
Cert string
Key string
TLS bool
TLSProfile string ` yaml:"tls_compatibility" `
URLPrefix string ` yaml:"url_prefix" `
Keepalive bool ` yaml:"keepalive" `
SandboxEnabled bool ` yaml:"sandbox_enabled" `
WebsocketsAllowUnsafeOrigin bool ` yaml:"websockets_allow_unsafe_origin" `
2016-09-12 17:26:56 +00:00
}
2022-10-19 10:42:21 +00:00
func ( s * ServerConfig ) DefaultHTTPServer ( ctx context . Context , handler http . Handler ) * http . Server {
return & http . Server {
Addr : s . Address ,
Handler : handler ,
ReadTimeout : 25 * time . Second ,
WriteTimeout : 40 * time . Second ,
ReadHeaderTimeout : 5 * time . Second ,
IdleTimeout : 5 * time . Minute ,
MaxHeaderBytes : 1 << 18 , // 0.25 MB (262144 bytes)
BaseContext : func ( l net . Listener ) context . Context {
return ctx
} ,
}
}
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 {
2022-12-23 22:04:13 +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 is deprecated. It was replaced by FilesystemConfig.StatusLogFile.
//
// TODO(lucas): We should at least add a warning if this field is populated.
StatusLogFile string ` yaml:"status_log_file" `
// ResultLogFile is deprecated. It was replaced by FilesystemConfig.ResultLogFile.
//
// TODO(lucas): We should at least add a warning if this field is populated.
ResultLogFile string ` yaml:"result_log_file" `
2021-11-01 18:13:16 +00:00
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 (
2022-08-10 14:01:05 +00:00
AsyncTaskLabelMembership AsyncTaskName = "label_membership"
AsyncTaskPolicyMembership AsyncTaskName = "policy_membership"
AsyncTaskHostLastSeen AsyncTaskName = "host_last_seen"
AsyncTaskScheduledQueryStats AsyncTaskName = "scheduled_query_stats"
2022-05-16 13:44:50 +00:00
)
var knownAsyncTasks = map [ AsyncTaskName ] struct { } {
2022-08-10 14:01:05 +00:00
AsyncTaskLabelMembership : { } ,
AsyncTaskPolicyMembership : { } ,
AsyncTaskHostLastSeen : { } ,
AsyncTaskScheduledQueryStats : { } ,
2022-05-16 13:44:50 +00:00
}
// 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
}
2022-12-23 22:04:13 +00:00
// ActivityConfig defines configs related to activities.
type ActivityConfig struct {
// EnableAuditLog enables logging for audit activities.
EnableAuditLog bool ` yaml:"enable_audit_log" `
// AuditLogPlugin sets the plugin to use to log activities.
AuditLogPlugin string ` yaml:"audit_log_plugin" `
}
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" `
2022-12-23 22:04:13 +00:00
AuditStream string ` yaml:"audit_stream" `
2020-08-19 21:56:44 +00:00
}
// 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" `
2022-12-23 22:04:13 +00:00
AuditStream string ` yaml:"audit_stream" `
2019-04-08 18:47:15 +00:00
}
2023-04-06 18:21:07 +00:00
// SESConfig defines configs for the AWS SES service for emailing
type SESConfig struct {
Region string
EndpointURL string ` yaml:"endpoint_url" `
AccessKeyID string ` yaml:"access_key_id" `
SecretAccessKey string ` yaml:"secret_access_key" `
StsAssumeRoleArn string ` yaml:"sts_assume_role_arn" `
SourceArn string ` yaml:"source_arn" `
}
type EmailConfig struct {
EmailBackend string ` yaml:"backend" `
}
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" `
2022-12-23 22:04:13 +00:00
AuditFunction string ` yaml:"audit_function" `
2021-02-24 18:02:26 +00:00
}
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" `
2022-12-23 22:04:13 +00:00
AuditTopic string ` json:"audit_topic" yaml:"audit_topic" `
2021-07-30 15:45:49 +00:00
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" `
2022-12-23 22:04:13 +00:00
AuditLogFile string ` json:"audit_log_file" yaml:"audit_log_file" `
2021-07-30 15:45:49 +00:00
EnableLogRotation bool ` json:"enable_log_rotation" yaml:"enable_log_rotation" `
EnableLogCompression bool ` json:"enable_log_compression" yaml:"enable_log_compression" `
2023-02-24 12:44:56 +00:00
MaxSize int ` json:"max_size" yaml:"max_size" `
MaxAge int ` json:"max_age" yaml:"max_age" `
MaxBackups int ` json:"max_backups" yaml:"max_backups" `
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" `
2022-12-23 22:04:13 +00:00
AuditTopic string ` json:"audit_topic" yaml:"audit_topic" `
2022-03-09 22:22:29 +00:00
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-08-26 18:55:03 +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" `
2022-09-01 16:02:07 +00:00
CPETranslationsURL string ` json:"cpe_translations_url" yaml:"cpe_translations_url" `
2022-08-26 18:55:03 +00:00
CVEFeedPrefixURL string ` json:"cve_feed_prefix_url" yaml:"cve_feed_prefix_url" `
CurrentInstanceChecks string ` json:"current_instance_checks" yaml:"current_instance_checks" `
2023-02-17 15:00:57 +00:00
DisableSchedule bool ` json:"disable_schedule" yaml:"disable_schedule" `
2022-08-26 18:55:03 +00:00
DisableDataSync bool ` json:"disable_data_sync" yaml:"disable_data_sync" `
RecentVulnerabilityMaxAge time . Duration ` json:"recent_vulnerability_max_age" yaml:"recent_vulnerability_max_age" `
DisableWinOSVulnerabilities bool ` json:"disable_win_os_vulnerabilities" yaml:"disable_win_os_vulnerabilities" `
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" `
2023-03-23 22:00:11 +00:00
// Disable allows running the Prometheus metrics endpoint without Basic Auth.
Disable bool ` json:"disable" yaml:"disable" `
2022-04-07 12:40:53 +00:00
}
2022-07-12 22:12:10 +00:00
// PackagingConfig holds configuration to build and retrieve Fleet packages
type PackagingConfig struct {
// GlobalEnrollSecret is the enroll secret that will be used to enroll
// hosts in the global scope
GlobalEnrollSecret string ` yaml:"global_enroll_secret" `
2022-07-13 12:34:25 +00:00
// S3 configuration used to retrieve pre-built installers
S3 S3Config ` yaml:"s3" `
2022-07-12 22:12:10 +00:00
}
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
2022-12-23 22:04:13 +00:00
Activity ActivityConfig
2021-09-01 19:50:52 +00:00
Logging LoggingConfig
Firehose FirehoseConfig
Kinesis KinesisConfig
Lambda LambdaConfig
S3 S3Config
2023-04-06 18:21:07 +00:00
Email EmailConfig
SES SESConfig
2021-09-01 19:50:52 +00:00
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
2022-07-12 22:12:10 +00:00
Packaging PackagingConfig
2022-12-05 15:22:56 +00:00
MDM MDMConfig
2016-09-12 17:26:56 +00:00
}
2022-12-05 15:22:56 +00:00
type MDMConfig struct {
AppleAPNsCert string ` yaml:"apple_apns_cert" `
AppleAPNsCertBytes string ` yaml:"apple_apns_cert_bytes" `
AppleAPNsKey string ` yaml:"apple_apns_key" `
AppleAPNsKeyBytes string ` yaml:"apple_apns_key_bytes" `
AppleSCEPCert string ` yaml:"apple_scep_cert" `
AppleSCEPCertBytes string ` yaml:"apple_scep_cert_bytes" `
AppleSCEPKey string ` yaml:"apple_scep_key" `
AppleSCEPKeyBytes string ` yaml:"apple_scep_key_bytes" `
// the following fields hold the parsed, validated TLS certificate set the
// first time AppleAPNs or AppleSCEP is called, as well as the PEM-encoded
// bytes for the certificate and private key.
appleAPNs * tls . Certificate
appleAPNsPEMCert [ ] byte
appleAPNsPEMKey [ ] byte
appleSCEP * tls . Certificate
appleSCEPPEMCert [ ] byte
appleSCEPPEMKey [ ] byte
2022-12-06 20:50:56 +00:00
AppleBMServerToken string ` yaml:"apple_bm_server_token" `
AppleBMServerTokenBytes string ` yaml:"apple_bm_server_token_bytes" `
AppleBMCert string ` yaml:"apple_bm_cert" `
AppleBMCertBytes string ` yaml:"apple_bm_cert_bytes" `
AppleBMKey string ` yaml:"apple_bm_key" `
AppleBMKeyBytes string ` yaml:"apple_bm_key_bytes" `
// the following fields hold the decrypted, validated Apple BM token set the
// first time AppleBM is called.
appleBMToken * nanodep_client . OAuth1Tokens
2023-03-06 17:47:29 +00:00
2023-03-23 10:30:28 +00:00
// AppleEnable enables Apple MDM functionality on Fleet.
AppleEnable bool ` yaml:"apple_enable" `
// AppleDEPSyncPeriodicity is the duration between DEP device syncing
// (fetching and setting of DEP profiles).
AppleDEPSyncPeriodicity time . Duration ` yaml:"apple_dep_sync_periodicity" `
// AppleSCEPChallenge is the SCEP challenge for SCEP enrollment requests.
AppleSCEPChallenge string ` yaml:"apple_scep_challenge" `
// AppleSCEPSignerValidityDays are the days signed client certificates will
// be valid.
AppleSCEPSignerValidityDays int ` yaml:"apple_scep_signer_validity_days" `
// AppleSCEPSignerAllowRenewalDays are the allowable renewal days for
// certificates.
AppleSCEPSignerAllowRenewalDays int ` yaml:"apple_scep_signer_allow_renewal_days" `
2022-12-05 15:22:56 +00:00
}
type x509KeyPairConfig struct {
certPath string
certBytes [ ] byte
keyPath string
keyBytes [ ] byte
}
func ( x * x509KeyPairConfig ) IsSet ( ) bool {
// if any setting is provided, then the key pair is considered set
return x . certPath != "" || len ( x . certBytes ) != 0 || x . keyPath != "" || len ( x . keyBytes ) != 0
}
func ( x * x509KeyPairConfig ) Parse ( keepLeaf bool ) ( * tls . Certificate , error ) {
if x . certPath == "" && len ( x . certBytes ) == 0 {
return nil , errors . New ( "no certificate provided" )
}
if x . certPath != "" && len ( x . certBytes ) != 0 {
return nil , errors . New ( "only one of the certificate path or bytes must be provided" )
}
if x . keyPath == "" && len ( x . keyBytes ) == 0 {
return nil , errors . New ( "no key provided" )
}
if x . keyPath != "" && len ( x . keyBytes ) != 0 {
return nil , errors . New ( "only one of the key path or bytes must be provided" )
}
if len ( x . certBytes ) == 0 {
b , err := os . ReadFile ( x . certPath )
if err != nil {
return nil , fmt . Errorf ( "reading certificate file: %w" , err )
}
x . certBytes = b
}
if len ( x . keyBytes ) == 0 {
b , err := os . ReadFile ( x . keyPath )
if err != nil {
return nil , fmt . Errorf ( "reading key file: %w" , err )
}
x . keyBytes = b
}
cert , err := tls . X509KeyPair ( x . certBytes , x . keyBytes )
if err != nil {
return nil , fmt . Errorf ( "parse key pair: %w" , err )
}
if keepLeaf {
// X509KeyPair does not store the parsed certificate leaf
parsed , err := x509 . ParseCertificate ( cert . Certificate [ 0 ] )
if err != nil {
2023-04-27 11:44:39 +00:00
return nil , fmt . Errorf ( "parse leaf certificate: %w" , err )
2022-12-05 15:22:56 +00:00
}
cert . Leaf = parsed
}
return & cert , nil
}
func ( m * MDMConfig ) IsAppleAPNsSet ( ) bool {
pair := x509KeyPairConfig {
m . AppleAPNsCert ,
[ ] byte ( m . AppleAPNsCertBytes ) ,
m . AppleAPNsKey ,
[ ] byte ( m . AppleAPNsKeyBytes ) ,
}
return pair . IsSet ( )
}
func ( m * MDMConfig ) IsAppleSCEPSet ( ) bool {
pair := x509KeyPairConfig {
m . AppleSCEPCert ,
[ ] byte ( m . AppleSCEPCertBytes ) ,
m . AppleSCEPKey ,
[ ] byte ( m . AppleSCEPKeyBytes ) ,
}
return pair . IsSet ( )
}
2022-12-06 20:50:56 +00:00
func ( m * MDMConfig ) IsAppleBMSet ( ) bool {
pair := x509KeyPairConfig {
m . AppleBMCert ,
[ ] byte ( m . AppleBMCertBytes ) ,
m . AppleBMKey ,
[ ] byte ( m . AppleBMKeyBytes ) ,
}
// the BM token options is not taken into account by pair.IsSet
return pair . IsSet ( ) || m . AppleBMServerToken != "" || m . AppleBMServerTokenBytes != ""
}
2022-12-05 15:22:56 +00:00
// AppleAPNs returns the parsed and validated TLS certificate for Apple APNs.
// It parses and validates it if it hasn't been done yet.
func ( m * MDMConfig ) AppleAPNs ( ) ( cert * tls . Certificate , pemCert , pemKey [ ] byte , err error ) {
if m . appleAPNs == nil {
pair := x509KeyPairConfig {
m . AppleAPNsCert ,
[ ] byte ( m . AppleAPNsCertBytes ) ,
m . AppleAPNsKey ,
[ ] byte ( m . AppleAPNsKeyBytes ) ,
}
cert , err := pair . Parse ( true )
if err != nil {
return nil , nil , nil , fmt . Errorf ( "Apple MDM APNs configuration: %w" , err )
}
m . appleAPNs = cert
m . appleAPNsPEMCert = pair . certBytes
m . appleAPNsPEMKey = pair . keyBytes
}
return m . appleAPNs , m . appleAPNsPEMCert , m . appleAPNsPEMKey , nil
}
// AppleSCEP returns the parsed and validated TLS certificate for Apple SCEP.
// It parses and validates it if it hasn't been done yet.
func ( m * MDMConfig ) AppleSCEP ( ) ( cert * tls . Certificate , pemCert , pemKey [ ] byte , err error ) {
if m . appleSCEP == nil {
pair := x509KeyPairConfig {
m . AppleSCEPCert ,
[ ] byte ( m . AppleSCEPCertBytes ) ,
m . AppleSCEPKey ,
[ ] byte ( m . AppleSCEPKeyBytes ) ,
}
2023-02-08 14:49:42 +00:00
cert , err := pair . Parse ( true )
2022-12-05 15:22:56 +00:00
if err != nil {
return nil , nil , nil , fmt . Errorf ( "Apple MDM SCEP configuration: %w" , err )
}
m . appleSCEP = cert
m . appleSCEPPEMCert = pair . certBytes
m . appleSCEPPEMKey = pair . keyBytes
}
return m . appleSCEP , m . appleSCEPPEMCert , m . appleSCEPPEMKey , nil
}
2022-12-06 20:50:56 +00:00
// AppleBM returns the parsed, validated and decrypted server token for Apple
// Business Manager. It also parses and validates the Apple BM certificate and
// private key in the process, in order to decrypt the token.
func ( m * MDMConfig ) AppleBM ( ) ( tok * nanodep_client . OAuth1Tokens , err error ) {
if m . appleBMToken == nil {
pair := x509KeyPairConfig {
m . AppleBMCert ,
[ ] byte ( m . AppleBMCertBytes ) ,
m . AppleBMKey ,
[ ] byte ( m . AppleBMKeyBytes ) ,
}
cert , err := pair . Parse ( true )
if err != nil {
return nil , fmt . Errorf ( "Apple BM configuration: %w" , err )
}
encToken , err := m . loadAppleBMEncryptedToken ( )
if err != nil {
return nil , fmt . Errorf ( "Apple BM configuration: %w" , err )
}
bmKey , err := tokenpki . RSAKeyFromPEM ( pair . keyBytes )
if err != nil {
return nil , fmt . Errorf ( "Apple BM configuration: parse private key: %w" , err )
}
token , err := tokenpki . DecryptTokenJSON ( encToken , cert . Leaf , bmKey )
if err != nil {
return nil , fmt . Errorf ( "Apple BM configuration: decrypt token: %w" , err )
}
var jsonTok nanodep_client . OAuth1Tokens
if err := json . Unmarshal ( token , & jsonTok ) ; err != nil {
return nil , fmt . Errorf ( "Apple BM configuration: unmarshal JSON token: %w" , err )
}
if jsonTok . AccessTokenExpiry . Before ( time . Now ( ) ) {
return nil , errors . New ( "Apple BM configuration: token is expired" )
}
m . appleBMToken = & jsonTok
}
return m . appleBMToken , nil
}
func ( m * MDMConfig ) loadAppleBMEncryptedToken ( ) ( [ ] byte , error ) {
if m . AppleBMServerToken == "" && m . AppleBMServerTokenBytes == "" {
return nil , errors . New ( "no token provided" )
}
if m . AppleBMServerToken != "" && m . AppleBMServerTokenBytes != "" {
return nil , errors . New ( "only one of the token path or bytes must be provided" )
}
tokBytes := [ ] byte ( m . AppleBMServerTokenBytes )
if m . AppleBMServerTokenBytes == "" {
b , err := os . ReadFile ( m . AppleBMServerToken )
if err != nil {
return nil , fmt . Errorf ( "reading token file: %w" , err )
}
tokBytes = b
}
return tokBytes , nil
}
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 )
2022-07-20 16:10:03 +00:00
man . addConfigString ( prefix + ".sql_mode" , "" , "MySQL sql_mode" + usageSuffix )
2021-09-01 19:50:52 +00:00
}
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)" )
2022-12-14 13:53:38 +00:00
man . addConfigString ( "redis.username" , "" ,
"Redis server username" )
2017-01-31 18:06:30 +00:00
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 ,
2022-07-12 21:21:15 +00:00
"Controls whether HTTP keep-alives are enabled." )
man . addConfigBool ( "server.sandbox_enabled" , false ,
"When enabled, Fleet limits some features for the Sandbox" )
2023-03-28 05:23:29 +00:00
man . addConfigBool ( "server.websockets_allow_unsafe_origin" , false , "Disable checking the origin header on websocket connections, this is sometimes necessary when proxies rewrite origin headers between the client and the Fleet webserver" )
2016-09-12 17:26:56 +00:00
2022-07-27 19:47:39 +00:00
// Hide the sandbox flag as we don't want it to be discoverable for users for now
sandboxFlag := man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( "server.sandbox_enabled" ) )
if sandboxFlag != nil {
sandboxFlag . Hidden = true
}
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
2022-12-23 22:04:13 +00:00
// Activities
man . addConfigBool ( "activity.enable_audit_log" , false ,
"Enable audit logs" )
man . addConfigString ( "activity.audit_log_plugin" , "filesystem" ,
"Log plugin to use for audit logs" )
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
2023-04-06 18:21:07 +00:00
// Email
man . addConfigString ( "email.backend" , "" , "Provide the email backend type, acceptable values are currently \"ses\" and \"default\" or empty string which will default to SMTP" )
// SES
man . addConfigString ( "ses.region" , "" , "AWS Region to use" )
man . addConfigString ( "ses.endpoint_url" , "" , "AWS Service Endpoint to use (leave empty for default service endpoints)" )
man . addConfigString ( "ses.access_key_id" , "" , "Access Key ID for AWS authentication" )
man . addConfigString ( "ses.secret_access_key" , "" , "Secret Access Key for AWS authentication" )
man . addConfigString ( "ses.sts_assume_role_arn" , "" , "ARN of role to assume for AWS" )
man . addConfigString ( "ses.source_arn" , "" , "ARN of the identity that is associated with the sending authorization policy that permits you to send for the email address specified in the Source parameter" )
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" )
2022-12-23 22:04:13 +00:00
man . addConfigString ( "firehose.audit_stream" , "" ,
"Firehose stream name for audit logs" )
2019-04-08 18:47:15 +00:00
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" )
2022-12-23 22:04:13 +00:00
man . addConfigString ( "kinesis.audit_stream" , "" ,
"Kinesis stream name for audit logs" )
2020-08-19 21:56:44 +00:00
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" )
2022-12-23 22:04:13 +00:00
man . addConfigString ( "lambda.audit_function" , "" ,
"Lambda function name for audit logs" )
2021-02-24 18:02:26 +00:00
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" )
2022-12-23 22:04:13 +00:00
man . addConfigString ( "pubsub.audit_topic" , "" , "PubSub topic for audit 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" )
2022-12-23 22:04:13 +00:00
man . addConfigString ( "filesystem.audit_log_file" , filepath . Join ( os . TempDir ( ) , "audit" ) ,
"Log file path to use for audit logs" )
2019-04-08 18:47:15 +00:00
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" )
2023-02-24 12:44:56 +00:00
man . addConfigInt ( "filesystem.max_size" , 500 , "Maximum size in megabytes log files will grow until rotated (only valid if enable_log_rotation is true) default is 500MB" )
man . addConfigInt ( "filesystem.max_age" , 28 , "Maximum number of days to retain old log files based on the timestamp encoded in their filename. Setting to zero wil retain old log files indefinitely (only valid if enable_log_rotation is true) default is 28 days" )
man . addConfigInt ( "filesystem.max_backups" , 3 , "Maximum number of old log files to retain. Setting to zero will retain all old log files (only valid if enable_log_rotation is true) default is 3" )
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" )
2022-12-23 22:04:13 +00:00
man . addConfigString ( "kafkarest.audit_topic" , "" , "Kafka REST topic for audit logs" )
2021-10-28 04:51:17 +00:00
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" , "" ,
2022-09-01 16:02:07 +00:00
"URL from which to get the latest CPE database. If empty, it will be downloaded from the latest release available at https://github.com/fleetdm/nvd/releases." )
man . addConfigString ( "vulnerabilities.cpe_translations_url" , "" ,
"URL from which to get the latest CPE translations. If empty, it will be downloaded from the latest release available at https://github.com/fleetdm/nvd/releases." )
2021-08-18 20:25:14 +00:00
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." )
2023-02-17 15:00:57 +00:00
man . addConfigBool ( "vulnerabilities.disable_schedule" , false ,
"Set this to true when the vulnerability processing job is scheduled by an external mechanism" )
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'." )
2022-08-26 18:55:03 +00:00
man . addConfigBool (
"vulnerabilities.disable_win_os_vulnerabilities" ,
false ,
"Don't sync installed Windows updates nor perform Windows OS vulnerability processing." ,
)
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" )
2023-03-23 22:00:11 +00:00
man . addConfigBool ( "prometheus.basic_auth.disable" , false , "Disable HTTP Basic Auth for Prometheus" )
2022-07-12 22:12:10 +00:00
// Packaging config
man . addConfigString ( "packaging.global_enroll_secret" , "" , "Enroll secret to be used for the global domain (instead of randomly generating one)" )
2022-07-13 12:34:25 +00:00
man . addConfigString ( "packaging.s3.bucket" , "" , "Bucket where to retrieve installers" )
man . addConfigString ( "packaging.s3.prefix" , "" , "Prefix under which installers are stored" )
man . addConfigString ( "packaging.s3.region" , "" , "AWS Region (if blank region is derived)" )
man . addConfigString ( "packaging.s3.endpoint_url" , "" , "AWS Service Endpoint to use (leave blank for default service endpoints)" )
man . addConfigString ( "packaging.s3.access_key_id" , "" , "Access Key ID for AWS authentication" )
man . addConfigString ( "packaging.s3.secret_access_key" , "" , "Secret Access Key for AWS authentication" )
man . addConfigString ( "packaging.s3.sts_assume_role_arn" , "" , "ARN of role to assume for AWS" )
man . addConfigBool ( "packaging.s3.disable_ssl" , false , "Disable SSL (typically for local testing)" )
man . addConfigBool ( "packaging.s3.force_s3_path_style" , false , "Set this to true to force path-style addressing, i.e., `http://s3.amazonaws.com/BUCKET/KEY`" )
2022-10-05 22:53:54 +00:00
2022-12-05 15:22:56 +00:00
// MDM config
man . addConfigString ( "mdm.apple_apns_cert" , "" , "Apple APNs PEM-encoded certificate path" )
man . addConfigString ( "mdm.apple_apns_cert_bytes" , "" , "Apple APNs PEM-encoded certificate bytes" )
man . addConfigString ( "mdm.apple_apns_key" , "" , "Apple APNs PEM-encoded private key path" )
man . addConfigString ( "mdm.apple_apns_key_bytes" , "" , "Apple APNs PEM-encoded private key bytes" )
man . addConfigString ( "mdm.apple_scep_cert" , "" , "Apple SCEP PEM-encoded certificate path" )
man . addConfigString ( "mdm.apple_scep_cert_bytes" , "" , "Apple SCEP PEM-encoded certificate bytes" )
man . addConfigString ( "mdm.apple_scep_key" , "" , "Apple SCEP PEM-encoded private key path" )
man . addConfigString ( "mdm.apple_scep_key_bytes" , "" , "Apple SCEP PEM-encoded private key bytes" )
2022-12-06 20:50:56 +00:00
man . addConfigString ( "mdm.apple_bm_server_token" , "" , "Apple Business Manager encrypted server token path (.p7m file)" )
man . addConfigString ( "mdm.apple_bm_server_token_bytes" , "" , "Apple Business Manager encrypted server token bytes" )
man . addConfigString ( "mdm.apple_bm_cert" , "" , "Apple Business Manager PEM-encoded certificate path" )
man . addConfigString ( "mdm.apple_bm_cert_bytes" , "" , "Apple Business Manager PEM-encoded certificate bytes" )
man . addConfigString ( "mdm.apple_bm_key" , "" , "Apple Business Manager PEM-encoded private key path" )
man . addConfigString ( "mdm.apple_bm_key_bytes" , "" , "Apple Business Manager PEM-encoded private key bytes" )
2023-03-23 10:30:28 +00:00
man . addConfigBool ( "mdm.apple_enable" , false , "Enable MDM Apple functionality" )
man . addConfigInt ( "mdm.apple_scep_signer_validity_days" , 365 , "Days signed client certificates will be valid" )
man . addConfigInt ( "mdm.apple_scep_signer_allow_renewal_days" , 14 , "Allowable renewal days for client certificates" )
man . addConfigString ( "mdm.apple_scep_challenge" , "" , "SCEP static challenge for enrollment" )
man . addConfigDuration ( "mdm.apple_dep_sync_periodicity" , 1 * time . Minute , "How much time to wait for DEP profile assignment" )
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-07-20 16:10:03 +00:00
SQLMode : man . getConfigString ( prefix + ".sql_mode" ) ,
2021-09-01 19:50:52 +00:00
}
}
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" ) ,
2022-12-14 13:53:38 +00:00
Username : man . getConfigString ( "redis.username" ) ,
2021-09-15 12:50:32 +00:00
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 {
2023-03-28 05:23:29 +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 ( ) ,
URLPrefix : man . getConfigString ( "server.url_prefix" ) ,
Keepalive : man . getConfigBool ( "server.keepalive" ) ,
SandboxEnabled : man . getConfigBool ( "server.sandbox_enabled" ) ,
WebsocketsAllowUnsafeOrigin : man . getConfigBool ( "server.websockets_allow_unsafe_origin" ) ,
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 {
2022-12-23 22:04:13 +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 is deprecated. FilesystemConfig.StatusLogFile is used instead.
StatusLogFile : man . getConfigString ( "osquery.status_log_file" ) ,
// ResultLogFile is deprecated. FilesystemConfig.ResultLogFile is used instead.
2021-11-01 18:13:16 +00:00
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
} ,
2022-12-23 22:04:13 +00:00
Activity : ActivityConfig {
EnableAuditLog : man . getConfigBool ( "activity.enable_audit_log" ) ,
AuditLogPlugin : man . getConfigString ( "activity.audit_log_plugin" ) ,
} ,
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" ) ,
2022-12-23 22:04:13 +00:00
AuditStream : man . getConfigString ( "firehose.audit_stream" ) ,
2020-08-19 21:56:44 +00:00
} ,
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" ) ,
2022-12-23 22:04:13 +00:00
AuditStream : man . getConfigString ( "kinesis.audit_stream" ) ,
2020-08-19 21:56:44 +00:00
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" ) ,
2022-12-23 22:04:13 +00:00
AuditFunction : man . getConfigString ( "lambda.audit_function" ) ,
2021-02-24 18:02:26 +00:00
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
} ,
2023-04-06 18:21:07 +00:00
Email : EmailConfig {
EmailBackend : man . getConfigString ( "email.backend" ) ,
} ,
SES : SESConfig {
Region : man . getConfigString ( "ses.region" ) ,
EndpointURL : man . getConfigString ( "ses.endpoint_url" ) ,
AccessKeyID : man . getConfigString ( "ses.access_key_id" ) ,
SecretAccessKey : man . getConfigString ( "ses.secret_access_key" ) ,
StsAssumeRoleArn : man . getConfigString ( "ses.sts_assume_role_arn" ) ,
SourceArn : man . getConfigString ( "ses.source_arn" ) ,
} ,
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" ) ,
2022-12-23 22:04:13 +00:00
AuditTopic : man . getConfigString ( "pubsub.audit_topic" ) ,
2021-05-08 19:29:52 +00:00
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" ) ,
2022-12-23 22:04:13 +00:00
AuditLogFile : man . getConfigString ( "filesystem.audit_log_file" ) ,
2020-09-09 20:33:32 +00:00
EnableLogRotation : man . getConfigBool ( "filesystem.enable_log_rotation" ) ,
EnableLogCompression : man . getConfigBool ( "filesystem.enable_log_compression" ) ,
2023-02-24 12:44:56 +00:00
MaxSize : man . getConfigInt ( "filesystem.max_size" ) ,
MaxAge : man . getConfigInt ( "filesystem.max_age" ) ,
MaxBackups : man . getConfigInt ( "filesystem.max_backups" ) ,
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" ) ,
2022-12-23 22:04:13 +00:00
AuditTopic : man . getConfigString ( "kafkarest.audit_topic" ) ,
2022-03-09 22:22:29 +00:00
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-08-26 18:55:03 +00:00
DatabasesPath : man . getConfigString ( "vulnerabilities.databases_path" ) ,
Periodicity : man . getConfigDuration ( "vulnerabilities.periodicity" ) ,
CPEDatabaseURL : man . getConfigString ( "vulnerabilities.cpe_database_url" ) ,
2022-09-01 16:02:07 +00:00
CPETranslationsURL : man . getConfigString ( "vulnerabilities.cpe_translations_url" ) ,
2022-08-26 18:55:03 +00:00
CVEFeedPrefixURL : man . getConfigString ( "vulnerabilities.cve_feed_prefix_url" ) ,
CurrentInstanceChecks : man . getConfigString ( "vulnerabilities.current_instance_checks" ) ,
2023-02-17 15:00:57 +00:00
DisableSchedule : man . getConfigBool ( "vulnerabilities.disable_schedule" ) ,
2022-08-26 18:55:03 +00:00
DisableDataSync : man . getConfigBool ( "vulnerabilities.disable_data_sync" ) ,
RecentVulnerabilityMaxAge : man . getConfigDuration ( "vulnerabilities.recent_vulnerability_max_age" ) ,
DisableWinOSVulnerabilities : man . getConfigBool ( "vulnerabilities.disable_win_os_vulnerabilities" ) ,
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" ) ,
2023-03-23 22:00:11 +00:00
Disable : man . getConfigBool ( "prometheus.basic_auth.disable" ) ,
2022-04-07 12:40:53 +00:00
} ,
} ,
2022-07-12 22:12:10 +00:00
Packaging : PackagingConfig {
GlobalEnrollSecret : man . getConfigString ( "packaging.global_enroll_secret" ) ,
2022-07-18 16:44:30 +00:00
S3 : S3Config {
Bucket : man . getConfigString ( "packaging.s3.bucket" ) ,
Prefix : man . getConfigString ( "packaging.s3.prefix" ) ,
Region : man . getConfigString ( "packaging.s3.region" ) ,
EndpointURL : man . getConfigString ( "packaging.s3.endpoint_url" ) ,
AccessKeyID : man . getConfigString ( "packaging.s3.access_key_id" ) ,
SecretAccessKey : man . getConfigString ( "packaging.s3.secret_access_key" ) ,
StsAssumeRoleArn : man . getConfigString ( "packaging.s3.sts_assume_role_arn" ) ,
DisableSSL : man . getConfigBool ( "packaging.s3.disable_ssl" ) ,
ForceS3PathStyle : man . getConfigBool ( "packaging.s3.force_s3_path_style" ) ,
} ,
2022-07-12 22:12:10 +00:00
} ,
2022-12-05 15:22:56 +00:00
MDM : MDMConfig {
2023-03-23 10:30:28 +00:00
AppleAPNsCert : man . getConfigString ( "mdm.apple_apns_cert" ) ,
AppleAPNsCertBytes : man . getConfigString ( "mdm.apple_apns_cert_bytes" ) ,
AppleAPNsKey : man . getConfigString ( "mdm.apple_apns_key" ) ,
AppleAPNsKeyBytes : man . getConfigString ( "mdm.apple_apns_key_bytes" ) ,
AppleSCEPCert : man . getConfigString ( "mdm.apple_scep_cert" ) ,
AppleSCEPCertBytes : man . getConfigString ( "mdm.apple_scep_cert_bytes" ) ,
AppleSCEPKey : man . getConfigString ( "mdm.apple_scep_key" ) ,
AppleSCEPKeyBytes : man . getConfigString ( "mdm.apple_scep_key_bytes" ) ,
AppleBMServerToken : man . getConfigString ( "mdm.apple_bm_server_token" ) ,
AppleBMServerTokenBytes : man . getConfigString ( "mdm.apple_bm_server_token_bytes" ) ,
AppleBMCert : man . getConfigString ( "mdm.apple_bm_cert" ) ,
AppleBMCertBytes : man . getConfigString ( "mdm.apple_bm_cert_bytes" ) ,
AppleBMKey : man . getConfigString ( "mdm.apple_bm_key" ) ,
AppleBMKeyBytes : man . getConfigString ( "mdm.apple_bm_key_bytes" ) ,
AppleEnable : man . getConfigBool ( "mdm.apple_enable" ) ,
AppleSCEPSignerValidityDays : man . getConfigInt ( "mdm.apple_scep_signer_validity_days" ) ,
AppleSCEPSignerAllowRenewalDays : man . getConfigInt ( "mdm.apple_scep_signer_allow_renewal_days" ) ,
AppleSCEPChallenge : man . getConfigString ( "mdm.apple_scep_challenge" ) ,
AppleDEPSyncPeriodicity : man . getConfigDuration ( "mdm.apple_dep_sync_periodicity" ) ,
2022-12-05 15:22:56 +00:00
} ,
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 ) )
2022-12-05 22:50:49 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) ) //nolint:errcheck
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) ) //nolint:errcheck
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 ) )
2022-12-05 22:50:49 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) ) //nolint:errcheck
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) ) //nolint:errcheck
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 ) )
2022-12-05 22:50:49 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) ) //nolint:errcheck
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) ) //nolint:errcheck
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 ) )
2022-12-05 22:50:49 +00:00
man . viper . BindPFlag ( key , man . command . PersistentFlags ( ) . Lookup ( flagNameFromConfigKey ( key ) ) ) //nolint:errcheck
man . viper . BindEnv ( key , envNameFromConfigKey ( key ) ) //nolint:errcheck
2016-09-14 16:11:06 +00:00
// 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
} ,
2022-12-23 22:04:13 +00:00
Activity : ActivityConfig {
EnableAuditLog : true ,
AuditLogPlugin : "filesystem" ,
} ,
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 ,
2022-12-23 22:04:13 +00:00
AuditLogFile : testLogFile ,
2023-02-24 12:44:56 +00:00
MaxSize : 500 ,
2019-04-08 18:47:15 +00:00
} ,
2016-09-14 16:11:06 +00:00
}
}
2023-01-16 15:22:12 +00:00
// SetTestMDMConfig modifies the provided cfg so that MDM is enabled and
// configured properly. The provided certificate and private key are used for
// all required pairs and the Apple BM token is used as-is, instead of
// decrypting the encrypted value that is usually provided via the fleet
// server's flags.
func SetTestMDMConfig ( t testing . TB , cfg * FleetConfig , cert , key [ ] byte , appleBMToken * nanodep_client . OAuth1Tokens ) {
tlsCert , err := tls . X509KeyPair ( cert , key )
if err != nil {
t . Fatal ( err )
}
parsed , err := x509 . ParseCertificate ( tlsCert . Certificate [ 0 ] )
if err != nil {
t . Fatal ( err )
}
tlsCert . Leaf = parsed
cfg . MDM . AppleAPNsCertBytes = string ( cert )
cfg . MDM . AppleAPNsKeyBytes = string ( key )
cfg . MDM . AppleSCEPCertBytes = string ( cert )
cfg . MDM . AppleSCEPKeyBytes = string ( key )
cfg . MDM . AppleBMCertBytes = string ( cert )
cfg . MDM . AppleBMKeyBytes = string ( key )
cfg . MDM . AppleBMServerTokenBytes = "whatever-will-not-be-accessed"
cfg . MDM . appleAPNs = & tlsCert
cfg . MDM . appleAPNsPEMCert = cert
cfg . MDM . appleAPNsPEMKey = key
cfg . MDM . appleSCEP = & tlsCert
cfg . MDM . appleSCEPPEMCert = cert
cfg . MDM . appleSCEPPEMKey = key
cfg . MDM . appleBMToken = appleBMToken
2023-03-23 10:30:28 +00:00
cfg . MDM . AppleSCEPSignerValidityDays = 365
cfg . MDM . AppleSCEPChallenge = "testchallenge"
2023-01-16 15:22:12 +00:00
}
2023-06-14 12:44:42 +00:00
2023-06-22 20:31:17 +00:00
// Undocumented feature flag for Microsoft MDM, used to determine if the Windows
2023-06-14 12:44:42 +00:00
// MDM feature is visible in the UI and can be enabled. More details here:
// https://github.com/fleetdm/fleet/issues/12257
//
2023-06-22 20:31:17 +00:00
// TODO: remove this flag once the Microsoft MDM feature is ready for
2023-06-14 12:44:42 +00:00
// release.
func IsMDMFeatureFlagEnabled ( ) bool {
return os . Getenv ( "FLEET_DEV_MDM_ENABLED" ) == "1"
}