SpoofDPI/dns/dns.go

111 lines
2.4 KiB
Go
Raw Normal View History

2024-07-21 07:57:47 +00:00
package dns
import (
"context"
"errors"
"net"
2024-07-21 07:57:47 +00:00
"regexp"
2024-07-31 11:47:19 +00:00
"strconv"
2024-08-10 07:15:22 +00:00
"time"
2024-07-21 07:57:47 +00:00
"github.com/miekg/dns"
log "github.com/sirupsen/logrus"
"github.com/xvzc/SpoofDPI/util"
)
type DnsResolver struct {
host string
port string
enableDoh bool
}
func NewResolver(config *util.Config) *DnsResolver {
return &DnsResolver{
host: *config.DnsAddr,
2024-07-21 08:12:16 +00:00
port: strconv.Itoa(*config.DnsPort),
2024-07-21 07:57:47 +00:00
enableDoh: *config.EnableDoh,
}
}
func (d *DnsResolver) Lookup(domain string, useSystemDns bool) (string, error) {
2024-07-21 07:57:47 +00:00
ipRegex := "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if r, _ := regexp.MatchString(ipRegex, domain); r {
return domain, nil
}
if useSystemDns {
2024-08-10 06:34:37 +00:00
log.Debug("[DNS] ", domain, " resolving with system dns")
return systemLookup(domain)
}
2024-07-21 07:57:47 +00:00
if d.enableDoh {
2024-08-10 06:34:37 +00:00
log.Debug("[DNS] ", domain, " resolving with dns over https")
2024-08-12 22:53:37 +00:00
return dohLookup(d.host, domain)
2024-07-21 07:57:47 +00:00
}
2024-08-10 06:34:37 +00:00
log.Debug("[DNS] ", domain, " resolving with custom dns")
return customLookup(d.host, d.port, domain)
}
func customLookup(host string, port string, domain string) (string, error) {
dnsServer := host + ":" + port
2024-07-21 07:57:47 +00:00
msg := new(dns.Msg)
msg.SetQuestion(dns.Fqdn(domain), dns.TypeA)
c := new(dns.Client)
response, _, err := c.Exchange(msg, dnsServer)
if err != nil {
2024-08-12 22:37:20 +00:00
return "", errors.New("could not resolve the domain(custom)")
2024-07-21 07:57:47 +00:00
}
for _, answer := range response.Answer {
if record, ok := answer.(*dns.A); ok {
return record.A.String(), nil
}
}
return "", errors.New("no record found(custom)")
}
func systemLookup(domain string) (string, error) {
systemResolver := net.Resolver{PreferGo: true}
ips, err := systemResolver.LookupIPAddr(context.Background(), domain)
if err != nil {
2024-08-12 22:37:20 +00:00
return "", errors.New("could not resolve the domain(system)")
}
for _, ip := range ips {
return ip.String(), nil
}
return "", errors.New("no record found(system)")
2024-07-21 07:57:47 +00:00
}
2024-08-12 22:53:37 +00:00
func dohLookup(host string, domain string) (string, error) {
2024-08-10 07:15:22 +00:00
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
2024-08-12 22:53:37 +00:00
client := getDOHClient(host)
2024-08-12 22:37:20 +00:00
msg := new(dns.Msg)
msg.SetQuestion(dns.Fqdn(domain), dns.TypeA)
2024-08-12 22:53:37 +00:00
response, err := client.dohExchange(ctx, msg)
2024-08-12 22:37:20 +00:00
if err != nil {
return "", errors.New("could not resolve the domain(doh)")
2024-07-21 07:57:47 +00:00
}
2024-08-12 22:37:20 +00:00
for _, answer := range response.Answer {
if record, ok := answer.(*dns.A); ok {
return record.A.String(), nil
}
}
return "", errors.New("no record found(doh)")
2024-07-21 07:57:47 +00:00
}