Hi,
I'm setting up an openvpn server and I'd like to use our already existing FreeIPA CA to issue user keys/certs for openvpn's use. Since our OpenVPN box is a freeipa client, I thought it'd be nice to use certmonger to issue and keep up to date these certs.
Ergo, I've created a certificate profile:
pat@apex-freeipa ~$ ipa certprofile-show --all OpenVPNUserCert dn: cn=OpenVPNUserCert,cn=certprofiles,cn=ca,dc=int,dc=apexmw,dc=com Profile ID: OpenVPNUserCert Profile description: OpenVPN User Certificates Store issued certificates: FALSE objectclass: ipacertprofile, top
And also a CA acl. For experimentation (and working vs our test freeipa) I've left this as wide open as I can:
[pat@apex-freeipa ~]$ ipa caacl-show --all OpenVPN_User_Certificate_ACL dn: ipaUniqueID=6dde33a6-7849-11e9-aa05-525400b52c7b,cn=caacls,cn=ca,dc=int,dc=apexmw,dc=com ACL name: OpenVPN_User_Certificate_ACL Enabled: TRUE CA category: all Profile category: all User category: all Host category: all Service category: all ipauniqueid: 6dde33a6-7849-11e9-aa05-525400b52c7b objectclass: ipaassociation, ipacaacl
Then, on my openvpn server, I ask for a cert for use for one of my users (myself, in this case):
root@apex-openvpn:~# ipa-getcert request -f /etc/openvpn/client/pat.crt -k /etc/openvpn/client/pat.key -r -N 'CN=pat,O=INT.APEXMW.COM' -K pat -g 4096 --profile OpenVPNUserCert New signing request "20190603014016" added.
But, it fails due to an access err vs the 'userCertificate' attribute of my account:
root@apex-openvpn:~# ipa-getcert list (...snippy snip excess...) Request ID '20190603014016': status: CA_REJECTED ca-error: Server at https://apex-freeipa.int.apexmw.com/ipa/xml denied our request, giving up: 2100 (RPC failed at server. Insufficient access: Insufficient 'write' privilege to the 'userCertificate' attribute of entry 'uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com'.). stuck: yes key pair storage: type=FILE,location='/etc/openvpn/client/pat.key' certificate: type=FILE,location='/etc/openvpn/client/pat.crt' CA: IPA issuer: subject: expires: unknown pre-save command: post-save command: track: yes auto-renew: yes
If I look at the dirsrv log, here's the accesses I see for this request (trimmed off the date/time to make the lines a _little_ shorter):
root@apex-freeipa slapd-INT-APEXMW-COM# grep conn=178 access | cut -d' ' -f3- conn=178 fd=114 slot=114 connection from 10.10.200.1 to 10.10.200.1 conn=178 op=0 BIND dn="" method=sasl version=3 mech=GSS-SPNEGO conn=178 op=0 RESULT err=0 tag=97 nentries=0 etime=0.0025554208 dn="fqdn=apex-openvpn.int.apexmw.com,cn=computers,cn=accounts,dc=int,dc=apexmw,dc=com" conn=178 op=1 SRCH base="cn=ipaconfig,cn=etc,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs=ALL conn=178 op=1 RESULT err=0 tag=101 nentries=1 etime=0.0001319554 conn=178 op=2 SRCH base="cn=masters,cn=ipa,cn=etc,dc=int,dc=apexmw,dc=com" scope=2 filter="(&(objectClass=ipaConfigObject)(cn=CA))" attrs=ALL conn=178 op=2 RESULT err=0 tag=101 nentries=1 etime=0.0000979573 conn=178 op=3 SRCH base="cn=masters,cn=ipa,cn=etc,dc=int,dc=apexmw,dc=com" scope=2 filter="(&(objectClass=ipaConfigObject)(cn=CA))" attrs=ALL conn=178 op=3 RESULT err=0 tag=101 nentries=1 etime=0.0000736730 conn=178 op=4 SRCH base="cn=cas,cn=ca,dc=int,dc=apexmw,dc=com" scope=2 filter="(&(objectClass=ipaca)(cn=ipa))" attrs="" conn=178 op=4 RESULT err=0 tag=101 nentries=1 etime=0.0000499142 conn=178 op=5 SRCH base="cn=ipa,cn=cas,cn=ca,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="ipaCaId ipaCaSubjectDN cn ipaCaIssuerDN description" conn=178 op=5 RESULT err=0 tag=101 nentries=1 etime=0.0000482726 conn=178 op=6 SRCH base="cn=apex-freeipa.int.apexmw.com,cn=masters,cn=ipa,cn=etc,dc=int,dc=apexmw,dc=com" scope=2 filter="(&(objectClass=ipaConfigObject)(ipaConfigString=enabledService)(cn=CA))" attrs=ALL conn=178 op=6 RESULT err=0 tag=101 nentries=1 etime=0.0000950646 notes=U conn=178 op=7 SRCH base="cn=accounts,dc=int,dc=apexmw,dc=com" scope=2 filter="(&(objectClass=krbprincipalaux)(krbPrincipalName=pat@INT.APEXMW.COM))" attrs=ALL conn=178 op=7 RESULT err=0 tag=101 nentries=1 etime=0.0002747849 conn=178 op=8 EXT oid="1.3.6.1.4.1.4203.1.11.3" name="whoami-plugin" conn=178 op=8 RESULT err=0 tag=120 nentries=0 etime=0.0000135034 conn=178 op=9 SRCH base="cn=request certificate ignore caacl,cn=virtual operations,cn=etc,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="objectClass" conn=178 op=9 RESULT err=0 tag=101 nentries=1 etime=0.0000932668 - entryLevelRights: none conn=178 op=10 SRCH base="uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="distinguishedName" conn=178 op=10 RESULT err=0 tag=101 nentries=1 etime=0.0000640289 conn=178 op=11 SRCH base="uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="telephoneNumber ipaSshPubKey uid krbCanonicalName ipatokenRadiusUserName ipaUserAuthType krbPrincipalExpiration homeDirectory nsAccountLock usercertificate;binary title loginShell uidNumber mail ipaCertMapData memberOf memberofindirect krbPrincipalName givenName gidNumber sn ou userClass ipatokenRadiusConfigLink" conn=178 op=11 RESULT err=0 tag=101 nentries=1 etime=0.0001401737 conn=178 op=12 SRCH base="dc=int,dc=apexmw,dc=com" scope=2 filter="(|(member=uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com)(memberUser=uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com)(memberHost=uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com))" attrs="" conn=178 op=12 RESULT err=0 tag=101 nentries=7 etime=0.0001492344 notes=P pr_idx=0 pr_cookie=-1 conn=178 op=13 SRCH base="uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com" scope=0 filter="(userPassword=*)" attrs="userPassword" conn=178 op=13 RESULT err=0 tag=101 nentries=1 etime=0.0000524838 conn=178 op=14 SRCH base="uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com" scope=0 filter="(krbPrincipalKey=*)" attrs="krbPrincipalKey" conn=178 op=14 RESULT err=0 tag=101 nentries=1 etime=0.0000597589 conn=178 op=15 SRCH base="ipaUniqueID=80b23b30-6a0c-11e9-baa3-525400b52c7b,cn=sudorules,cn=sudo,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="cn" conn=178 op=15 RESULT err=0 tag=101 nentries=1 etime=0.0000379744 conn=178 op=16 SRCH base="ipaUniqueID=5fb3a640-705a-11e9-aa05-525400b52c7b,cn=hbac,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="cn" conn=178 op=16 RESULT err=0 tag=101 nentries=1 etime=0.0000337904 conn=178 op=17 SRCH base="cn=caacls,cn=ca,dc=int,dc=apexmw,dc=com" scope=1 filter="(&(objectClass=ipaassociation)(objectClass=ipacaacl))" attrs="serviceCategory cn ipaMemberCertProfile ipaMemberCa ipaCertProfileCategory memberUser userCategory hostCategory memberHost ipaEnabledFlag ipaCaCategory memberService description" conn=178 op=17 RESULT err=0 tag=101 nentries=2 etime=0.0001647058 conn=178 op=18 EXT oid="1.3.6.1.4.1.4203.1.11.3" name="whoami-plugin" conn=178 op=18 RESULT err=0 tag=120 nentries=0 etime=0.0000138321 conn=178 op=19 SRCH base="uid=pat,cn=users,cn=accounts,dc=int,dc=apexmw,dc=com" scope=0 filter="(objectClass=*)" attrs="userCertificate" conn=178 op=19 RESULT err=0 tag=101 nentries=1 etime=0.0001475052 - entryLevelRights: none conn=178 op=20 UNBIND conn=178 op=20 fd=114 closed - U1
To begin with, I note that this session does a BIND with 'dn=""', right at the beginning, it's essentially an anonymous bind, yah?
That operation near the end, here:
op=17 SRCH base="cn=caacls,cn=ca,dc=int,dc=apexmw,dc=com" scope=1 filter="(&(objectClass=ipaassociation)(objectClass=ipacaacl))"
seems like it might be kinda key. and indeed, if I attempt to run this by hand as an anonymous bind, I get no results:
root@apex-freeipa slapd-INT-APEXMW-COM# ldapsearch -x -h localhost -b dc=int,dc=apexmw,dc=com -s sub "(|(objectClass=ipaassociation)(objectClass=ipacaacl))" # extended LDIF # # LDAPv3 # base <dc=int,dc=apexmw,dc=com> with scope subtree # filter: (|(objectClass=ipaassociation)(objectClass=ipacaacl)) # requesting: ALL #
# search result search: 2 result: 0 Success
# numResponses: 1
It's only if I run this as an _authenticated_ bind, that I can find my ACL:
root@apex-freeipa slapd-INT-APEXMW-COM# ldapsearch -x -D "cn=Directory Manager" -W -h localhost -b dc=int,dc=apexmw,dc=com -s sub "(&(objectClass=ipaassociation)(objectClass=ipacaacl))" cn Enter LDAP Password: # extended LDIF # # LDAPv3 # base <dc=int,dc=apexmw,dc=com> with scope subtree # filter: (&(objectClass=ipaassociation)(objectClass=ipacaacl)) # requesting: cn #
# c98b740c-6903-11e9-ad1b-525400b52c7b, caacls, ca, int.apexmw.com dn: ipaUniqueID=c98b740c-6903-11e9-ad1b-525400b52c7b,cn=caacls,cn=ca,dc=int,dc =apexmw,dc=com cn: hosts_services_caIPAserviceCert
# 6dde33a6-7849-11e9-aa05-525400b52c7b, caacls, ca, int.apexmw.com dn: ipaUniqueID=6dde33a6-7849-11e9-aa05-525400b52c7b,cn=caacls,cn=ca,dc=int,dc =apexmw,dc=com cn: OpenVPN_User_Certificate_ACL
# search result search: 2 result: 0 Success
# numResponses: 3 # numEntries: 2
Is this (using certmonger to auto-issue signed certs/keys for my openvpn users) going to be essentially impossible to do, here? Do I need to go a more traditional route of creating a seperate keystore/certdb, issuing a CSR, and feeding that to FreeIPA to sign?
Any advice appreciated, and thanks in advance, -- Pat