Give addrFilter a type and add the config wiring
This commit is contained in:
parent
94095796b9
commit
5a1a3c7e0d
|
|
@ -6,6 +6,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
||||
|
|
@ -42,6 +44,13 @@ func main() {
|
|||
cmd.FailOnError(err, "Couldn't parse DNS timeout")
|
||||
vai.DNSResolver = core.NewDNSResolverImpl(dnsTimeout, []string{c.Common.DNSResolver})
|
||||
vai.UserAgent = c.VA.UserAgent
|
||||
addrFilter, ok := core.NameToFilter[c.VA.AddressFilter]
|
||||
if !ok {
|
||||
// AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3
|
||||
fmt.Fprint(os.Stderr, "Invalid address filter")
|
||||
os.Exit(1)
|
||||
}
|
||||
vai.AddressFilter = addrFilter
|
||||
|
||||
for {
|
||||
ch, err := cmd.AmqpChannel(c)
|
||||
|
|
|
|||
|
|
@ -102,6 +102,13 @@ func main() {
|
|||
va := va.NewValidationAuthorityImpl(c.CA.TestMode)
|
||||
va.DNSResolver = dnsResolver
|
||||
va.UserAgent = c.VA.UserAgent
|
||||
addrFilter, ok := core.NameToFilter[c.VA.AddressFilter]
|
||||
if !ok {
|
||||
// AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3
|
||||
fmt.Fprint(os.Stderr, "Invalid address filter")
|
||||
os.Exit(1)
|
||||
}
|
||||
va.AddressFilter = addrFilter
|
||||
|
||||
cadb, err := ca.NewCertificateAuthorityDatabaseImpl(c.CA.DBDriver, c.CA.DBConnect)
|
||||
cmd.FailOnError(err, "Failed to create CA database")
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ type Config struct {
|
|||
}
|
||||
|
||||
VA struct {
|
||||
UserAgent string
|
||||
UserAgent string
|
||||
AddressFilter string
|
||||
|
||||
// DebugAddr is the address to run the /debug handlers on.
|
||||
DebugAddr string
|
||||
|
|
|
|||
39
core/dns.go
39
core/dns.go
|
|
@ -14,15 +14,20 @@ import (
|
|||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type AddrFilter int
|
||||
|
||||
const (
|
||||
// NoAddrFilter is used to tell LookupHost to query both A and AAAA records
|
||||
NoAddrFilter = iota
|
||||
noAddrFilter AddrFilter = iota
|
||||
// IPv4OnlyFilter is used to tell LookupHost to only query A records
|
||||
IPv4OnlyFilter
|
||||
// IPv6OnlyFilter is used to tell LookupHost to only query AAAA records
|
||||
IPv6OnlyFilter
|
||||
ipv4OnlyFilter
|
||||
)
|
||||
|
||||
var NameToFilter = map[string]AddrFilter{
|
||||
"": noAddrFilter,
|
||||
"v4": ipv4OnlyFilter,
|
||||
}
|
||||
|
||||
var (
|
||||
privateNetworkA = net.IPNet{
|
||||
IP: []byte{10, 0, 0, 0},
|
||||
|
|
@ -109,25 +114,23 @@ func isPrivate(ip net.IP) bool {
|
|||
|
||||
// LookupHost sends a DNS query to find all A/AAAA records associated with
|
||||
// the provided hostname.
|
||||
func (dnsResolver *DNSResolverImpl) LookupHost(hostname string, filter int) ([]net.IP, time.Duration, time.Duration, error) {
|
||||
func (dnsResolver *DNSResolverImpl) LookupHost(hostname string, filter AddrFilter) ([]net.IP, time.Duration, time.Duration, error) {
|
||||
var addrs []net.IP
|
||||
var answers []dns.RR
|
||||
var aRtt time.Duration
|
||||
var aaaaRtt time.Duration
|
||||
|
||||
if filter != IPv6OnlyFilter {
|
||||
r, aRtt, err := dnsResolver.ExchangeOne(hostname, dns.TypeA)
|
||||
if err != nil {
|
||||
return addrs, aRtt, 0, err
|
||||
}
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
err = fmt.Errorf("DNS failure: %d-%s for A query", r.Rcode, dns.RcodeToString[r.Rcode])
|
||||
return nil, aRtt, 0, err
|
||||
}
|
||||
answers = append(answers, r.Answer...)
|
||||
r, aRtt, err := dnsResolver.ExchangeOne(hostname, dns.TypeA)
|
||||
if err != nil {
|
||||
return addrs, aRtt, 0, err
|
||||
}
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
err = fmt.Errorf("DNS failure: %d-%s for A query", r.Rcode, dns.RcodeToString[r.Rcode])
|
||||
return nil, aRtt, 0, err
|
||||
}
|
||||
answers = append(answers, r.Answer...)
|
||||
|
||||
if filter != IPv4OnlyFilter {
|
||||
if filter != ipv4OnlyFilter {
|
||||
r, aaaaRtt, err := dnsResolver.ExchangeOne(hostname, dns.TypeAAAA)
|
||||
if err != nil {
|
||||
return addrs, aRtt, aaaaRtt, err
|
||||
|
|
@ -141,11 +144,11 @@ func (dnsResolver *DNSResolverImpl) LookupHost(hostname string, filter int) ([]n
|
|||
|
||||
for _, answer := range answers {
|
||||
if answer.Header().Rrtype == dns.TypeA {
|
||||
if a, ok := answer.(*dns.A); ok && a.A.To4() != nil && !isPrivate(a.A) && filter != IPv6OnlyFilter {
|
||||
if a, ok := answer.(*dns.A); ok && a.A.To4() != nil && !isPrivate(a.A) {
|
||||
addrs = append(addrs, a.A)
|
||||
}
|
||||
} else if answer.Header().Rrtype == dns.TypeAAAA {
|
||||
if aaaa, ok := answer.(*dns.AAAA); ok && aaaa.AAAA.To16() != nil && !isPrivate(aaaa.AAAA) && filter != IPv4OnlyFilter {
|
||||
if aaaa, ok := answer.(*dns.AAAA); ok && aaaa.AAAA.To16() != nil && !isPrivate(aaaa.AAAA) && filter != ipv4OnlyFilter {
|
||||
addrs = append(addrs, aaaa.AAAA)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ func TestDNSLookupsNoServer(t *testing.T) {
|
|||
_, _, err := obj.LookupTXT("letsencrypt.org")
|
||||
test.AssertError(t, err, "No servers")
|
||||
|
||||
_, _, _, err = obj.LookupHost("letsencrypt.org", NoAddrFilter)
|
||||
_, _, _, err = obj.LookupHost("letsencrypt.org", noAddrFilter)
|
||||
test.AssertError(t, err, "No servers")
|
||||
|
||||
_, _, err = obj.LookupCNAME("letsencrypt.org")
|
||||
|
|
@ -198,7 +198,7 @@ func TestDNSServFail(t *testing.T) {
|
|||
_, _, err = obj.LookupCNAME(bad)
|
||||
test.AssertError(t, err, "LookupCNAME didn't return an error")
|
||||
|
||||
_, _, _, err = obj.LookupHost(bad, NoAddrFilter)
|
||||
_, _, _, err = obj.LookupHost(bad, noAddrFilter)
|
||||
test.AssertError(t, err, "LookupHost didn't return an error")
|
||||
|
||||
// CAA lookup ignores validation failures from the resolver for now
|
||||
|
|
@ -220,40 +220,28 @@ func TestDNSLookupTXT(t *testing.T) {
|
|||
func TestDNSLookupHost(t *testing.T) {
|
||||
obj := NewDNSResolverImpl(time.Second*10, []string{dnsLoopbackAddr})
|
||||
|
||||
ip, _, _, err := obj.LookupHost("servfail.com", NoAddrFilter)
|
||||
ip, _, _, err := obj.LookupHost("servfail.com", noAddrFilter)
|
||||
t.Logf("servfail.com - IP: %s, Err: %s", ip, err)
|
||||
test.AssertError(t, err, "Server failure")
|
||||
test.Assert(t, len(ip) == 0, "Should not have IPs")
|
||||
|
||||
ip, _, _, err = obj.LookupHost("nonexistent.letsencrypt.org", NoAddrFilter)
|
||||
ip, _, _, err = obj.LookupHost("nonexistent.letsencrypt.org", noAddrFilter)
|
||||
t.Logf("nonexistent.letsencrypt.org - IP: %s, Err: %s", ip, err)
|
||||
test.AssertNotError(t, err, "Not an error to not exist")
|
||||
test.Assert(t, len(ip) == 0, "Should not have IPs")
|
||||
|
||||
// Single IPv4 address
|
||||
ip, _, _, err = obj.LookupHost("cps.letsencrypt.org", NoAddrFilter)
|
||||
ip, _, _, err = obj.LookupHost("cps.letsencrypt.org", noAddrFilter)
|
||||
t.Logf("cps.letsencrypt.org - IP: %s, Err: %s", ip, err)
|
||||
test.AssertNotError(t, err, "Not an error to exist")
|
||||
test.Assert(t, len(ip) == 1, "Should have IP")
|
||||
ip, _, _, err = obj.LookupHost("cps.letsencrypt.org", IPv4OnlyFilter)
|
||||
ip, _, _, err = obj.LookupHost("cps.letsencrypt.org", ipv4OnlyFilter)
|
||||
t.Logf("cps.letsencrypt.org - IP: %s, Err: %s", ip, err)
|
||||
test.AssertNotError(t, err, "Not an error to exist")
|
||||
test.Assert(t, len(ip) == 1, "Should have IP")
|
||||
|
||||
// No IPv6 addresses
|
||||
ip, _, _, err = obj.LookupHost("cps.letsencrypt.org", IPv6OnlyFilter)
|
||||
t.Logf("cps.letsencrypt.org - IP: %s, Err: %s", ip, err)
|
||||
test.AssertNotError(t, err, "Not an error to exist")
|
||||
test.Assert(t, len(ip) == 0, "Should not have IPs")
|
||||
|
||||
// Single IPv6 address
|
||||
ip, _, _, err = obj.LookupHost("v6.letsencrypt.org", IPv6OnlyFilter)
|
||||
t.Logf("cps.letsencrypt.org - IP: %s, Err: %s", ip, err)
|
||||
test.AssertNotError(t, err, "Not a error to exist")
|
||||
test.Assert(t, len(ip) == 1, "Should have IP")
|
||||
|
||||
// Both addresses
|
||||
ip, _, _, err = obj.LookupHost("mixed.letsencrypt.org", NoAddrFilter)
|
||||
ip, _, _, err = obj.LookupHost("mixed.letsencrypt.org", noAddrFilter)
|
||||
t.Logf("mixed.letsencrypt.org - IP: %s, Err: %s", ip, err)
|
||||
test.AssertNotError(t, err, "Not an error to exist")
|
||||
test.Assert(t, len(ip) == 2, "Should not have IPs")
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ type CertificateAuthorityDatabase interface {
|
|||
type DNSResolver interface {
|
||||
ExchangeOne(string, uint16) (*dns.Msg, time.Duration, error)
|
||||
LookupTXT(string) ([]string, time.Duration, error)
|
||||
LookupHost(string, int) ([]net.IP, time.Duration, time.Duration, error)
|
||||
LookupHost(string, AddrFilter) ([]net.IP, time.Duration, time.Duration, error)
|
||||
LookupCNAME(string) (string, time.Duration, error)
|
||||
LookupDNAME(string) (string, time.Duration, error)
|
||||
LookupCAA(string) ([]*dns.CAA, time.Duration, error)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
||||
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
)
|
||||
|
||||
// MockCADatabase is a mock
|
||||
|
|
@ -66,7 +67,7 @@ func (mock *MockDNS) LookupTXT(hostname string) ([]string, time.Duration, error)
|
|||
}
|
||||
|
||||
// LookupHost is a mock
|
||||
func (mock *MockDNS) LookupHost(hostname string, filter int) ([]net.IP, time.Duration, time.Duration, error) {
|
||||
func (mock *MockDNS) LookupHost(hostname string, filter core.AddrFilter) ([]net.IP, time.Duration, time.Duration, error) {
|
||||
if hostname == "always.invalid" || hostname == "invalid.invalid" {
|
||||
return []net.IP{}, 0, 0, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@
|
|||
|
||||
"va": {
|
||||
"userAgent": "boulder",
|
||||
"addressFilter": "v4",
|
||||
"debugAddr": "localhost:8004"
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ type ValidationAuthorityImpl struct {
|
|||
IssuerDomain string
|
||||
TestMode bool
|
||||
UserAgent string
|
||||
AddressFilter int
|
||||
AddressFilter core.AddrFilter
|
||||
}
|
||||
|
||||
// NewValidationAuthorityImpl constructs a new VA, and may place it
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ func brokenTLSSrv(t *testing.T, stopChan, waitChan chan bool) {
|
|||
func TestSimpleHttpTLS(t *testing.T) {
|
||||
va := NewValidationAuthorityImpl(true)
|
||||
va.DNSResolver = &mocks.MockDNS{}
|
||||
va.AddressFilter = core.NoAddrFilter
|
||||
va.AddressFilter = core.AddrFilter(0) // No filter
|
||||
|
||||
chall := core.Challenge{Type: core.ChallengeTypeSimpleHTTP, Token: expectedToken}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue