To be able to issue certificates with IP address in SAN, we need to look up both DNS name specified in SAN and IP address. The name resolution is done via ipa dnsrecord-show to demonstrate that IPA itself owns the zone and the record. A requestor needs to be able to read DNS object content.
ipa dnsrecord-show
However, when this procedure is executed by certmonger, it uses host Kerberos principal to authenticate. This principal has no rights to look up the data in DNS subtree and thus gets no entry returned back. As result, the whole certificate request fails:
# ipa-getcert request -v -r -k /etc/pki/tls/private/some.key -f /etc/pki/tls/certs/some.crt -D `hostname` -A "10.10.10.10" -K SOME/master.ipa.test@IPA.TEST New signing request "20191016121343" added. # ipa-getcert list -i 20191016121343 Number of certificates and requests being tracked: 17. Request ID '20191016121343': status: CA_REJECTED ca-error: Server at https://master.ipa.test/ipa/xml denied our request, giving up: 3009 (RPC failed at server. invalid 'csr': IP address in subjectAltName (10.10.10.10) unreachable from DNS names). stuck: yes key pair storage: type=FILE,location='/etc/pki/tls/private/some.key' certificate: type=FILE,location='/etc/pki/tls/certs/some.crt' CA: IPA issuer: subject: expires: unknown pre-save command: post-save command: track: yes auto-renew: yes
Indeed, direct ldapsearch also returns nothing as host principal:
# kinit -k # ldapsearch -b idnsname=ipa.test.,cn=dns,dc=ipa,dc=test -s base 'objectClass=*' objectclass SASL/GSS-SPNEGO authentication started SASL username: host/master.ipa.test@IPA.TEST SASL SSF: 256 SASL data security layer installed. # extended LDIF # # LDAPv3 # base <idnsname=ipa.test.,cn=dns,dc=ipa,dc=test> with scope baseObject # filter: objectClass=* # requesting: objectclass # # search result search: 3 result: 0 Success # numResponses: 1
This is the ACI with least privileged that I was able to come up: (targetattr = "aaaarecord || arecord || cnamerecord || idnsname || objectclass || ptrrecord")(targetfilter = "(&(objectclass=idnsrecord)(|(aaarecord=*)(arecord=*)(cnamerecord=*)(ptrrecord=*)(idnsZoneActive=TRUE)))")(version 3.0; acl "Allow hosts to read DNS A/AAA/CNAME/PTR records"; allow (read,search,compare) userdn = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX";)
(targetattr = "aaaarecord || arecord || cnamerecord || idnsname || objectclass || ptrrecord")(targetfilter = "(&(objectclass=idnsrecord)(|(aaarecord=*)(arecord=*)(cnamerecord=*)(ptrrecord=*)(idnsZoneActive=TRUE)))")(version 3.0; acl "Allow hosts to read DNS A/AAA/CNAME/PTR records"; allow (read,search,compare) userdn = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX";)
It only allows to read A, AAAA, CNAME, and PTR attributes from DNS entries. These attributes are used by _san_ip_update_reachable and _ip_ptr_records helpers in ipaserver.plugins.cert. idnsZoneActive=TRUE is required for dnsrecord_show to find the DNS zone. The target filter is very strict. A target filter of (objectclass=idnsrecord) may be OK, too.
_san_ip_update_reachable
_ip_ptr_records
ipaserver.plugins.cert
idnsZoneActive=TRUE
dnsrecord_show
(objectclass=idnsrecord)
Note to implementer: there is a typo in the ACI. in the targetfilter replace aaarecord with aaaarecord. Hats off to Ade Lee for catching it.
Yup , just confirming that this works with the typo fixed.
master:
ipa-4-8:
Metadata Update from @cheimes: - Issue close_status updated to: fixed - Issue status updated to: Closed (was: Open)
Login to comment on this ticket.