mirror of
https://github.com/folbricht/routedns.git
synced 2026-05-01 05:29:18 -05:00
Default ports feature (#195)
* Static ports file added
* Removed .idea
* Added options for default ports
* Fixed var name ty[e
* Added default port function
* Fixed methods to be proper go
* Fixed port method
* Added blank add part
* Fixed http
* Fixed port bool
* Update to use host instead
* Fixed improper imp,amentation
* Better version
* Soltion for { in address
* Starting commit
* Removed unneeded code
* Added forgotten function
* Test for default-ports feature and simplify the function
* missing test
Co-authored-by: folbrich <frank.olbricht@gmail.com>
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
.idea/
|
||||
.idea/
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
# This file shows a selection of well-known DNS resolvers and supported protocols to
|
||||
# help build RoutedDNS configs. It isn't intended to be used directly but can for testing.
|
||||
# Ports are not set in a config because they are set to use the default protocols port
|
||||
|
||||
title = "Resolvers for well-known DNS services"
|
||||
|
||||
# Cloudflare DNS-over-TLS
|
||||
[resolvers.cloudflare-dot-1-1-1-1]
|
||||
address = "1.1.1.1"
|
||||
protocol = "dot"
|
||||
|
||||
[resolvers.cloudflare-dot-1-1-1-1-w-port]
|
||||
address = "1.1.1.1:853"
|
||||
protocol = "dot"
|
||||
|
||||
|
||||
# Cloudflare DNS-over-HTTPS using the POST method
|
||||
[resolvers.cloudflare-doh-1-1-1-1-post]
|
||||
address = "https://1.1.1.1/dns-query"
|
||||
protocol = "doh"
|
||||
|
||||
[resolvers.cloudflare-doh-1-0-0-1-post]
|
||||
address = "https://1.0.0.1:443/dns-query"
|
||||
protocol = "doh"
|
||||
|
||||
# Cloudflare DNS-over-HTTPS using the GET method
|
||||
[resolvers.cloudflare-doh-1-1-1-1-get]
|
||||
address = "https://1.1.1.1:443/dns-query{?dns}"
|
||||
protocol = "doh"
|
||||
doh = { method = "GET" }
|
||||
|
||||
[resolvers.cloudflare-doh-1-0-0-1-get]
|
||||
address = "https://1.0.0.1/dns-query{?dns}"
|
||||
protocol = "doh"
|
||||
doh = { method = "GET" }
|
||||
|
||||
# Cloudflare DNS-over-HTTPS using the QUIC protocol
|
||||
[resolvers.cloudflare-doh-quic]
|
||||
address = "https://cloudflare-dns.com/dns-query"
|
||||
protocol = "doh"
|
||||
transport = "quic"
|
||||
|
||||
# Cloudflare plain DNS
|
||||
[resolvers.cloudflare-udp-1-1-1-1]
|
||||
address = "1.1.1.1"
|
||||
protocol = "udp"
|
||||
|
||||
[resolvers.cloudflare-tcp-1-0-0-1]
|
||||
address = "1.0.0.1:53"
|
||||
protocol = "tcp"
|
||||
|
||||
# dnscrypt.ca server-1, DoH-GET
|
||||
[resolvers.dnscrypt-1-doh-get]
|
||||
address = "https://dns1.dnscrypt.ca:453/dns-query{?dns}"
|
||||
protocol = "doh"
|
||||
doh = { method = "GET" }
|
||||
|
||||
# dnscrypt.ca server-2, DoH-GET
|
||||
[resolvers.dnscrypt-2-doh-get]
|
||||
address = "https://dns2.dnscrypt.ca:453/dns-query{?dns}"
|
||||
protocol = "doh"
|
||||
doh = { method = "GET" }
|
||||
|
||||
# dnscrypt.ca server-1, DoH-POST
|
||||
[resolvers.dnscrypt-1-doh-post]
|
||||
address = "https://dns1.dnscrypt.ca:453/dns-query"
|
||||
protocol = "doh"
|
||||
|
||||
# dnscrypt.ca server-2, DoH-POST
|
||||
[resolvers.dnscrypt-2-doh-post]
|
||||
address = "https://dns2.dnscrypt.ca:453/dns-query"
|
||||
protocol = "doh"
|
||||
|
||||
# Google plain DNS
|
||||
[resolvers.google-udp-8-8-8-8]
|
||||
address = "8.8.8.8:53"
|
||||
protocol = "udp"
|
||||
|
||||
[resolvers.google-tcp-8-8-4-4]
|
||||
address = "8.8.4.4:53"
|
||||
protocol = "udp"
|
||||
|
||||
# Google DNS-over-TLS
|
||||
[resolvers.google-dot-8-8-8-8]
|
||||
address = "8.8.8.8:853"
|
||||
protocol = "dot"
|
||||
|
||||
[resolvers.google-dot-8-8-4-4]
|
||||
address = "8.8.4.4"
|
||||
protocol = "dot"
|
||||
|
||||
# Google DNS-over-HTTP using the POST method
|
||||
[resolvers.google-doh-post]
|
||||
address = "https://dns.google/dns-query"
|
||||
protocol = "doh"
|
||||
|
||||
# Google DNS-over-HTTP using the GET method
|
||||
[resolvers.google-doh-get]
|
||||
address = "https://dns.google/dns-query{?dns}"
|
||||
protocol = "doh"
|
||||
doh = { method = "GET" }
|
||||
|
||||
# Google DNS-over-HTTP with bootstrapping to avoid initial lookup
|
||||
[resolvers.google-doh-post-bootstrap]
|
||||
address = "https://dns.google/dns-query"
|
||||
protocol = "doh"
|
||||
bootstrap-address = "8.8.8.8"
|
||||
|
||||
# Quad9 DNS-over-TLS
|
||||
[resolvers.quad9-dot]
|
||||
address = "9.9.9.9:853"
|
||||
protocol = "dot"
|
||||
|
||||
# Quad9 DNS-over-HTTP using the POST method
|
||||
[resolvers.quad9-doh-post]
|
||||
address = "https://9.9.9.9/dns-query{?dns}"
|
||||
protocol = "doh"
|
||||
|
||||
# CleanBrowsing DoT resolver
|
||||
[resolvers.cleanbrowsing-dot]
|
||||
address = "family-filter-dns.cleanbrowsing.org:853"
|
||||
protocol = "dot"
|
||||
|
||||
# OpenDNS plain DNS (resolver1.opendns.com)
|
||||
[resolvers.opendns-udp-1]
|
||||
address = "208.67.222.222:53"
|
||||
protocol = "udp"
|
||||
|
||||
# OpenDNS plain DNS (resolver2.opendns.com)
|
||||
[resolvers.opendns-udp-2]
|
||||
address = "208.67.222.220:53"
|
||||
protocol = "udp"
|
||||
|
||||
# Adguard DNS-over-QUIC
|
||||
[resolvers.adguard-doq]
|
||||
address = "dns-unfiltered.adguard.com:8853"
|
||||
protocol = "doq"
|
||||
|
||||
# Listeners
|
||||
|
||||
[listeners.local-udp]
|
||||
address = "127.0.0.1:53"
|
||||
protocol = "udp"
|
||||
resolver = "cloudflare-doh-1-1-1-1-post"
|
||||
|
||||
[listeners.local-tcp]
|
||||
address = "127.0.0.1"
|
||||
protocol = "tcp"
|
||||
resolver = "cloudflare-doh-1-1-1-1-post"
|
||||
|
||||
[listeners.all-dot]
|
||||
address = ":853"
|
||||
protocol = "dot"
|
||||
resolver = "cloudflare-doh-1-1-1-1-post"
|
||||
+11
-1
@@ -182,7 +182,6 @@ func start(opt options, args []string) error {
|
||||
if !ok && l.Protocol != "admin" {
|
||||
return fmt.Errorf("listener '%s' references non-existant resolver, group or router '%s'", id, l.Resolver)
|
||||
}
|
||||
|
||||
allowedNet, err := parseCIDRList(l.AllowedNet)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -192,8 +191,10 @@ func start(opt options, args []string) error {
|
||||
|
||||
switch l.Protocol {
|
||||
case "tcp":
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.PlainDNSPort)
|
||||
listeners = append(listeners, rdns.NewDNSListener(id, l.Address, "tcp", opt, resolver))
|
||||
case "udp":
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.PlainDNSPort)
|
||||
listeners = append(listeners, rdns.NewDNSListener(id, l.Address, "udp", opt, resolver))
|
||||
case "admin":
|
||||
tlsConfig, err := rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS)
|
||||
@@ -211,6 +212,7 @@ func start(opt options, args []string) error {
|
||||
}
|
||||
listeners = append(listeners, ln)
|
||||
case "dot":
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.DoTPort)
|
||||
tlsConfig, err := rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -218,6 +220,7 @@ func start(opt options, args []string) error {
|
||||
ln := rdns.NewDoTListener(id, l.Address, rdns.DoTListenerOptions{TLSConfig: tlsConfig, ListenOptions: opt}, resolver)
|
||||
listeners = append(listeners, ln)
|
||||
case "dtls":
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.DTLSPort)
|
||||
dtlsConfig, err := rdns.DTLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -225,6 +228,11 @@ func start(opt options, args []string) error {
|
||||
ln := rdns.NewDTLSListener(id, l.Address, rdns.DTLSListenerOptions{DTLSConfig: dtlsConfig, ListenOptions: opt}, resolver)
|
||||
listeners = append(listeners, ln)
|
||||
case "doh":
|
||||
if l.Transport != "quic" {
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.DoHPort)
|
||||
} else if l.Transport == "quic" {
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.DohQuicPort)
|
||||
}
|
||||
tlsConfig, err := rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -248,6 +256,8 @@ func start(opt options, args []string) error {
|
||||
}
|
||||
listeners = append(listeners, ln)
|
||||
case "doq":
|
||||
l.Address = rdns.AddressWithDefault(l.Address, rdns.DoQPort)
|
||||
|
||||
tlsConfig, err := rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -11,7 +11,10 @@ import (
|
||||
func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolver) error {
|
||||
var err error
|
||||
switch r.Protocol {
|
||||
|
||||
case "doq":
|
||||
r.Address = rdns.AddressWithDefault(r.Address, rdns.DoQPort)
|
||||
|
||||
tlsConfig, err := rdns.TLSClientConfig(r.CA, r.ClientCrt, r.ClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -26,6 +29,8 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv
|
||||
return err
|
||||
}
|
||||
case "dot":
|
||||
r.Address = rdns.AddressWithDefault(r.Address, rdns.DoTPort)
|
||||
|
||||
tlsConfig, err := rdns.TLSClientConfig(r.CA, r.ClientCrt, r.ClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -40,6 +45,8 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv
|
||||
return err
|
||||
}
|
||||
case "dtls":
|
||||
r.Address = rdns.AddressWithDefault(r.Address, rdns.DTLSPort)
|
||||
|
||||
dtlsConfig, err := rdns.DTLSClientConfig(r.CA, r.ClientCrt, r.ClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -55,6 +62,8 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv
|
||||
return err
|
||||
}
|
||||
case "doh":
|
||||
r.Address = rdns.AddressWithDefault(r.Address, rdns.DoHPort)
|
||||
|
||||
tlsConfig, err := rdns.TLSClientConfig(r.CA, r.ClientCrt, r.ClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -71,6 +80,8 @@ func instantiateResolver(id string, r resolver, resolvers map[string]rdns.Resolv
|
||||
return err
|
||||
}
|
||||
case "tcp", "udp":
|
||||
r.Address = rdns.AddressWithDefault(r.Address, rdns.PlainDNSPort)
|
||||
|
||||
opt := rdns.DNSClientOptions{
|
||||
LocalAddr: net.ParseIP(r.LocalAddr),
|
||||
UDPSize: r.EDNS0UDPSize,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package rdns
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
DoQPort string = "8853"
|
||||
DohQuicPort string = "1443"
|
||||
DoTPort string = "853"
|
||||
DTLSPort string = DoTPort
|
||||
DoHPort string = "443"
|
||||
PlainDNSPort = "53"
|
||||
)
|
||||
|
||||
// AddressWithDefault takes an endpoint or a URL and adds a port unless it
|
||||
// already has one. If it fails to parse addr, it returns the original value.
|
||||
func AddressWithDefault(addr, defaultPort string) string {
|
||||
// Endpoints like DoH can contain URL templates, so we want to strip those
|
||||
// off first
|
||||
parts := strings.SplitN(addr, "{", 2)
|
||||
endpointPart := parts[0]
|
||||
var templatePart string
|
||||
if len(parts) == 2 {
|
||||
templatePart = "{" + parts[1]
|
||||
}
|
||||
|
||||
// Now let's see if it's a URL. If it is, it'll have a "/" in it
|
||||
if strings.Contains(endpointPart, "/") {
|
||||
u, err := url.Parse(endpointPart)
|
||||
if err != nil {
|
||||
return addr
|
||||
}
|
||||
if u.Port() == "" {
|
||||
u.Host = net.JoinHostPort(u.Host, defaultPort)
|
||||
}
|
||||
return u.String() + templatePart
|
||||
}
|
||||
|
||||
// Here we know it's not a URL, so it should be either <host>:<port> or just <host>
|
||||
if strings.Contains(endpointPart, ":") {
|
||||
return addr
|
||||
}
|
||||
return net.JoinHostPort(endpointPart, defaultPort)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package rdns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDefaultPort(t *testing.T) {
|
||||
tests := []struct {
|
||||
address string
|
||||
defaultPort string
|
||||
expected string
|
||||
}{
|
||||
{"", DoTPort, ":853"},
|
||||
{"localhost", DoTPort, "localhost:853"},
|
||||
{"localhost:123", DoTPort, "localhost:123"},
|
||||
{"1.2.3.4", DoTPort, "1.2.3.4:853"},
|
||||
{"1.2.3.4:123", DoTPort, "1.2.3.4:123"},
|
||||
{"https://localhost", DoHPort, "https://localhost:443"},
|
||||
{"https://localhost:123", DoHPort, "https://localhost:123"},
|
||||
{"https://localhost:123/path", DoHPort, "https://localhost:123/path"},
|
||||
{"https://localhost/dns-query{?dns}", DoHPort, "https://localhost:443/dns-query{?dns}"},
|
||||
{"https://1.1.1.1:443/dns-query{?dns}", DoHPort, "https://1.1.1.1:443/dns-query{?dns}"},
|
||||
|
||||
// Invalid endpoints should ideally not be changed
|
||||
{"localhost:", DoTPort, "localhost:"},
|
||||
{"localhost::123", DoTPort, "localhost::123"},
|
||||
{"127.0.0.1:", DoTPort, "127.0.0.1:"},
|
||||
{"127.0.0.1::123", DoTPort, "127.0.0.1::123"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out := AddressWithDefault(test.address, test.defaultPort)
|
||||
require.Equal(t, test.expected, out)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user