Make sure we don't provision to a private hosted zone

Route 53 allows multiple zones with the same name to co-exist in an
account. The most common use case for this is a split-view DNS with one
private and one public zone for the same domain name. This patch makes
sure we don’t ever provision the authorization record to the private
zone.
The other case where a user has multiple public zones with the same
name is not covered here since this would require a bigger change in
code in order to determine which of the zones is active from the
viewpoint of the internet. Also this is probably an edge use case that
can be addressed once it comes up in the issues.
This commit is contained in:
JanB 2016-04-21 15:47:43 +02:00
parent 094e3d41bb
commit 4d9e4f1487

View file

@ -84,7 +84,7 @@ func (r *DNSProvider) CleanUp(domain, token, keyAuth string) error {
func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error { func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
hostedZoneID, err := r.getHostedZoneID(fqdn) hostedZoneID, err := r.getHostedZoneID(fqdn)
if err != nil { if err != nil {
return err return fmt.Errorf("Failed to determine Route 53 hosted zone ID: %v", err)
} }
recordSet := newTXTRecordSet(fqdn, value, ttl) recordSet := newTXTRecordSet(fqdn, value, ttl)
@ -103,7 +103,7 @@ func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
resp, err := r.client.ChangeResourceRecordSets(reqParams) resp, err := r.client.ChangeResourceRecordSets(reqParams)
if err != nil { if err != nil {
return err return fmt.Errorf("Failed to change Route 53 record set: %v", err)
} }
statusID := resp.ChangeInfo.Id statusID := resp.ChangeInfo.Id
@ -114,7 +114,7 @@ func (r *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
} }
resp, err := r.client.GetChange(reqParams) resp, err := r.client.GetChange(reqParams)
if err != nil { if err != nil {
return false, err return false, fmt.Errorf("Failed to query Route 53 change status: %v", err)
} }
if *resp.ChangeInfo.Status == route53.ChangeStatusInsync { if *resp.ChangeInfo.Status == route53.ChangeStatusInsync {
return true, nil return true, nil
@ -131,25 +131,31 @@ func (r *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
// .DNSName should not have a trailing dot // .DNSName should not have a trailing dot
reqParams := &route53.ListHostedZonesByNameInput{ reqParams := &route53.ListHostedZonesByNameInput{
DNSName: aws.String(acme.UnFqdn(authZone)), DNSName: aws.String(acme.UnFqdn(authZone)),
MaxItems: aws.String("1"),
} }
resp, err := r.client.ListHostedZonesByName(reqParams) resp, err := r.client.ListHostedZonesByName(reqParams)
if err != nil { if err != nil {
return "", err return "", err
} }
// .Name has a trailing dot var hostedZoneID string
if len(resp.HostedZones) == 0 || *resp.HostedZones[0].Name != authZone { for _, hostedZone := range resp.HostedZones {
return "", fmt.Errorf("Zone %s not found in Route53 for domain %s", authZone, fqdn) // .Name has a trailing dot
if !*hostedZone.Config.PrivateZone && *hostedZone.Name == authZone {
hostedZoneID = *hostedZone.Id
break
}
} }
zoneID := *resp.HostedZones[0].Id if len(hostedZoneID) == 0 {
if strings.HasPrefix(zoneID, "/hostedzone/") { return "", fmt.Errorf("Zone %s not found in Route 53 for domain %s", authZone, fqdn)
zoneID = strings.TrimPrefix(zoneID, "/hostedzone/")
} }
return zoneID, nil if strings.HasPrefix(hostedZoneID, "/hostedzone/") {
hostedZoneID = strings.TrimPrefix(hostedZoneID, "/hostedzone/")
}
return hostedZoneID, nil
} }
func newTXTRecordSet(fqdn, value string, ttl int) *route53.ResourceRecordSet { func newTXTRecordSet(fqdn, value string, ttl int) *route53.ResourceRecordSet {