Hide Forgot
Description of problem: In an IPA environment with a trust setup to AD domain, I am seeing some AVC denials when the AD user tries to ssh to IPA server with kerberos ticket. [root@rhel7-1 ~]# kdestroy -A [root@rhel7-1 ~]# kinit aduser1.TEST Password for aduser1.TEST: [root@rhel7-1 ~]# klist Ticket cache: KEYRING:persistent:0:0 Default principal: aduser1.TEST Valid starting Expires Service principal 12/20/2013 10:02:20 12/20/2013 20:02:20 krbtgt/AD2.EXAMPLE.TEST.TEST renew until 12/21/2013 10:02:18 [root@rhel7-1 ~]# ssh -K -l aduser1.test $(hostname) Last login: Fri Dec 20 10:03:37 2013 from rhel7-1.ipa1.example.test -sh-4.2$ exit logout Connection to rhel7-1.ipa1.example.test closed. [root@rhel7-1 ~]# date Fri Dec 20 10:05:44 CST 2013 [root@rhel7-1 ~]# ausearch -m avc -ts 10:05 ---- time->Fri Dec 20 10:05:41 2013 type=SYSCALL msg=audit(1387555541.289:1315): arch=c000003e syscall=250 success=yes exit=0 a0=7 a1=28acd7b0 a2=1 a3=0 items=0 ppid=5736 pid=22954 auid=4294967295 uid=0 gid=0 euid=551801125 suid=0 fsuid=551801125 egid=551801125 sgid=0 fsgid=551801125 tty=(none) ses=4294967295 comm="sshd" exe="/usr/sbin/sshd" subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 key=(null) type=AVC msg=audit(1387555541.289:1315): avc: denied { write } for pid=22954 comm="sshd" scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:system_r:sssd_t:s0 tclass=key ---- time->Fri Dec 20 10:05:41 2013 type=SYSCALL msg=audit(1387555541.289:1316): arch=c000003e syscall=250 success=yes exit=8 a0=b a1=28acd7b0 a2=0 a3=0 items=0 ppid=5736 pid=22954 auid=4294967295 uid=0 gid=0 euid=551801125 suid=0 fsuid=551801125 egid=551801125 sgid=0 fsgid=551801125 tty=(none) ses=4294967295 comm="sshd" exe="/usr/sbin/sshd" subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 key=(null) type=AVC msg=audit(1387555541.289:1316): avc: denied { read } for pid=22954 comm="sshd" scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:system_r:sssd_t:s0 tclass=key ---- time->Fri Dec 20 10:05:41 2013 type=SYSCALL msg=audit(1387555541.289:1317): arch=c000003e syscall=250 success=yes exit=0 a0=f a1=28acd7b0 a2=8bd7 a3=0 items=0 ppid=5736 pid=22954 auid=4294967295 uid=0 gid=0 euid=551801125 suid=0 fsuid=551801125 egid=551801125 sgid=0 fsgid=551801125 tty=(none) ses=4294967295 comm="sshd" exe="/usr/sbin/sshd" subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 key=(null) type=AVC msg=audit(1387555541.289:1317): avc: denied { setattr } for pid=22954 comm="sshd" scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:system_r:sssd_t:s0 tclass=key Version-Release number of selected component (if applicable): selinux-policy-3.12.1-110.el7.noarch sssd-1.11.2-15.el7.x86_64 openssh-6.4p1-3.el7.x86_64 How reproducible: Not sure yet but, I'm seeing it often in my automated tests. And the above was from a manual test. Steps to Reproduce: 1. Setup IPA Server 2. Setup Trust to AD domain 3. setenforce 0 # was doing this to avoid another bug 4. kdestroy -A # make sure all clear 5. kinit aduser 6. ssh -K -l aduser $(hostname) Actual results: ssh works (possibly due to permissive mode) but, see AVC denials. Expected results: no AVC denials Additional info:
These AVC's indicate a kernel keyring was created by sssd and is being written to by sshd. I know there was work being done with Kerberos around this. Do I need to allow all login programs to use sssd_t keyrings?
Does this keyring end up getting handed to a logged in user? IE Should we have the keyring owned by unconfined_t/staff_t rather then sssd_t?
(In reply to Daniel Walsh from comment #3) > Does this keyring end up getting handed to a logged in user? IE Should we > have the keyring owned by unconfined_t/staff_t rather then sssd_t? Yes, this Kernel keyring hold the credential cache of the user. If the user logs in with a password sssd will create the credential cache for the user. If the user use GSSAPI with credential forwarding sshd will put the Kerberos TGT of the user into the credential cache. If the session is running the user might want to call kinit which would write the new TGT into the credential cache as well.
Right but if the user does a kdestroy/kinit the user cache would be unconfined_t:key. If they login with sssd getting the keyring it is owned by sssd_t. We have seen another case where the user logged in as staff_t, then ran ssh which created an empty keyring ssh_t:key, when ssh tried to do kerberos. The user then did a kinit, and got a rule saying staff_t wants to write to ssh_t:key. The problem I have is the user keyring should always be labeled based on the user, and we need to figure a way to get this right, otherwise we might as well eliminate the checking of the keyring from an SELinux point of view, because It will end up allowing all users of kerberos to use all keyrings.
Stephen, Simo, what do you think should be the right solution with respect to SELinux?
Including David Howells in the discussion. I'm not sure what exactly we want to do with regards to SELinux. When SELinux isn't in the picture, the standard behavior is that the kerberos keyring is accessible only to the user ID associated with it or root. Beyond that, any processor owned by the user or root can update it. We definitely need for all login programs and kerberos-workstation tools to be able to have access to it. I *thought* that the keyring was created as kernel_t when created with the keyctl() system calls, but I could be mistaken. David might have more insight here.
From an SELinux point of view the kernel keyring is assigned to the label of the process that creates it. sshd_t, sssd_t, ssh_t, staff_t, unconfined_t. My belief is that if a daemon is creating a keyring on behalf of a user we need to have the keyring created with the user type. setkeycreatecon (3) - get or set the SELinux security context used for creating a new kernel key... We have a function in SELinux that can do this. Does sssd create a keyring for the user and somehow pass it to him? The AVC's above lead to the following allow rule. allow sshd_t sssd_t:key { write read setattr }; Which indicates that sshd daemon needs access to the sshd_t keyring? Is this keyring related to a user session or something different?
This also affects at least credentials acquired when logging in on a VT (local_login_t) or with gdm (xdm_t). Wouldn't it be best to have a different credentials cache for each session?
If the credential cache is for a logged in user to use, IE You assign it a UID, then it should have a user context, unconfined_t, staff_t, guest_t. If the CC is to be used for a service then it should have the services label httpd_t, nfsd_t. Bottom line if the user executes kinit in his login session the key ring he is using should have the same type as the process running kinit. Otherwise we will not be able to write sane policy. I want to have stuff that says allow login_pgm userdomain:key manage_key_perms; But I am ending up with allow userdomain login_pgm:key manage_key_perms; And worse.
dwalsh: two possibilities that might make things a little better.... 1) type transitions on key creation, so you can get something other than the label of the creating process... 2) setkeycreatecon() interface so programs doing work on behalf of another process can explicitly set the label on the newly created key... Do either/both of these help? (neither exists today that I know of) dhowells, i know we've talked about this a little...
(In reply to Eric Paris from comment #12) > dwalsh: two possibilities that might make things a little better.... > > 1) type transitions on key creation, so you can get something other than the > label of the creating process... So it would require only policy changes to have login_pgm domains creating userdomain_key_t for example and allow userdomain userdomain_key_t:key manage_key_perms; > > 2) setkeycreatecon() interface so programs doing work on behalf of another > process can explicitly set the label on the newly created key... I believe it is a preferred solution. Also how Dan described above. > > Do either/both of these help? (neither exists today that I know of) > > dhowells, i know we've talked about this a little...
(In reply to Miroslav Grepl from comment #13) > (In reply to Eric Paris from comment #12) > > 2) setkeycreatecon() interface so programs doing work on behalf of another > > process can explicitly set the label on the newly created key... > > I believe it is a preferred solution. Also how Dan described above. We already have "/proc/self/attr/keycreate", don't we have an associated libselinux API?
My understanding is we want to call setkeycreatecon() with a context which we get from a username for which a daemon is creating a keyring.
(In reply to Miroslav Grepl from comment #15) > My understanding is we want to call setkeycreatecon() with a context which > we get from a username for which a daemon is creating a keyring. Or how Dan described here https://bugzilla.redhat.com/show_bug.cgi?id=1001703#c6
Thanks for the clarification, I thought the second possibility above was for the creation of a setkeycreatecon() interface which left me a bit confused.
The problem is that these operations are done during the login phase, there is no 'user process' yet, and we do not know what pam_selinux will decide to give to a user as context, could be unconfined_t, staff_t, guest_t ... etc.
dwalsh: How does sshd handle this? They manage to get the label things will run as. Simo: is there a way we can rearchitect things to not put a key into the kernel until we know the label of the process? if we can't find such a way, pretty much every gov't certified installation is going to have to ban all kernel keyring usage...
(In reply to Eric Paris from comment #19) > dwalsh: How does sshd handle this? They manage to get the label things will > run as. It uses ssh_selinux_getctxbyname() getseuserbyname() get_default_context_with_level() > Simo: is there a way we can rearchitect things to not put a key into the > kernel until we know the label of the process? > > if we can't find such a way, pretty much every gov't certified installation > is going to have to ban all kernel keyring usage...
(In reply to Eric Paris from comment #19) > dwalsh: How does sshd handle this? They manage to get the label things will > run as. > > Simo: is there a way we can rearchitect things to not put a key into the > kernel until we know the label of the process? Probably not, but we might be able to relabel the keyring after the fact ? I was asking Dan if pam_selinux could actually do it once it determines the user's label. > if we can't find such a way, pretty much every gov't certified installation > is going to have to ban all kernel keyring usage... Uh, why would that be ?
(In reply to Simo Sorce from comment #21) > (In reply to Eric Paris from comment #19) > > dwalsh: How does sshd handle this? They manage to get the label things will > > run as. > > > > Simo: is there a way we can rearchitect things to not put a key into the > > kernel until we know the label of the process? > > Probably not, but we might be able to relabel the keyring after the fact ? > I was asking Dan if pam_selinux could actually do it once it determines the > user's label. Relabeling data is almost always a bad idea. I'll certainly roll around in the back of my head and see what I think of it. The basic idea is the problem I describe below. Who can access the key/data before it is relabeled? One of primary concepts of the SELinux mandatory access control system is something called 'label tranquility', aka labels on object should never change. We do a lot of work to make sure data is labeled correctly at the beginning to take care of these races. The question comes down to, who can relabel the key? Can I race in and relabel a key that should belong to some other SELinux user? > > > if we can't find such a way, pretty much every gov't certified installation > > is going to have to ban all kernel keyring usage... > > Uh, why would that be ? because any time multiple labels of users are able to read/write to the same labeled object you have completely broken the security model. If a classified user is able to write to a key and the same user logged in unclassified was able to read that data out the system is a failure. No different that having a mechanism by which a classified user could put data in a file and have the unclassified user read it out. Policy must be able to prove that such things are impossible. So if we can't make sure data is never labeled in a way that information can leak between two selinux labels (of the same user) they are going to have to use policy to block all access to those resources. And I think that's a big deal, we know we have lots of machines that need these kinds of promises :-(
Ok I see 2 options here. A) with relabeling: we label with a label no user is allowed to access until a login process relabels it, it stinks a bit and has pessimal failure modes in usability if the login program 'forgets' to relabel ... B) we find a way to figure out what the label *will* be in the auth phase so sssd, pam_krb5 and other actors can find out the label before doing the AS request. Keep in mind however that 'changing labels' may be needed anyway in some edge cases. For example if a user label is changed and the user logs back in, but the old keyring (with the old label) is still available. Of course we can simply try to detect that and blow away the keyring and then re-create it. Here's the problem with (B) pam_selinux.so at the moment is executed only in the session phase, not the auth phase, plus selinux users are dumped into the right file (to be read by pam_selinux) by sssd (when a central authority like a freeipa server serves these policies) only after authentication. So we have quite a bit of chickens and eggs around here. Ideas ?
So I have been buried with docker issues. But after the call to pam_selinux, the login programs can call getfscreatecon() which will return the label that the user will run with. If sssd/login programs can not wait to create the keyring until after that call then we will have to do some kind of transition hack.
We have workaround in 7.1 coming from Fedora.
Based on AVCs in comment#0, the latest policy contains the fix: # rpm -qa selinux-policy\* selinux-policy-sandbox-3.13.1-53.el7.noarch selinux-policy-mls-3.13.1-53.el7.noarch selinux-policy-minimum-3.13.1-53.el7.noarch selinux-policy-3.13.1-53.el7.noarch selinux-policy-doc-3.13.1-53.el7.noarch selinux-policy-targeted-3.13.1-53.el7.noarch selinux-policy-devel-3.13.1-53.el7.noarch # sesearch -s sshd_t -t sssd_t -c key -p setattr -A -C Found 2 semantic av rules: allow nsswitch_domain sssd_t : key { view read write search link setattr create } ; allow login_pgm nsswitch_domain : key { view read write search link setattr create } ; # It seems that the rules are present for a long time. Why are we shifting the bug to RHEL-7.3?