Documentation
¶
Index ¶
- func Check(tld string) (bool, error)
- func ConfigureResolver() error
- func DebounceEvents(in <-chan struct{}, out chan<- struct{}, wait time.Duration, ...)
- func InstallSudoers() error
- func LinkChanges(out chan<- struct{}, done <-chan struct{}) error
- func ReadContainerDNS() []string
- func ReadUpstreamDNS() []string
- func RepairPossible() bool
- func ResolverHint() string
- func Setup() errordeprecated
- func Teardown()
- func VPNActive() bool
- func WaitReady(timeout time.Duration) error
- func WriteDnsmasqConfig(dir string) error
- func WriteDnsmasqConfigDual(dir, v4Target, v6Target string) error
- func WriteDnsmasqConfigFor(dir, target string) error
- type Diagnostic
- type Status
- type Step
- type StepStatus
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Check ¶
Check resolves test-lerd-probe.{tld} and reports whether the answer is one the lerd dnsmasq could legitimately return. With lan:expose off, the expected answer is 127.0.0.1 (loopback). With lan:expose on, the dnsmasq answers with the host's primary LAN IP so remote clients can reach the actual nginx instance, but the local host still routes those packets through its own loopback interface so the site is reachable from the server itself too.
Returns (true, nil) if DNS resolution is working correctly for the given TLD in either mode.
func ConfigureResolver ¶ added in v0.1.53
func ConfigureResolver() error
ConfigureResolver configures the system DNS resolver to forward .test to the lerd-dns dnsmasq container on port 5300. Call this after lerd-dns is running so that any immediate resolvectl changes don't break DNS before dnsmasq is up.
func DebounceEvents ¶ added in v1.22.0
func DebounceEvents(in <-chan struct{}, out chan<- struct{}, wait time.Duration, done <-chan struct{})
DebounceEvents collapses a burst on in into a single emit on out after wait of silence. The first event after silence starts the timer; every later event during the window resets it. done closes shut the goroutine down on caller exit. Used by both the lerd-watcher and lerd-ui processes to smooth the kernel's RTM_NEWLINK / RTM_NEWADDR burst that follows a single VPN connect or disconnect into one settled reaction.
func InstallSudoers ¶ added in v0.3.0
func InstallSudoers() error
InstallSudoers writes a sudoers drop-in granting the current user passwordless access to resolvectl commands. This is required for the autostart service which runs non-interactively and cannot prompt for a sudo password.
func LinkChanges ¶ added in v1.22.0
func LinkChanges(out chan<- struct{}, done <-chan struct{}) error
LinkChanges opens an rtnetlink multicast subscription and emits a struct{} on out every time the kernel reports a link or address state change. Message contents are intentionally discarded: callers re-fingerprint the host DNS environment on each settled event, so we only need the "something moved" signal. Returns nil after done closes, or a non-nil error if the netlink socket can't be opened or bound so the caller can log a one-shot warning before falling back to its time-based poll.
func ReadContainerDNS ¶ added in v1.0.4
func ReadContainerDNS() []string
ReadContainerDNS returns DNS servers for aardvark-dns on the lerd network, preferring pasta's info.json (typically 169.254.1.1) and falling back to host upstreams then pastaDefaultForwarder so the list is never empty.
func ReadUpstreamDNS ¶ added in v1.0.3
func ReadUpstreamDNS() []string
ReadUpstreamDNS returns upstream DNS server IPs from the running system. Sources tried in order:
- /run/systemd/resolve/resolv.conf — real upstreams on systemd-resolved systems
- /etc/resolv.conf — fallback
- nmcli — DHCP-provided DNS from NetworkManager
Returns nil if nothing is found; callers should omit no-resolv in that case.
func RepairPossible ¶ added in v1.20.0
func RepairPossible() bool
RepairPossible reports whether the DNS watcher can fix /etc/resolv.conf or NetworkManager configuration from the current process. Linux's repair path runs through systemd-resolved / nmcli / resolvectl and does not require root for the user-scoped commands lerd issues, so this is always true. Mirrors the macOS variant which gates on whether the lerd passwordless-sudo drop-in is in place.
func ResolverHint ¶ added in v1.6.0
func ResolverHint() string
ResolverHint returns a user-facing hint for restarting the active DNS resolver.
func Setup
deprecated
func Setup() error
Setup writes DNS configuration for .test resolution and restarts the resolver. On systemd-resolved + NetworkManager systems (Ubuntu etc.) it uses an NM dispatcher script. On pure systemd-resolved systems it uses a resolved drop-in. On NetworkManager-only systems it uses NM's embedded dnsmasq.
Deprecated: prefer calling WriteDnsmasqConfig then ConfigureResolver separately so that the dnsmasq container can be started between the two steps.
func Teardown ¶ added in v0.1.55
func Teardown()
Teardown removes all lerd DNS configuration from the system and restores normal resolution.
func VPNActive ¶ added in v1.22.0
func VPNActive() bool
VPNActive reports whether a VPN tunnel interface is currently up. It is used to word the "DNS degraded" hint and the doctor diagnostic, since a VPN client rewriting the system resolver is by far the most common cause of the system-resolver path failing while lerd-dns itself stays healthy. Detection is name-prefix first and falls back to the POINTOPOINT flag so branded clients (ProtonVPN's proton0, Mullvad's wg variants, custom names) are recognised even when they don't follow the conventional prefix.
func WaitReady ¶ added in v0.4.3
WaitReady blocks until lerd-dns is accepting TCP connections on port 5300 (dnsmasq supports DNS over TCP), or until the timeout elapses. Returns nil when ready, error on timeout.
func WriteDnsmasqConfig ¶
WriteDnsmasqConfig writes the lerd dnsmasq config to the given directory, auto-detecting the right target based on whether `lerd lan:expose` is on.
When cfg.LAN.Exposed is false the config answers .test queries with 127.0.0.1 / ::1, suitable for local-only use. When it's true the config answers with the host's primary LAN IP (v4 + v6 when available) so remote clients reach the actual nginx instance through the lerd-dns-forwarder service.
func WriteDnsmasqConfigDual ¶ added in v1.18.0
WriteDnsmasqConfigDual is the v4+v6 form of WriteDnsmasqConfigFor. Pass v6Target = "" to skip the AAAA record entirely.
func WriteDnsmasqConfigFor ¶ added in v1.8.0
WriteDnsmasqConfigFor writes the lerd dnsmasq config with `target` as the IPv4 answer for `*.test`. An AAAA pair is derived (::1 locally, host's global v6 when LAN-exposed). Upstreams come from the system; if none are usable, the pasta default forwarder is used so .test routing keeps working.
Types ¶
type Diagnostic ¶ added in v1.19.0
type Diagnostic struct {
TLD string `json:"tld"`
Steps []Step `json:"steps"`
FirstFailure int `json:"first_failure"`
}
Diagnostic is the result of walking the DNS chain end to end. Steps are returned in chain order; FirstFailure points at the index of the first rung that returned Fail (or -1 when everything passed).
func Diagnose ¶ added in v1.19.0
func Diagnose(tld string) Diagnostic
Diagnose walks the DNS chain top to bottom and returns a structured result. tld defaults to "test" when empty.
type Status ¶ added in v1.22.0
type Status string
Status is the three-way DNS health the dashboard pill renders. It exists to separate a genuine lerd-dns outage from the common case where lerd-dns is perfectly healthy but the system resolver isn't routing the TLD to it, which a VPN client typically causes by rewriting systemd-resolved when it connects.
func CheckStatus ¶ added in v1.22.0
CheckStatus reports three-way DNS health. It runs Check first (the end-to-end system-resolver path); when that fails it queries lerd's dnsmasq directly on 127.0.0.1:5300. A direct answer means lerd-dns is up and only the resolver hookup is bypassed, so the result is Degraded rather than Down.
type Step ¶ added in v1.19.0
type Step struct {
Name string `json:"name"`
Status StepStatus `json:"status"`
Detail string `json:"detail,omitempty"`
Hint string `json:"hint,omitempty"`
}
Step is a single rung in the layered diagnostic. Higher rungs can only pass when the lower ones do; once a rung fails, the orchestrator marks every subsequent rung Skip with a brief reason so the user sees exactly where the chain breaks without a wall of cascaded failures.
type StepStatus ¶ added in v1.19.0
type StepStatus string
StepStatus is the outcome of a single rung in the layered DNS check.
const ( StepOK StepStatus = "ok" StepFail StepStatus = "fail" StepWarn StepStatus = "warn" StepSkip StepStatus = "skip" )