proxy

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Forward

func Forward(ctx context.Context, client, upstream net.Conn, peeked []byte, logger zerolog.Logger)

Forward pipes data bidirectionally between client and upstream, replaying peeked ClientHello bytes to upstream first.

func LimitWriter added in v0.15.0

func LimitWriter(w io.Writer, n int64) io.Writer

LimitWriter returns a writer that writes at most n bytes to w.

func LoadOrCreateCA added in v0.15.0

func LoadOrCreateCA(dir string) (*x509.Certificate, *ecdsa.PrivateKey, *tls.Certificate, error)

LoadOrCreateCA loads an existing CA certificate and key from dir, or generates a new self-signed CA if none exists. Returns the parsed certificate, private key, and a tls.Certificate ready for signing leaf certs.

func LogModeString added in v0.15.0

func LogModeString(m LogMode) string

LogModeString returns the string representation of a LogMode.

func PeekClientHello

func PeekClientHello(conn net.Conn) (peeked []byte, serverName string, err error)

PeekClientHello reads the TLS ClientHello from conn without consuming it. Returns the peeked bytes (to replay to upstream) and the extracted SNI hostname.

func RemoveStats added in v0.14.0

func RemoveStats(path string)

RemoveStats removes the proxy stats file (best-effort).

func SetLogMode added in v0.15.0

func SetLogMode(mode LogMode)

SetLogMode sets the global traffic log mode.

func StatsPath added in v0.14.0

func StatsPath() string

StatsPath returns the default path for the proxy stats file (~/.human/proxy-stats.json).

func WriteStats added in v0.14.0

func WriteStats(path string, s Stats) error

WriteStats atomically writes stats to path (write tmp + rename).

Types

type Config

type Config struct {
	Mode      Mode     `mapstructure:"mode"`
	Domains   []string `mapstructure:"domains"`
	Intercept []string `mapstructure:"intercept"` // domains to MITM for traffic logging
}

Config holds the proxy section of .humanconfig.yaml.

func LoadConfig

func LoadConfig(dir string) (*Config, error)

LoadConfig reads the proxy configuration from .humanconfig.yaml in dir. Returns (nil, nil) when the proxy section is absent.

type Decider

type Decider interface {
	Allowed(hostname string) bool
}

Decider decides whether a given hostname is allowed to pass through the proxy.

type InteractiveDecider

type InteractiveDecider struct {
	// contains filtered or unexported fields
}

InteractiveDecider wraps a base Decider and prompts the user for hostnames that the base does not allow. Decisions are cached for the session.

func NewInteractiveDecider

func NewInteractiveDecider(base Decider, prompt PromptFunc) *InteractiveDecider

NewInteractiveDecider creates an InteractiveDecider that falls through to prompt for hostnames not allowed by base.

func (*InteractiveDecider) Allowed

func (d *InteractiveDecider) Allowed(hostname string) bool

Allowed returns true if the hostname is permitted. Hostnames allowed by the base decider pass through immediately. Unknown hostnames trigger a prompt; the result is cached for subsequent calls.

type Interceptor added in v0.15.0

type Interceptor interface {
	// ShouldIntercept returns true if this domain should be MITM'd.
	ShouldIntercept(hostname string) bool
	// Intercept handles a MITM'd connection. The peeked bytes contain the
	// already-read ClientHello that must be replayed into the TLS handshake.
	Intercept(ctx context.Context, conn net.Conn, hostname string, peeked []byte) error
}

Interceptor can intercept and inspect decrypted traffic for specific domains.

type LeafCache added in v0.15.0

type LeafCache struct {
	CACert *x509.Certificate
	CAKey  *ecdsa.PrivateKey
	// contains filtered or unexported fields
}

LeafCache generates and caches per-domain TLS certificates signed by a CA.

func (*LeafCache) Get added in v0.15.0

func (lc *LeafCache) Get(hostname string) (*tls.Certificate, error)

Get returns a cached leaf certificate for hostname, or generates a new one.

type LogMode added in v0.15.0

type LogMode int32

LogMode controls the verbosity of traffic logging.

const (
	LogModeOff  LogMode = 0 // no logging (default, zero value)
	LogModeMeta LogMode = 1 // log method, path, status, body_size only
	LogModeFull LogMode = 2 // log everything including body
)

func GetLogMode added in v0.15.0

func GetLogMode() LogMode

GetLogMode returns the current global traffic log mode.

func ParseLogMode added in v0.15.0

func ParseLogMode(s string) (LogMode, error)

ParseLogMode parses a string into a LogMode.

type LoggingInterceptor added in v0.15.0

type LoggingInterceptor struct {
	Domains   []string // exact domain matches to intercept
	LeafCache *LeafCache
	Logger    zerolog.Logger
	LogDir    string // directory for traffic log files

	// Dialer connects to upstream servers. Injected for testing.
	// If nil, tls.Dial is used.
	Dialer func(ctx context.Context, network, address string) (net.Conn, error)
}

LoggingInterceptor performs MITM interception for configured domains, logging HTTP request/response bodies to JSON-lines files.

func (*LoggingInterceptor) Intercept added in v0.15.0

func (li *LoggingInterceptor) Intercept(ctx context.Context, conn net.Conn, hostname string, peeked []byte) error

Intercept performs a MITM TLS handshake with the client, dials the real upstream, and proxies HTTP traffic while logging request/response bodies.

func (*LoggingInterceptor) ShouldIntercept added in v0.15.0

func (li *LoggingInterceptor) ShouldIntercept(hostname string) bool

ShouldIntercept returns true if hostname matches a configured intercept domain.

type Mode

type Mode string

Mode determines whether the domain list is an allowlist or blocklist.

const (
	ModeAllow Mode = "allowlist"
	ModeBlock Mode = "blocklist"
)

type Policy

type Policy struct {
	// contains filtered or unexported fields
}

Policy decides whether a given hostname is allowed to pass through the proxy.

func BlockAllPolicy

func BlockAllPolicy() *Policy

BlockAllPolicy returns a policy that blocks every hostname.

func NewPolicy

func NewPolicy(mode Mode, domains []string) (*Policy, error)

NewPolicy creates a policy from a mode and domain list.

func (*Policy) Allowed

func (p *Policy) Allowed(hostname string) bool

Allowed reports whether hostname is permitted by this policy.

type PromptFunc

type PromptFunc func(hostname string) (bool, error)

PromptFunc asks the user whether a hostname should be allowed. It returns true to allow, false to deny.

func NewTerminalPrompt

func NewTerminalPrompt(in io.Reader, out io.Writer) PromptFunc

NewTerminalPrompt returns a PromptFunc that asks the user via the terminal. It serialises I/O with its own mutex so that concurrent prompts don't interleave on the terminal.

type Server

type Server struct {
	Addr        string
	Policy      Decider
	Interceptor Interceptor // optional: MITM interceptor for specific domains
	Logger      zerolog.Logger
	// Dialer connects to upstream servers. Injected for testing.
	Dialer func(ctx context.Context, network, address string) (net.Conn, error)
	// contains filtered or unexported fields
}

Server is a transparent HTTPS proxy that reads the SNI from TLS ClientHello to block/allow domains without decrypting traffic. Domains listed in the Interceptor are MITM'd for traffic inspection/logging.

func (*Server) ActiveConns added in v0.14.0

func (s *Server) ActiveConns() int64

ActiveConns returns the number of currently active forwarded connections.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe(ctx context.Context) error

ListenAndServe starts the TCP listener and blocks until ctx is cancelled.

type Stats added in v0.14.0

type Stats struct {
	ActiveConns int64 `json:"active_conns"`
}

Stats holds proxy runtime metrics written by the daemon and read by the TUI.

func ReadStats added in v0.14.0

func ReadStats(path string) Stats

ReadStats reads proxy stats from path. Returns zero stats on any error.

type TrafficLog added in v0.15.0

type TrafficLog struct {
	Timestamp time.Time `json:"ts"`
	Direction string    `json:"dir"` // "request" or "response"
	Host      string    `json:"host"`
	Method    string    `json:"method,omitempty"` // request only
	Path      string    `json:"path,omitempty"`   // request only
	Status    int       `json:"status,omitempty"` // response only
	Body      string    `json:"body"`
	BodySize  int64     `json:"body_size"`
}

TrafficLog is a single JSON-lines entry written to the traffic log.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL