Package / arch (push) Canceled after 0s
Package / user (push) Canceled after 0s
Package / deb (push) Canceled after 0s
Package / freebsd (push) Canceled after 0s
Package / image (push) Canceled after 0s
Test / test (push) Canceled after 0s
Test / e2e (push) Canceled after 0s
lwconf: sparse stages, every problem of a part, pastes read by form
372 lines
26 KiB
Go
372 lines
26 KiB
Go
// Package config is lw's configuration: the settings and pipeline tables, the
|
|
// plugin catalogue whose option structs' tags are the schema, the pipeline
|
|
// flags, LOGWISP_ variables and presets that build pipelines, and the rules
|
|
// Decode and ValidateConfig apply. Load's Manager merges the file, environment
|
|
// and command line, and rereads the file on reload.
|
|
package config
|
|
|
|
// --- LogWisp Configuration Options ---
|
|
|
|
// Config is the top-level configuration structure for the LogWisp application
|
|
type Config struct {
|
|
Quiet bool `toml:"quiet" help:"silence lw's own log and notices; pipeline output still flows"`
|
|
|
|
// "auto" is a terminal with NO_COLOR unset and TERM not dumb
|
|
Color string `toml:"color" lw:"enum=auto|always|never" help:"level names in color on console sinks without their own"`
|
|
|
|
StatusReporter bool `toml:"status_reporter" help:"log pipeline statistics every 30 s at debug; without a file, off"`
|
|
ConfigAutoReload bool `toml:"auto_reload" help:"reload when the file changes"`
|
|
|
|
// Selected file path is runtime metadata, never a configurable override.
|
|
ConfigFile string `toml:"-"`
|
|
|
|
Logging *LogConfig `toml:"logging"`
|
|
Pipelines []PipelineConfig `toml:"pipelines"`
|
|
}
|
|
|
|
// --- Logging Options ---
|
|
|
|
// LogConfig represents the logging configuration for the LogWisp application itself
|
|
type LogConfig struct {
|
|
Output string `toml:"output" lw:"enum=file|stdout|stderr|split|all|none" help:"where lw's own log goes; split: warn and error to stderr"`
|
|
Level string `toml:"level" lw:"enum=debug|info|warn|error" help:"lowest level logged; without a file, warn"`
|
|
Format string `toml:"format" lw:"enum=raw|txt|json,zero=the log default" help:"format of lw's own log"`
|
|
Sanitization string `toml:"sanitization" lw:"enum=raw|json|txt|shell,zero=the log default" help:"how the console log escapes control characters"`
|
|
|
|
// File output settings (when Output includes "file" or "all")
|
|
File *LogFileConfig `toml:"file"`
|
|
|
|
// Accepted for older files: logging.output chooses the console
|
|
Console *LogConsoleConfig `toml:"console"`
|
|
}
|
|
|
|
// LogFileConfig defines settings for file-based application logging
|
|
type LogFileConfig struct {
|
|
Directory string `toml:"directory" lw:"hint=dir" help:"where file and all write; the limits below delete old .log files in it"`
|
|
Name string `toml:"name" help:"base name of the files"`
|
|
MaxSizeMB int64 `toml:"max_size_mb" help:"size at which a file rotates"`
|
|
MaxTotalSizeMB int64 `toml:"max_total_size_mb" help:"size of all .log files there, beyond which the oldest go"`
|
|
RetentionHours float64 `toml:"retention_hours" help:"hours a .log file is kept; 0 keeps them"`
|
|
}
|
|
|
|
// LogConsoleConfig is logging.console, whose target has no effect:
|
|
// logging.output chooses the console stream
|
|
type LogConsoleConfig struct {
|
|
Target string `toml:"target" lw:"enum=stdout|stderr|split" help:"accepted without effect: logging.output chooses the console"`
|
|
}
|
|
|
|
// --- Pipeline ---
|
|
|
|
// PipelineConfig defines a complete data flow from sources to sinks
|
|
type PipelineConfig struct {
|
|
Name string `toml:"name"`
|
|
Flow *FlowConfig `toml:"flow"`
|
|
|
|
PluginSources []PluginSourceConfig `toml:"plugin_sources,omitempty"`
|
|
PluginSinks []PluginSinkConfig `toml:"plugin_sinks,omitempty"`
|
|
}
|
|
|
|
// --- Flow ---
|
|
|
|
// FlowConfig holds the stages between sources and sinks, in the order entries
|
|
// pass them; the heartbeat runs beside them. Help is each stage's summary.
|
|
type FlowConfig struct {
|
|
RateLimit *RateLimitConfig `toml:"rate_limit" help:"Drop entries beyond a rate, and those over a size"`
|
|
Filters []FilterConfig `toml:"filters,omitempty" help:"Pass or drop entries by RE2 patterns, in order"`
|
|
Format *FormatConfig `toml:"format" help:"How entries are written: raw, txt or json"`
|
|
Heartbeat *HeartbeatConfig `toml:"heartbeat" help:"A keep-alive entry on a timer, beside the entries"`
|
|
}
|
|
|
|
// --- Flow stages ---
|
|
//
|
|
// A stage key's zero is its unset, the default or what zero means there, so
|
|
// a stage is written with the keys set alone.
|
|
|
|
// HeartbeatConfig defines settings for periodic keep-alive or status messages
|
|
type HeartbeatConfig struct {
|
|
Enabled bool `toml:"enabled,omitempty" help:"send heartbeats; false keeps these settings and sends none"`
|
|
IntervalMS int64 `toml:"interval_ms,omitempty" default:"1000" lw:"min=100" help:"milliseconds between heartbeats"`
|
|
IncludeTimestamp bool `toml:"include_timestamp,omitempty" help:"stamp each heartbeat with its time"`
|
|
IncludeStats bool `toml:"include_stats,omitempty" help:"add type, beat_count and, from the second beat, the measured interval_ms"`
|
|
Format string `toml:"format,omitempty" default:"txt" lw:"enum=txt|json|raw" help:"kept for older files; heartbeats are written in the flow's format"`
|
|
}
|
|
|
|
// FormatConfig is how a pipeline writes its entries
|
|
type FormatConfig struct {
|
|
Type string `toml:"type,omitempty" default:"raw" lw:"enum=raw|txt|json" help:"raw writes each message as it came, txt a line with time and level, json one object an entry"`
|
|
Flags int64 `toml:"flags,omitempty" lw:"zero=by type" help:"for experts, a sum of bits over the type's choice: 1 writes messages verbatim, 16 drops the time, 32 the level"`
|
|
TimestampFormat string `toml:"timestamp_format,omitempty" lw:"zero=RFC 3339 with nanoseconds" help:"timestamp layout: the reference time 2006-01-02 15:04:05 written as timestamps should look, such as 02 Jan 15:04"`
|
|
SanitizerPolicy string `toml:"sanitizer_policy,omitempty" lw:"enum=raw|json|txt|shell,zero=by type" help:"how control characters are escaped"`
|
|
}
|
|
|
|
// RateLimitPolicy defines the action to take when a rate limit is exceeded
|
|
type RateLimitPolicy int
|
|
|
|
const (
|
|
// PolicyPass allows all logs through, effectively disabling the limiter
|
|
PolicyPass RateLimitPolicy = iota
|
|
// PolicyDrop drops logs that exceed the rate limit
|
|
PolicyDrop
|
|
)
|
|
|
|
// RateLimitConfig defines the configuration for pipeline-level rate limiting
|
|
type RateLimitConfig struct {
|
|
EntriesPerSecond float64 `toml:"entries_per_second,omitempty" lw:"min=0,zero=off" help:"entries a second let through; unset, the stage limits nothing, sizes included"`
|
|
BurstEntries float64 `toml:"burst_entries,omitempty" lw:"min=0,zero=one second's worth" help:"entries that may pass in a burst before entries_per_second holds them back"`
|
|
Policy string `toml:"policy,omitempty" default:"pass" lw:"enum=pass|drop" help:"drop enforces entries_per_second and max_entry_size_bytes; pass lets every entry through"`
|
|
MaxEntrySizeBytes int64 `toml:"max_entry_size_bytes,omitempty" lw:"min=0,zero=unlimited" help:"drop larger entries; needs entries_per_second and policy drop"`
|
|
}
|
|
|
|
// FilterType represents the filter's behavior (include or exclude)
|
|
type FilterType string
|
|
|
|
const (
|
|
// FilterTypeInclude specifies that only matching logs will pass
|
|
FilterTypeInclude FilterType = "include"
|
|
// FilterTypeExclude specifies that matching logs will be dropped
|
|
FilterTypeExclude FilterType = "exclude"
|
|
)
|
|
|
|
// FilterLogic represents how multiple filter patterns are combined
|
|
type FilterLogic string
|
|
|
|
const (
|
|
// FilterLogicOr specifies that a match on any pattern is sufficient
|
|
FilterLogicOr FilterLogic = "or"
|
|
// FilterLogicAnd specifies that all patterns must match
|
|
FilterLogicAnd FilterLogic = "and"
|
|
)
|
|
|
|
// FilterConfig represents the configuration for a single filter
|
|
type FilterConfig struct {
|
|
Type FilterType `toml:"type,omitempty" default:"include" lw:"enum=include|exclude" help:"pass only matching entries, or drop them"`
|
|
Logic FilterLogic `toml:"logic,omitempty" default:"or" lw:"enum=or|and" help:"match any pattern, or all"`
|
|
Patterns []string `toml:"patterns,omitempty" lw:"required,hint=regex" help:"RE2 patterns"`
|
|
}
|
|
|
|
// --- Sources ---
|
|
|
|
// PluginSourceConfig represents a source plugin instance configuration
|
|
type PluginSourceConfig struct {
|
|
ID string `toml:"id"`
|
|
Type string `toml:"type"`
|
|
Config map[string]any `toml:"config"`
|
|
ConfigFile string `toml:"config_file,omitempty"` // accepted, never read
|
|
}
|
|
|
|
// NullSourceOptions defines settings for a null source (no configuration needed)
|
|
type NullSourceOptions struct{}
|
|
|
|
// RandomSourceOptions defines settings for a random log generator source
|
|
type RandomSourceOptions struct {
|
|
IntervalMS int64 `toml:"interval_ms" default:"500" lw:"min=1" help:"milliseconds between entries"`
|
|
JitterMS int64 `toml:"jitter_ms" lw:"min=0,zero=none" help:"milliseconds the interval varies by, half each way; at most the interval"`
|
|
Format string `toml:"format" default:"txt" lw:"enum=raw|txt|json" help:"entry format"`
|
|
Length int64 `toml:"length" default:"20" lw:"min=1" help:"bytes of random text"`
|
|
Special bool `toml:"special" help:"mix in control and non-ASCII bytes"`
|
|
}
|
|
|
|
// FileSourceOptions defines settings for a file-based source
|
|
type FileSourceOptions struct {
|
|
Directory string `toml:"directory" lw:"required,hint=dir" help:"directory whose files are followed"`
|
|
Pattern string `toml:"pattern" default:"*" lw:"hint=glob" help:"glob the file names match"`
|
|
CheckIntervalMS int64 `toml:"check_interval_ms" default:"100" lw:"min=10" help:"milliseconds between scans for files"`
|
|
Raw bool `toml:"raw" help:"keep the whole line as the message, never parse it"`
|
|
From string `toml:"from" default:"end" lw:"enum=start|end" help:"where reading a newly found file starts"`
|
|
}
|
|
|
|
// ConsoleSourceOptions defines settings for a stdin-based source
|
|
type ConsoleSourceOptions struct {
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
}
|
|
|
|
// TCPChainSourceOptions defines settings for a stdlib TCP listener ingesting
|
|
// NDJSON entries from upstream logwisp tcp_chain sinks
|
|
type TCPChainSourceOptions struct {
|
|
TLS *TLSOptions `toml:"tls" help:"TLS for the connections it accepts"`
|
|
Host string `toml:"host" default:"0.0.0.0" lw:"hint=host" help:"address to listen on, one family per listener: 0.0.0.0 every IPv4 interface, :: every IPv6 interface, 127.0.0.1 or ::1 this machine only"`
|
|
Port int64 `toml:"port" lw:"required,min=1,max=65535" help:"port to listen on"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
MaxConnections int64 `toml:"max_connections" lw:"min=0,zero=unlimited" help:"connections at once"`
|
|
ReadTimeoutMS int64 `toml:"read_timeout_ms" lw:"min=0,zero=none" help:"milliseconds a connection may idle"`
|
|
HelloTimeoutMS int64 `toml:"hello_timeout_ms" default:"10000" lw:"min=1" help:"milliseconds for a peer's hello"`
|
|
TrustNode bool `toml:"trust_node" default:"true" help:"keep the node label a peer declares; off, the label is its address"`
|
|
Auth *AuthOptions `toml:"auth" help:"how peers authenticate: mtls by client certificate, scram by user and password"`
|
|
ACL *ACLOptions `toml:"acl" help:"client addresses admitted or refused, and per-client limits"`
|
|
}
|
|
|
|
// HTTPChainSourceOptions defines settings for a stdlib HTTP listener ingesting
|
|
// NDJSON batches from upstream logwisp http_chain sinks
|
|
type HTTPChainSourceOptions struct {
|
|
TLS *TLSOptions `toml:"tls" help:"TLS for the connections it accepts"`
|
|
Host string `toml:"host" default:"0.0.0.0" lw:"hint=host" help:"address to listen on, one family per listener: 0.0.0.0 every IPv4 interface, :: every IPv6 interface, 127.0.0.1 or ::1 this machine only"`
|
|
Port int64 `toml:"port" lw:"required,min=1,max=65535" help:"port to listen on"`
|
|
IngestPath string `toml:"ingest_path" default:"/ingest" lw:"hint=path" help:"path batches are posted to"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
MaxBodyBytes int64 `toml:"max_body_bytes" default:"8388608" lw:"min=1" help:"largest batch accepted"`
|
|
ReadTimeoutMS int64 `toml:"read_timeout_ms" default:"30000" lw:"min=1" help:"milliseconds to read a request"`
|
|
TrustNode bool `toml:"trust_node" default:"true" help:"keep the node label a peer declares; off, the label is its address"`
|
|
Auth *AuthOptions `toml:"auth" help:"how peers authenticate: mtls by client certificate, scram by user and password"`
|
|
ACL *ACLOptions `toml:"acl" help:"client addresses admitted or refused, and per-client limits"`
|
|
}
|
|
|
|
// --- Sinks ---
|
|
|
|
// PluginSinkConfig represents a sink plugin instance configuration
|
|
type PluginSinkConfig struct {
|
|
ID string `toml:"id"`
|
|
Type string `toml:"type"`
|
|
Config map[string]any `toml:"config"`
|
|
ConfigFile string `toml:"config_file,omitempty"` // accepted, never read
|
|
}
|
|
|
|
// NullSinkOptions defines settings for a null sink (no configuration needed)
|
|
type NullSinkOptions struct{}
|
|
|
|
// ConsoleSinkOptions defines settings for a console-based sink
|
|
type ConsoleSinkOptions struct {
|
|
Target string `toml:"target" default:"stdout" lw:"enum=stdout|stderr" help:"stream written to"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
Escape string `toml:"escape" default:"auto" lw:"enum=auto|always|never" help:"write control characters as <hex>; auto on a terminal"`
|
|
Color string `toml:"color" default:"auto" lw:"enum=auto|always|never" help:"level names in color; unset, the top-level color"`
|
|
}
|
|
|
|
// FileSinkOptions defines settings for a file-based sink
|
|
type FileSinkOptions struct {
|
|
Directory string `toml:"directory" lw:"required,hint=dir" help:"directory written to"`
|
|
Name string `toml:"name" lw:"required" help:"base name of the files"`
|
|
MaxSizeMB int64 `toml:"max_size_mb" default:"100" lw:"min=1" help:"size at which a file rotates"`
|
|
MaxTotalSizeMB int64 `toml:"max_total_size_mb" default:"1000" lw:"min=1" help:"size of all files, beyond which the oldest go"`
|
|
MinDiskFreeMB int64 `toml:"min_disk_free_mb" lw:"zero=none" help:"megabytes kept free on the disk, the oldest .log files deleted for it; a negative value means 100"`
|
|
RetentionHours float64 `toml:"retention_hours" default:"168" lw:"min=0,zero=kept" help:"hours a .log file is kept; 0 keeps them"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
FlushIntervalMs int64 `toml:"flush_interval_ms" default:"100" lw:"min=1" help:"milliseconds between flushes"`
|
|
}
|
|
|
|
// TCPSinkOptions defines settings for a TCP server sink
|
|
type TCPSinkOptions struct {
|
|
TLS *TLSOptions `toml:"tls" help:"TLS for the connections it accepts"`
|
|
Host string `toml:"host" default:"0.0.0.0" lw:"hint=host" help:"address to listen on, one family per listener: 0.0.0.0 every IPv4 interface, :: every IPv6 interface, 127.0.0.1 or ::1 this machine only"`
|
|
Port int64 `toml:"port" lw:"required,min=1,max=65535" help:"port to listen on"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued for all clients"`
|
|
ClientBufferSize int64 `toml:"client_buffer_size" default:"256" lw:"min=1" help:"entries queued per client"`
|
|
WriteTimeoutMS int64 `toml:"write_timeout_ms" default:"5000" lw:"min=1" help:"milliseconds a write may take before the client is dropped"`
|
|
KeepAlive bool `toml:"keep_alive" default:"true" help:"TCP keep-alive"`
|
|
KeepAlivePeriodMS int64 `toml:"keep_alive_period_ms" default:"30000" lw:"min=1" help:"milliseconds idle before a keep-alive probe"`
|
|
MaxConnections int64 `toml:"max_connections" lw:"min=0,zero=unlimited" help:"clients at once"`
|
|
Auth *AuthOptions `toml:"auth" help:"how peers authenticate: mtls by client certificate, scram by user and password"`
|
|
ACL *ACLOptions `toml:"acl" help:"client addresses admitted or refused, and per-client limits"`
|
|
}
|
|
|
|
// HTTPSinkOptions defines settings for an HTTP SSE server sink
|
|
type HTTPSinkOptions struct {
|
|
TLS *TLSOptions `toml:"tls" help:"TLS for the connections it accepts"`
|
|
Host string `toml:"host" default:"0.0.0.0" lw:"hint=host" help:"address to listen on, one family per listener: 0.0.0.0 every IPv4 interface, :: every IPv6 interface, 127.0.0.1 or ::1 this machine only"`
|
|
Port int64 `toml:"port" lw:"required,min=1,max=65535" help:"port to listen on"`
|
|
StreamPath string `toml:"stream_path" default:"/stream" lw:"hint=path" help:"path of the event stream"`
|
|
StatusPath string `toml:"status_path" default:"/status" lw:"hint=path" help:"path of the status document"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued for all clients"`
|
|
ClientBufferSize int64 `toml:"client_buffer_size" default:"256" lw:"min=1" help:"entries queued per client"`
|
|
WriteTimeoutMS int64 `toml:"write_timeout_ms" lw:"min=0,zero=none" help:"milliseconds an event write may take"`
|
|
MaxConnections int64 `toml:"max_connections" lw:"min=0,zero=unlimited" help:"clients at once"`
|
|
ReplayLines int64 `toml:"replay_lines" lw:"min=0,zero=none" help:"recent entries a new stream gets first"`
|
|
LoginPage bool `toml:"login_page" help:"scram behind auth.trusted_proxies only: a login page at /auth/login"`
|
|
ViewerPage bool `toml:"viewer_page" help:"scram behind auth.trusted_proxies only: the viewer after a login; without scram it is always at /"`
|
|
Auth *AuthOptions `toml:"auth" help:"how peers authenticate: mtls by client certificate, scram by user and password"`
|
|
ACL *ACLOptions `toml:"acl" help:"client addresses admitted or refused, and per-client limits"`
|
|
}
|
|
|
|
// TCPChainSinkOptions defines settings for a stdlib TCP client forwarding
|
|
// entries to a downstream logwisp tcp_chain source
|
|
type TCPChainSinkOptions struct {
|
|
TLS *TLSOptions `toml:"tls" help:"TLS to the source it connects to"`
|
|
Node string `toml:"node" lw:"zero=the host name" help:"origin label of the entries"`
|
|
Host string `toml:"host" lw:"required,hint=host" help:"host of the tcp_chain source"`
|
|
Port int64 `toml:"port" lw:"required,min=1,max=65535" help:"port of the tcp_chain source"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
DialTimeoutMS int64 `toml:"dial_timeout_ms" default:"5000" lw:"min=1" help:"milliseconds to connect"`
|
|
WriteTimeoutMS int64 `toml:"write_timeout_ms" default:"5000" lw:"min=1" help:"milliseconds a write may take"`
|
|
BackoffMinMS int64 `toml:"backoff_min_ms" default:"500" lw:"min=1" help:"first wait before reconnecting"`
|
|
BackoffMaxMS int64 `toml:"backoff_max_ms" default:"30000" lw:"min=1" help:"longest wait before reconnecting; below the first, the default"`
|
|
KeepAlivePeriodMS int64 `toml:"keep_alive_period_ms" default:"30000" lw:"min=1" help:"milliseconds idle before a keep-alive probe"`
|
|
KeepAlive bool `toml:"keep_alive" default:"true" help:"TCP keep-alive"`
|
|
Auth *AuthOptions `toml:"auth" help:"how it authenticates with the source: scram logs in, mtls checks the source's identity"`
|
|
}
|
|
|
|
// HTTPChainSinkOptions defines settings for a stdlib HTTP client posting
|
|
// NDJSON batches to a downstream logwisp http_chain source
|
|
type HTTPChainSinkOptions struct {
|
|
TLS *TLSOptions `toml:"tls" help:"TLS to the source it connects to"`
|
|
Node string `toml:"node" lw:"zero=the host name" help:"origin label of the entries"`
|
|
Host string `toml:"host" lw:"required,hint=host" help:"host of the http_chain source"`
|
|
Port int64 `toml:"port" lw:"required,min=1,max=65535" help:"port of the http_chain source"`
|
|
IngestPath string `toml:"ingest_path" default:"/ingest" lw:"hint=path" help:"path batches are posted to"`
|
|
BufferSize int64 `toml:"buffer_size" default:"1000" lw:"min=1" help:"entries queued"`
|
|
MaxBatchCount int64 `toml:"max_batch_count" default:"100" lw:"min=1" help:"entries in a batch"`
|
|
MaxBatchBytes int64 `toml:"max_batch_bytes" default:"1048576" lw:"min=1" help:"bytes in a batch"`
|
|
FlushIntervalMS int64 `toml:"flush_interval_ms" default:"1000" lw:"min=1" help:"milliseconds before a partial batch is sent"`
|
|
RequestTimeoutMS int64 `toml:"request_timeout_ms" default:"10000" lw:"min=1" help:"milliseconds for a request: dial, write and response"`
|
|
BackoffMinMS int64 `toml:"backoff_min_ms" default:"500" lw:"min=1" help:"first wait before retrying"`
|
|
BackoffMaxMS int64 `toml:"backoff_max_ms" default:"30000" lw:"min=1" help:"longest wait before retrying; below the first, the default"`
|
|
Auth *AuthOptions `toml:"auth" help:"how it authenticates with the source: scram logs in, mtls checks the source's identity"`
|
|
}
|
|
|
|
// --- Auth Options ---
|
|
|
|
// AuthOptions selects how a network plugin authenticates its peer. It sits
|
|
// beside `tls`: TLS answers "is this channel private", auth answers "may this
|
|
// peer do this". Listeners verify (mtls: certificate identity; scram: the
|
|
// credentials_file's users, or one username and password_file); dialers prove
|
|
// themselves (scram) or pin the server (mtls). Check holds each side's rules.
|
|
type AuthOptions struct {
|
|
Type string `toml:"type" default:"none" lw:"enum=none|mtls|scram" help:"how peers authenticate"`
|
|
Identity string `toml:"identity" lw:"enum=cn|san_dns|san_uri|san_email,zero=cn under mtls; no binding under scram" help:"certificate field naming the peer; under scram it must equal the user"`
|
|
Allow []string `toml:"allow" help:"mtls: identities admitted; with neither this nor allow_patterns set, any the CA issued"`
|
|
AllowPatterns []string `toml:"allow_patterns" lw:"hint=regex" help:"mtls: RE2 patterns of identities admitted; anchor them"`
|
|
NodeBinding string `toml:"node_binding" lw:"chain_listener,enum=none|assert|force,zero=force" help:"chain sources: force labels every entry with the peer's identity, assert refuses a peer declaring another node, none leaves it to trust_node"`
|
|
CredentialsFile string `toml:"credentials_file" lw:"listener,hint=file" help:"scram: file of the users who may log in, made by lw auth add-user"`
|
|
// exp has whole seconds, a sub-second expires_in reads as unknown, and 10 s
|
|
// leaves room for renewal ahead of expiry
|
|
TokenLifetimeMS int64 `toml:"token_lifetime_ms" lw:"listener,http,min=10000,max=86400000,zero=15 minutes" help:"scram on HTTP: bearer token lifetime"`
|
|
TrustedProxies []string `toml:"trusted_proxies" lw:"listener,http,hint=cidr" help:"scram on the http sink: addresses or CIDRs of the proxies that end browsers' TLS, through which browsers then log in"`
|
|
Username string `toml:"username" help:"scram: the user a dialer logs in as, or a listener's one user"`
|
|
PasswordFile string `toml:"password_file" lw:"hint=file" help:"scram: file holding the password; /dev/fd/N or a pipe is read once, /dev/tty asks"`
|
|
}
|
|
|
|
// ACLOptions is a listener's address rules, entries being addresses or CIDRs:
|
|
// deny wins, then a set allow list admits only its entries. proxy_from lists
|
|
// the L4 proxies whose PROXY header names the client the rules then see; the
|
|
// per-client limits count that client. ACLOptions.Check holds the rules.
|
|
type ACLOptions struct {
|
|
Allow []string `toml:"allow" lw:"hint=cidr" help:"addresses or CIDRs that may connect; unset, any that deny does not refuse"`
|
|
Deny []string `toml:"deny" lw:"hint=cidr" help:"addresses or CIDRs refused, even when allow lists them"`
|
|
ProxyProtocol string `toml:"proxy_protocol" default:"off" lw:"enum=off|optional|required" help:"read a PROXY header from proxy_from"`
|
|
ProxyFrom []string `toml:"proxy_from" lw:"hint=cidr" help:"proxies that may send a PROXY header"`
|
|
MaxConnectionsPerClient int64 `toml:"max_connections_per_client" lw:"min=0,zero=unlimited" help:"connections a client may hold"`
|
|
RequestsPerSecondPerClient float64 `toml:"requests_per_second_per_client" lw:"http,min=0,zero=unlimited" help:"HTTP: requests a client may make each second"`
|
|
}
|
|
|
|
// --- TLS Options ---
|
|
|
|
// TLSOptions is one shape for both roles. Listeners present cert_file and
|
|
// key_file, or a certificate issued at startup (self_signed, or from the
|
|
// issuer files), and verify clients with client_auth and client_ca_file;
|
|
// dialers verify the server with ca_file and server_name, or pin_sha256, and
|
|
// may present cert_file and key_file.
|
|
type TLSOptions struct {
|
|
Enabled bool `toml:"enabled" help:"use TLS"`
|
|
CertFile string `toml:"cert_file" lw:"hint=file" help:"certificate file this end presents; a dialer's, for a listener with client_auth"`
|
|
KeyFile string `toml:"key_file" lw:"hint=file" help:"key of cert_file"`
|
|
SelfSigned bool `toml:"self_signed" lw:"listener" help:"a self-signed certificate on a key made at startup"`
|
|
IssuerCertFile string `toml:"issuer_cert_file" lw:"listener,hint=file" help:"CA certificate file (lw tls ca) that signs a certificate made at startup"`
|
|
IssuerKeyFile string `toml:"issuer_key_file" lw:"listener,hint=file" help:"key of issuer_cert_file"`
|
|
Hosts []string `toml:"hosts" lw:"listener" help:"more names and addresses for a certificate made at startup, which always carries host, this machine's name and localhost"`
|
|
ClientAuth bool `toml:"client_auth" lw:"listener" help:"require and verify client certificates"`
|
|
ClientCAFile string `toml:"client_ca_file" lw:"listener,hint=file" help:"CA bundle verifying client certificates"`
|
|
CAFile string `toml:"ca_file" lw:"dialer,hint=file,zero=the system roots" help:"CA bundle verifying the server"`
|
|
ServerName string `toml:"server_name" lw:"dialer,zero=the host" help:"name the server's certificate must carry"`
|
|
InsecureSkipVerify bool `toml:"insecure_skip_verify" lw:"dialer" help:"verify nothing of the server; never in production"`
|
|
PinSHA256 string `toml:"pin_sha256" lw:"dialer" help:"sha256//BASE64 of the server's key, ';' between several; replaces ca_file"`
|
|
MinVersion string `toml:"min_version" default:"1.3" lw:"enum=1.2|1.3" help:"lowest TLS version"`
|
|
}
|