sigs.k8s.io/external-dns@v0.14.1/docs/tutorials/rfc2136.md (about) 1 # Configuring RFC2136 provider 2 This tutorial describes how to use the RFC2136 with either BIND or Windows DNS. 3 4 ## Using with BIND 5 To use external-dns with BIND: generate/procure a key, configure DNS and add a 6 deployment of external-dns. 7 8 ### Server credentials: 9 - RFC2136 was developed for and tested with 10 [BIND](https://www.isc.org/downloads/bind/) DNS server. This documentation 11 assumes that you already have a configured and working server. If you don't, 12 please check BIND documents or tutorials. 13 - If your DNS is provided for you, ask for a TSIG key authorized to update and 14 transfer the zone you wish to update. The key will look something like below. 15 Skip the next steps wrt BIND setup. 16 ```text 17 key "externaldns-key" { 18 algorithm hmac-sha256; 19 secret "96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8="; 20 }; 21 ``` 22 - If you are your own DNS administrator create a TSIG key. Use 23 `tsig-keygen -a hmac-sha256 externaldns` or on older distributions 24 `dnssec-keygen -a HMAC-SHA256 -b 256 -n HOST externaldns`. You will end up with 25 a key printed to standard out like above (or in the case of dnssec-keygen in a 26 file called `Kexternaldns......key`). 27 28 ### BIND Configuration: 29 If you do not administer your own DNS, skip to RFC provider configuration 30 31 - Edit your named.conf file (or appropriate included file) and add/change the 32 following. 33 - Make sure You are listening on the right interfaces. At least whatever 34 interface external-dns will be communicating over and the interface that 35 faces the internet. 36 - Add the key that you generated/was given to you above. Copy paste the four 37 lines that you got (not the same as the example key) into your file. 38 - Create a zone for kubernetes. If you already have a zone, skip to the next 39 step. (I put the zone in it's own subdirectory because named, 40 which shouldn't be running as root, needs to create a journal file and the 41 default zone directory isn't writeable by named). 42 ```text 43 zone "k8s.example.org" { 44 type master; 45 file "/etc/bind/pri/k8s/k8s.zone"; 46 }; 47 ``` 48 - Add your key to both transfer and update. For instance with our previous 49 zone. 50 ```text 51 zone "k8s.example.org" { 52 type master; 53 file "/etc/bind/pri/k8s/k8s.zone"; 54 allow-transfer { 55 key "externaldns-key"; 56 }; 57 update-policy { 58 grant externaldns-key zonesub ANY; 59 }; 60 }; 61 ``` 62 - Create a zone file (k8s.zone): 63 ```text 64 $TTL 60 ; 1 minute 65 k8s.example.org IN SOA k8s.example.org. root.k8s.example.org. ( 66 16 ; serial 67 60 ; refresh (1 minute) 68 60 ; retry (1 minute) 69 60 ; expire (1 minute) 70 60 ; minimum (1 minute) 71 ) 72 NS ns.k8s.example.org. 73 ns A 123.456.789.012 74 ``` 75 - Reload (or restart) named 76 77 78 ### Using external-dns 79 To use external-dns add an ingress or a LoadBalancer service with a host that 80 is part of the domain-filter. For example both of the following would produce 81 A records. 82 ```text 83 apiVersion: v1 84 kind: Service 85 metadata: 86 name: nginx 87 annotations: 88 external-dns.alpha.kubernetes.io/hostname: svc.example.org 89 spec: 90 type: LoadBalancer 91 ports: 92 - port: 80 93 targetPort: 80 94 selector: 95 app: nginx 96 --- 97 apiVersion: networking.k8s.io/v1 98 kind: Ingress 99 metadata: 100 name: my-ingress 101 spec: 102 rules: 103 - host: ingress.example.org 104 http: 105 paths: 106 - path: / 107 backend: 108 serviceName: my-service 109 servicePort: 8000 110 ``` 111 112 ### Custom TTL 113 114 The default DNS record TTL (Time-To-Live) is 0 seconds. You can customize this value by setting the annotation `external-dns.alpha.kubernetes.io/ttl`. e.g., modify the service manifest YAML file above: 115 116 ``` 117 apiVersion: v1 118 kind: Service 119 metadata: 120 name: nginx 121 annotations: 122 external-dns.alpha.kubernetes.io/hostname: nginx.external-dns-test.my-org.com 123 external-dns.alpha.kubernetes.io/ttl: 60 124 spec: 125 ... 126 ``` 127 128 This will set the DNS record's TTL to 60 seconds. 129 130 A default TTL for all records can be set using the the flag with a time in seconds, minutes or hours, such as `--rfc2136-min-ttl=60s` 131 132 There are other annotation that can affect the generation of DNS records, but these are beyond the scope of this 133 tutorial and are covered in the main documentation. 134 135 ### Test with external-dns installed on local machine (optional) 136 You may install external-dns and test on a local machine by running: 137 ```external-dns --txt-owner-id k8s --provider rfc2136 --rfc2136-host=192.168.0.1 --rfc2136-port=53 --rfc2136-zone=k8s.example.org --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= --rfc2136-tsig-secret-alg=hmac-sha256 --rfc2136-tsig-keyname=externaldns-key --rfc2136-tsig-axfr --source ingress --once --domain-filter=k8s.example.org --dry-run``` 138 - host should be the IP of your master DNS server. 139 - tsig-secret should be changed to match your secret. 140 - tsig-keyname needs to match the keyname you used (if you changed it). 141 - domain-filter can be used as shown to filter the domains you wish to update. 142 143 ### RFC2136 provider configuration: 144 In order to use external-dns with your cluster you need to add a deployment 145 with access to your ingress and service resources. The following are two 146 example manifests with and without RBAC respectively. 147 148 - With RBAC: 149 ```text 150 apiVersion: v1 151 kind: Namespace 152 metadata: 153 name: external-dns 154 labels: 155 name: external-dns 156 --- 157 apiVersion: rbac.authorization.k8s.io/v1 158 kind: ClusterRole 159 metadata: 160 name: external-dns 161 namespace: external-dns 162 rules: 163 - apiGroups: 164 - "" 165 resources: 166 - services 167 - endpoints 168 - pods 169 - nodes 170 verbs: 171 - get 172 - watch 173 - list 174 - apiGroups: 175 - extensions 176 - networking.k8s.io 177 resources: 178 - ingresses 179 verbs: 180 - get 181 - list 182 - watch 183 --- 184 apiVersion: v1 185 kind: ServiceAccount 186 metadata: 187 name: external-dns 188 namespace: external-dns 189 --- 190 apiVersion: rbac.authorization.k8s.io/v1 191 kind: ClusterRoleBinding 192 metadata: 193 name: external-dns-viewer 194 namespace: external-dns 195 roleRef: 196 apiGroup: rbac.authorization.k8s.io 197 kind: ClusterRole 198 name: external-dns 199 subjects: 200 - kind: ServiceAccount 201 name: external-dns 202 namespace: external-dns 203 --- 204 apiVersion: apps/v1 205 kind: Deployment 206 metadata: 207 name: external-dns 208 namespace: external-dns 209 spec: 210 selector: 211 matchLabels: 212 app: external-dns 213 template: 214 metadata: 215 labels: 216 app: external-dns 217 spec: 218 serviceAccountName: external-dns 219 containers: 220 - name: external-dns 221 image: registry.k8s.io/external-dns/external-dns:v0.14.0 222 args: 223 - --registry=txt 224 - --txt-prefix=external-dns- 225 - --txt-owner-id=k8s 226 - --provider=rfc2136 227 - --rfc2136-host=192.168.0.1 228 - --rfc2136-port=53 229 - --rfc2136-zone=k8s.example.org 230 - --rfc2136-zone=k8s.your-zone.org 231 - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= 232 - --rfc2136-tsig-secret-alg=hmac-sha256 233 - --rfc2136-tsig-keyname=externaldns-key 234 - --rfc2136-tsig-axfr 235 - --source=ingress 236 - --domain-filter=k8s.example.org 237 ``` 238 239 - Without RBAC: 240 ```text 241 apiVersion: v1 242 kind: Namespace 243 metadata: 244 name: external-dns 245 labels: 246 name: external-dns 247 --- 248 apiVersion: apps/v1 249 kind: Deployment 250 metadata: 251 name: external-dns 252 namespace: external-dns 253 spec: 254 selector: 255 matchLabels: 256 app: external-dns 257 template: 258 metadata: 259 labels: 260 app: external-dns 261 spec: 262 containers: 263 - name: external-dns 264 image: registry.k8s.io/external-dns/external-dns:v0.14.0 265 args: 266 - --registry=txt 267 - --txt-prefix=external-dns- 268 - --txt-owner-id=k8s 269 - --provider=rfc2136 270 - --rfc2136-host=192.168.0.1 271 - --rfc2136-port=53 272 - --rfc2136-zone=k8s.example.org 273 - --rfc2136-zone=k8s.your-zone.org 274 - --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8= 275 - --rfc2136-tsig-secret-alg=hmac-sha256 276 - --rfc2136-tsig-keyname=externaldns-key 277 - --rfc2136-tsig-axfr 278 - --source=ingress 279 - --domain-filter=k8s.example.org 280 ``` 281 282 ## Microsoft DNS (Insecure Updates) 283 284 While `external-dns` was not developed or tested against Microsoft DNS, it can be configured to work against it. YMMV. 285 286 ### Insecure Updates 287 288 #### DNS-side configuration 289 290 1. Create a DNS zone 291 2. Enable insecure dynamic updates for the zone 292 3. Enable Zone Transfers to all servers 293 294 #### `external-dns` configuration 295 296 You'll want to configure `external-dns` similarly to the following: 297 298 ```text 299 ... 300 - --provider=rfc2136 301 - --rfc2136-host=192.168.0.1 302 - --rfc2136-port=53 303 - --rfc2136-zone=k8s.example.org 304 - --rfc2136-zone=k8s.your-zone.org 305 - --rfc2136-insecure 306 - --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records. 307 ... 308 ``` 309 310 ### Secure Updates Using RFC3645 (GSS-TSIG) 311 312 ### DNS-side configuration 313 314 1. Create a DNS zone 315 2. Enable secure dynamic updates for the zone 316 3. Enable Zone Transfers to all servers 317 318 If you see any error messages which indicate that `external-dns` was somehow not able to fetch 319 existing DNS records from your DNS server, this could mean that you forgot about step 3. 320 321 #### Kerberos Configuration 322 323 DNS with secure updates relies upon a valid Kerberos configuration running within the `external-dns` container. At this time, you will need to create a ConfigMap for the `external-dns` container to use and mount it in your deployment. Below is an example of a working Kerberos configuration inside a ConfigMap definition. This may be different depending on many factors in your environment: 324 325 ```yaml 326 apiVersion: v1 327 kind: ConfigMap 328 metadata: 329 creationTimestamp: null 330 name: krb5.conf 331 data: 332 krb5.conf: | 333 [logging] 334 default = FILE:/var/log/krb5libs.log 335 kdc = FILE:/var/log/krb5kdc.log 336 admin_server = FILE:/var/log/kadmind.log 337 338 [libdefaults] 339 dns_lookup_realm = false 340 ticket_lifetime = 24h 341 renew_lifetime = 7d 342 forwardable = true 343 rdns = false 344 pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt 345 default_ccache_name = KEYRING:persistent:%{uid} 346 347 default_realm = YOUR-REALM.COM 348 349 [realms] 350 YOUR-REALM.COM = { 351 kdc = dc1.yourdomain.com 352 admin_server = dc1.yourdomain.com 353 } 354 355 [domain_realm] 356 yourdomain.com = YOUR-REALM.COM 357 .yourdomain.com = YOUR-REALM.COM 358 ``` 359 In most cases, the realm name will probably be the same as the domain name, so you can simply replace 360 `YOUR-REALM.COM` with something like `YOURDOMAIN.COM`. 361 362 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: 363 364 ```yaml 365 ... 366 volumeMounts: 367 - mountPath: /etc/krb5.conf 368 name: kerberos-config-volume 369 subPath: krb5.conf 370 ... 371 volumes: 372 - configMap: 373 defaultMode: 420 374 name: krb5.conf 375 name: kerberos-config-volume 376 ... 377 ``` 378 379 #### `external-dns` configuration 380 381 You'll want to configure `external-dns` similarly to the following: 382 383 ```text 384 ... 385 - --provider=rfc2136 386 - --rfc2136-gss-tsig 387 - --rfc2136-host=dns-host.yourdomain.com 388 - --rfc2136-port=53 389 - --rfc2136-zone=your-zone.com 390 - --rfc2136-zone=your-secondary-zone.com 391 - --rfc2136-kerberos-username=your-domain-account 392 - --rfc2136-kerberos-password=your-domain-password 393 - --rfc2136-kerberos-realm=your-domain.com 394 - --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records. 395 ... 396 ``` 397 398 As noted above, the `--rfc2136-kerberos-realm` flag is completely optional and won't be necessary in many cases. 399 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`. 400 401 The flag `--rfc2136-host` can be set to the host's domain name or IP address. 402 However, it also determines the name of the Kerberos principal which is used during authentication. 403 This means that Active Directory might only work if this is set to a specific domain name, possibly leading to errors like this: 404 `KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database`. 405 To fix this, try setting `--rfc2136-host` to the "actual" hostname of your DNS server. 406 407 ## DNS Over TLS (RFCs 7858 and 9103) 408 409 If your DNS server does zone transfers over TLS, you can instruct `external-dns` to connect over TLS with the following flags: 410 411 * `--rfc2136-use-tls` Will enable TLS for both zone transfers and for updates. 412 * `--tls-ca=<cert-file>` Is the path to a file containing certificate(s) that can be used to verify the DNS server 413 * `--tls-client-cert=<client-cert-file>` and 414 * `--tls-client-cert-key=<client-key-file>` Set the client certificate and key for mutual verification 415 * `--rfc2136-skip-tls-verify` Disables verification of the certificate supplied by the DNS server. 416 417 It is currently not supported to do only zone transfers over TLS, but not the updates. They are enabled and disabled together.