Per bind-dyndb-ldap instance record generation

Overview

FreeIPA DNS is using multiple bind-dyndb-ldap instances connected the same base DN of a replicated LDAP database.

As a consequence, it means that all instances servive the same data. In some special cases, this is not sufficient because different bind-dyndb-ldap instances should use different data.

This feature will allow bind-dyndb-ldap instance to generate records using user-provided template and variables from bind-dyndb-ldap’s configuration.

Design

Per-server variables

idnsServerConfigObject will be extended with idnsSubstitutionVariable attribute. This attribute can be used by user for defining own variables usable by record generation mechanism described later.

Attribute syntax:

attributeTypes: ( 2.16.840.1.113730.3.8.5.30 NAME 'idnsSubstitutionVariable' DESC 'User defined variable for DNS plugin' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'IPA v4.4' )

Attribute usage

  • Variable name must follow naming rules for LDAP attribute subtypes and is compared as such - case insensitively.

    • ABNF:

      option = 1*keychar
      keychar = ALPHA / DIGIT / HYPHEN
      ALPHA   = %x41-5A / %x61-7A   ; "A"-"Z" / "a"-"z"
      DIGIT   = %x30 / LDIGIT       ; "0"-"9"
      LDIGIT  = %x31-39             ; "1"-"9"
      HYPHEN  = %x2D ; hyphen ("-")
      
  • Legal usage: Use exactly one instance of each sub-type. The attribute cannot be used without sub-type.

Example

Configuration for server ipa-brno.example.com defines two variables: ipalocation = cz and siplocation = emea:

dn: idnsServerId=krbprincipalname\3Ddns/ipa-brno.example.com@example.com\,cn\3Dservices\,cn\3Daccounts\,dc\3Dexample\,dc\3Dcom,cn=servers,cn=dns,dc=example,dc=com
objectClass: idnsConfigObject
objectClass: idnsServerConfigObject
idnsServerId: krbprincipalname=dns/ipa-brno.example.com@example.com,cn=services,cn=accounts,dc=example,dc=com
idnsSubstitutionVariable;ipalocation: cz
idnsSubstitutionVariable;siplocation: emea

Configuration for server ipa-london.example.com defines two variables: ipalocation = uk and siplocation = emea:

dn: idnsServerId=krbprincipalname\3Ddns/ipa-london.example.com@example.com\,cn\3Dservices\,cn\3Daccounts\,dc\3Dexample\,dc\3Dcom,cn=servers,cn=dns,dc=example,dc=com
objectClass: idnsConfigObject
objectClass: idnsServerConfigObject
idnsServerId: krbprincipalname=dns/ipa-london.example.com@example.com,cn=services,cn=accounts,dc=example,dc=com
idnsSubstitutionVariable;ipalocation: uk
idnsSubstitutionVariable;siplocation: emea

These variables can be used for record generation later on.

Data generation

LDAP entries representing DNS data can be made dynamic by adding auxiliary object class idnsTemplateObject. This will allow the user to add idnsTemplateAttribute which will generate attributes while the zone is loading. The template can reference user-defined attributes from idnsServerConfigObject and other variables used by bind-dyndb-ldap.

attributeTypes: ( 2.16.840.1.113730.3.8.5.29 NAME 'idnsTemplateAttribute' DESC 'Template attribute for dynamic attribute generation' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'IPA v4.4' )
objectClasses: ( 2.16.840.1.113730.3.8.6.5 NAME 'idnsTemplateObject' DESC 'Template object for dynamic DNS attribute generation' AUXILIARY MUST ( idnsTemplateAttribute ) X-ORIGIN 'IPA v4.4' )

Attribute usage

  • Name of the generated attribute is determined by LDAP subtype of idnsTemplateAttribute.
  • All strings in idnsTemplateAttribute except variable names will be copied as-is to the generated attribute.
  • Character sequences \{ and \} start and end blocks which will be replaced by value taken from the variable.
    • Name of the variable is the value between delimiters \{ and \}.
      • If the variable was defined by user using idnsSubstitutionVariable attribute, then its name is prefixed with prefix substitutionvariable_ to avoid collisions with internal variable names defined by bind-dyndb-ldap.
    • Special meaning of \{ and \} can be disabled by escaping the \ character. I.e. character sequence \\{ will be copied over to the resulting string as \{.
  • If all variables used by idnsTemplateObject are defined then all attributes which are not result of dynamic generation are ignored. Effectivelly the template overrides all attributes in the whole object.
  • If any undefined variable is found during processing any of idnsTemplateObject attributes, the whole idnsTemplateObject and its attributes are ignored. This means that whenever a variable used in a template is undefined, the template is ignored and statically defined attributes from the object are used.
  • Legal usage:
    • The attribute cannot be used without sub-type.
    • The attribute has to be used with exactly one sub-type.
    • One sub-type can have multiple values.
    • Subtypes cannot be combined on one attribute instance. (I.e. idnsTemplateAttribute;dname;cname: value is not allowed.)

Example

Following example will generate DNAMERecord attribute with value constructed from prefix _udp., user-defined variable ipalocation, and suffix _locations.

dn: idnsName=_udp,idnsname=example.com.,cn=dns,dc=example,dc=com
objectClass: idnsTemplateObject
objectClass: top
objectClass: idnsRecord
idnsName: _udp
idnsTemplateAttribute;dnamerecord: _udp.\{substitutionvariable_ipalocation\}._locations
dNSTTL: 3600

This will generate two different DNAME records on our two servers:

  • Server ipa-brno.example.com will generate record DNAME _udp.cz._locations.example.com.
  • Server ipa-london.example.com will generate record DNAME _udp.uk._locations.example.com.

Following example will generate DNAMERecord attribute with value constructed from prefix _udp., user-defined variable siplocation, and suffix _locations.

dn: idnsName=_udp,idnsname=phone.example.com.,cn=dns,dc=example,dc=com
objectClass: idnsTemplateObject
objectClass: top
objectClass: idnsRecord
idnsName: _udp
idnsTemplateAttribute;dnamerecord: _udp.\{substitutionvariable_siplocation\}._locations
txtRecord: "this static record and it will be ignored when generator is configured"
dNSTTL: 3600

The new DNAMERecord attribute will replace all original (static) attributes. As a result, the TXT record will not be present and resulting TTL will be the default one.

If need, an additional static values can be defined using idnsTemplateAttribute values without a substitution, e.g.:

dn: idnsName=_udp,idnsname=phone.example.com.,cn=dns,dc=example,dc=com
objectClass: idnsTemplateObject
objectClass: top
objectClass: idnsRecord
idnsName: _udp
idnsTemplateAttribute;dnamerecord: _udp.\{substitutionvariable_siplocation\}._locations
idnsTemplateAttribute;txtRecord: "DNAME was auto-generated using siplocation variable"
idnsTemplateAttribute;dNSTTL: 300
txtRecord: "this static record and it will be ignored when generator is configured"
dNSTTL: 3600
  • On servers where variable siplocation is defined, the TTL will be 300 seconds and TXT will contain text indicating that the DNAME was auto-generated.
  • On servers where variable siplocation is not defined, the TTL will be 3600 seconds and TXT will contain text indicating that it is a static record. DNAME record will not exist.

The proposed solution. This may include but is not limited to:

Access control

  • No expected impact. Variables must not be used for sensitive data.
  • idnsTemplateAttribute can be used by regular users as it allows to create only regular DNS records and nothing else.

Compatibility with other (older) version of FreeIPA

No expected impact. Older versions will just ignore the new object class and attributes.

Implementation

Any implementation details you would like to spell out. Describe any technical details here. Make sure you cover

  • Dependencies: any new dependencies that FreeIPA project or it’s part would gain and that needs to be packaged in distros?
  • Backup and Restore: any new file to back up or change required in Backup and Restore?

If this section is not trivial, move it to Implementation sub page and only include link.

Feature Management

This feature will not have any user-visible knobs - it will be used internally by FreeIPA. FreeIPA should generate a warning whenever DNS entry in LDAP contains idnsTemplateObject and a static values at the same time. In this case static values might or might not be ignored which will be confusing for users.

Configuration

No new configuration options.

Upgrade

No expected impact on upgrades.

How to Test

Easy to follow instructions how to test the new feature. FreeIPA user needs to be able to follow the steps and demonstrate the new features.

Test Plan

Test scenarios that will be transformed to test cases for FreeIPA Continuous Integration during implementation or review phase. This can be also link to source in git with the test, if appropriate.