Bug 869340 - SELinux Enforcing Prevents OpenSSH Chroot Shell Logins
SELinux Enforcing Prevents OpenSSH Chroot Shell Logins
Status: CLOSED ERRATA
Product: Fedora
Classification: Fedora
Component: selinux-policy (Show other bugs)
18
i386 Linux
unspecified Severity low
: ---
: ---
Assigned To: Miroslav Grepl
Fedora Extras Quality Assurance
: Reopened
Depends On: 830237
Blocks: 831271 833352
  Show dependency treegraph
 
Reported: 2012-10-23 11:48 EDT by Petr Lautrbach
Modified: 2013-01-21 11:03 EST (History)
9 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 830237
Environment:
Last Closed: 2012-12-20 10:51:36 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Petr Lautrbach 2012-10-23 11:48:45 EDT
+++ This bug was initially created as a clone of Bug #830237 +++

Description of problem:

Using OpenSSH chroot shell functionality the sshd process attempts a process transition from "chroot_user_t" to "unconfined_t" when launching the user shell (in this case "/bin/bash -r") and is denied, which disconnects the SSH session shortly after authentication.

This OpenSSH session disconnection behaviour also appears to occur in FC16.

Under FC15 i386 PAE the OpenSSH chroot ran as "sshd_t" and SELinux did not deny the process transition to "unconfined_t" when launching a chroot shell.


FC17 i386 PAE ps dump (captured with SELinux in Permissive mode):

system_u:system_r:sshd_t:s0-s0:c0.c1023 1143 2277 2277 2277 ?       -1 Ss       0   0:00  \_ sshd: testuser [priv]
system_u:system_r:chroot_user_t:s0-s0:c0.c1023 2277 2280 2277 2277 ? -1 S    1001   0:00      \_ sshd: testuser@pts/3
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2280 2281 2281 2281 pts/3 2281 Ss+ 1001   0:00          \_ /bin/bash -r



--- Additional comment from dwalsh@redhat.com on 2012-06-08 17:36:14 CEST ---

We do not want ssh_chroot_t to transition to unconfined_t at all. 

ssh guys could this be related to the privsep patch?

--- Additional comment from plautrba@redhat.com on 2012-06-11 16:39:37 CEST ---

The transition is probably done by pam_selinux module which sets context for next executed shell. Maybe ssh_selinux_change_context() should clean SELinux exec context after SELinux context change.


--- Additional comment from plautrba@redhat.com on 2012-06-14 15:03:30 CEST ---

I realized that simply adding setexeccon() won't help. All chroot users are run 
with chroot_user_t, but this context is supposed to be used only for
internal-sftp. chroot_user_t process can't exec bash, use char files 
and so.

I believe that since we have privsep patch we don't need chroot_user_t
anymore - all unprivileged sshd child processes included internal-sftp 
are run with user's context so there's no need to change their context
to chroot_user_t if they are chrooted.

--- Additional comment from mgrepl@redhat.com on 2012-06-14 16:28:48 CEST ---

(In reply to comment #4)
> I realized that simply adding setexeccon() won't help. All chroot users are
> run 
> with chroot_user_t, but this context is supposed to be used only for
> internal-sftp. chroot_user_t process can't exec bash, use char files 
> and so.
> 
> I believe that since we have privsep patch we don't need chroot_user_t
> anymore - all unprivileged sshd child processes included internal-sftp 
> are run with user's context so there's no need to change their context
> to chroot_user_t if they are chrooted.

Sounds as good idea. If I remember correctly, we wanted to get out at least this users stuff (interlnal-sftp) from sshd_t label. It was first step.

But now we have working privsep patch which makes me to agree with you.

--- Additional comment from dwalsh@redhat.com on 2012-06-19 15:58:29 CEST ---

But if the user runs with unconfined_t, we loose any lock down.  If you are saying we will recommend that the chroot_t user run with guest_t then I am fine with it.

--- Additional comment from adam.macmurray@princessauto.com on 2012-07-04 17:15:01 CEST ---

Is there a workaround we can use prior to a fix being released? In our particular case it would be better for us to have user processes for restricted users running as "unconfined" in a chroot SSH environment than to turn SELinux off altogether just to get chroot SSH to work.

Is there a policy file we can apply or some other temporary measure we can take to get this working for now?

--- Additional comment from dwalsh@redhat.com on 2012-07-11 20:40:23 CEST ---

Adam If you want you can add a policy module to make the chroot_user_t an unconfined_domain.

Create a file mychrootuser.te with the following content.
policy_module(mychrootuser,1.0
gen_require(`
type chroot_user_t;
')
unconfined_domain(chroot_user_t)

Then make the policy file

# make -f /usr/share/selinux/devel/include/Makefile
# semodule -i mychrootuser.pp

--- Additional comment from adam.macmurray@princessauto.com on 2012-07-11 21:59:35 CEST ---

Thanks for the policy module Daniel.

I tried to compile it under fc17 i386 PAE and modified it as follows [I believe the ")" was missing on the first line]:

---
policy_module(ssh_chroot_workaround,1.0)

gen_require(`
    type chroot_user_t;
')

unconfined_domain(chroot_user_t)
---



--- Additional comment from mgrepl@redhat.com on 2012-07-13 11:18:08 CEST ---

Dan,
this is a problem. Maybe we could say them to run chroot_user_t as permissive, collect AVC msgs and allow them.

--- Additional comment from dwalsh@redhat.com on 2012-07-23 19:33:12 CEST ---

That is fine with me.

--- Additional comment from plautrba@redhat.com on 2012-08-27 15:52:05 CEST ---

I've finally prepared a test build for Fedora 18 [1] based on 
the openssh-6.0p1 version and without the chroot_user_t. 

I'd rather don't add this change to currrent versions given that there are 
probably some existing configurations depending on chroot_user_t and this 
update would break behavior.

Also I'd propose to note this change in release notes with notice that
chroot users shall be set to guest_u as Dan suggested.


[1] http://plautrba.fedorapeople.org/openssh/openssh-6.0p1-no-chroot_user_t/

--- Additional comment from mgrepl@redhat.com on 2012-08-27 15:52:54 CEST ---

Great. I am willing to test it.

--- Additional comment from mgrepl@redhat.com on 2012-09-06 14:26:51 CEST ---

It works and a user has a userdomain instead of chroot_user_t.


--- Additional comment from adam.macmurray@princessauto.com on 2012-09-19 02:16:10 CEST ---

I'm still seeing the user get disconnected when they ssh in with a chroot home directory set.

...

--- Additional comment from plautrba@redhat.com on 2012-10-22 15:41:23 CEST ---

I've hit another issue with the whole concept. The F18 SELinux policy disallows setuid() call to confined users. A sshd process needs to do 3 steps: change its SELinux context, chroot() itself to a new directory, and change uid. SELinux context has to be changed before chroot() since we can't assume that there's the SELinux infrastructure in the chrooted dir. chroot() has to be called by uid 0 so setuid() must be called after chroot(). But since process is already running with the user's context, it's denied by the policy.


Dan, would be possible to re-allow confined users to call setuid() as it is in Fedora 17?

--- Additional comment from plautrba@redhat.com on 2012-10-23 17:43:47 CEST ---

I've prepared a test build with dropped the sftp-chroot patch. You can find it
here [1]. There's completely dropped usage of sftp_t and chroot_user_t, and
system configured SELinux users are used instead. It's strongly recommended to
use guest_u for chrooted users. Also it might be a good idea to add a new
SELinux user just for sftp sessions.

It needs the change in the selinux-policy. Confined users needs to be allowed to
call setuid() as described in comment 25. Before I push it to F18 update, I'd like to know if it's possible to do this change in selinux-policy. 

In the mean time, you need to create and load your custom SELinux module:

# cat user-setuid.te
module user-setuid 1.0;
require {
        attribute userdomain;
        class capability setuid;
}
#============= staff_t ==============
allow userdomain self:capability setuid;


[1] http://plautrba.fedorapeople.org/openssh/830237/
Comment 1 Miroslav Grepl 2012-10-24 02:37:24 EDT
The problem is we have on F17

allow $1_t self:capability { setgid setuid chown fowner };

in the userdom_login_user_template() interface.

We have on F18

dontaudit $1_t self:capability { sys_nice fsetid };


I like your idea with a new user. Something like we have the web user and so on.
Comment 2 Miroslav Grepl 2012-10-24 03:38:43 EDT
I believe we have two options here:

1. Add a boolean
  * but I believe this is correct to have confined users without setuid and also a new boolean is probably powerful

2. Add a new user as you suggest
  * are you thinking about a name? We have chroot_user_t but as you said it does not look as the correct name.
Comment 3 Petr Lautrbach 2012-10-24 10:27:26 EDT
First, I wasn't probably right about that opnlu setuid() is needed, sys_chroot() is needed too.

> 1. Add a boolean
>   * but I believe this is correct to have confined users without setuid and
> also a new boolean is probably powerful

I don't think that this is a good idea.

> 
> 2. Add a new user as you suggest
>   * are you thinking about a name? We have chroot_user_t but as you said it
> does not look as the correct name.

chroot_user_t; which is allowed to exec shell, use devpts, chr files, and transition to user's context; might work, but we'll loose benefits of the privsep patch - an unprivileged sshd process
will run with chroot_user_t and shell will run with user's context like:

system_u:system_r:sshd_t:s0-s0:c0.c1023        \_ sshd: guest [priv]
system_u:system_r:chroot_user_t:s0-s0:c0.c1023  \_ sshd: guest@pts/1
guest_u:guest_r:guest_t:s0                       \_ -bash


The main problem here is that it's not possible to change a process's context via setcon() without re-exec() so a sshd process needs to change it's context before chroot() and therefore before setuid().
Comment 4 Miroslav Grepl 2012-10-24 11:01:24 EDT
Petr, 
I think we will need to go back with chroot_user_t.
Comment 5 Daniel Walsh 2012-10-24 12:18:02 EDT
Looks like it.  Do we need to add something to libselinux to allow sshd to figure out what type to use?
Comment 6 Miroslav Grepl 2012-10-26 11:23:29 EDT
Fixed in selinux-policy-3.11.1-45.fc18

commit 30c65924b9ae9c2d91a229564ff1e8ae406aabe6
Author: Miroslav Grepl <mgrepl@redhat.com>
Date:   Fri Oct 26 10:44:47 2012 +0200

    Add new selinuxuser_use_ssh_chroot boolean
Comment 7 Fedora Update System 2012-10-26 11:39:33 EDT
selinux-policy-3.11.1-46.fc18 has been submitted as an update for Fedora 18.
https://admin.fedoraproject.org/updates/selinux-policy-3.11.1-46.fc18
Comment 8 Fedora Update System 2012-10-26 15:29:03 EDT
Package selinux-policy-3.11.1-46.fc18:
* should fix your issue,
* was pushed to the Fedora 18 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing selinux-policy-3.11.1-46.fc18'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2012-16862/selinux-policy-3.11.1-46.fc18
then log in and leave karma (feedback).
Comment 9 adam.macmurray 2012-10-26 20:14:17 EDT
With the new FC19 openssh packages posted by Petr and the new FC18 selinux-policy packages posted by Miroslav I am now able to use an openssh  chroot shell with targeted SELinux in Enforcing mode. The connection was successful with the new boolean when on and when off.

After a very basic logon and then logoff of a chroot ssh shell there were a number of AVC messages related to dhcpc_t, ldconfig_t, local_login_t, policykit_t, sshd_t, systemd_logind_t, and systemd_tmpfiles_t, but the audit2allow of the AVC messages specifically related to the chroot user (chroot_user_t & guest_t) follow  --

With selinuxuser_use_ssh_chroot set to 'off':

#============= chroot_user_t ==============
allow chroot_user_t default_t:chr_file { read write };
allow chroot_user_t default_t:file execute;
allow chroot_user_t devlog_t:sock_file write;
allow chroot_user_t guest_t:process transition;
allow chroot_user_t unconfined_t:process transition;


#============= guest_t ==============
allow guest_t chroot_user_t:process sigchld;
#!!!! This avc can be allowed using the boolean 'selinuxuser_use_ssh_chroot'

allow guest_t self:capability setuid;
allow guest_t user_home_dir_t:file { read open };




With selinuxuser_use_ssh_chroot set to 'on':

#============= chroot_user_t ==============
allow chroot_user_t default_t:chr_file { read write };
allow chroot_user_t default_t:file execute;
allow chroot_user_t devlog_t:sock_file write;
allow chroot_user_t guest_t:process transition;
allow chroot_user_t unconfined_t:process transition;

#============= guest_t ==============
allow guest_t chroot_user_t:process sigchld;
#!!!! This avc is allowed in the current policy

allow guest_t self:capability setuid;
allow guest_t user_home_dir_t:file { read open };



State of other ssh SELinux booleans in latest test:

fenced_can_ssh --> off
sftpd_write_ssh_home --> off
ssh_chroot_rw_homedirs --> off
ssh_keysign --> off
ssh_sysadm_login --> off

Kernel: Linux fc18alpha.<x>.<y> 3.6.3-3.fc18.i686.PAE

Packages:
openssh-6.1p1-1.1.fc19.i686
openssh-clients-6.1p1-1.1.fc19.i686
openssh-server-6.1p1-1.1.fc19.i686
libselinux-python-2.1.12-4.fc18.i686
selinux-policy-3.11.1-46.fc18.noarch
selinux-policy-doc-3.11.1-46.fc18.noarch
libselinux-2.1.12-4.fc18.i686
libselinux-utils-2.1.12-4.fc18.i686
selinux-policy-devel-3.11.1-46.fc18.noarch
selinux-policy-targeted-3.11.1-46.fc18.noarch

Thank you for your efforts! Feedback left.
Comment 10 Petr Lautrbach 2012-10-29 07:18:12 EDT
It works for me and I'm not able to reproduce behavior from comment 9. Please use openssh-6.1p1-2.fc18 [1] or openssh-6.1p1-2.fc19 from Rawhide. 

# rpm -q openssh selinux-policy
openssh-6.1p1-2.fc18.x86_64
selinux-policy-3.11.1-46.fc18.noarch

# getenforce
Enforcing

--
# getsebool selinuxuser_use_ssh_chroot
selinuxuser_use_ssh_chroot --> off        

$ ssh guest@f18-devel
guest@f18-devel's password:
Write failed: Broken pipe

$ sftp guest@f18-devel
Connecting to f18-devel...
guest@f18-devel's password:
Write failed: Broken pipe
Couldn't read packet: Connection reset by peer

--
# setsebool selinuxuser_use_ssh_chroot on

$ ssh guest@f18-devel
guest@f18-devel's password:
Last login: Mon Oct 29 11:06:53 2012 from master.virt
-bash-4.2$ exit

$ sftp guest@f18-devel
Connecting to f18-devel...
guest@f18-devel's password:
sftp>

system_u:system_r:sshd_t:s0-s0:c0.c1023 1801 /usr/sbin/sshd -D
system_u:system_r:sshd_t:s0-s0:c0.c1023 1806 \_ sshd: guest [priv]
guest_u:guest_r:guest_t:s0       1810         \_ sshd: guest@notty
guest_u:guest_r:guest_t:s0       1811          \_ sshd: guest@internal-sftp

# ls -l /proc/1810/root
lrwxrwxrwx. 1 root root 0 Oct 29 12:14 /proc/1810/root -> /mnt/root


/mnt/root is minimal chroot with correct SElinux labels on directories and files.
Comment 11 adam.macmurray 2012-10-29 19:55:14 EDT
I changed packages and rebooted such that I now have:

# rpm -q openssh selinux-policy
openssh-6.1p1-2.fc18.i686
selinux-policy-3.11.1-46.fc18.noarch

The result is that my chroot SSH login shells for user "testuser" are being disconnected again.

I have both of the following bools on. ssh_chroot_rw_homedirs was off on my first test. Turning it on did not change the end result.

selinuxuser_use_ssh_chroot --> on
ssh_chroot_rw_homedirs --> on


# getenforce
Enforcing


# semanage login -l

Login Name                SELinux User              MLS/MCS Range
<... others ...>
testuser                  guest_u                   s0


I switched from login shell /bin/bash -r to simply /bin/bash for my ssh chroot'd users with no change in results and then went to Permissive mode to get the following from ps:

system_u:system_r:sshd_t:s0-s0:c0.c1023 894 ?  Ss     0:00  \_ sshd: testuser [priv]
guest_u:guest_r:guest_t:s0        897 ?        S      0:00      \_ sshd: testuser@pts/1
guest_u:guest_r:guest_t:s0        898 pts/1    Ss+    0:00          \_ /bin/bash


Is it possible to attach a list and SELinux context dump of your test chroot tree? I still have a FC15 chroot ssh system running with SELinux enabled, so I mirror many of the same contexts. But it would be interesting to see what differences there are between my non-working setup and your working setup.
Comment 12 Petr Lautrbach 2012-10-30 05:31:12 EDT
unconfined_u:object_r:root_t:s0  /mnt/root/
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libpcre.so.1
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libc.so.6
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libtinfo.so.5
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/librt.so.1
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libattr.so.1
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libacl.so.1
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libcap.so.2
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libselinux.so.1
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libdl.so.2
unconfined_u:object_r:lib_t:s0   /mnt/root/lib64/libpthread.so.0
unconfined_u:object_r:ld_so_t:s0 /mnt/root/lib64/ld-linux-x86-64.so.2
unconfined_u:object_r:device_t:s0 /mnt/root/dev
unconfined_u:object_r:bin_t:s0   /mnt/root/bin
unconfined_u:object_r:bin_t:s0   /mnt/root/bin/ls
unconfined_u:object_r:shell_exec_t:s0 /mnt/root/bin/bash
Comment 13 adam.macmurray 2012-10-30 13:35:59 EDT
Thank you for the list Petr.

I use more folders and files for things such as user home directories. What are the shell users using as a home directory in your example setup?

A couple of issues I have encountered when mirroring your setup and then adding basic home directory functionality (chroot: ~/.bash*, /etc/bashrc, /etc/passwd, and related):

1. Even with SELinux in permissive mode and the ability to cat (the chroot versions of) /etc/passwd and /etc/group, the user cannot resolve uids and gids to names. See the following logon example:

Using username "testuser".

Authenticating with public key "<key>" from agent
id: cannot find name for group ID 1001
id: cannot find name for user ID 1001
id: cannot find name for group ID 1001
id: cannot find name for user ID 1001
[I have no name!@fc18alpha ~]$

With SELinux in permissive mode, is this an OpenSSH chroot issue? It did not used to be a problem under FC17 with SELinux in permissive mode.


2. The primary use for our chroot SSH environment is SSH port forwarding to other hosts (some shell functionality is also required). With SELinux in Enforcing mode, OpenSSH port forwarding does not work with a chroot user. I would guess the following audit2allow entry is related(?):

allow guest_t unreserved_port_t:tcp_socket name_connect;

Does it make sense to add an SELinux boolean allowing guest to port forward since I'm assuming this could be considered something guest shouldn't be able to do by default?


Given that port forwarding is a useful component of OpenSSH that used to work with a chroot shell, I would say that an bug report should be created for that issue if we are to consider the shell logon issue resolved. I would also like to know why the id command isn't working -- should that be a separate bug report? It would be interesting to see if you encounter the same issue.

To reproduce -- identical results with SELinux Enforcing and Permissive:

a) create a test user with home directory /home/username, shell /bin/bash, SSH pub key, and SELInux user type guest_u

b) configure sshd_config such that test user is put into chroot shell jail when shell logging on via OpenSSH

c) create a chroot /home/username folder with the same contents (.b*) as /home/username (minus .ssh folder)

d) Ensure that chroot versions of /etc/bashrc, /etc/passwd, /etc/group, and /bin/id [or /usr/bin/id] all exist. For this example I have used complete passwd and group files that mirror the non-chroot versions.

e) Logon via SSH

f) If id error messages don't show up when logging in, try to use "id" to return the associated user and group names for the test user's uid and gid. When listing directory contents the ownership and group information will not resolve to names either.
Comment 14 adam.macmurray 2012-10-30 19:49:49 EDT
Re: #2 (port forwarding for guest_t user under chroot ssh shell), SELinux boolean "nis_enabled" set to "on" allows ssh port forwarding to work. I'm not sure if any of the other side effects from turning this boolean on are desirable or not.
Comment 15 Daniel Walsh 2012-10-31 10:10:53 EDT
Which is exactly what guest_t users were designed to block, if you want port forwarding why not label the users as user_t?
Comment 16 adam.macmurray 2012-10-31 10:56:53 EDT
The "nis_enabled" boolean will suffice for port forwarding.

guest_t was the suggested user to replace chroot_user_t, which wasn't working, so that's the direction I went.

As long as SELinux can be in Enforcing mode and will allow chroot ssh shell access, the user context doesn't need to be the most limited for my purposes. The chrooted and restricted SSH bash shell will suffice. Thank you for your work that fixed this.

The id issue (point #1 from Comment 13. Steps to reproduce in comment 13) is currently the only problem I have. It doesn't seem related to SELinux though given that it's still an issue when SELinux is in Permissive mode.
Comment 17 Fedora Update System 2012-12-20 10:51:44 EST
selinux-policy-3.11.1-46.fc18 has been pushed to the Fedora 18 stable repository.  If problems still persist, please make note of it in this bug report.
Comment 18 adam.macmurray 2013-01-21 11:03:55 EST
Re: Comment of 2012-10-30 and "id" problems in chroot environment.

The chroot environment was set to get user and group information from "files" in nsswitch.conf, and the files were present with appropriate information, however the "libnss_files*" library files were missing from the chroot "lib" directory. It was unrelated to the (now fixed) chroot ssh issues.

Note You need to log in before you can comment on or make changes to this bug.