netguard

package
v0.3.6 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package netguard is the one place that decides where the server may connect on behalf of somebody else's input (security.md "ACME validation = outbound requests to attacker-chosen names"). The http-01 validator, the agent enrollment check and the TLS scan all dial through it, so there is one address policy and one set of tests:

  • a name is resolved once and the connection goes to exactly the address that was checked – no DNS rebinding between check and connect;
  • the address policy of a domain decides which addresses are allowed; loopback, link-local, multicast, unspecified, reserved and other not globally reachable addresses never are;
  • the caller decides which ports are allowed (CheckPort); without that function every port is refused;
  • the client learns counts and kinds of failures, never addresses or what a target said – the server log keeps the details.

Index

Constants

View Source
const (
	PolicyInternal = "internal" // private networks are allowed (the default)
	PolicyPublic   = "public"   // public addresses only
)

Address policies of a domain (internal/ca: AddressInternal, AddressPublic).

View Source
const (
	KindDNS        = "dns"        // the name could not be resolved
	KindConnection = "connection" // no address could be reached or was allowed
)

Kinds of an *Error.

Variables

This section is empty.

Functions

func Allowed

func Allowed(a netip.Addr, policy string) error

Allowed applies the address policy: nil if a may be connected to under policy ("internal" or "public"). The error names the address and the rule – for the log, not for the client.

func DNSProblem

func DNSProblem(err error) string

DNSProblem names the kind of a DNS error, without the resolver's address.

func NetProblem

func NetProblem(err error) string

NetProblem names the kind of a network error – never its text, which can carry what the target sent (a malformed HTTP response quotes it).

func NewResolver

func NewResolver(resolverAddr string) *net.Resolver

NewResolver returns the resolver for names the server connects to: resolverAddr ("IP:port") instead of the system's when set (acme.resolver).

Types

type DialFunc

type DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)

DialFunc and LookupFunc are the network edges. Tests replace them, never the rules around them.

type Dialer

type Dialer struct {
	Policy   string
	Dial     DialFunc   // nil = net.Dialer
	LookupIP LookupFunc // required for names (an IP literal needs none)
	// CheckPort decides which ports may be dialed; its error is returned as
	// is, before anything is resolved. nil refuses every port.
	CheckPort func(port uint16) error
	// Log gets one line per refused or failed address, with LogName as the
	// start of the message ("acme validation"). nil = no log.
	Log      *slog.Logger
	LogName  string
	LogLevel slog.Level // the zero value is Info
	// MaxTries limits the addresses that are dialed (0 = all); TryTimeout
	// limits each dial (0 = only the context).
	MaxTries   int
	TryTimeout time.Duration
}

Dialer resolves once, checks every address and connects to an allowed one.

func (*Dialer) DialContext

func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

DialContext has the signature of http.Transport.DialContext.

type Error

type Error struct {
	Kind, Detail string
	// Refused: every usable address was refused by the address policy.
	Refused bool
	// Err is the last underlying error. It is not part of the text (it can
	// carry what the target sent); callers classify it with errors.Is/As.
	Err error
}

Error is a refused or failed connect with text that is safe to show to the client who asked for it: counts and kinds, never an address.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the last underlying error, if any.

type LookupFunc

type LookupFunc func(ctx context.Context, host string) ([]netip.Addr, error)

DialFunc and LookupFunc are the network edges. Tests replace them, never the rules around them.

Jump to

Keyboard shortcuts

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