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 ¶
const ( PolicyInternal = "internal" // private networks are allowed (the default) PolicyPublic = "public" // public addresses only )
Address policies of a domain (internal/ca: AddressInternal, AddressPublic).
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 ¶
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 ¶
DNSProblem names the kind of a DNS error, without the resolver's address.
func NetProblem ¶
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 ¶
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 ¶
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.
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.