Documentation
¶
Overview ¶
Package setup provides setup functionality for CheeseWAF.
Package setup handles first-launch initialization: setup wizard, default config, and local CA-signed admin certificate generation. 首次启动初始化:安装向导、默认配置、本地 CA 签发管理端证书生成。
Index ¶
- Constants
- Variables
- func BrowserSetupURL(scheme, adminListen string) string
- func BrowserURL(scheme, adminListen, token string) string
- func BrowserURLWithHost(scheme, adminListen, publicHost, token string) string
- func DefaultConfigPath(dataDir string) string
- func DefaultConfigYAML(paths DefaultPaths) []byte
- func GenerateAdminCertificateBundle(certFile, keyFile, caFile, caKeyFile string, hosts []string, ...) error
- func GenerateSelfSignedCertificate(certFile, keyFile string, hosts []string, validFor time.Duration) error
- func GenerateSetupToken() (string, error)
- func GetSetupToken() string
- func MarkComplete(dataDir string) error
- func NeedsSetup(dataDir string) bool
- func NewSecurityEntrySegment() (string, error)
- func NewSetupToken() (string, error)
- func ReadURLOnce(dataDir string) (string, error)
- func RemoveURL(dataDir string) error
- func SetupErrorStatus(err error) int
- func TokenFilePath(dataDir string) string
- func ValidateSecurityEntrySegment(value string) error
- func WriteURL(dataDir, page string) error
- func WriteURLWithReceipt(dataDir, page string) (string, error)
- type CompleteOptions
- type CompleteResult
- type DefaultBundle
- type DefaultOptions
- type DefaultPaths
- type DraftStore
- func (s *DraftStore) CompleteProbe(id string, result ProbeResult) (*SetupDraft, bool)
- func (s *DraftStore) Create() (*SetupDraft, error)
- func (s *DraftStore) Delete(id string)
- func (s *DraftStore) Get(id string) (*SetupDraft, bool)
- func (s *DraftStore) Password(id string) (string, bool)
- func (s *DraftStore) ReserveProbe(id string) (*SetupDraft, bool, error)
- func (s *DraftStore) SetPassword(id, password string) bool
- func (s *DraftStore) Update(id string, mut func(*SetupDraft)) (*SetupDraft, bool)
- type HardwareProfile
- type IntegrationsConfig
- type ProbeResult
- type ProfileConfig
- type SetupDraft
- type SetupPayload
- type TokenSource
- type TokenStore
- type Wizard
Constants ¶
const ( DefaultConfigFile = "cheesewaf.yaml" DefaultConfigDirName = "config" LegacyConfigFile = "waf.yaml" DefaultCertDir = "certs" DefaultLogDir = "logs" DefaultRuntimeDir = "run" DefaultSQLiteFile = "cheesewaf.db" DefaultAdminCertFile = "admin.crt" DefaultAdminKeyFile = "admin.key" DefaultAdminCAFile = "admin-ca.crt" DefaultAdminCAKeyFile = "admin-ca.key" // The admin surface is private-by-default. Operators can explicitly opt in // to a public listener; TLS and the post-setup random security entry remain // mandatory for public access. DefaultAdminListen = "127.0.0.1:9443" DefaultHTTPListen = ":80" DefaultHTTPSListen = ":443" )
const ( // SetupSessionCookie is the server-side draft binder (HttpOnly). SetupSessionCookie = "cheesewaf_setup_session" // DefaultDraftTTL discards incomplete drafts. DefaultDraftTTL = 30 * time.Minute DefaultMaxDrafts = 100 )
const ( // SetupTokenFileName is the runtime token state used by the first-install // server and by `cheesewaf setup token`. It is deliberately separate from // setup.url: the URL is a short-lived delivery envelope, while this file is // the revocation source checked by the running API. SetupTokenFileName = "setup.token" SetupTokenTTL = 10 * time.Minute )
const ( // URLFileName is the first-install browser URL written under the data directory. URLFileName = "setup.url" // SetupURLTTL bounds how long the out-of-band setup URL remains usable. The // setup token itself is still validated by the API and is revoked on setup // completion; this bound only protects an unattended URL file. SetupURLTTL = 10 * time.Minute )
const ( // DefaultDataDir is the default data directory for CheeseWAF. // 默认数据目录。 DefaultDataDir = "/var/lib/cheesewaf" // SetupLockFile indicates that initial setup has been completed. // 标识初始化已完成的锁文件。 SetupLockFile = ".setup_complete" )
Variables ¶
var ( // ErrDraftStoreFull is returned when max draft capacity is reached. ErrDraftStoreFull = errors.New("draft store full") // ErrDraftProbeInProgress prevents duplicate probe I/O for one session. ErrDraftProbeInProgress = errors.New("draft probe already in progress") )
var ( ErrSetupValidation = errors.New("setup validation failed") ErrSetupAlreadyComplete = errors.New("setup has already completed") )
var ( // ErrURLNotFound reports that no setup URL is available. A consumed URL has // the same result, which prevents callers from distinguishing replay from // an absent file. ErrURLNotFound = errors.New("setup URL not found") // ErrURLExpired reports that the setup URL exceeded its short delivery TTL. ErrURLExpired = errors.New("setup URL expired") )
var DefaultCertificateHosts = []string{"127.0.0.1", "::1", "localhost"}
DefaultCertificateHosts are included in the admin certificate SAN. 默认管理端证书 SAN。
Functions ¶
func BrowserSetupURL ¶ added in v0.4.2
BrowserSetupURL returns the setup page without a token fragment. It uses the same bind-versus-advertised-host rules as the tokenized URL.
func BrowserURL ¶
BrowserURL is the first-install page, with the token in the URL fragment. A public host supplied by CHEESEWAF_ADMIN_PUBLIC_HOST is preferred when the listener binds a wildcard address; otherwise the historical loopback URL is retained for local CLI use.
func BrowserURLWithHost ¶ added in v0.4.2
BrowserURLWithHost separates the bind address from the address an operator can actually open in a browser. This prevents 0.0.0.0 from leaking into setup links while allowing the installer to advertise the detected public IP.
func DefaultConfigPath ¶
DefaultConfigPath is the generated/runtime config file under the data directory's config subdirectory, not next to the SQLite file.
func DefaultConfigYAML ¶
func DefaultConfigYAML(paths DefaultPaths) []byte
DefaultConfigYAML returns the bootstrap configuration used before the database-backed configuration store is initialized. 返回数据库配置存储初始化前使用的启动配置。
func GenerateAdminCertificateBundle ¶
func GenerateAdminCertificateBundle(certFile, keyFile, caFile, caKeyFile string, hosts []string, validFor time.Duration) error
GenerateAdminCertificateBundle writes a local CA certificate/key plus a server-auth leaf certificate/key for the admin interface. The leaf cert file contains the leaf first and CA second, matching common TLS chain layout. 生成本地 CA 与管理端叶子证书;叶子证书文件按 leaf + CA 链顺序写入。
func GenerateSelfSignedCertificate ¶
func GenerateSelfSignedCertificate(certFile, keyFile string, hosts []string, validFor time.Duration) error
GenerateSelfSignedCertificate writes an ECDSA P-256 admin certificate chain signed by a local self-signed CheeseWAF CA. 为管理端生成由本地 CheeseWAF CA 签发的 ECDSA P-256 证书链。
func GenerateSetupToken ¶
GenerateSetupToken creates a high-entropy one-time setup token on first call. Returns the same token on subsequent calls within the same process lifetime.
func GetSetupToken ¶
func GetSetupToken() string
GetSetupToken returns the generated token if one exists, empty string otherwise.
func MarkComplete ¶
func NeedsSetup ¶
func NewSecurityEntrySegment ¶ added in v0.4.2
NewSecurityEntrySegment returns a URL-safe, symbol-free management entry. It is intentionally independent from the setup token so the entry can be rotated without invalidating the one-time first-install credential.
func NewSetupToken ¶ added in v0.4.0
NewSetupToken creates a fresh high-entropy setup token. Unlike GenerateSetupToken it never reuses a process-global value and is therefore suitable for explicit CLI rotation.
func ReadURLOnce ¶
ReadURLOnce atomically claims and consumes the setup URL file. It returns ErrURLExpired for stale files and removes them in either case, making retries and explicit replay fail closed.
func RemoveURL ¶
RemoveURL deletes the first-install URL file after setup completes. It is idempotent so completion cleanup can be safely retried.
func SetupErrorStatus ¶
func TokenFilePath ¶ added in v0.4.0
TokenFilePath returns the runtime path used for the active setup token.
func ValidateSecurityEntrySegment ¶ added in v0.4.2
ValidateSecurityEntrySegment accepts only a path segment made of ASCII letters and digits. The bounds keep accidental empty or unbounded entries out of the admin router while leaving custom values easy to type.
func WriteURL ¶
WriteURL stores the first-install URL next to the data directory. It keeps the historical error-only signature; callers that need a log-safe receipt should use WriteURLWithReceipt.
func WriteURLWithReceipt ¶
WriteURLWithReceipt writes a short-lived setup URL atomically with mode 0600 and returns a random receipt that contains no setup secret. The file is an operator-readable envelope so the URL remains easy to copy while its expiry and receipt are explicit.
Types ¶
type CompleteOptions ¶
type CompleteOptions struct {
DataDir string
ConfigPath string
DefaultAdminListen string
Paths DefaultPaths
Config *config.Config
Store storage.Store
// ApplyRuntime applies the completed setup configuration before setup is
// marked complete. It returns a compensating action that restores the prior
// runtime state if application partially fails or setup cannot commit.
ApplyRuntime func(next, previous *config.Config) (rollback func() error, err error)
// contains filtered or unexported fields
}
type CompleteResult ¶
type CompleteResult struct {
User *storage.User
Config *config.Config
Paths DefaultPaths
SecurityEntryPath string
}
func CompleteSetup ¶
func CompleteSetup(ctx context.Context, opts CompleteOptions, payload SetupPayload) (*CompleteResult, error)
type DefaultBundle ¶
type DefaultBundle struct {
Paths DefaultPaths
}
DefaultBundle reports files created or reused by EnsureDefaults. EnsureDefaults 创建或复用的默认文件集合。
func EnsureDefaults ¶
func EnsureDefaults(opts DefaultOptions) (*DefaultBundle, error)
EnsureDefaults creates the runtime layout, default config, and admin TLS pair. It avoids overwriting existing files unless Overwrite is set. 创建运行目录、默认配置和管理端 TLS 证书;默认不覆盖已有文件。
type DefaultOptions ¶
type DefaultOptions struct {
DataDir string
ConfigPath string
Hostnames []string
ValidFor time.Duration
Overwrite bool
}
DefaultOptions controls default file generation. 默认文件生成参数。
type DefaultPaths ¶
type DefaultPaths struct {
DataDir string
ConfigFile string
CertDir string
CertFile string
KeyFile string
CAFile string
CAKeyFile string
LogDir string
RuntimeDir string
SQLiteFile string
}
DefaultPaths contains the resolved paths used by setup. 初始化使用的解析后路径。
func ResolveDefaultPaths ¶
func ResolveDefaultPaths(opts DefaultOptions) DefaultPaths
ResolveDefaultPaths returns setup paths without touching the filesystem. 仅解析默认路径,不写入文件。
type DraftStore ¶
type DraftStore struct {
// contains filtered or unexported fields
}
DraftStore is an in-memory draft registry keyed by setup session id.
func NewDraftStore ¶
func NewDraftStore(ttl time.Duration) *DraftStore
NewDraftStore creates a draft store with the given TTL.
func NewDraftStoreWithLimit ¶
func NewDraftStoreWithLimit(ttl time.Duration, maxDrafts int) *DraftStore
NewDraftStoreWithLimit creates a draft store with an explicit capacity.
func (*DraftStore) CompleteProbe ¶
func (s *DraftStore) CompleteProbe(id string, result ProbeResult) (*SetupDraft, bool)
CompleteProbe stores a reserved probe result.
func (*DraftStore) Create ¶
func (s *DraftStore) Create() (*SetupDraft, error)
Create allocates a new draft and returns it.
func (*DraftStore) Get ¶
func (s *DraftStore) Get(id string) (*SetupDraft, bool)
Get returns a draft by id if present and not expired.
func (*DraftStore) Password ¶
func (s *DraftStore) Password(id string) (string, bool)
Password returns the stored password for CompleteSetup.
func (*DraftStore) ReserveProbe ¶
func (s *DraftStore) ReserveProbe(id string) (*SetupDraft, bool, error)
ReserveProbe atomically reuses a completed probe, reserves an existing draft, or creates and reserves a new draft.
func (*DraftStore) SetPassword ¶
func (s *DraftStore) SetPassword(id, password string) bool
SetPassword stores the admin password in the draft (memory only).
func (*DraftStore) Update ¶
func (s *DraftStore) Update(id string, mut func(*SetupDraft)) (*SetupDraft, bool)
Update merges non-zero fields into the draft.
type HardwareProfile ¶
type HardwareProfile string
HardwareProfile is the Setup 2.0 recommended performance tier.
const ( ProfileLow HardwareProfile = "low" ProfileMedium HardwareProfile = "medium" ProfileSmart HardwareProfile = "smart" ProfileHigh HardwareProfile = "high" ProfileCustom HardwareProfile = "custom" )
type IntegrationsConfig ¶
type IntegrationsConfig struct {
PostgresEnabled bool `json:"postgresEnabled"`
PostgresDSN string `json:"postgresDsn"`
PostgresTable string `json:"postgresTable"`
PrometheusEnabled bool `json:"prometheusEnabled"`
PrometheusPath string `json:"prometheusPath"`
PrometheusPublic bool `json:"prometheusPublic"`
VictoriaEnabled bool `json:"victoriaEnabled"`
VictoriaEndpoint string `json:"victoriaEndpoint"`
}
IntegrationsConfig captures optional external integrations entered during setup. Values are stored in the draft but are not applied to the live config until the operator saves them under System Settings after installation.
type ProbeResult ¶
type ProbeResult struct {
Profile HardwareProfile `json:"profile"`
Incomplete bool `json:"incomplete"`
CPULogical int `json:"cpu_logical"`
MemoryTotalMB uint64 `json:"memory_total_mb"`
MemoryAvailMB uint64 `json:"memory_avail_mb"`
DiskWriteMBps float64 `json:"disk_write_mbps"`
DiskOK bool `json:"disk_ok"`
DurationMS int64 `json:"duration_ms"`
Notes []string `json:"notes,omitempty"`
SuggestedConfig ProfileConfig `json:"suggested_config"`
}
ProbeResult is the outcome of a bounded first-install performance probe.
type ProfileConfig ¶
type ProfileConfig struct {
PipelineBudgetMS int `json:"pipeline_budget_ms"`
SemanticDepth int `json:"semantic_depth"`
WebAttackLevel string `json:"web_attack_level"`
ChallengeConcurrency int `json:"challenge_concurrency"`
ChallengeCapacity int `json:"challenge_capacity"`
RateLimitRequests int `json:"rate_limit_requests"`
MaxBodyBytes int64 `json:"max_body_bytes"`
AccessLogSamplePct int `json:"access_log_sample_pct"`
}
ProfileConfig maps a tier to safe defaults (Setup custom knobs minimum set).
func ProfileDefaults ¶
func ProfileDefaults(p HardwareProfile) ProfileConfig
ProfileDefaults returns the safe baseline mapping for every selectable profile.
type SetupDraft ¶
type SetupDraft struct {
ID string `json:"id"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
Probe *ProbeResult `json:"probe,omitempty"`
Profile HardwareProfile `json:"profile,omitempty"`
Custom *ProfileConfig `json:"custom,omitempty"`
Username string `json:"username,omitempty"`
AdminListen string `json:"admin_listen,omitempty"`
AdminStrategy string `json:"admin_strategy,omitempty"`
Integrations *IntegrationsConfig `json:"integrations,omitempty"`
PasswordSet bool `json:"password_set"`
Confirmed bool `json:"confirmed"`
// contains filtered or unexported fields
}
SetupDraft holds multi-step wizard state until final confirmation.
type SetupPayload ¶
type SetupPayload struct {
Username string `json:"username"`
Password string `json:"password"`
AdminListen string `json:"admin_listen"`
AdminStrategy string `json:"admin_strategy"`
AdminPublic bool `json:"admin_public"`
SecurityEntryPath string `json:"security_entry_path"`
Profile HardwareProfile `json:"profile"`
}
type TokenSource ¶ added in v0.4.0
type TokenSource interface {
Current() string
}
TokenSource is the small contract used by setup mutation handlers. A source may be backed by a file so a separate CLI process can rotate the token while the service is still running.
type TokenStore ¶ added in v0.4.0
type TokenStore struct {
// contains filtered or unexported fields
}
TokenStore persists the active first-install token in the runtime data directory. Current intentionally reads the file for every validation so a CLI rotation takes effect on the next request without restarting the service.
func NewTokenStore ¶ added in v0.4.0
func NewTokenStore(dataDir string) *TokenStore
NewTokenStore creates a file-backed first-install token source.
func (*TokenStore) Current ¶ added in v0.4.0
func (s *TokenStore) Current() string
Current returns the active token, or an empty string when the state is absent, malformed, or not a regular private file. Errors are intentionally fail-closed because this method is used on the HTTP authorization path.
func (*TokenStore) Ensure ¶ added in v0.4.0
func (s *TokenStore) Ensure(token string) (string, error)
Ensure keeps an existing token, otherwise persists the supplied token or a newly generated high-entropy value. This lets a restart preserve a token rotated by the CLI instead of allowing CHEESEWAF_SETUP_TOKEN to overwrite it.
func (*TokenStore) Remove ¶ added in v0.4.0
func (s *TokenStore) Remove() error
Remove revokes the active token and removes its runtime state.
func (*TokenStore) Rotate ¶ added in v0.4.0
func (s *TokenStore) Rotate() (string, error)
Rotate replaces the active token atomically. Readers either observe the previous complete value or the new complete value; there is no empty window.
type Wizard ¶
type Wizard struct {
DataDir string // 数据目录 / Data directory
ConfigPath string // 配置文件路径 / Config file path
AdminAPI string // 管理 API 地址 / Admin API address
CertHosts []string // 管理端证书 SAN / Admin certificate SANs
CertValidFor time.Duration // 管理端叶子证书有效期 / Admin leaf certificate lifetime
}
Wizard handles the first-launch setup process. If a Web UI is available, it serves a browser-based wizard. Otherwise, it falls back to a TUI-based setup. 首次启动安装向导。优先使用 Web UI 向导,否则回退到 TUI 向导。
func (*Wizard) MarkComplete ¶
MarkComplete marks the setup as complete by creating the lock file. 标记初始化完成。
func (*Wizard) NeedsSetup ¶
NeedsSetup checks if the initial setup has been completed. 检查是否需要初始化。
func (*Wizard) PrepareDefaults ¶
func (w *Wizard) PrepareDefaults() (*DefaultBundle, error)
PrepareDefaults creates the default directory layout, config file, and local CA-signed admin certificate bundle. It is safe to call repeatedly. 准备默认目录、配置文件和本地 CA 签发管理端证书包,可重复调用。