From 0b8e047d2e025225b422851ae5ba3c7276524cd0 Mon Sep 17 00:00:00 2001 From: stovemeerkat Date: Thu, 18 Mar 2021 11:36:46 +0100 Subject: [PATCH 1/2] rfc2136: Add new flag to specify Kerberos realm for GSS-TSIG --- main.go | 2 +- pkg/apis/externaldns/types.go | 3 +++ provider/rfc2136/rfc2136.go | 8 ++++++-- provider/rfc2136/rfc2136_test.go | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 09860c08d2..0773cc619f 100644 --- a/main.go +++ b/main.go @@ -283,7 +283,7 @@ func main() { p, err = oci.NewOCIProvider(*config, domainFilter, zoneIDFilter, cfg.DryRun) } case "rfc2136": - p, err = rfc2136.NewRfc2136Provider(cfg.RFC2136Host, cfg.RFC2136Port, cfg.RFC2136Zone, cfg.RFC2136Insecure, cfg.RFC2136TSIGKeyName, cfg.RFC2136TSIGSecret, cfg.RFC2136TSIGSecretAlg, cfg.RFC2136TAXFR, domainFilter, cfg.DryRun, cfg.RFC2136MinTTL, cfg.RFC2136GSSTSIG, cfg.RFC2136KerberosUsername, cfg.RFC2136KerberosPassword, nil) + p, err = rfc2136.NewRfc2136Provider(cfg.RFC2136Host, cfg.RFC2136Port, cfg.RFC2136Zone, cfg.RFC2136Insecure, cfg.RFC2136TSIGKeyName, cfg.RFC2136TSIGSecret, cfg.RFC2136TSIGSecretAlg, cfg.RFC2136TAXFR, domainFilter, cfg.DryRun, cfg.RFC2136MinTTL, cfg.RFC2136GSSTSIG, cfg.RFC2136KerberosRealm, cfg.RFC2136KerberosUsername, cfg.RFC2136KerberosPassword, nil) case "ns1": p, err = ns1.NewNS1Provider( ns1.NS1Config{ diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index b8d43f4620..5fc354a1db 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -142,6 +142,7 @@ type Config struct { RFC2136Zone string RFC2136Insecure bool RFC2136GSSTSIG bool + RFC2136KerberosRealm string RFC2136KerberosUsername string RFC2136KerberosPassword string RFC2136TSIGKeyName string @@ -255,6 +256,7 @@ var defaultConfig = &Config{ RFC2136Zone: "", RFC2136Insecure: false, RFC2136GSSTSIG: false, + RFC2136KerberosRealm: "", RFC2136KerberosUsername: "", RFC2136KerberosPassword: "", RFC2136TSIGKeyName: "", @@ -434,6 +436,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("rfc2136-tsig-axfr", "When using the RFC2136 provider, specify the TSIG (base64) value to attached to DNS messages (required when --rfc2136-insecure=false)").BoolVar(&cfg.RFC2136TAXFR) app.Flag("rfc2136-min-ttl", "When using the RFC2136 provider, specify minimal TTL (in duration format) for records. This value will be used if the provided TTL for a service/ingress is lower than this").Default(defaultConfig.RFC2136MinTTL.String()).DurationVar(&cfg.RFC2136MinTTL) app.Flag("rfc2136-gss-tsig", "When using the RFC2136 provider, specify whether to use secure updates with GSS-TSIG using Kerberos (default: false, requires --rfc2136-kerberos-username and rfc2136-kerberos-password)").Default(strconv.FormatBool(defaultConfig.RFC2136GSSTSIG)).BoolVar(&cfg.RFC2136GSSTSIG) + app.Flag("rfc2136-kerberos-realm", "When using the RFC2136 provider with GSS-TSIG, specify the Kerberos realm used for authentication (default: the value of --rfc2316-zone converted to uppercase)").Default(defaultConfig.RFC2136KerberosRealm).StringVar(&cfg.RFC2136KerberosRealm) app.Flag("rfc2136-kerberos-username", "When using the RFC2136 provider with GSS-TSIG, specify the username of the user with permissions to update DNS records (required when --rfc2136-gss-tsig=true)").Default(defaultConfig.RFC2136KerberosUsername).StringVar(&cfg.RFC2136KerberosUsername) app.Flag("rfc2136-kerberos-password", "When using the RFC2136 provider with GSS-TSIG, specify the password of the user with permissions to update DNS records (required when --rfc2136-gss-tsig=true)").Default(defaultConfig.RFC2136KerberosPassword).StringVar(&cfg.RFC2136KerberosPassword) diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index 6112611606..893c98be13 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -85,12 +85,16 @@ type rfc2136Actions interface { } // NewRfc2136Provider is a factory function for OpenStack rfc2136 providers -func NewRfc2136Provider(host string, port int, zoneName string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, gssTsig bool, krb5Username string, krb5Password string, actions rfc2136Actions) (provider.Provider, error) { +func NewRfc2136Provider(host string, port int, zoneName string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, gssTsig bool, krb5Realm string, krb5Username string, krb5Password string, actions rfc2136Actions) (provider.Provider, error) { secretAlgChecked, ok := tsigAlgs[secretAlg] if !ok && !insecure && !gssTsig { return nil, errors.Errorf("%s is not supported TSIG algorithm", secretAlg) } + if krb5Realm == "" { + krb5Realm = strings.ToUpper(zoneName) + } + r := &rfc2136Provider{ nameserver: net.JoinHostPort(host, strconv.Itoa(port)), zoneName: dns.Fqdn(zoneName), @@ -98,7 +102,7 @@ func NewRfc2136Provider(host string, port int, zoneName string, insecure bool, k gssTsig: gssTsig, krb5Username: krb5Username, krb5Password: krb5Password, - krb5Realm: strings.ToUpper(zoneName), + krb5Realm: krb5Realm, domainFilter: domainFilter, dryRun: dryRun, axfr: axfr, diff --git a/provider/rfc2136/rfc2136_test.go b/provider/rfc2136/rfc2136_test.go index 1df3ea1c6c..59d3ea818d 100644 --- a/provider/rfc2136/rfc2136_test.go +++ b/provider/rfc2136/rfc2136_test.go @@ -95,7 +95,7 @@ func (r *rfc2136Stub) IncomeTransfer(m *dns.Msg, a string) (env chan *dns.Envelo } func createRfc2136StubProvider(stub *rfc2136Stub) (provider.Provider, error) { - return NewRfc2136Provider("", 0, "", false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, "", "", stub) + return NewRfc2136Provider("", 0, "", false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, "", "", "", stub) } func extractAuthoritySectionFromMessage(msg fmt.Stringer) []string { From 098cedb7f98094ac58fa20adb6c775a9a965e818 Mon Sep 17 00:00:00 2001 From: stovemeerkat Date: Thu, 18 Mar 2021 12:07:36 +0100 Subject: [PATCH 2/2] docs: Update and improve tutorial for the RFC2136 provider --- docs/tutorials/rfc2136.md | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/docs/tutorials/rfc2136.md b/docs/tutorials/rfc2136.md index 9234778131..d352dee615 100644 --- a/docs/tutorials/rfc2136.md +++ b/docs/tutorials/rfc2136.md @@ -287,7 +287,7 @@ While `external-dns` was not developed or tested against Microsoft DNS, it can b 1. Create a DNS zone 2. Enable insecure dynamic updates for the zone -3. Enable Zone Transfers from all servers +3. Enable Zone Transfers to all servers #### `external-dns` configuration @@ -310,8 +310,10 @@ You'll want to configure `external-dns` similarly to the following: 1. Create a DNS zone 2. Enable secure dynamic updates for the zone -3. Enable Zone Transfers from all servers +3. Enable Zone Transfers to all servers +If you see any error messages which indicate that `external-dns` was somehow not able to fetch +existing DNS records from your DNS server, this could mean that you forgot about step 3. #### Kerberos Configuration @@ -339,18 +341,20 @@ data: pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt default_ccache_name = KEYRING:persistent:%{uid} - default_realm = YOURDOMAIN.COM + default_realm = YOUR-REALM.COM [realms] - YOURDOMAIN.COM = { + YOUR-REALM.COM = { kdc = dc1.yourdomain.com admin_server = dc1.yourdomain.com } [domain_realm] - yourdomain.com = YOURDOMAIN.COM - .yourdomain.com = YOURDOMAIN.COM + yourdomain.com = YOUR-REALM.COM + .yourdomain.com = YOUR-REALM.COM ``` +In most cases, the realm name will probably be the same as the domain name, so you can simply replace +`YOUR-REALM.COM` with something like `YOURDOMAIN.COM`. Once the ConfigMap is created, the container `external-dns` container needs to be told to mount that ConfigMap as a volume at the default Kerberos configuration location. The pod spec should include a similar configuration to the following: @@ -376,11 +380,22 @@ You'll want to configure `external-dns` similarly to the following: ```text ... - --provider=rfc2136 - - --rfc2136-host=123.123.123.123 + - --rfc2136-host=dns-host.yourdomain.com - --rfc2136-port=53 - --rfc2136-zone=your-domain.com + - --rfc2136-gss-tsig + - --rfc2136-kerberos-realm=YOUR-REALM.COM # optional; use if your realm's name differs from the DNS zone - --rfc2136-kerberos-username=your-domain-account - --rfc2136-kerberos-password=your-domain-password - --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records. ... ``` + +As noted above, the `--rfc2136-kerberos-realm` flag is completely optional and won't be necessary in many cases. +Most likely, you will only need it if you see errors similar to this: `KRB Error: (68) KDC_ERR_WRONG_REALM Reserved for future use`. + +The flag `--rfc2136-host` can be set to the host's domain name or IP address. +However, it also determines the name of the Kerberos principal which is used during authentication. +This means that Active Directory might only work if this is set to a specific domain name, possibly leading to errors like this: +`KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database`. +To fix this, try setting `--rfc2136-host` to the "actual" hostname of your DNS server.