Let jarld recognize this host's addresses under systemd
release / release (push) Successful in 1m58s
release / release (push) Successful in 1m58s
The unit's RestrictAddressFamilies lacked AF_NETLINK, which listing the host's addresses needs, so the name server checks didn't know this server's own addresses: the Name servers tab queried them like another server's, and the delegation check didn't sign them with the view key. Allow AF_NETLINK, and fall back to /proc/net without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9d9ae37367
commit
ecffc2d5c1
4 files changed
+117
-10
No files matched your search
@@ -15,10 +15,13 @@ package nscheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -257,20 +260,67 @@ func IsLocalAddr(a netip.Addr) bool {
|
||||
if a.IsLoopback() {
|
||||
return true
|
||||
}
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, ia := range addrs {
|
||||
if n, ok := ia.(*net.IPNet); ok {
|
||||
if b, ok := netip.AddrFromSlice(n.IP); ok && b.Unmap() == a.Unmap() {
|
||||
return true
|
||||
}
|
||||
for _, b := range LocalAddrs() {
|
||||
if b == a.Unmap() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// LocalAddrs returns this host's interface addresses. Listing them needs a
|
||||
// netlink socket; where that is not allowed (a systemd unit without
|
||||
// AF_NETLINK in RestrictAddressFamilies), they are read from /proc.
|
||||
func LocalAddrs() []netip.Addr {
|
||||
var out []netip.Addr
|
||||
if addrs, err := net.InterfaceAddrs(); err == nil {
|
||||
for _, ia := range addrs {
|
||||
if n, ok := ia.(*net.IPNet); ok {
|
||||
if b, ok := netip.AddrFromSlice(n.IP); ok {
|
||||
out = append(out, b.Unmap())
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
return procAddrs("/proc/net")
|
||||
}
|
||||
|
||||
// procAddrs reads the host's addresses from /proc/net: IPv6 from
|
||||
// if_inet6, IPv4 from the local (/32 host LOCAL) entries of fib_trie.
|
||||
func procAddrs(dir string) []netip.Addr {
|
||||
var out []netip.Addr
|
||||
if b, err := os.ReadFile(filepath.Join(dir, "if_inet6")); err == nil {
|
||||
for _, line := range strings.Split(string(b), "\n") {
|
||||
f := strings.Fields(line)
|
||||
if len(f) == 0 || len(f[0]) != 32 {
|
||||
continue
|
||||
}
|
||||
raw, err := hex.DecodeString(f[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if a, ok := netip.AddrFromSlice(raw); ok {
|
||||
out = append(out, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
if b, err := os.ReadFile(filepath.Join(dir, "fib_trie")); err == nil {
|
||||
seen := map[netip.Addr]bool{}
|
||||
var last netip.Addr
|
||||
for _, line := range strings.Split(string(b), "\n") {
|
||||
t := strings.TrimSpace(line)
|
||||
if strings.HasPrefix(t, "|-- ") {
|
||||
last, _ = netip.ParseAddr(strings.TrimPrefix(t, "|-- "))
|
||||
} else if strings.HasPrefix(t, "/32 host LOCAL") && last.IsValid() && !seen[last] {
|
||||
seen[last] = true
|
||||
out = append(out, last)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// SystemResolver returns the first nameserver in /etc/resolv.conf as
|
||||
// host:port.
|
||||
func SystemResolver() (string, error) {
|
||||
|
||||
Reference in new issue
Block a user