2021-10-18 20:16:29 +00:00
|
|
|
package dns
|
|
|
|
|
|
|
|
import (
|
2021-11-13 22:04:58 +00:00
|
|
|
"context"
|
2021-10-18 20:16:29 +00:00
|
|
|
"fmt"
|
2021-11-13 22:04:58 +00:00
|
|
|
"net"
|
2021-10-18 20:16:29 +00:00
|
|
|
"os"
|
2021-11-13 22:04:58 +00:00
|
|
|
"time"
|
2021-10-18 20:16:29 +00:00
|
|
|
|
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewToken constructs a new DNS provider token.
|
|
|
|
func NewToken(provider, providerTokenEnvVar string) (string, error) {
|
|
|
|
if token, present := os.LookupEnv(providerTokenEnvVar); present {
|
|
|
|
return token, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
logrus.Debugf("no %s in environment, asking via stdin", providerTokenEnvVar)
|
|
|
|
|
|
|
|
var token string
|
|
|
|
prompt := &survey.Input{
|
|
|
|
Message: fmt.Sprintf("%s API token?", provider),
|
|
|
|
}
|
|
|
|
if err := survey.AskOne(prompt, &token); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return token, nil
|
|
|
|
}
|
2021-11-13 22:04:58 +00:00
|
|
|
|
|
|
|
// EnsureIPv4 ensures that an ipv4 address is set for a domain name
|
|
|
|
func EnsureIPv4(domainName string) (string, error) {
|
|
|
|
var ipv4 string
|
|
|
|
|
|
|
|
// comrade librehosters DNS resolver -> https://www.privacy-handbuch.de/handbuch_93d.htm
|
|
|
|
freifunkDNS := "5.1.66.255:53"
|
|
|
|
|
|
|
|
resolver := &net.Resolver{
|
|
|
|
PreferGo: false,
|
|
|
|
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
|
|
d := net.Dialer{
|
|
|
|
Timeout: time.Millisecond * time.Duration(10000),
|
|
|
|
}
|
|
|
|
return d.DialContext(ctx, "udp", freifunkDNS)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-12-25 01:03:09 +00:00
|
|
|
logrus.Debugf("created DNS resolver via %s", freifunkDNS)
|
2021-11-13 22:04:58 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
ips, err := resolver.LookupIPAddr(ctx, domainName)
|
|
|
|
if err != nil {
|
|
|
|
return ipv4, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(ips) == 0 {
|
|
|
|
return ipv4, fmt.Errorf("unable to retrieve ipv4 address for %s", domainName)
|
|
|
|
}
|
|
|
|
|
|
|
|
ipv4 = ips[0].IP.To4().String()
|
|
|
|
logrus.Debugf("discovered the following ipv4 addr: %s", ipv4)
|
|
|
|
|
|
|
|
return ipv4, nil
|
|
|
|
}
|
2021-11-14 21:45:49 +00:00
|
|
|
|
|
|
|
// EnsureDomainsResolveSameIPv4 ensures that domains resolve to the same ipv4 address
|
|
|
|
func EnsureDomainsResolveSameIPv4(domainName, server string) (string, error) {
|
|
|
|
var ipv4 string
|
|
|
|
|
|
|
|
domainIPv4, err := EnsureIPv4(domainName)
|
|
|
|
if err != nil {
|
|
|
|
return ipv4, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if domainIPv4 == "" {
|
|
|
|
return ipv4, fmt.Errorf("cannot resolve ipv4 for %s?", domainName)
|
|
|
|
}
|
|
|
|
|
|
|
|
serverIPv4, err := EnsureIPv4(server)
|
|
|
|
if err != nil {
|
|
|
|
return ipv4, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if serverIPv4 == "" {
|
|
|
|
return ipv4, fmt.Errorf("cannot resolve ipv4 for %s?", server)
|
|
|
|
}
|
|
|
|
|
|
|
|
if domainIPv4 != serverIPv4 {
|
|
|
|
err := "app domain %s (%s) does not appear to resolve to app server %s (%s)?"
|
|
|
|
return ipv4, fmt.Errorf(err, domainName, domainIPv4, server, serverIPv4)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ipv4, nil
|
|
|
|
}
|
2021-12-23 00:41:12 +00:00
|
|
|
|
|
|
|
// GetTTL parses a ttl string into a duration
|
|
|
|
func GetTTL(ttl string) (time.Duration, error) {
|
|
|
|
val, err := time.ParseDuration(ttl)
|
|
|
|
if err != nil {
|
|
|
|
return val, err
|
|
|
|
}
|
|
|
|
return val, nil
|
|
|
|
}
|