Documentation
¶
Overview ¶
Package network: container DNS resolution.
DNSServer is a small authoritative+forwarding DNS server that:
- Resolves container names (a/b -> 172.17.0.x) locally.
- Forwards everything else to upstream resolvers (host resolv.conf by default).
- Caches both positive and negative responses with TTL.
- Handles concurrent queries safely.
- Supports both UDP and TCP (RFC 5966).
- Handles A and AAAA queries.
It binds to 127.0.0.11:53 (well-known, like Docker) by default and is exposed on the container's loopback inside the namespace via the runtime's network setup. Containers get 127.0.0.11 in their /etc/resolv.conf.
Package network provides a unified firewall interface via the `firewall` sub-package. This file re-exports the new Manager type for callers that want auto-detection between nftables and iptables.
Package network provides container networking.
Index ¶
- func AndroidDNSServers() []string
- func DNSWellKnownAddress() string
- func DefaultCNIPlugins() []string
- func IsCNIAvailable() bool
- func IsIptablesAvailable() bool
- func IsNftablesAvailable() bool
- func IsPastaAvailable() bool
- func IsSlirp4netnsAvailable() bool
- func NewAutoFirewallManager() (firewall.Manager, error)
- func NewFirewallManagerWithBackend(b firewall.Backend) (firewall.Manager, error)
- func ValidatePortBinding(hostPort uint16, privileged bool) error
- type AdvancedDNS
- type CNIManager
- type CNIPlugin
- type CacheConfig
- type DNSSECConfig
- type DNSSECValidator
- type DNSServer
- func (d *DNSServer) AddEntry(name, ip string)
- func (d *DNSServer) Addr() string
- func (d *DNSServer) CacheCapacity() int
- func (d *DNSServer) EntryCount() int
- func (d *DNSServer) RemoveEntry(name string)
- func (d *DNSServer) Resolve(name string) (string, bool)
- func (d *DNSServer) ResolveAAAA(name string) (string, bool)
- func (d *DNSServer) ResolvePTR(ip string) (string, bool)
- func (d *DNSServer) Start(addr string) error
- func (d *DNSServer) Stats() map[string]uint64
- func (d *DNSServer) Stop()
- func (d *DNSServer) Upstreams() []string
- type DomainResolver
- type DomainRule
- type Endpoint
- type FirewallBackend
- type FirewallManager
- type Manager
- func (m *Manager) ApplyPortForwardings(containerID string, ports []common.Port, _ int) error
- func (m *Manager) Connect(networkID, containerID string, ipAddr string, aliases []string, ...) error
- func (m *Manager) ContainerIP(networkName, containerID string) string
- func (m *Manager) CreateNetwork(cfg *NetworkConfig) (*Network, error)
- func (m *Manager) Disconnect(networkID, containerID string, containerPid int) error
- func (m *Manager) GetNetwork(idOrName string) (*Network, error)
- func (m *Manager) Inspect(idOrName string) (*common.NetworkInfo, error)
- func (m *Manager) ListNetworks() ([]common.NetworkInfo, error)
- func (m *Manager) Prune() ([]string, error)
- func (m *Manager) ReRegisterDNS(containerID string)
- func (m *Manager) RemoveNetwork(idOrName string) error
- func (m *Manager) RemovePortForwardings(containerID string)
- func (m *Manager) SetupNetwork(containerID string, containerPid int, networkName string) error
- func (m *Manager) TeardownNetwork(containerID string, networkName string) error
- type Network
- type NetworkConfig
- type PastaManager
- type PersistentCache
- type PortForwarder
- type PortMap
- type ResolvConf
- type SRVRecord
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AndroidDNSServers ¶
func AndroidDNSServers() []string
AndroidDNSServers discovers DNS servers on Android via getprop. Android does not use /etc/resolv.conf — DNS is managed by netd. Returns servers as "host:port" strings suitable for upstream dialing.
func DNSWellKnownAddress ¶
func DNSWellKnownAddress() string
DNSWellKnownAddress returns the well-known address for the internal DNS server. Docker uses 127.0.0.11:53; on Android we use 127.0.0.11:8053 (port 53 is blocked).
BUG-09 fix: the previous implementation unconditionally returned port 53, which fails on Android where port 53 requires root. Now checks the DOKI_DNS_LISTEN environment variable first, then falls back to 8053 on Android (detected via /data/data/com.termux), and 53 elsewhere.
func DefaultCNIPlugins ¶
func DefaultCNIPlugins() []string
DefaultCNIPlugins returns standard CNI plugin names.
func IsCNIAvailable ¶
func IsCNIAvailable() bool
IsCNIAvailable checks if CNI plugins are installed.
func IsIptablesAvailable ¶
func IsIptablesAvailable() bool
IsIptablesAvailable checks if iptables is available.
func IsNftablesAvailable ¶
func IsNftablesAvailable() bool
IsNftablesAvailable checks if nftables is available.
func IsPastaAvailable ¶
func IsPastaAvailable() bool
IsPastaAvailable checks if pasta is available for rootless networking.
func IsSlirp4netnsAvailable ¶
func IsSlirp4netnsAvailable() bool
IsSlirp4netnsAvailable checks if slirp4netns is available.
func NewAutoFirewallManager ¶ added in v0.12.0
NewAutoFirewallManager returns a firewall.Manager that auto-detects nftables first, then iptables. It is the recommended way to construct the firewall in 2026: nftables is preferred on every modern distro (Fedora 40+, Ubuntu 24.04+, RHEL 10+, openSUSE Leap 16+).
func NewFirewallManagerWithBackend ¶ added in v0.12.0
NewFirewallManagerWithBackend returns a manager that forces a specific backend. Pass firewall.BackendNFTables or firewall.BackendIPTables.
func ValidatePortBinding ¶
AE10: ValidatePortBinding checks if a port binding is allowed.
Types ¶
type AdvancedDNS ¶ added in v0.10.0
type AdvancedDNS struct {
// contains filtered or unexported fields
}
AdvancedDNS provides SRV resolution, DNSSEC validation, persistent caching, and domain rules.
func NewAdvancedDNS ¶ added in v0.10.0
func NewAdvancedDNS() *AdvancedDNS
NewAdvancedDNS creates a new AdvancedDNS instance.
func (*AdvancedDNS) ConfigureCache ¶ added in v0.10.0
func (a *AdvancedDNS) ConfigureCache(cfg CacheConfig) error
ConfigureCache initializes the persistent DNS cache with the given configuration.
func (*AdvancedDNS) ConfigureDNSSEC ¶ added in v0.10.0
func (a *AdvancedDNS) ConfigureDNSSEC(cfg DNSSECConfig)
ConfigureDNSSEC enables DNSSEC validation with the given configuration.
func (*AdvancedDNS) ConfigureDomains ¶ added in v0.10.0
func (a *AdvancedDNS) ConfigureDomains(rules []DomainRule)
ConfigureDomains sets domain resolution rules.
func (*AdvancedDNS) ConfigureSRV ¶ added in v0.10.0
func (a *AdvancedDNS) ConfigureSRV(records []SRVRecord)
ConfigureSRV sets the SRV records for the advanced DNS resolver.
type CNIManager ¶
type CNIManager struct {
// contains filtered or unexported fields
}
CNIManager manages CNI plugins and network configuration.
func NewCNIManager ¶
func NewCNIManager(pluginDir, configDir string) *CNIManager
NewCNIManager creates a CNI manager.
func (*CNIManager) AvailablePlugins ¶
func (c *CNIManager) AvailablePlugins() []string
AvailablePlugins returns list of available plugins.
func (*CNIManager) LoadPlugins ¶
func (c *CNIManager) LoadPlugins() error
LoadPlugins discovers available CNI plugins.
type CacheConfig ¶ added in v0.10.0
type CacheConfig struct {
Persistent bool `json:"persistent"`
Path string `json:"path"`
MaxEntries int `json:"max_entries"`
PositiveTTL string `json:"positive_ttl"`
NegativeTTL string `json:"negative_ttl"`
}
CacheConfig holds persistent DNS cache settings.
type DNSSECConfig ¶ added in v0.10.0
type DNSSECConfig struct {
Enabled bool `json:"enabled"`
Anchors []string `json:"anchors"`
Validate bool `json:"validate"`
}
DNSSECConfig holds DNSSEC validation settings.
type DNSSECValidator ¶ added in v0.10.0
type DNSSECValidator struct {
// contains filtered or unexported fields
}
DNSSECValidator validates DNS responses using DNSSEC trust anchors.
type DNSServer ¶
type DNSServer struct {
// contains filtered or unexported fields
}
DNSServer provides internal DNS resolution for containers.
func NewDNSServer ¶
NewDNSServer creates a DNS server with the given upstream resolvers. If upstreams is empty, tries Android DNS discovery (getprop), then host /etc/resolv.conf, falls back to 8.8.8.8 + 1.1.1.1.
func (*DNSServer) AddEntry ¶
AddEntry registers a name -> IP mapping. Supports both IPv4 and IPv6. id-qualified names (a/b, container_id) take precedence over plain aliases.
func (*DNSServer) Addr ¶
Addr returns the actual bound address (e.g. "127.0.0.11:53"). Empty string if not yet started.
func (*DNSServer) CacheCapacity ¶
CacheCapacity returns the number of cached entries.
func (*DNSServer) EntryCount ¶
EntryCount returns the number of registered DNS entries.
func (*DNSServer) RemoveEntry ¶
RemoveEntry removes a name -> ip mapping.
func (*DNSServer) Resolve ¶
Resolve returns the locally-registered IPv4 for name, or empty string + false.
func (*DNSServer) ResolveAAAA ¶
ResolveAAAA returns the locally-registered IPv6 for name, or empty string + false.
func (*DNSServer) ResolvePTR ¶
ResolvePTR returns the name for a given IP address (reverse lookup). IP can be in standard form (e.g. "172.17.0.2" or "::1").
func (*DNSServer) Start ¶
Start binds the UDP and TCP sockets and begins serving. addr can be "127.0.0.11:53" or "127.0.0.1:0" for ephemeral.
type DomainResolver ¶ added in v0.10.0
type DomainResolver struct {
// contains filtered or unexported fields
}
DomainResolver resolves domain names using pattern-based rules.
type DomainRule ¶ added in v0.10.0
type DomainRule struct {
Pattern string `json:"pattern"`
Target string `json:"target"`
TTL uint32 `json:"ttl"`
}
DomainRule defines a pattern-based domain resolution rule.
type Endpoint ¶
type Endpoint struct {
EndpointID string `json:"EndpointID"`
MacAddress string `json:"MacAddress"`
IPv4Address string `json:"IPv4Address"`
IPv6Address string `json:"IPv6Address"`
VethHost string `json:"VethHost,omitempty"`
VethPeer string `json:"VethPeer,omitempty"`
Aliases []string `json:"Aliases,omitempty"`
PortMapping []PortMap `json:"PortMapping,omitempty"`
}
Endpoint represents a container endpoint in a network.
type FirewallBackend ¶
type FirewallBackend string
FirewallBackend represents a firewall backend.
const ( FirewallIptables FirewallBackend = "iptables" FirewallNftables FirewallBackend = "nftables" )
func DetectFirewallBackend ¶
func DetectFirewallBackend() FirewallBackend
DetectFirewallBackend auto-detects the best firewall backend.
type FirewallManager ¶
type FirewallManager struct {
// contains filtered or unexported fields
}
FirewallManager manages firewall rules for containers.
func NewFirewallManager ¶
func NewFirewallManager(backend FirewallBackend) *FirewallManager
NewFirewallManager creates a firewall manager.
func (*FirewallManager) AddPortMapping ¶
func (f *FirewallManager) AddPortMapping(containerIP string, hostPort, containerPort int, proto string) error
AddPortMapping adds a port mapping rule.
func (*FirewallManager) RemovePortMapping ¶
func (f *FirewallManager) RemovePortMapping(containerIP string, hostPort, containerPort int, proto string) error
RemovePortMapping removes a port mapping rule.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages container networks.
func NewManager ¶
func NewManager(root string, firewall *FirewallManager, dns *DNSServer) (*Manager, error)
NewManager creates a new network manager.
func (*Manager) ApplyPortForwardings ¶
ApplyPortForwardings creates TCP/UDP proxies from host ports to container ports.
func (*Manager) Connect ¶
func (m *Manager) Connect(networkID, containerID string, ipAddr string, aliases []string, ports []PortMap, containerPid int) error
Connect connects a container to a network and configures networking.
func (*Manager) ContainerIP ¶ added in v0.12.0
ContainerIP returns the IPv4 address allocated to containerID on the named network, or "" if it has no endpoint there. Used by the CRI to report a pod's IP in PodSandboxStatus.
func (*Manager) CreateNetwork ¶
func (m *Manager) CreateNetwork(cfg *NetworkConfig) (*Network, error)
CreateNetwork creates a new network.
func (*Manager) Disconnect ¶
Disconnect disconnects a container from a network and removes configuration.
func (*Manager) GetNetwork ¶
GetNetwork returns a network by ID or name.
func (*Manager) Inspect ¶
func (m *Manager) Inspect(idOrName string) (*common.NetworkInfo, error)
Inspect returns network details.
func (*Manager) ListNetworks ¶
func (m *Manager) ListNetworks() ([]common.NetworkInfo, error)
ListNetworks returns all networks.
func (*Manager) ReRegisterDNS ¶
ReRegisterDNS re-registers DNS entries for a container across all networks. Used after daemon restart to restore container name resolution.
func (*Manager) RemoveNetwork ¶
RemoveNetwork removes a network.
func (*Manager) RemovePortForwardings ¶
RemovePortForwardings stops all port forwards for a container. Works for both DokiLink-Lite proxies (Close on TCPProxy/UDPProxy) and the legacy socat fallback (execCmdForwarder.Close kills and reaps).
func (*Manager) SetupNetwork ¶
SetupNetwork configures networking for a container. If no endpoint exists yet (Connect was not called), creates one with an IP allocation and registers DNS entries.
func (*Manager) TeardownNetwork ¶
TeardownNetwork removes networking for a container.
BUG-05 fix: the previous implementation called GetNetwork (which releases m.mu.RLock() on return) and then accessed nw.Containers without holding any lock. Concurrent Connect/Disconnect calls (which take m.mu.Lock()) could mutate nw.Containers during the read.
type Network ¶
type Network struct {
ID string `json:"Id"`
Name string `json:"Name"`
Driver string `json:"Driver"`
Subnet string `json:"Subnet"`
Gateway string `json:"Gateway"`
EnableIPv6 bool `json:"EnableIPv6"`
Internal bool `json:"Internal"`
Options map[string]string `json:"Options"`
Labels map[string]string `json:"Labels"`
Containers map[string]*Endpoint `json:"Containers"`
Created time.Time `json:"Created"`
}
Network represents a container network.
type NetworkConfig ¶
type NetworkConfig struct {
Name string
Driver string
Subnet string
Gateway string
EnableIPv6 bool
Internal bool
Options map[string]string
Labels map[string]string
}
NetworkConfig holds configuration for creating a network.
type PastaManager ¶
type PastaManager struct {
// contains filtered or unexported fields
}
PastaManager manages pasta-based rootless networking.
func NewPastaManager ¶
func NewPastaManager() *PastaManager
NewPastaManager creates a pasta manager.
func (*PastaManager) IsAvailable ¶
func (p *PastaManager) IsAvailable() bool
IsAvailable checks if pasta is available.
type PersistentCache ¶ added in v0.10.0
type PersistentCache struct {
// contains filtered or unexported fields
}
PersistentCache stores DNS responses in a SQLite database.
func (*PersistentCache) Close ¶ added in v0.10.0
func (c *PersistentCache) Close()
Close releases the database connection held by the cache.
type PortForwarder ¶ added in v0.9.3
type PortForwarder interface {
Close() error
}
PortForwarder is anything that can be cleanly stopped: a socat process (wrapped in execCmdForwarder) or a DokiLink-Lite proxy (TCPProxy/UDPProxy). The interface lets us mix implementations in the same map and reaps zombie socat children consistently (BUG-11 fix).
func StartPortForwarding ¶
func StartPortForwarding(hostPort int, containerIP string, containerPort int, proto string) (PortForwarder, error)
StartPortForwarding starts a port forward from hostPort to the container's (IP, containerPort) using DokiLink-Lite (pure-Go TCP/UDP proxy). If DokiLink is explicitly disabled via DOKI_USE_SOCAT=1, it falls back to the legacy socat process. The returned value implements PortForwarder (closeable, reaps child processes).
DokiLink-Lite is preferred because:
- It does not require socat to be installed (Termux does not ship it by default; users must `apt install socat`).
- It works on platforms where the kernel blocks fork+exec for network-related syscalls (Android seccomp).
- It can be wrapped in TLS/secretbox in v0.9.3+ (see netlink/crypto.go).
type PortMap ¶
type PortMap struct {
HostPort uint16 `json:"HostPort"`
HostIP string `json:"HostIP"`
Proto string `json:"Proto"`
ContainerPort uint16 `json:"ContainerPort"`
}
PortMap represents a port mapping for an endpoint.
type ResolvConf ¶
ResolvConf holds parsed /etc/resolv.conf content. Nameservers are stored WITHOUT port numbers (resolv.conf format). Use NameserverList() to get host:port format for dialling.
func HostResolvConf ¶
func HostResolvConf() *ResolvConf
HostResolvConf reads the host's /etc/resolv.conf. Falls back to Google DNS if no resolv.conf found.
func ParseResolvConf ¶
func ParseResolvConf(path string) (*ResolvConf, error)
ParseResolvConf parses a resolv.conf file from the given path. Supports: nameserver, search, options, sortlist directives. Lines starting with # or ; are comments. Nameservers are stored as plain IPs (no port) for safe resolv.conf output.
func (*ResolvConf) NameserverList ¶
func (rc *ResolvConf) NameserverList() []string
NameserverList returns the nameservers as host:port strings suitable for dialling. Appends ":53" to nameservers without a port.
BUG-12 fix: the previous code used strings.Contains(ns, ":") to detect whether a port was present. IPv6 addresses contain colons (e.g. "2001:4860:4860::8888") and were incorrectly treated as already having a port. Use net.SplitHostPort to correctly distinguish bare IPs from host:port pairs.