mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 15:26:40 +00:00
213 lines
7.3 KiB
Go
213 lines
7.3 KiB
Go
package inspect
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/x509"
|
|
"net"
|
|
"net/netip"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/acl/id"
|
|
"github.com/netbirdio/netbird/shared/management/domain"
|
|
)
|
|
|
|
// InspectResult holds the outcome of connection inspection.
|
|
type InspectResult struct {
|
|
// Action is the rule evaluation result.
|
|
Action Action
|
|
// PassthroughConn is the client connection with buffered peeked bytes.
|
|
// Non-nil only when Action is ActionAllow and the caller should relay
|
|
// (TLS passthrough or non-HTTP/TLS protocol). The caller takes ownership
|
|
// and is responsible for closing this connection.
|
|
PassthroughConn net.Conn
|
|
}
|
|
|
|
const (
|
|
// DefaultTProxyPort is the default TPROXY listener port for kernel mode.
|
|
// Override with NB_TPROXY_PORT environment variable.
|
|
DefaultTProxyPort = 22080
|
|
)
|
|
|
|
// Action determines how the proxy handles a matched connection.
|
|
type Action string
|
|
|
|
const (
|
|
// ActionAllow passes the connection through without decryption.
|
|
ActionAllow Action = "allow"
|
|
// ActionBlock denies the connection.
|
|
ActionBlock Action = "block"
|
|
// ActionInspect decrypts (MITM) and inspects the connection.
|
|
ActionInspect Action = "inspect"
|
|
)
|
|
|
|
// ProxyMode determines the proxy operating mode.
|
|
type ProxyMode string
|
|
|
|
const (
|
|
// ModeBuiltin uses the built-in proxy with rules and optional ICAP.
|
|
ModeBuiltin ProxyMode = "builtin"
|
|
// ModeEnvoy runs a local envoy sidecar for L7 processing.
|
|
// Go manages envoy lifecycle, config generation, and rule evaluation.
|
|
// USP path forwards via PROXY protocol v2; kernel path uses nftables redirect.
|
|
ModeEnvoy ProxyMode = "envoy"
|
|
// ModeExternal forwards all traffic to an external proxy.
|
|
ModeExternal ProxyMode = "external"
|
|
)
|
|
|
|
// PolicyID is the management policy identifier associated with a connection.
|
|
type PolicyID []byte
|
|
|
|
// MatchDomain reports whether target matches the pattern.
|
|
// If pattern starts with "*.", it matches any subdomain (but not the base itself).
|
|
// Otherwise it requires an exact match.
|
|
func MatchDomain(pattern, target domain.Domain) bool {
|
|
p := pattern.PunycodeString()
|
|
t := target.PunycodeString()
|
|
|
|
if strings.HasPrefix(p, "*.") {
|
|
base := p[2:]
|
|
return strings.HasSuffix(t, "."+base)
|
|
}
|
|
|
|
return p == t
|
|
}
|
|
|
|
// SourceInfo carries source identity context for rule evaluation.
|
|
// The source may be a direct WireGuard peer or a host behind
|
|
// a site-to-site gateway.
|
|
type SourceInfo struct {
|
|
// IP is the original source address from the packet.
|
|
IP netip.Addr
|
|
// PolicyID is the management policy that allowed this traffic
|
|
// through route ACLs.
|
|
PolicyID PolicyID
|
|
}
|
|
|
|
// ProtoType identifies a protocol handled by the proxy.
|
|
type ProtoType string
|
|
|
|
const (
|
|
ProtoHTTP ProtoType = "http"
|
|
ProtoHTTPS ProtoType = "https"
|
|
ProtoH2 ProtoType = "h2"
|
|
ProtoH3 ProtoType = "h3"
|
|
ProtoWebSocket ProtoType = "websocket"
|
|
ProtoOther ProtoType = "other"
|
|
)
|
|
|
|
// Rule defines a proxy inspection/filtering rule.
|
|
type Rule struct {
|
|
// ID uniquely identifies this rule.
|
|
ID id.RuleID
|
|
// Sources are the source CIDRs this rule applies to.
|
|
// Includes both direct peer IPs and routed networks behind gateways.
|
|
Sources []netip.Prefix
|
|
// Domains are the destination domain patterns to match (via SNI or Host header).
|
|
// Supports exact match ("example.com") and wildcard ("*.example.com").
|
|
Domains []domain.Domain
|
|
// Networks are the destination CIDRs to match.
|
|
Networks []netip.Prefix
|
|
// Ports are the destination ports to match. Empty means all ports.
|
|
Ports []uint16
|
|
// Protocols restricts which protocols this rule applies to.
|
|
// Empty means all protocols.
|
|
Protocols []ProtoType
|
|
// Paths are URL path patterns to match (HTTP only, requires inspect for HTTPS).
|
|
// Supports prefix ("/api/"), exact ("/login"), and wildcard ("/admin/*").
|
|
// Empty means all paths.
|
|
Paths []string
|
|
// Action determines what to do with matched connections.
|
|
Action Action
|
|
// Priority controls evaluation order. Lower values are evaluated first.
|
|
Priority int
|
|
}
|
|
|
|
// ICAPConfig holds ICAP service configuration.
|
|
type ICAPConfig struct {
|
|
// ReqModURL is the ICAP REQMOD service URL (e.g., icap://server:1344/reqmod).
|
|
ReqModURL *url.URL
|
|
// RespModURL is the ICAP RESPMOD service URL (e.g., icap://server:1344/respmod).
|
|
RespModURL *url.URL
|
|
// MaxConnections is the connection pool size. Zero uses a default.
|
|
MaxConnections int
|
|
}
|
|
|
|
// TLSConfig holds the MITM CA configuration for TLS inspection.
|
|
type TLSConfig struct {
|
|
// CA is the certificate authority used to sign dynamic certificates.
|
|
CA *x509.Certificate
|
|
// CAKey is the CA's private key.
|
|
CAKey crypto.PrivateKey
|
|
}
|
|
|
|
// Config holds the transparent proxy configuration.
|
|
type Config struct {
|
|
// Enabled controls whether the proxy is active.
|
|
Enabled bool
|
|
// Mode selects built-in or external proxy operation.
|
|
Mode ProxyMode
|
|
// ExternalURL is the upstream proxy URL for ModeExternal.
|
|
// Supports http:// and socks5:// schemes.
|
|
ExternalURL *url.URL
|
|
|
|
// DefaultAction applies when no rule matches a connection.
|
|
DefaultAction Action
|
|
|
|
// RedirectSources are the source CIDRs whose traffic should be intercepted.
|
|
// Admin decides: "activate for these users/subnets."
|
|
// Used for both kernel TPROXY rules and userspace forwarder source filtering.
|
|
RedirectSources []netip.Prefix
|
|
// RedirectPorts are the destination ports to intercept. Empty means all ports.
|
|
RedirectPorts []uint16
|
|
|
|
// Rules are the proxy inspection/filtering rules, evaluated in Priority order.
|
|
Rules []Rule
|
|
|
|
// ICAP holds ICAP service configuration. Nil disables ICAP.
|
|
ICAP *ICAPConfig
|
|
// TLS holds the MITM CA. Nil means no MITM capability (ActionInspect rules ignored).
|
|
TLS *TLSConfig
|
|
|
|
// Envoy configuration (ModeEnvoy only)
|
|
Envoy *EnvoyConfig
|
|
|
|
// ListenAddr is the TPROXY listen address for kernel mode.
|
|
// Zero value disables the TPROXY listener.
|
|
ListenAddr netip.AddrPort
|
|
// WGNetwork is the WireGuard overlay network prefix.
|
|
// The proxy blocks dialing destinations inside this network.
|
|
WGNetwork netip.Prefix
|
|
// LocalIPChecker reports whether an IP belongs to the routing peer.
|
|
// Used to prevent SSRF to local services. May be nil.
|
|
LocalIPChecker LocalIPChecker
|
|
}
|
|
|
|
// EnvoyConfig holds configuration for the envoy sidecar mode.
|
|
type EnvoyConfig struct {
|
|
// BinaryPath is the path to the envoy binary.
|
|
// Empty means search $PATH for "envoy".
|
|
BinaryPath string
|
|
// AdminPort is the port for envoy's admin API (health checks, stats).
|
|
// Zero means auto-assign.
|
|
AdminPort uint16
|
|
// Snippets are user-provided config fragments merged into the generated bootstrap.
|
|
Snippets *EnvoySnippets
|
|
}
|
|
|
|
// EnvoySnippets holds user-provided YAML fragments for envoy config customization.
|
|
// Only safe snippet types are allowed: filters (HTTP and network) and clusters
|
|
// needed as dependencies for filter services. Listeners and bootstrap overrides
|
|
// are not exposed since we manage the listener and bootstrap.
|
|
type EnvoySnippets struct {
|
|
// HTTPFilters is YAML injected into the HCM filter chain before the router filter.
|
|
// Used for ext_authz, rate limiting, Lua, Wasm, RBAC, JWT auth, etc.
|
|
HTTPFilters string
|
|
// NetworkFilters is YAML injected into the TLS filter chain before tcp_proxy.
|
|
// Used for network-level RBAC, rate limiting, ext_authz on raw TCP.
|
|
NetworkFilters string
|
|
// Clusters is YAML for additional upstream clusters referenced by filters.
|
|
// Needed when filters call external services (ext_authz backend, rate limit service).
|
|
Clusters string
|
|
}
|