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=p...@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-le...@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.fedorahosted.org

--
/ Alexander Bokovoy
Sr. Principal Software Engineer
Security / Identity Management Engineering
Red Hat Limited, Finland
_______________________________________________
FreeIPA-users mailing list -- freeipa-users@lists.fedorahosted.org
To unsubscribe send an email to freeipa-users-le...@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.fedorahosted.org

Reply via email to