Health: show IPv6 uplink and public IPv4/IPv6 addresses

The uplink check only reported the IPv4 default route. Split it into
IPv4 and IPv6 uplink rows, and add a public address row for each, read
from the uplink interface (private addresses are shown as behind NAT).
This commit is contained in:
Daniel Redetzke
2026-10-04 00:39:13 +03:00
parent 7d4cd48ca4
commit 3a93ec35ee
2 changed files with 46 additions and 2 deletions
+44 -1
View File
@@ -287,6 +287,37 @@ func lanNetworks(uplink string) []netip.Prefix {
return out return out
} }
// publicAddr reports the uplink's address for the health check: the first
// public one, or else the first private one, marked as behind NAT. It reads
// the interface rather than asking an outside service.
func publicAddr(uplink string, v6 bool) (bool, string) {
l, err := netlink.LinkByName(uplink)
if err != nil {
return false, uplink + " not found"
}
family := netlink.FAMILY_V4
if v6 {
family = netlink.FAMILY_V6
}
addrs, _ := netlink.AddrList(l, family)
var private string
for _, a := range addrs {
if !a.IP.IsGlobalUnicast() {
continue
}
if !a.IP.IsPrivate() {
return true, a.IP.String()
}
if private == "" {
private = a.IP.String()
}
}
if private != "" {
return true, private + " (private, behind NAT)"
}
return false, "no address on " + uplink
}
func readSysctl(path string) string { func readSysctl(path string) string {
b, err := os.ReadFile(path) b, err := os.ReadFile(path)
if err != nil { if err != nil {
@@ -313,7 +344,19 @@ func (k *linuxKernel) Checks(c *Config) []Check {
ok, detail := firewallPresent() ok, detail := firewallPresent()
out = append(out, Check{"nftables rules", ok, detail}) out = append(out, Check{"nftables rules", ok, detail})
up4 := k.Uplink(c, false) up4 := k.Uplink(c, false)
out = append(out, Check{"Uplink", up4 != "", map[bool]string{true: "IPv4 via " + up4, false: "no default route found"}[up4 != ""]}) out = append(out, Check{"IPv4 uplink", up4 != "", map[bool]string{true: "via " + up4, false: "no default route found"}[up4 != ""]})
if up4 != "" {
ok, detail := publicAddr(up4, false)
out = append(out, Check{"Public IPv4", ok, detail})
}
if c.Server.IPv6Enabled {
up6 := k.Uplink(c, true)
out = append(out, Check{"IPv6 uplink", up6 != "", map[bool]string{true: "via " + up6, false: "no default route found"}[up6 != ""]})
if up6 != "" {
ok, detail := publicAddr(up6, true)
out = append(out, Check{"Public IPv6", ok, detail})
}
}
return out return out
} }
+2 -1
View File
@@ -73,7 +73,8 @@ func (k *simKernel) Checks(c *Config) []Check {
{"WireGuard interface", true, c.Server.Interface + " is up"}, {"WireGuard interface", true, c.Server.Interface + " is up"},
{"IPv4 forwarding", true, "net.ipv4.ip_forward=1"}, {"IPv4 forwarding", true, "net.ipv4.ip_forward=1"},
{"nftables rules", true, "table inet " + appName + " present"}, {"nftables rules", true, "table inet " + appName + " present"},
{"Uplink", true, "IPv4 via eth0"}, {"IPv4 uplink", true, "via eth0"},
{"Public IPv4", true, "203.0.113.10"},
} }
} }