Documentation
¶
Overview ¶
Package decryptprofile is the named SSL-decryption-profile engine: a PAN-OS-style "how to decrypt" object that policy rules reference by name to control HOW an inspected (SSLAction=Inspect) tunnel is decrypted — whether to inspect natively as HTTP/2, the upstream server-certificate-verification posture, the unsupported-TLS failure posture, the TLS version floor/cap, and the per-stream inactivity bound. It is the "how" half that complements the "what to match" half already in package main's policy rules + sslbypass.
This engine owns storage + validation ONLY. The resolvers that turn a matched rule's profile reference into a runtime decision (resolveStripALPN and friends) live in package main on the proxy hot path, mirroring how catgroup exposes the pure store while categoryGroupMatchesHost stays in main.
Concurrency: an RWMutex protects the store; reads (GetByName) take RLock, writes rebuild order under Lock. All validation is enforced in Add/Update AND ReplaceAll, because profiles are written by THREE paths — the admin API, config import, and CP→DP snapshot apply — and a handler-only check would be bypassed by the latter two.
Index ¶
- Constants
- func Validate(p *Profile) error
- type Profile
- type Store
- func (s *Store) Add(p Profile) (*Profile, error)
- func (s *Store) Delete(name string) error
- func (s *Store) FailOpenScope(name string) (id string, ok bool)
- func (s *Store) GetByName(name string) *Profile
- func (s *Store) List() []Profile
- func (s *Store) Load(path string) error
- func (s *Store) Names() []string
- func (s *Store) Path() string
- func (s *Store) ReplaceAll(profiles []Profile)
- func (s *Store) Save()
- func (s *Store) SetPathForTest(path string)
- func (s *Store) Update(p Profile) error
Constants ¶
const ( MinStallSecs = 5 MaxStallSecs = 3600 )
Clamp bounds for StallTimeoutSecs. 0 means "engine default" (the caller substitutes sslInspectBodyStallTimeout); any other value must fall in [MinStallSecs, MaxStallSecs]. A too-low value kills legitimate long-poll/SSE/ large-download streams; a too-high value lets a slow-loris stream pin a handler + scan buffer. MaxStallSecs matches the default tunnel-idle ceiling (1h).
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Profile ¶
type Profile struct {
ID string `json:"id"`
Name string `json:"name"`
// InspectHTTP2: nil = inherit (strip → HTTP/1.1, today's default); true =
// native HTTP/2 inspection; false = force strip/HTTP-1.1.
InspectHTTP2 *bool `json:"inspectHttp2,omitempty"`
// CertVerification of the upstream (origin) cert on the inspect leg:
// "" inherit (rule's TLSSkipVerify) | "strict" (verify, block untrusted/expired)
// | "permissive" (verify, allow+log — DEFERRED enforcement) | "skip".
CertVerification string `json:"certVerification,omitempty"`
// OnUnsupported posture when the origin TLS can't be inspected (version/cipher
// below floor): "" inherit | "fail-close" (drop — today's behavior) | "fail-open"
// (raw-relay bypass — DEFERRED, superseded by OnInspectError for fail-open).
OnUnsupported string `json:"onUnsupported,omitempty"`
// OnInspectError is the adaptive decryption-exclusion / fail-open posture when
// an inspected tunnel CANNOT be established because the host is incompatible
// with inspection (origin demands a client cert we can't present, or the TLS
// parameters are unsupported, or a pinned client rejects our forged leaf):
// "" inherit (fail-close, today's behavior) | "fail-close" (502/drop) |
// "fail-open" (record the host in the auto-exclusion cache after a
// confirm-count of distinct clients, rescue the current session where it has
// not yet committed to the client, and bypass subsequent sessions to the host
// until the entry expires). It deliberately does NOT fire on an untrusted/
// expired origin cert — that stays a block. See internal/autoexclude.
OnInspectError string `json:"onInspectError,omitempty"`
// MinTLSVersion / MaxTLSVersion floor and cap on the inspect handshakes:
// "" inherit | "1.2" | "1.3".
MinTLSVersion string `json:"minTlsVersion,omitempty"`
MaxTLSVersion string `json:"maxTlsVersion,omitempty"`
// StallTimeoutSecs per-stream inactivity bound; 0 = engine default, else
// clamped to [MinStallSecs, MaxStallSecs].
StallTimeoutSecs int `json:"stallTimeoutSecs,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
}
Profile is a named decryption profile. Zero/empty fields mean "inherit the default" so an absent or partially-filled profile never silently changes today's behavior (back-compat with the pre-profile inline rule fields).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store manages persistent decryption profiles with O(1) name lookups.
func (*Store) Add ¶
Add creates a new profile. Validates fields, then name uniqueness. Assigns a short unique ID (a truncated UUID) when absent (ID-preserving otherwise).
func (*Store) FailOpenScope ¶ added in v1.0.82
FailOpenScope returns the profile's ID and true IFF a profile with the given name exists AND opts into fail-open (OnInspectError=="fail-open"). It is a HOT-PATH accessor (resolveSSLAction calls it per CONNECT for fail-open rules): it reads only two string fields under the RLock and returns NO copy, avoiding the copyOut allocation a full GetByName pays. The learn/cold paths keep the copy-returning accessors.
func (*Store) GetByName ¶
GetByName returns a profile by name (case-insensitive). O(1). nil if not found.
func (*Store) Load ¶
Load reads profiles from a JSON file. Invalid profiles on disk are skipped with a log line (fail-safe — a corrupt entry never blocks startup or the valid ones).
func (*Store) ReplaceAll ¶
ReplaceAll atomically replaces all profiles (cluster sync / rollback / import). Invalid profiles are skipped (fail-safe) so a bad remote/imported entry never takes down the store or the valid entries. IDs are PRESERVED as provided (backfilled only when empty) so a capture→apply→re-capture round-trip is stable.
func (*Store) Save ¶
func (s *Store) Save()
Save persists the current profiles to disk (atomic write). No-op when path unset.
func (*Store) SetPathForTest ¶
SetPathForTest points persistence at path without loading.