9
9
"io"
10
10
"net"
11
11
"net/http"
12
+ "net/netip"
12
13
"net/url"
13
14
"slices"
14
15
"strconv"
@@ -23,83 +24,7 @@ import (
23
24
"github.com/letsencrypt/boulder/features"
24
25
blog "github.com/letsencrypt/boulder/log"
25
26
"github.com/letsencrypt/boulder/metrics"
26
- )
27
-
28
- func parseCidr (network string , comment string ) net.IPNet {
29
- _ , net , err := net .ParseCIDR (network )
30
- if err != nil {
31
- panic (fmt .Sprintf ("error parsing %s (%s): %s" , network , comment , err ))
32
- }
33
- return * net
34
- }
35
-
36
- var (
37
- // TODO(#8040): Rebuild these as structs that track the structure of IANA's
38
- // CSV files, for better automated handling.
39
- //
40
- // Private CIDRs to ignore. Sourced from:
41
- // https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
42
- privateV4Networks = []net.IPNet {
43
- parseCidr ("0.0.0.0/8" , "RFC 791, Section 3.2: This network" ),
44
- parseCidr ("0.0.0.0/32" , "RFC 1122, Section 3.2.1.3: This host on this network" ),
45
- parseCidr ("10.0.0.0/8" , "RFC 1918: Private-Use" ),
46
- parseCidr ("100.64.0.0/10" , "RFC 6598: Shared Address Space" ),
47
- parseCidr ("127.0.0.0/8" , "RFC 1122, Section 3.2.1.3: Loopback" ),
48
- parseCidr ("169.254.0.0/16" , "RFC 3927: Link Local" ),
49
- parseCidr ("172.16.0.0/12" , "RFC 1918: Private-Use" ),
50
- parseCidr ("192.0.0.0/24" , "RFC 6890, Section 2.1: IETF Protocol Assignments" ),
51
- parseCidr ("192.0.0.0/29" , "RFC 7335: IPv4 Service Continuity Prefix" ),
52
- parseCidr ("192.0.0.8/32" , "RFC 7600: IPv4 dummy address" ),
53
- parseCidr ("192.0.0.9/32" , "RFC 7723: Port Control Protocol Anycast" ),
54
- parseCidr ("192.0.0.10/32" , "RFC 8155: Traversal Using Relays around NAT Anycast" ),
55
- parseCidr ("192.0.0.170/32" , "RFC 8880 & RFC 7050, Section 2.2: NAT64/DNS64 Discovery" ),
56
- parseCidr ("192.0.0.171/32" , "RFC 8880 & RFC 7050, Section 2.2: NAT64/DNS64 Discovery" ),
57
- parseCidr ("192.0.2.0/24" , "RFC 5737: Documentation (TEST-NET-1)" ),
58
- parseCidr ("192.31.196.0/24" , "RFC 7535: AS112-v4" ),
59
- parseCidr ("192.52.193.0/24" , "RFC 7450: AMT" ),
60
- parseCidr ("192.88.99.0/24" , "RFC 7526: Deprecated (6to4 Relay Anycast)" ),
61
- parseCidr ("192.168.0.0/16" , "RFC 1918: Private-Use" ),
62
- parseCidr ("192.175.48.0/24" , "RFC 7534: Direct Delegation AS112 Service" ),
63
- parseCidr ("198.18.0.0/15" , "RFC 2544: Benchmarking" ),
64
- parseCidr ("198.51.100.0/24" , "RFC 5737: Documentation (TEST-NET-2)" ),
65
- parseCidr ("203.0.113.0/24" , "RFC 5737: Documentation (TEST-NET-3)" ),
66
- parseCidr ("240.0.0.0/4" , "RFC1112, Section 4: Reserved" ),
67
- parseCidr ("255.255.255.255/32" , "RFC 8190 & RFC 919, Section 7: Limited Broadcast" ),
68
- // 224.0.0.0/4 are multicast addresses as per RFC 3171. They are not
69
- // present in the IANA registry.
70
- parseCidr ("224.0.0.0/4" , "RFC 3171: Multicast Addresses" ),
71
- }
72
- // Sourced from:
73
- // https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
74
- privateV6Networks = []net.IPNet {
75
- parseCidr ("::/128" , "RFC 4291: Unspecified Address" ),
76
- parseCidr ("::1/128" , "RFC 4291: Loopback Address" ),
77
- parseCidr ("::ffff:0:0/96" , "RFC 4291: IPv4-mapped Address" ),
78
- parseCidr ("64:ff9b::/96" , "RFC 6052: IPv4-IPv6 Translat." ),
79
- parseCidr ("64:ff9b:1::/48" , "RFC 8215: IPv4-IPv6 Translat." ),
80
- parseCidr ("100::/64" , "RFC 6666: Discard-Only Address Block" ),
81
- parseCidr ("2001::/23" , "RFC 2928: IETF Protocol Assignments" ),
82
- parseCidr ("2001::/32" , "RFC 4380 & RFC 8190: TEREDO" ),
83
- parseCidr ("2001:1::1/128" , "RFC 7723: Port Control Protocol Anycast" ),
84
- parseCidr ("2001:1::2/128" , "RFC 8155: Traversal Using Relays around NAT Anycast" ),
85
- parseCidr ("2001:1::3/128" , "RFC-ietf-dnssd-srp-25: DNS-SD Service Registration Protocol Anycast" ),
86
- parseCidr ("2001:2::/48" , "RFC 5180 & RFC Errata 1752: Benchmarking" ),
87
- parseCidr ("2001:3::/32" , "RFC 7450: AMT" ),
88
- parseCidr ("2001:4:112::/48" , "RFC 7535: AS112-v6" ),
89
- parseCidr ("2001:10::/28" , "RFC 4843: Deprecated (previously ORCHID)" ),
90
- parseCidr ("2001:20::/28" , "RFC 7343: ORCHIDv2" ),
91
- parseCidr ("2001:30::/28" , "RFC 9374: Drone Remote ID Protocol Entity Tags (DETs) Prefix" ),
92
- parseCidr ("2001:db8::/32" , "RFC 3849: Documentation" ),
93
- parseCidr ("2002::/16" , "RFC 3056: 6to4" ),
94
- parseCidr ("2620:4f:8000::/48" , "RFC 7534: Direct Delegation AS112 Service" ),
95
- parseCidr ("3fff::/20" , "RFC 9637: Documentation" ),
96
- parseCidr ("5f00::/16" , "RFC 9602: Segment Routing (SRv6) SIDs" ),
97
- parseCidr ("fc00::/7" , "RFC 4193 & RFC 8190: Unique-Local" ),
98
- parseCidr ("fe80::/10" , "RFC 4291: Link-Local Unicast" ),
99
- // ff00::/8 are multicast addresses as per RFC 4291, Sections 2.4 & 2.7.
100
- // They are not present in the IANA registry.
101
- parseCidr ("ff00::/8" , "RFC 4291: Multicast Addresses" ),
102
- }
27
+ "github.com/letsencrypt/boulder/policy"
103
28
)
104
29
105
30
// ResolverAddrs contains DNS resolver(s) that were chosen to perform a
@@ -432,24 +357,6 @@ func (dnsClient *impl) LookupTXT(ctx context.Context, hostname string) ([]string
432
357
return txt , ResolverAddrs {resolver }, err
433
358
}
434
359
435
- func isPrivateV4 (ip net.IP ) bool {
436
- for _ , net := range privateV4Networks {
437
- if net .Contains (ip ) {
438
- return true
439
- }
440
- }
441
- return false
442
- }
443
-
444
- func isPrivateV6 (ip net.IP ) bool {
445
- for _ , net := range privateV6Networks {
446
- if net .Contains (ip ) {
447
- return true
448
- }
449
- }
450
- return false
451
- }
452
-
453
360
func (dnsClient * impl ) lookupIP (ctx context.Context , hostname string , ipType uint16 ) ([]dns.RR , string , error ) {
454
361
resp , resolver , err := dnsClient .exchangeOne (ctx , hostname , ipType )
455
362
switch ipType {
@@ -474,6 +381,9 @@ func (dnsClient *impl) lookupIP(ctx context.Context, hostname string, ipType uin
474
381
// chase CNAME/DNAME aliases and return relevant records. It will retry
475
382
// requests in the case of temporary network errors. It returns an error if
476
383
// both the A and AAAA lookups fail or are empty, but succeeds otherwise.
384
+ //
385
+ // TODO(#5925): Changing from net.IP to netip.Addr could start from here
386
+ // outwards.
477
387
func (dnsClient * impl ) LookupHost (ctx context.Context , hostname string ) ([]net.IP , ResolverAddrs , error ) {
478
388
var recordsA , recordsAAAA []dns.RR
479
389
var errA , errAAAA error
@@ -502,8 +412,11 @@ func (dnsClient *impl) LookupHost(ctx context.Context, hostname string) ([]net.I
502
412
for _ , answer := range recordsA {
503
413
if answer .Header ().Rrtype == dns .TypeA {
504
414
a , ok := answer .(* dns.A )
505
- if ok && a .A .To4 () != nil && (! isPrivateV4 (a .A ) || dnsClient .allowRestrictedAddresses ) {
506
- addrsA = append (addrsA , a .A )
415
+ if ok && a .A .To4 () != nil {
416
+ netIP , ok := netip .AddrFromSlice (a .A )
417
+ if ok && (policy .IsReservedIP (netIP ) == nil || dnsClient .allowRestrictedAddresses ) {
418
+ addrsA = append (addrsA , a .A )
419
+ }
507
420
}
508
421
}
509
422
}
@@ -517,8 +430,11 @@ func (dnsClient *impl) LookupHost(ctx context.Context, hostname string) ([]net.I
517
430
for _ , answer := range recordsAAAA {
518
431
if answer .Header ().Rrtype == dns .TypeAAAA {
519
432
aaaa , ok := answer .(* dns.AAAA )
520
- if ok && aaaa .AAAA .To16 () != nil && (! isPrivateV6 (aaaa .AAAA ) || dnsClient .allowRestrictedAddresses ) {
521
- addrsAAAA = append (addrsAAAA , aaaa .AAAA )
433
+ if ok && aaaa .AAAA .To16 () != nil {
434
+ netIP , ok := netip .AddrFromSlice (aaaa .AAAA )
435
+ if ok && (policy .IsReservedIP (netIP ) == nil || dnsClient .allowRestrictedAddresses ) {
436
+ addrsAAAA = append (addrsAAAA , aaaa .AAAA )
437
+ }
522
438
}
523
439
}
524
440
}
@@ -686,20 +602,3 @@ func (d *dohExchanger) Exchange(query *dns.Msg, server string) (*dns.Msg, time.D
686
602
687
603
return response , d .clk .Since (start ), nil
688
604
}
689
-
690
- // IsReservedIP reports whether an IP address is part of a reserved range.
691
- //
692
- // TODO(#7311): Once we're fully ready to issue for IP address identifiers, dev
693
- // environments should have a way to bypass this check for their own Private-Use
694
- // IP addresses. Maybe plumb the DNSAllowLoopbackAddresses feature flag through
695
- // to here.
696
- //
697
- // TODO(#8040): Move this and its dependencies into the policy package. As part
698
- // of this, consider changing it to return an error and/or the description of
699
- // the reserved network.
700
- func IsReservedIP (ip net.IP ) bool {
701
- if ip .To4 () == nil {
702
- return isPrivateV6 (ip )
703
- }
704
- return isPrivateV4 (ip )
705
- }
0 commit comments