"go.fuhry.dev/runtime/mtls/certutil"
"go.fuhry.dev/runtime/mtls/fsnotify"
+ "go.fuhry.dev/runtime/utils/fsutil"
)
type FileBackedCertificate struct {
rootPath := path.Join(mtlsRootPath, "rootca.pem")
for _, file := range []string{leafPath, chainPath, keyPath, rootPath} {
- if err := fileExistsAndIsReadable(file); err != nil {
+ if err := fsutil.FileExistsAndIsReadable(file); err != nil {
return nil, err
}
}
rootPath := path.Join(defaultMtlsRootPath, "rootca.pem")
for _, file := range []string{fullChainPath, keyPath, rootPath} {
- if err := fileExistsAndIsReadable(file); err != nil {
+ if err := fsutil.FileExistsAndIsReadable(file); err != nil {
return nil, err
}
}
rootPath := "/etc/ssl/certs/ISRG_Root_X1.pem"
for _, file := range []string{leafPath, chainPath, keyPath, rootPath} {
- if err := fileExistsAndIsReadable(file); err != nil {
+ if err := fsutil.FileExistsAndIsReadable(file); err != nil {
return nil, err
}
}
}
}
-func fileExistsAndIsReadable(path string) error {
- stat, err := os.Stat(path)
- if err != nil {
- return err
- }
- if !stat.Mode().IsRegular() {
- return fmt.Errorf("%q is not a regular file", path)
- }
- fp, err := os.Open(path)
- if err != nil {
- return err
- }
- fp.Close()
-
- return nil
-}
-
func appendMtlsCertificateDir(path string) error {
stat, err := os.Stat(path)
if err != nil {
lru "github.com/hashicorp/golang-lru"
"github.com/miekg/dns"
+ "go.fuhry.dev/runtime/utils/fsutil"
"go.fuhry.dev/runtime/utils/log"
)
var dnsCache *lru.Cache
var dnsCacheInit sync.Once
+var loopbackIPv4 = net.IPNet{
+ IP: net.IP{127, 0, 0, 0},
+ Mask: net.IPMask{255, 0, 0, 0},
+}
+
+var localIPv6 = net.IPNet{
+ IP: net.IP{
+ 0xfe, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ Mask: net.CIDRMask(64, 128),
+}
+
func ResolveDualStack(hostname string) (string, string, error) {
var msg *dns.Msg
var err error
for _, rr := range msg.Answer {
switch a := rr.(type) {
case *dns.A:
- ip4 = a.A.String()
+ if !loopbackIPv4.Contains(a.A) {
+ ip4 = a.A.String()
+ }
case *dns.AAAA:
- ip6 = a.AAAA.String()
+ if !localIPv6.Contains(a.AAAA) {
+ ip6 = a.AAAA.String()
+ }
}
}
+ if ip4 == "" && ip6 == "" {
+ return "", "", fmt.Errorf(
+ "did not receive any valid, non-loopback/local-scope answers for %q",
+ hostname,
+ )
+ }
+
return ip4, ip6, nil
}
func doDualStackQuery(hostname string) (*dns.Msg, error) {
var msg *dns.Msg
- cc, err := dns.ClientConfigFromFile("/etc/resolv.conf")
+ // On Linux systems, the stub resolv.conf points at systemd-resolved which uses the hosts
+ // file. We don't want this - we need the system's addresses as described by the network's
+ // DNS server.
+ resolvConfPath := "/run/systemd/resolve/resolv.conf"
+ if err := fsutil.FileExistsAndIsReadable(resolvConfPath); err != nil {
+ resolvConfPath = "/etc/resolv.conf"
+ }
+ cc, err := dns.ClientConfigFromFile(resolvConfPath)
if err != nil {
return nil, err
}