Give addrFilter a type and add the config wiring

This commit is contained in:
Roland Shoemaker 2015-07-31 15:47:03 -07:00
parent 94095796b9
commit 5a1a3c7e0d
10 changed files with 52 additions and 42 deletions

View File

@ -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)

View File

@ -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")

View File

@ -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

View File

@ -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)
}
}

View File

@ -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")

View File

@ -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)

View File

@ -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
}

View File

@ -125,6 +125,7 @@
"va": {
"userAgent": "boulder",
"addressFilter": "v4",
"debugAddr": "localhost:8004"
},

View File

@ -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

View File

@ -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}