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
On Mon, 03 Jun 2019, Patrick Spinler via FreeIPA-users wrote:
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?
No, it is not. BIND operation may be multi-round and actual result is not known until all rounds passed through. In your cases, SASL GSS-SPNEGO is in use, so on the first round you get the bound identity:
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"
E.g. all connection was done using host keytab of that machine (apex-openvpn.int....). This is how certmonger works -- it uses a host keytab of the machine it runs on.
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?
You'd need to create an ACL that would allow a host identity that certmonger uses to have write rights to the userCertificate attribute of the target user. You are already successfully passed CA ACL check because the framework tried to see if you have rights to actually write the resulting certificate (public cert) to the userCertficiate attribute of the target entry, so it was not a question whether you can issue (yes, you can) but whether you can store the cert (you cannot).
A way to create that would be by utilizing permissions/roles system of FreeIPA.
Something like this:
ipa permission-add write-user-certificate-permission \ --right=write --attrs=userCertificate --type=user
ipa privilege-add write-user-certificate-privilege ipa privilege-add-permission write-user-certificate-privilege \ --permissions=write-user-certificate-permission
ipa role-add user-certificate-issuer ipa role-add-privilege user-certificate-issuer \ --privileges=write-user-certificate-privilege ipa role-add-member user-certificate-issuer \ --hosts=apex-openvpn
Any advice appreciated, and thanks in advance, -- Pat
FreeIPA-users mailing list -- freeipa-users@lists.fedorahosted.org To unsubscribe send an email to freeipa-users-leave@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahoste...
Thank you kindly Alexander! I confirm this set of privs and permissions did allow me to issue a user key and cert via certmonger.
It also helped me understand a little better the structure of IPA permissions from the point of view of someone who's done a little bit of LDAP backend work. Examples are useful. :)
-- Pat
On ma, 03 kesä 2019, Patrick Spinler via FreeIPA-users wrote:
Thank you kindly Alexander! I confirm this set of privs and permissions did allow me to issue a user key and cert via certmonger.
It also helped me understand a little better the structure of IPA permissions from the point of view of someone who's done a little bit of LDAP backend work. Examples are useful. :)
You can also follow my blog from 2016 about the same topic: https://vda.li/en/posts/2016/08/30/Creating-permissions-in-FreeIPA/
On 03/06/2019 05:19, Alexander Bokovoy via FreeIPA-users wrote:
On Mon, 03 Jun 2019, Patrick Spinler via FreeIPA-users wrote:
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?
No, it is not. BIND operation may be multi-round and actual result is not known until all rounds passed through. In your cases, SASL GSS-SPNEGO is in use, so on the first round you get the bound identity:
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"
E.g. all connection was done using host keytab of that machine (apex-openvpn.int....). This is how certmonger works -- it uses a host keytab of the machine it runs on.
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?
You'd need to create an ACL that would allow a host identity that certmonger uses to have write rights to the userCertificate attribute of the target user. You are already successfully passed CA ACL check because the framework tried to see if you have rights to actually write the resulting certificate (public cert) to the userCertficiate attribute of the target entry, so it was not a question whether you can issue (yes, you can) but whether you can store the cert (you cannot).
A way to create that would be by utilizing permissions/roles system of FreeIPA.
Something like this:
ipa permission-add write-user-certificate-permission \ --right=write --attrs=userCertificate --type=user
ipa privilege-add write-user-certificate-privilege ipa privilege-add-permission write-user-certificate-privilege \ --permissions=write-user-certificate-permission
ipa role-add user-certificate-issuer ipa role-add-privilege user-certificate-issuer \ --privileges=write-user-certificate-privilege ipa role-add-member user-certificate-issuer \ --hosts=apex-openvpn
I'm curious - what do you guys do/advise would be best "logistics" for user certs - would you have separate user certs per-service or for perhaps, for sake of easing the burden of it all, just single cert for a user no matter the services?
many thanks, L.
Any advice appreciated, and thanks in advance, -- Pat
FreeIPA-users mailing list -- freeipa-users@lists.fedorahosted.org To unsubscribe send an email to freeipa-users-leave@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahoste...
lejeczek via FreeIPA-users wrote:
On 03/06/2019 05:19, Alexander Bokovoy via FreeIPA-users wrote:
On Mon, 03 Jun 2019, Patrick Spinler via FreeIPA-users wrote:
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?
No, it is not. BIND operation may be multi-round and actual result is not known until all rounds passed through. In your cases, SASL GSS-SPNEGO is in use, so on the first round you get the bound identity:
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"
E.g. all connection was done using host keytab of that machine (apex-openvpn.int....). This is how certmonger works -- it uses a host keytab of the machine it runs on.
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?
You'd need to create an ACL that would allow a host identity that certmonger uses to have write rights to the userCertificate attribute of the target user. You are already successfully passed CA ACL check because the framework tried to see if you have rights to actually write the resulting certificate (public cert) to the userCertficiate attribute of the target entry, so it was not a question whether you can issue (yes, you can) but whether you can store the cert (you cannot).
A way to create that would be by utilizing permissions/roles system of FreeIPA.
Something like this:
ipa permission-add write-user-certificate-permission \ --right=write --attrs=userCertificate --type=user
ipa privilege-add write-user-certificate-privilege ipa privilege-add-permission write-user-certificate-privilege \ --permissions=write-user-certificate-permission
ipa role-add user-certificate-issuer ipa role-add-privilege user-certificate-issuer \ --privileges=write-user-certificate-privilege ipa role-add-member user-certificate-issuer \ --hosts=apex-openvpn
I'm curious - what do you guys do/advise would be best "logistics" for user certs - would you have separate user certs per-service or for perhaps, for sake of easing the burden of it all, just single cert for a user no matter the services?
Are we still talking VPN? I mean for that having a single purpose cert could be useful since a VPN is generally launched separately from a typical user use case. But otherwise I think it would be a drag for user's to have to pick from a list in the browser as they switch services. It could be a high overhead method of access control. High because the more certs, the more chances of renewal problems, revocation, CRL management, etc.
rob
many thanks, L.
Any advice appreciated, and thanks in advance, -- Pat
FreeIPA-users mailing list -- freeipa-users@lists.fedorahosted.org To unsubscribe send an email to freeipa-users-leave@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahoste...
FreeIPA-users mailing list -- freeipa-users@lists.fedorahosted.org To unsubscribe send an email to freeipa-users-leave@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahoste...
Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure
On 27/06/2022 15:16, Rob Crittenden wrote:
lejeczek via FreeIPA-users wrote:
On 03/06/2019 05:19, Alexander Bokovoy via FreeIPA-users wrote:
On Mon, 03 Jun 2019, Patrick Spinler via FreeIPA-users wrote:
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?
No, it is not. BIND operation may be multi-round and actual result is not known until all rounds passed through. In your cases, SASL GSS-SPNEGO is in use, so on the first round you get the bound identity:
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"
E.g. all connection was done using host keytab of that machine (apex-openvpn.int....). This is how certmonger works -- it uses a host keytab of the machine it runs on.
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?
You'd need to create an ACL that would allow a host identity that certmonger uses to have write rights to the userCertificate attribute of the target user. You are already successfully passed CA ACL check because the framework tried to see if you have rights to actually write the resulting certificate (public cert) to the userCertficiate attribute of the target entry, so it was not a question whether you can issue (yes, you can) but whether you can store the cert (you cannot).
A way to create that would be by utilizing permissions/roles system of FreeIPA.
Something like this:
ipa permission-add write-user-certificate-permission \ --right=write --attrs=userCertificate --type=user
ipa privilege-add write-user-certificate-privilege ipa privilege-add-permission write-user-certificate-privilege \ --permissions=write-user-certificate-permission
ipa role-add user-certificate-issuer ipa role-add-privilege user-certificate-issuer \ --privileges=write-user-certificate-privilege ipa role-add-member user-certificate-issuer \ --hosts=apex-openvpn
I'm curious - what do you guys do/advise would be best "logistics" for user certs - would you have separate user certs per-service or for perhaps, for sake of easing the burden of it all, just single cert for a user no matter the services?
Are we still talking VPN? I mean for that having a single purpose cert could be useful since a VPN is generally launched separately from a typical user use case. But otherwise I think it would be a drag for user's to have to pick from a list in the browser as they switch services. It could be a high overhead method of access control. High because the more certs, the more chances of renewal problems, revocation, CRL management, etc.
rob
That is was thinking - even if I did not mean each "http service/site" separately - that for some/any-thing that can use 'pam', so each DB, say mariadb, pgsql, etc, even if one-user-cert for all 'http', it would be not worth the "benefits" to manage user-cert for each such 'service'.
thanks, L.
freeipa-users@lists.fedorahosted.org