Validate domain fronting availability

This commit is contained in:
9seconds
2026-03-23 19:22:21 +01:00
parent b6b900e430
commit f0ae4ce290
+43
View File
@@ -8,6 +8,7 @@ import (
"net" "net"
"os" "os"
"slices" "slices"
"strconv"
"strings" "strings"
"text/template" "text/template"
"time" "time"
@@ -56,6 +57,13 @@ var (
tplEDNSSNIMatch = template.Must( tplEDNSSNIMatch = template.Must(
template.New("").Parse(" ❌ Hostname {{ .hostname }} {{ if .resolved }}is resolved to {{ .resolved }} addresses, not {{ if .ip4 }}{{ .ip4 }}{{ else }}{{ .ip6 }}{{ end }}{{ else }}cannot be resolved to any host{{ end }}\n"), template.New("").Parse(" ❌ Hostname {{ .hostname }} {{ if .resolved }}is resolved to {{ .resolved }} addresses, not {{ if .ip4 }}{{ .ip4 }}{{ else }}{{ .ip6 }}{{ end }}{{ else }}cannot be resolved to any host{{ end }}\n"),
) )
tplOFrontingDomain = template.Must(
template.New("").Parse(" ✅ {{ .address }} is reachable\n"),
)
tplEFrontingDomain = template.Must(
template.New("").Parse(" ❌ {{ .address }}: {{ .error }}\n"),
)
) )
type Doctor struct { type Doctor struct {
@@ -104,6 +112,9 @@ func (d *Doctor) Run(cli *CLI, version string) error {
everythingOK = d.checkNetwork(value) && everythingOK everythingOK = d.checkNetwork(value) && everythingOK
} }
fmt.Println("Validate fronting domain connectivity")
everythingOK = d.checkFrontingDomain(base) && everythingOK
fmt.Println("Validate SNI-DNS match") fmt.Println("Validate SNI-DNS match")
everythingOK = d.checkSecretHost(resolver, base) && everythingOK everythingOK = d.checkSecretHost(resolver, base) && everythingOK
@@ -279,6 +290,38 @@ func (d *Doctor) checkNetworkAddresses(ntw mtglib.Network, addresses []string) e
return err return err
} }
func (d *Doctor) checkFrontingDomain(ntw mtglib.Network) bool {
host := d.conf.Secret.Host
if ip := d.conf.GetDomainFrontingIP(nil); ip != "" {
host = ip
}
port := d.conf.GetDomainFrontingPort(mtglib.DefaultDomainFrontingPort)
address := net.JoinHostPort(host, strconv.Itoa(int(port)))
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
dialer := ntw.NativeDialer()
conn, err := dialer.DialContext(ctx, "tcp", address)
if err != nil {
tplEFrontingDomain.Execute(os.Stdout, map[string]any{ //nolint: errcheck
"address": address,
"error": err,
})
return false
}
conn.Close() //nolint: errcheck
tplOFrontingDomain.Execute(os.Stdout, map[string]any{ //nolint: errcheck
"address": address,
})
return true
}
func (d *Doctor) checkSecretHost(resolver *net.Resolver, ntw mtglib.Network) bool { func (d *Doctor) checkSecretHost(resolver *net.Resolver, ntw mtglib.Network) bool {
addresses, err := resolver.LookupIPAddr(context.Background(), d.conf.Secret.Host) addresses, err := resolver.LookupIPAddr(context.Background(), d.conf.Secret.Host)
if err != nil { if err != nil {