B.7. Chroot environment for SSH
Creating a restricted environment for SSH is a tough job due to its dependencies and the fact that, unlike other servers, SSH provides a remote shell to users. Thus, you will also have to consider the applications users will be allowed to use in the environment.
You have two options to setup a restricted remote shell:
Chrooting the ssh users, by properly configuring the ssh daemon you can ask it to chroot a user after authentication just before it is provided a shell. Each user can have their own environment.
Chrooting the ssh server, since you chroot the ssh application itself all users are chrooted to the defined environment.
The first option has the advantage of making it possible to have both non-chrooted and chrooted users, if you don’t introduce any setuid application in the user’s chroots it is more difficult to break out of it. However, you might need to setup individual chroots for each user and it is more difficult to setup (as it requires cooperation from the SSH server). The second option is more easy to setup, and protects from an exploitation of the ssh server itself (since it’s also in the chroot) but it will have the limitation that all users will share the same chroot environment (you cannot setup a per-user chroot environment).
B.7.1. Chrooting the ssh users
You can setup the ssh server so that it will chroot a set of defined users into a shell with a limited set of applications available.
B.7.1.1. Using libpam-chroot
Probably the easiest way is to use the libpam-chroot package provided in Debian. Once you install it you need to:
Modify
/etc/pam.d/ssh
to use this PAM module, add as its last line[80]:- session required pam_chroot.so
set a proper chroot environment for the user. You can try using the scripts available at
/usr/share/doc/libpam-chroot/examples/
, use the makejail[81] program or setup a minimum Debian environment with debootstrap. Make sure the environment includes the needed devices [82].Configure
/etc/security/chroot.conf
so that the users you determine are chrooted to the directory you setup previously. You might want to have independent directories for different users so that they will not be able to see neither the whole system nor each other’s.Configure SSH: Depending on your OpenSSH version the chroot environment might work straight of the box or not. Since 3.6.1p2 the do_pam_session() function is called after sshd has dropped privileges, since chroot() needs root priviledges it will not work with Privilege separation on. In newer OpenSSH versions, however, the PAM code has been modified and do_pam_session is called before dropping priviledges so it will work even with Privilege separation is on. If you have to disable it modify
/etc/ssh/sshd_config
like this:- UsePrivilegeSeparation no
Notice that this will lower the security of your system since the OpenSSH server will then run as root user. This means that if a remote attack is found against OpenSSH an attacker will get root privileges instead of sshd, thus compromising the whole system. [83]
If you don’t disable Privilege Separation you will need an /etc/passwd
which includes the user’s UID inside the chroot for Privilege Separation to work properly.
If you have Privilege Separation set to yes and your OpenSSH version does not behave properly you will need to disable it. If you don’t, users that try to connect to your server and would be chrooted by this module will see this:
- $ ssh -l user server
- user@server's password:
- Connection to server closed by remote host.
- Connection to server closed.
This is because the ssh daemon, which is running as ‘sshd’, is not be able to make the chroot() system call. To disable Privilege separation you have to modify the /etc/ssh/sshd_config
configuration file as described above.
Notice that if any of the following is missing the users will not be able to logon to the chroot:
The
/proc
filesystem needs to be mounted in the users’ chroot.The necessary
/dev/pts/
devices need to exist. If the files are generated by your running kernel automatically then you have to manually create them on the chroot’s/dev/
.The user’s home directory has to exist in the chroot, otherwise the ssh daemon will not continue.
You can debug all these issues if you use the debug keyword in the /etc/pam.d/ssh
PAM definition. If you encounter issues you might find it useful to enable the debugging mode on the ssh client too.
Note: This information is also available (and maybe more up to date) in /usr/share/doc/libpam-chroot/README.Debian.gz
, please review it for updated information before taking the above steps.
B.7.1.2. Patching the ssh server
Debian’s sshd
does not allow restriction of a user’s movement through the server, since it lacks the chroot
function that the commercial program sshd2
includes (using ‘ChrootGroups’ or ‘ChrootUsers’, see sshd2_config(5)). However, there is a patch available to add this functionality available from http://chrootssh.sourceforge.net (requested and available in http://bugs.debian.org/139047 in Debian). The patch may be included in future releases of the OpenSSH package. Emmanuel Lacour has ssh
deb packages for sarge with this feature. They are available at http://debian.home-dn.net/sarge/ssh/. Notice that those might not be up to date so completing the compilation step is recommended.
After applying the patch, modify /etc/passwd
by changing the home path of the users (with the special /./
token):
- joeuser:x:1099:1099:Joe Random User:/home/joe/./:/bin/bash
这将限制通过 ssh 隧道的远程 shell 访问, 和通过 ssh
隧道进行的远程拷贝.
确保用户的 chroot
目录下包含了所有需要的程序和库文件. 这些文件的宿主应当是 root 以避免被用户篡改(在用户退出 chroot
jail 时). 下边是一个范例:
- ./bin:
- total 660
- drwxr-xr-x 2 root root 4096 Mar 18 13:36 .
- drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 ..
- -r-xr-xr-x 1 root root 531160 Feb 6 22:36 bash
- -r-xr-xr-x 1 root root 43916 Nov 29 13:19 ls
- -r-xr-xr-x 1 root root 16684 Nov 29 13:19 mkdir
- -rwxr-xr-x 1 root root 23960 Mar 18 13:36 more
- -r-xr-xr-x 1 root root 9916 Jul 26 2001 pwd
- -r-xr-xr-x 1 root root 24780 Nov 29 13:19 rm
- lrwxrwxrwx 1 root root 4 Mar 30 16:29 sh -> bash
- ./etc:
- total 24
- drwxr-xr-x 2 root root 4096 Mar 15 16:13 .
- drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 ..
- -rw-r--r-- 1 root root 54 Mar 15 13:23 group
- -rw-r--r-- 1 root root 428 Mar 15 15:56 hosts
- -rw-r--r-- 1 root root 44 Mar 15 15:53 passwd
- -rw-r--r-- 1 root root 52 Mar 15 13:23 shells
- ./lib:
- total 1848
- drwxr-xr-x 2 root root 4096 Mar 18 13:37 .
- drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 ..
- -rwxr-xr-x 1 root root 92511 Mar 15 12:49 ld-linux.so.2
- -rwxr-xr-x 1 root root 1170812 Mar 15 12:49 libc.so.6
- -rw-r--r-- 1 root root 20900 Mar 15 13:01 libcrypt.so.1
- -rw-r--r-- 1 root root 9436 Mar 15 12:49 libdl.so.2
- -rw-r--r-- 1 root root 248132 Mar 15 12:48 libncurses.so.5
- -rw-r--r-- 1 root root 71332 Mar 15 13:00 libnsl.so.1
- -rw-r--r-- 1 root root 34144 Mar 15 16:10
- libnss_files.so.2
- -rw-r--r-- 1 root root 29420 Mar 15 12:57 libpam.so.0
- -rw-r--r-- 1 root root 105498 Mar 15 12:51 libpthread.so.0
- -rw-r--r-- 1 root root 25596 Mar 15 12:51 librt.so.1
- -rw-r--r-- 1 root root 7760 Mar 15 12:59 libutil.so.1
- -rw-r--r-- 1 root root 24328 Mar 15 12:57 libwrap.so.0
- ./usr:
- total 16
- drwxr-xr-x 4 root root 4096 Mar 15 13:00 .
- drwxr-xr-x 8 guest guest 4096 Mar 15 16:53 ..
- drwxr-xr-x 2 root root 4096 Mar 15 15:55 bin
- drwxr-xr-x 2 root root 4096 Mar 15 15:37 lib
- ./usr/bin:
- total 340
- drwxr-xr-x 2 root root 4096 Mar 15 15:55 .
- drwxr-xr-x 4 root root 4096 Mar 15 13:00 ..
- -rwxr-xr-x 1 root root 10332 Mar 15 15:55 env
- -rwxr-xr-x 1 root root 13052 Mar 15 13:13 id
- -r-xr-xr-x 1 root root 25432 Mar 15 12:40 scp
- -rwxr-xr-x 1 root root 43768 Mar 15 15:15 sftp
- -r-sr-xr-x 1 root root 218456 Mar 15 12:40 ssh
- -rwxr-xr-x 1 root root 9692 Mar 15 13:17 tty
- ./usr/lib:
- total 852
- drwxr-xr-x 2 root root 4096 Mar 15 15:37 .
- drwxr-xr-x 4 root root 4096 Mar 15 13:00 ..
- -rw-r--r-- 1 root root 771088 Mar 15 13:01
- libcrypto.so.0.9.6
- -rw-r--r-- 1 root root 54548 Mar 15 13:00 libz.so.1
- -rwxr-xr-x 1 root root 23096 Mar 15 15:37 sftp-server
B.7.2. Chrooting the ssh server
If you create a chroot which includes the SSH server files in, for example /var/chroot/ssh
, you would start the ssh
server chroot
‘ed with this command:
- # chroot /var/chroot/ssh /sbin/sshd -f /etc/sshd_config
That would make startup the sshd
daemon inside the chroot. In order to do that you have to first prepare the contents of the /var/chroot/ssh
directory so that it includes both the SSH server and all the utilities that the users connecting to that server might need. If you are doing this you should make certain that OpenSSH uses Privilege Separation (which is the default) having the following line in the configuration file /etc/ssh/sshd_config
:
- UsePrivilegeSeparation yes
That way the remote daemon will do as few things as possible as the root user so even if there is a bug in it it will not compromise the chroot. Notice that, unlike the case in which you setup a per-user chroot, the ssh daemon is running in the same chroot as the users so there is at least one potential process running as root which could break out of the chroot.
Notice, also, that in order for SSH to work in that location, the partition where the chroot directory resides cannot be mounted with the nodev option. If you use that option, then you will get the following error: PRNG is not seeded, because /dev/urandom
does not work in the chroot.
B.7.2.1. Setup a minimal system (the really easy way)
You can use debootstrap to setup a minimal environment that just includes the ssh server. In order to do this you just have to create a chroot as described in the http://www.debian.org/doc/manuals/reference/ch09#_chroot_system document. This method is bound to work (you will get all the necessary componentes for the chroot) but at the cost of disk space (a minimal installation of Debian will amount to several hundred megabytes). This minimal system might also include setuid files that a user in the chroot could use to break out of the chroot if any of those could be use for a privilege escalation.
B.7.2.2. 环境的自动构建(简单的方式)
You can easily create a restricted environment with the makejail package, since it automatically takes care of tracing the server daemon (with strace
), and makes it run under the restricted environment.
自动构建 chroot
环境程序的优势在于它能为 chroot
环境复制任何软件包(甚至下边的依赖包, 并能保证其完整性). 因此, 用户使用起来更加容易.
To set up the environment using makejail
‘s provided examples, just create /var/chroot/sshd
and use the command:
- # makejail /usr/share/doc/makejail/examples/sshd.py
This will setup the chroot in the /var/chroot/sshd
directory. Notice that this chroot will not fully work unless you:
Mount the procfs filesystem in
/var/chroot/sshd/proc
.Makejail
will mount it for you but if the system reboots you need to remount it running:- # mount -t proc proc /var/chroot/sshd/proc
You can also have it be mounted automatically by editing
/etc/fstab
and including this line:- proc-ssh /var/chroot/sshd/proc proc none 0 0
Have syslog listen to the device
/dev/log
inside the chroot. In order to do this you have modify/etc/default/syslogd
and add -a /var/chroot/sshd/dev/log to theSYSLOGD
variable definition.
Read the sample file to see what other changes need to be made to the environment. Some of these changes, such as copying user’s home directories, cannot be done automatically. Also, limit the exposure of sensitive information by only copying the data from a given number of users from the files /etc/shadow
or /etc/group
. Notice that if you are using Privilege Separation the sshd user needs to exist in those files.
The following sample environment has been (slightly) tested in Debian 3.0 and is built with the configuration file provided in the package and includes the fileutils package:
- .
- |-- bin
- | |-- ash
- | |-- bash
- | |-- chgrp
- | |-- chmod
- | |-- chown
- | |-- cp
- | |-- csh -> /etc/alternatives/csh
- | |-- dd
- | |-- df
- | |-- dir
- | |-- fdflush
- | |-- ksh
- | |-- ln
- | |-- ls
- | |-- mkdir
- | |-- mknod
- | |-- mv
- | |-- rbash -> bash
- | |-- rm
- | |-- rmdir
- | |-- sh -> bash
- | |-- sync
- | |-- tcsh
- | |-- touch
- | |-- vdir
- | |-- zsh -> /etc/alternatives/zsh
- | `-- zsh4
- |-- dev
- | |-- null
- | |-- ptmx
- | |-- pts
- | |-- ptya0
- (...)
- | |-- tty
- | |-- tty0
- (...)
- | `-- urandom
- |-- etc
- | |-- alternatives
- | | |-- csh -> /bin/tcsh
- | | `-- zsh -> /bin/zsh4
- | |-- environment
- | |-- hosts
- | |-- hosts.allow
- | |-- hosts.deny
- | |-- ld.so.conf
- | |-- localtime -> /usr/share/zoneinfo/Europe/Madrid
- | |-- motd
- | |-- nsswitch.conf
- | |-- pam.conf
- | |-- pam.d
- | | |-- other
- | | `-- ssh
- | |-- passwd
- | |-- resolv.conf
- | |-- security
- | | |-- access.conf
- | | |-- chroot.conf
- | | |-- group.conf
- | | |-- limits.conf
- | | |-- pam_env.conf
- | | `-- time.conf
- | |-- shadow
- | |-- shells
- | `-- ssh
- | |-- moduli
- | |-- ssh_host_dsa_key
- | |-- ssh_host_dsa_key.pub
- | |-- ssh_host_rsa_key
- | |-- ssh_host_rsa_key.pub
- | `-- sshd_config
- |-- home
- | `-- userX
- |-- lib
- | |-- ld-2.2.5.so
- | |-- ld-linux.so.2 -> ld-2.2.5.so
- | |-- libc-2.2.5.so
- | |-- libc.so.6 -> libc-2.2.5.so
- | |-- libcap.so.1 -> libcap.so.1.10
- | |-- libcap.so.1.10
- | |-- libcrypt-2.2.5.so
- | |-- libcrypt.so.1 -> libcrypt-2.2.5.so
- | |-- libdl-2.2.5.so
- | |-- libdl.so.2 -> libdl-2.2.5.so
- | |-- libm-2.2.5.so
- | |-- libm.so.6 -> libm-2.2.5.so
- | |-- libncurses.so.5 -> libncurses.so.5.2
- | |-- libncurses.so.5.2
- | |-- libnsl-2.2.5.so
- | |-- libnsl.so.1 -> libnsl-2.2.5.so
- | |-- libnss_compat-2.2.5.so
- | |-- libnss_compat.so.2 -> libnss_compat-2.2.5.so
- | |-- libnss_db-2.2.so
- | |-- libnss_db.so.2 -> libnss_db-2.2.so
- | |-- libnss_dns-2.2.5.so
- | |-- libnss_dns.so.2 -> libnss_dns-2.2.5.so
- | |-- libnss_files-2.2.5.so
- | |-- libnss_files.so.2 -> libnss_files-2.2.5.so
- | |-- libnss_hesiod-2.2.5.so
- | |-- libnss_hesiod.so.2 -> libnss_hesiod-2.2.5.so
- | |-- libnss_nis-2.2.5.so
- | |-- libnss_nis.so.2 -> libnss_nis-2.2.5.so
- | |-- libnss_nisplus-2.2.5.so
- | |-- libnss_nisplus.so.2 -> libnss_nisplus-2.2.5.so
- | |-- libpam.so.0 -> libpam.so.0.72
- | |-- libpam.so.0.72
- | |-- libpthread-0.9.so
- | |-- libpthread.so.0 -> libpthread-0.9.so
- | |-- libresolv-2.2.5.so
- | |-- libresolv.so.2 -> libresolv-2.2.5.so
- | |-- librt-2.2.5.so
- | |-- librt.so.1 -> librt-2.2.5.so
- | |-- libutil-2.2.5.so
- | |-- libutil.so.1 -> libutil-2.2.5.so
- | |-- libwrap.so.0 -> libwrap.so.0.7.6
- | |-- libwrap.so.0.7.6
- | `-- security
- | |-- pam_access.so
- | |-- pam_chroot.so
- | |-- pam_deny.so
- | |-- pam_env.so
- | |-- pam_filter.so
- | |-- pam_ftp.so
- | |-- pam_group.so
- | |-- pam_issue.so
- | |-- pam_lastlog.so
- | |-- pam_limits.so
- | |-- pam_listfile.so
- | |-- pam_mail.so
- | |-- pam_mkhomedir.so
- | |-- pam_motd.so
- | |-- pam_nologin.so
- | |-- pam_permit.so
- | |-- pam_rhosts_auth.so
- | |-- pam_rootok.so
- | |-- pam_securetty.so
- | |-- pam_shells.so
- | |-- pam_stress.so
- | |-- pam_tally.so
- | |-- pam_time.so
- | |-- pam_unix.so
- | |-- pam_unix_acct.so -> pam_unix.so
- | |-- pam_unix_auth.so -> pam_unix.so
- | |-- pam_unix_passwd.so -> pam_unix.so
- | |-- pam_unix_session.so -> pam_unix.so
- | |-- pam_userdb.so
- | |-- pam_warn.so
- | `-- pam_wheel.so
- |-- sbin
- | `-- start-stop-daemon
- |-- usr
- | |-- bin
- | | |-- dircolors
- | | |-- du
- | | |-- install
- | | |-- link
- | | |-- mkfifo
- | | |-- shred
- | | |-- touch -> /bin/touch
- | | `-- unlink
- | |-- lib
- | | |-- libcrypto.so.0.9.6
- | | |-- libdb3.so.3 -> libdb3.so.3.0.2
- | | |-- libdb3.so.3.0.2
- | | |-- libz.so.1 -> libz.so.1.1.4
- | | `-- libz.so.1.1.4
- | |-- sbin
- | | `-- sshd
- | `-- share
- | |-- locale
- | | `-- es
- | | |-- LC_MESSAGES
- | | | |-- fileutils.mo
- | | | |-- libc.mo
- | | | `-- sh-utils.mo
- | | `-- LC_TIME -> LC_MESSAGES
- | `-- zoneinfo
- | `-- Europe
- | `-- Madrid
- `-- var
- `-- run
- |-- sshd
- `-- sshd.pid
- 27 directories, 733 files
For Debian release 3.1 you have to make sure that the environment includes also the common files for PAM. The following files need to be copied over to the chroot if makejail
did not do it for you:
- $ ls /etc/pam.d/common-*
- /etc/pam.d/common-account /etc/pam.d/common-password
- /etc/pam.d/common-auth /etc/pam.d/common-session
B.7.2.3. Manually creating the environment (the hard way)
It is possible to create an environment, using a trial-and-error method, by monitoring the sshd
server traces and log files in order to determine the necessary files. The following environment, contributed by José Luis Ledesma, is a sample listing of files in a chroot
environment for ssh
in Debian woody (3.0): [84]
- .:
- total 36
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ./
- drwxr-xr-x 11 root root 4096 Jun 3 13:43 ../
- drwxr-xr-x 2 root root 4096 Jun 4 12:13 bin/
- drwxr-xr-x 2 root root 4096 Jun 4 12:16 dev/
- drwxr-xr-x 4 root root 4096 Jun 4 12:35 etc/
- drwxr-xr-x 3 root root 4096 Jun 4 12:13 lib/
- drwxr-xr-x 2 root root 4096 Jun 4 12:35 sbin/
- drwxr-xr-x 2 root root 4096 Jun 4 12:32 tmp/
- drwxr-xr-x 2 root root 4096 Jun 4 12:16 usr/
- ./bin:
- total 8368
- drwxr-xr-x 2 root root 4096 Jun 4 12:13 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- -rwxr-xr-x 1 root root 109855 Jun 3 13:45 a2p*
- -rwxr-xr-x 1 root root 387764 Jun 3 13:45 bash*
- -rwxr-xr-x 1 root root 36365 Jun 3 13:45 c2ph*
- -rwxr-xr-x 1 root root 20629 Jun 3 13:45 dprofpp*
- -rwxr-xr-x 1 root root 6956 Jun 3 13:46 env*
- -rwxr-xr-x 1 root root 158116 Jun 3 13:45 fax2ps*
- -rwxr-xr-x 1 root root 104008 Jun 3 13:45 faxalter*
- -rwxr-xr-x 1 root root 89340 Jun 3 13:45 faxcover*
- -rwxr-xr-x 1 root root 441584 Jun 3 13:45 faxmail*
- -rwxr-xr-x 1 root root 96036 Jun 3 13:45 faxrm*
- -rwxr-xr-x 1 root root 107000 Jun 3 13:45 faxstat*
- -rwxr-xr-x 1 root root 77832 Jun 4 11:46 grep*
- -rwxr-xr-x 1 root root 19597 Jun 3 13:45 h2ph*
- -rwxr-xr-x 1 root root 46979 Jun 3 13:45 h2xs*
- -rwxr-xr-x 1 root root 10420 Jun 3 13:46 id*
- -rwxr-xr-x 1 root root 4528 Jun 3 13:46 ldd*
- -rwxr-xr-x 1 root root 111386 Jun 4 11:46 less*
- -r-xr-xr-x 1 root root 26168 Jun 3 13:45 login*
- -rwxr-xr-x 1 root root 49164 Jun 3 13:45 ls*
- -rwxr-xr-x 1 root root 11600 Jun 3 13:45 mkdir*
- -rwxr-xr-x 1 root root 24780 Jun 3 13:45 more*
- -rwxr-xr-x 1 root root 154980 Jun 3 13:45 pal2rgb*
- -rwxr-xr-x 1 root root 27920 Jun 3 13:46 passwd*
- -rwxr-xr-x 1 root root 4241 Jun 3 13:45 pl2pm*
- -rwxr-xr-x 1 root root 2350 Jun 3 13:45 pod2html*
- -rwxr-xr-x 1 root root 7875 Jun 3 13:45 pod2latex*
- -rwxr-xr-x 1 root root 17587 Jun 3 13:45 pod2man*
- -rwxr-xr-x 1 root root 6877 Jun 3 13:45 pod2text*
- -rwxr-xr-x 1 root root 3300 Jun 3 13:45 pod2usage*
- -rwxr-xr-x 1 root root 3341 Jun 3 13:45 podchecker*
- -rwxr-xr-x 1 root root 2483 Jun 3 13:45 podselect*
- -r-xr-xr-x 1 root root 82412 Jun 4 11:46 ps*
- -rwxr-xr-x 1 root root 36365 Jun 3 13:45 pstruct*
- -rwxr-xr-x 1 root root 7120 Jun 3 13:45 pwd*
- -rwxr-xr-x 1 root root 179884 Jun 3 13:45 rgb2ycbcr*
- -rwxr-xr-x 1 root root 20532 Jun 3 13:45 rm*
- -rwxr-xr-x 1 root root 6720 Jun 4 10:15 rmdir*
- -rwxr-xr-x 1 root root 14705 Jun 3 13:45 s2p*
- -rwxr-xr-x 1 root root 28764 Jun 3 13:46 scp*
- -rwxr-xr-x 1 root root 385000 Jun 3 13:45 sendfax*
- -rwxr-xr-x 1 root root 67548 Jun 3 13:45 sendpage*
- -rwxr-xr-x 1 root root 88632 Jun 3 13:46 sftp*
- -rwxr-xr-x 1 root root 387764 Jun 3 13:45 sh*
- -rws--x--x 1 root root 744500 Jun 3 13:46 slogin*
- -rwxr-xr-x 1 root root 14523 Jun 3 13:46 splain*
- -rws--x--x 1 root root 744500 Jun 3 13:46 ssh*
- -rwxr-xr-x 1 root root 570960 Jun 3 13:46 ssh-add*
- -rwxr-xr-x 1 root root 502952 Jun 3 13:46 ssh-agent*
- -rwxr-xr-x 1 root root 575740 Jun 3 13:46 ssh-keygen*
- -rwxr-xr-x 1 root root 383480 Jun 3 13:46 ssh-keyscan*
- -rwxr-xr-x 1 root root 39 Jun 3 13:46 ssh_europa*
- -rwxr-xr-x 1 root root 107252 Jun 4 10:14 strace*
- -rwxr-xr-x 1 root root 8323 Jun 4 10:14 strace-graph*
- -rwxr-xr-x 1 root root 158088 Jun 3 13:46 thumbnail*
- -rwxr-xr-x 1 root root 6312 Jun 3 13:46 tty*
- -rwxr-xr-x 1 root root 55904 Jun 4 11:46 useradd*
- -rwxr-xr-x 1 root root 585656 Jun 4 11:47 vi*
- -rwxr-xr-x 1 root root 6444 Jun 4 11:45 whoami*
- ./dev:
- total 8
- drwxr-xr-x 2 root root 4096 Jun 4 12:16 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- crw-r--r-- 1 root root 1, 9 Jun 3 13:43 urandom
- ./etc:
- total 208
- drwxr-xr-x 4 root root 4096 Jun 4 12:35 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- -rw------- 1 root root 0 Jun 4 11:46 .pwd.lock
- -rw-r--r-- 1 root root 653 Jun 3 13:46 group
- -rw-r--r-- 1 root root 242 Jun 4 11:33 host.conf
- -rw-r--r-- 1 root root 857 Jun 4 12:04 hosts
- -rw-r--r-- 1 root root 1050 Jun 4 11:29 ld.so.cache
- -rw-r--r-- 1 root root 304 Jun 4 11:28 ld.so.conf
- -rw-r--r-- 1 root root 235 Jun 4 11:27 ld.so.conf~
- -rw-r--r-- 1 root root 88039 Jun 3 13:46 moduli
- -rw-r--r-- 1 root root 1342 Jun 4 11:34 nsswitch.conf
- drwxr-xr-x 2 root root 4096 Jun 4 12:02 pam.d/
- -rw-r--r-- 1 root root 28 Jun 4 12:00 pam_smb.conf
- -rw-r--r-- 1 root root 2520 Jun 4 11:57 passwd
- -rw-r--r-- 1 root root 7228 Jun 3 13:48 profile
- -rw-r--r-- 1 root root 1339 Jun 4 11:33 protocols
- -rw-r--r-- 1 root root 274 Jun 4 11:44 resolv.conf
- drwxr-xr-x 2 root root 4096 Jun 3 13:43 security/
- -rw-r----- 1 root root 1178 Jun 4 11:51 shadow
- -rw------- 1 root root 80 Jun 4 11:45 shadow-
- -rw-r----- 1 root root 1178 Jun 4 11:48 shadow.old
- -rw-r--r-- 1 root root 161 Jun 3 13:46 shells
- -rw-r--r-- 1 root root 1144 Jun 3 13:46 ssh_config
- -rw------- 1 root root 668 Jun 3 13:46 ssh_host_dsa_key
- -rw-r--r-- 1 root root 602 Jun 3 13:46 ssh_host_dsa_key.pub
- -rw------- 1 root root 527 Jun 3 13:46 ssh_host_key
- -rw-r--r-- 1 root root 331 Jun 3 13:46 ssh_host_key.pub
- -rw------- 1 root root 883 Jun 3 13:46 ssh_host_rsa_key
- -rw-r--r-- 1 root root 222 Jun 3 13:46 ssh_host_rsa_key.pub
- -rw-r--r-- 1 root root 2471 Jun 4 12:15 sshd_config
- ./etc/pam.d:
- total 24
- drwxr-xr-x 2 root root 4096 Jun 4 12:02 ./
- drwxr-xr-x 4 root root 4096 Jun 4 12:35 ../
- lrwxrwxrwx 1 root root 4 Jun 4 12:02 other -> sshd
- -rw-r--r-- 1 root root 318 Jun 3 13:46 passwd
- -rw-r--r-- 1 root root 546 Jun 4 11:36 ssh
- -rw-r--r-- 1 root root 479 Jun 4 12:02 sshd
- -rw-r--r-- 1 root root 370 Jun 3 13:46 su
- ./etc/security:
- total 32
- drwxr-xr-x 2 root root 4096 Jun 3 13:43 ./
- drwxr-xr-x 4 root root 4096 Jun 4 12:35 ../
- -rw-r--r-- 1 root root 1971 Jun 3 13:46 access.conf
- -rw-r--r-- 1 root root 184 Jun 3 13:46 chroot.conf
- -rw-r--r-- 1 root root 2145 Jun 3 13:46 group.conf
- -rw-r--r-- 1 root root 1356 Jun 3 13:46 limits.conf
- -rw-r--r-- 1 root root 2858 Jun 3 13:46 pam_env.conf
- -rw-r--r-- 1 root root 2154 Jun 3 13:46 time.conf
- ./lib:
- total 8316
- drwxr-xr-x 3 root root 4096 Jun 4 12:13 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- -rw-r--r-- 1 root root 1024 Jun 4 11:51 cracklib_dict.hwm
- -rw-r--r-- 1 root root 214324 Jun 4 11:51 cracklib_dict.pwd
- -rw-r--r-- 1 root root 11360 Jun 4 11:51 cracklib_dict.pwi
- -rwxr-xr-x 1 root root 342427 Jun 3 13:46 ld-linux.so.2*
- -rwxr-xr-x 1 root root 4061504 Jun 3 13:46 libc.so.6*
- lrwxrwxrwx 1 root root 15 Jun 4 12:11 libcrack.so -> libcrack.so.2.7*
- lrwxrwxrwx 1 root root 15 Jun 4 12:11 libcrack.so.2 -> libcrack.so.2.7*
- -rwxr-xr-x 1 root root 33291 Jun 4 11:39 libcrack.so.2.7*
- -rwxr-xr-x 1 root root 60988 Jun 3 13:46 libcrypt.so.1*
- -rwxr-xr-x 1 root root 71846 Jun 3 13:46 libdl.so.2*
- -rwxr-xr-x 1 root root 27762 Jun 3 13:46 libhistory.so.4.0*
- lrwxrwxrwx 1 root root 17 Jun 4 12:12 libncurses.so.4 -> libncurses.so.4.2*
- -rwxr-xr-x 1 root root 503903 Jun 3 13:46 libncurses.so.4.2*
- lrwxrwxrwx 1 root root 17 Jun 4 12:12 libncurses.so.5 -> libncurses.so.5.0*
- -rwxr-xr-x 1 root root 549429 Jun 3 13:46 libncurses.so.5.0*
- -rwxr-xr-x 1 root root 369801 Jun 3 13:46 libnsl.so.1*
- -rwxr-xr-x 1 root root 142563 Jun 4 11:49 libnss_compat.so.1*
- -rwxr-xr-x 1 root root 215569 Jun 4 11:49 libnss_compat.so.2*
- -rwxr-xr-x 1 root root 61648 Jun 4 11:34 libnss_dns.so.1*
- -rwxr-xr-x 1 root root 63453 Jun 4 11:34 libnss_dns.so.2*
- -rwxr-xr-x 1 root root 63782 Jun 4 11:34 libnss_dns6.so.2*
- -rwxr-xr-x 1 root root 205715 Jun 3 13:46 libnss_files.so.1*
- -rwxr-xr-x 1 root root 235932 Jun 3 13:49 libnss_files.so.2*
- -rwxr-xr-x 1 root root 204383 Jun 4 11:33 libnss_nis.so.1*
- -rwxr-xr-x 1 root root 254023 Jun 4 11:33 libnss_nis.so.2*
- -rwxr-xr-x 1 root root 256465 Jun 4 11:33 libnss_nisplus.so.2*
- lrwxrwxrwx 1 root root 14 Jun 4 12:12 libpam.so.0 -> libpam.so.0.72*
- -rwxr-xr-x 1 root root 31449 Jun 3 13:46 libpam.so.0.72*
- lrwxrwxrwx 1 root root 19 Jun 4 12:12 libpam_misc.so.0 ->
- libpam_misc.so.0.72*
- -rwxr-xr-x 1 root root 8125 Jun 3 13:46 libpam_misc.so.0.72*
- lrwxrwxrwx 1 root root 15 Jun 4 12:12 libpamc.so.0 -> libpamc.so.0.72*
- -rwxr-xr-x 1 root root 10499 Jun 3 13:46 libpamc.so.0.72*
- -rwxr-xr-x 1 root root 176427 Jun 3 13:46 libreadline.so.4.0*
- -rwxr-xr-x 1 root root 44729 Jun 3 13:46 libutil.so.1*
- -rwxr-xr-x 1 root root 70254 Jun 3 13:46 libz.a*
- lrwxrwxrwx 1 root root 13 Jun 4 12:13 libz.so -> libz.so.1.1.3*
- lrwxrwxrwx 1 root root 13 Jun 4 12:13 libz.so.1 -> libz.so.1.1.3*
- -rwxr-xr-x 1 root root 63312 Jun 3 13:46 libz.so.1.1.3*
- drwxr-xr-x 2 root root 4096 Jun 4 12:00 security/
- ./lib/security:
- total 668
- drwxr-xr-x 2 root root 4096 Jun 4 12:00 ./
- drwxr-xr-x 3 root root 4096 Jun 4 12:13 ../
- -rwxr-xr-x 1 root root 10067 Jun 3 13:46 pam_access.so*
- -rwxr-xr-x 1 root root 8300 Jun 3 13:46 pam_chroot.so*
- -rwxr-xr-x 1 root root 14397 Jun 3 13:46 pam_cracklib.so*
- -rwxr-xr-x 1 root root 5082 Jun 3 13:46 pam_deny.so*
- -rwxr-xr-x 1 root root 13153 Jun 3 13:46 pam_env.so*
- -rwxr-xr-x 1 root root 13371 Jun 3 13:46 pam_filter.so*
- -rwxr-xr-x 1 root root 7957 Jun 3 13:46 pam_ftp.so*
- -rwxr-xr-x 1 root root 12771 Jun 3 13:46 pam_group.so*
- -rwxr-xr-x 1 root root 10174 Jun 3 13:46 pam_issue.so*
- -rwxr-xr-x 1 root root 9774 Jun 3 13:46 pam_lastlog.so*
- -rwxr-xr-x 1 root root 13591 Jun 3 13:46 pam_limits.so*
- -rwxr-xr-x 1 root root 11268 Jun 3 13:46 pam_listfile.so*
- -rwxr-xr-x 1 root root 11182 Jun 3 13:46 pam_mail.so*
- -rwxr-xr-x 1 root root 5923 Jun 3 13:46 pam_nologin.so*
- -rwxr-xr-x 1 root root 5460 Jun 3 13:46 pam_permit.so*
- -rwxr-xr-x 1 root root 18226 Jun 3 13:46 pam_pwcheck.so*
- -rwxr-xr-x 1 root root 12590 Jun 3 13:46 pam_rhosts_auth.so*
- -rwxr-xr-x 1 root root 5551 Jun 3 13:46 pam_rootok.so*
- -rwxr-xr-x 1 root root 7239 Jun 3 13:46 pam_securetty.so*
- -rwxr-xr-x 1 root root 6551 Jun 3 13:46 pam_shells.so*
- -rwxr-xr-x 1 root root 55925 Jun 4 12:00 pam_smb_auth.so*
- -rwxr-xr-x 1 root root 12678 Jun 3 13:46 pam_stress.so*
- -rwxr-xr-x 1 root root 11170 Jun 3 13:46 pam_tally.so*
- -rwxr-xr-x 1 root root 11124 Jun 3 13:46 pam_time.so*
- -rwxr-xr-x 1 root root 45703 Jun 3 13:46 pam_unix.so*
- -rwxr-xr-x 1 root root 45703 Jun 3 13:46 pam_unix2.so*
- -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_acct.so*
- -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_auth.so*
- -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_passwd.so*
- -rwxr-xr-x 1 root root 45386 Jun 3 13:46 pam_unix_session.so*
- -rwxr-xr-x 1 root root 9726 Jun 3 13:46 pam_userdb.so*
- -rwxr-xr-x 1 root root 6424 Jun 3 13:46 pam_warn.so*
- -rwxr-xr-x 1 root root 7460 Jun 3 13:46 pam_wheel.so*
- ./sbin:
- total 3132
- drwxr-xr-x 2 root root 4096 Jun 4 12:35 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- -rwxr-xr-x 1 root root 178256 Jun 3 13:46 choptest*
- -rwxr-xr-x 1 root root 184032 Jun 3 13:46 cqtest*
- -rwxr-xr-x 1 root root 81096 Jun 3 13:46 dialtest*
- -rwxr-xr-x 1 root root 1142128 Jun 4 11:28 ldconfig*
- -rwxr-xr-x 1 root root 2868 Jun 3 13:46 lockname*
- -rwxr-xr-x 1 root root 3340 Jun 3 13:46 ondelay*
- -rwxr-xr-x 1 root root 376796 Jun 3 13:46 pagesend*
- -rwxr-xr-x 1 root root 13950 Jun 3 13:46 probemodem*
- -rwxr-xr-x 1 root root 9234 Jun 3 13:46 recvstats*
- -rwxr-xr-x 1 root root 64480 Jun 3 13:46 sftp-server*
- -rwxr-xr-x 1 root root 744412 Jun 3 13:46 sshd*
- -rwxr-xr-x 1 root root 30750 Jun 4 11:46 su*
- -rwxr-xr-x 1 root root 194632 Jun 3 13:46 tagtest*
- -rwxr-xr-x 1 root root 69892 Jun 3 13:46 tsitest*
- -rwxr-xr-x 1 root root 43792 Jun 3 13:46 typetest*
- ./tmp:
- total 8
- drwxr-xr-x 2 root root 4096 Jun 4 12:32 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- ./usr:
- total 8
- drwxr-xr-x 2 root root 4096 Jun 4 12:16 ./
- drwxr-xr-x 9 root root 4096 Jun 5 10:05 ../
- lrwxrwxrwx 1 root root 7 Jun 4 12:14 bin -> ../bin//
- lrwxrwxrwx 1 root root 7 Jun 4 11:33 lib -> ../lib//
- lrwxrwxrwx 1 root root 8 Jun 4 12:13 sbin -> ../sbin//
B.7.3. Chroot environment for Apache
B.7.3.1. 介绍
The chroot
utility is often used to jail a daemon in a restricted tree. You can use it to insulate services from one another, so that security issues in a software package do not jeopardize the whole server. When using the makejail
script, setting up and updating the chrooted tree is much easier.
FIXME: Apache can also be chrooted using http://www.modsecurity.org which is available in libapache-mod-security (for Apache 1.x) and libapache2-mod-security (for Apache 2.x).
B.7.3.1.1. 许可证
This document is copyright 2002 Alexandre Ratti. It has been dual-licensed and released under the GPL version 2 (GNU General Public License) the GNU-FDL 1.2 (GNU Free Documentation Licence) and is included in this manual with his explicit permission. (from the http://www.gabuzomeu.net/alex/doc/apache/index-en.html)
B.7.3.2. 安装服务器
This procedure was tested on Debian GNU/Linux 3.0 (Woody) with makejail
0.0.4-1 (in Debian/testing).
以
root
登录, 创建 jail 目录:- $ mkdir -p /var/chroot/apache
创造一个用户和新组. 除了 chroot 了的 Apache 服务器用这个用户/组运行, 在此系统上不再做别的用途. 在这个例子中, 用户和组都叫
chrapach
.- $ adduser --home /var/chroot/apache --shell /bin/false \
- --no-create-home --system --group chrapach
FIXME: 需要新的用户吗? (Apache 已经作为 apache 用户运行了)
象通常一样在 Debian 上安装 Apache:
apt-get install apache
Set up Apache (e.g. define your subdomains, etc.). In the
/etc/apache/httpd.conf
configuration file, set the Group and User options tochrapach
. Restart Apache and make sure the server is working correctly. Now, stop the Apache daemon.Install
makejail
(available in Debian/testing for now). You should also installwget
andlynx
as they will be used bymakejail
to test the chrooted server:apt-get install makejail wget lynx
复制 Apache 示例配置文件到
/etc/makejail
目录:- # cp /usr/share/doc/makejail/examples/apache.py /etc/makejail/
Edit
/etc/makejail/apache.py
. You need to change the chroot, users and groups options. To run this version ofmakejail
, you can also add apackages
option. See the http://www.floc.net/makejail/current/doc/. A sample is shown here:- chroot="/var/chroot/apache"
- testCommandsInsideJail=["/usr/sbin/apachectl start"]
- processNames=["apache"]
- testCommandsOutsideJail=["wget -r --spider http://localhost/",
- "lynx --source https://localhost/"]
- preserve=["/var/www",
- "/var/log/apache",
- "/dev/log"]
- users=["chrapach"]
- groups=["chrapach"]
- packages=["apache", "apache-common"]
- userFiles=["/etc/password",
- "/etc/shadow"]
- groupFiles=["/etc/group",
- "/etc/gshadow"]
- forceCopy=["/etc/hosts",
- "/etc/mime.types"]
FIXME: some options do not seem to work properly. For instance,
/etc/shadow
and/etc/gshadow
are not copied, whereas/etc/password
and/etc/group
are fully copied instead of being filtered.创造 chroot 目录树:
makejail /etc/makejail/apache.py
如果
/etc/password
和/etc/group
被全部复制, 键入:- $ grep chrapach /etc/passwd > /var/chroot/apache/etc/passwd
- $ grep chrapach /etc/group > /var/chroot/apache/etc/group
用过滤出的拷贝覆盖它们.
复制网站的网页和日志文件到 jail 中. 这些文件都不是自动复制的.(参阅
makejail
配置文件中的 preserve 项).- # cp -Rp /var/www /var/chroot/apache/var
- # cp -Rp /var/log/apache/*.log /var/chroot/apache/var/log/apache
Edit the startup script for the system logging daemon so that it also listen to the
/var/chroot/apache/dev/log
socket. In/etc/default/syslogd
, replace:SYSLOGD=""
withSYSLOGD=" -a /var/chroot/apache/dev/log"
and restart the daemon (/etc/init.d/sysklogd restart
).编辑 Apache 的启动脚本(
/etc/init.d/apache
). 您可能需要适当地做对缺省的启动脚本做一些调整, 使其在 chroot 目录树中运行正常. 譬如:在文件顶部设置一新 CHRDIR 变量;
编辑 start, stop, reload, 等部分;
增加一行用于在 jail 中加载和卸载
/proc
文件系统
<pre>#! /bin/bash
#
# apache Start the apache HTTP server.
#
CHRDIR=/var/chroot/apache
NAME=apache
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/apache
SUEXEC=/usr/lib/apache/suexec
PIDFILE=/var/run/$NAME.pid
CONF=/etc/apache/httpd.conf
APACHECTL=/usr/sbin/apachectl
trap "" 1
export LANG=C
export PATH
test -f $DAEMON || exit 0
test -f $APACHECTL || exit 0
# ensure we don't leak environment vars into apachectl
APACHECTL="env -i LANG=${LANG} PATH=${PATH} chroot $CHRDIR $APACHECTL"
if egrep -q -i "^[[:space:]]*ServerType[[:space:]]+inet" $CONF
then
exit 0
fi
case "$1" in
start)
echo -n "Starting web server: $NAME"
mount -t proc proc /var/chroot/apache/proc
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON \
--chroot $CHRDIR
;;
stop)
echo -n "Stopping web server: $NAME"
start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo
umount /var/chroot/apache/proc
;;
reload)
echo -n "Reloading $NAME configuration"
start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" \
--signal USR1 --startas $DAEMON --chroot $CHRDIR
;;
reload-modules)
echo -n "Reloading $NAME modules"
start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo \
--retry 30
start-stop-daemon --start --pidfile $PIDFILE \
--exec $DAEMON --chroot $CHRDIR
;;
restart)
$0 reload-modules
exit $?
;;
force-reload)
$0 reload-modules
exit $?
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|reload|reload-modules|force-reload|restart}"
exit 1
;;
esac
if [ $? == 0 ]; then
echo .
exit 0
else
echo failed
exit 1
fi
</pre>
*FIXME*: 第一个 Apache 进程应当以其它用户而不是 root 用户运行的(即, add --chuid chrapach:chrapach)? Cons: chrapache将需要对日志有写权限, 这非常不便.
在
/etc/logrotate.d/apache
中用/var/chroot/apache/var/log/apache/*.log
替换/var/log/apache/*.log
Start Apache (
/etc/init.d/apache start
) and check what is it reported in the jail log (/var/chroot/apache/var/log/apache/error.log
). If your setup is more complex, (e.g. if you also use PHP and MySQL), files will probably be missing. if some files are not copied automatically bymakejail
, you can list them in the forceCopy (to copy files directly) or packages (to copy full packages and their dependencies) option the/etc/makejail/apache.py
configuration file.键入
ps aux | grep apache
以确保 Apache 正在运行. 您应当看到如下类似内容:- root 180 0.0 1.1 2936 1436 ? S 04:03 0:00 /usr/sbin/apache
- chrapach 189 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
- chrapach 190 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
- chrapach 191 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
- chrapach 192 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
- chrapach 193 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
Make sure the Apache processes are running chrooted by looking in the
/proc
filesystem:ls -la /proc/`process_number`/root/.
whereprocess_number
is one of the PID numbers listed above (2nd column; 189 for instance). The entries for a restricted tree should be listed:- drwxr-sr-x 10 root staff 240 Dec 2 16:06 .
- drwxrwsr-x 4 root staff 72 Dec 2 08:07 ..
- drwxr-xr-x 2 root root 144 Dec 2 16:05 bin
- drwxr-xr-x 2 root root 120 Dec 3 04:03 dev
- drwxr-xr-x 5 root root 408 Dec 3 04:03 etc
- drwxr-xr-x 2 root root 800 Dec 2 16:06 lib
- dr-xr-xr-x 43 root root 0 Dec 3 05:03 proc
- drwxr-xr-x 2 root root 48 Dec 2 16:06 sbin
- drwxr-xr-x 6 root root 144 Dec 2 16:04 usr
- drwxr-xr-x 7 root root 168 Dec 2 16:06 var
键入:
ls -la /proc/`cat /var/chroot/apache/var/run/apache.pid`/root/.
自动完成整个测试FIXME: 增加其它的测试, 以确保 jail 被关闭了?
我喜欢这样的原因是因为设定 jail 不是很困难, 并且服务器可以通过下边两行更新:
- apt-get update && apt-get install apache
- makejail /etc/makejail/apache.py
B.7.4. 其它
If you are looking for more information you can consider these sources of information in which the information presented is based: http://www.floc.net/makejail/, this program was written by Alain Tesio
[80] You can use the debug option to have it send the progress of the module to the authpriv.notice facility
[81] You can create a very limited bash environment with the following python definition for makejail, just create the directory /var/chroots/users/foo
and a file with the following contents and call it bash.py
:
- chroot="/var/chroots/users/foo"
- cleanJailFirst=1
- testCommandsInsideJail=["bash ls"]
And then run makejail bash.py to create the user environment at /var/chroots/users/foo
. To test the environment run:
- # chroot /var/chroots/users/foo/ ls
- bin dev etc lib proc sbin usr
[82] In some occasions you might need the /dev/ptmx
and /dev/pty*
devices and the /dev/pts/
subdirectory. Running MAKEDEV in the /dev
directory of the chrooted environment should be sufficient to create them if they do not exist. If you are using kernels (version 2.6) which dynamically create device files you will need to create the /dev/pts/ files yourself and grant them the proper privileges.
[83] If you are using a kernel that implements Mandatory Access Control (RSBAC/SElinux) you can avoid changing this configuration just by granting the sshd user privileges to make the chroot() system call.
[84] Notice that there are no SETUID files. This makes it more difficult for remote users to escape the chroot
environment. However, it also prevents users from changing their passwords, since the passwd
program cannot modify the files /etc/passwd
or /etc/shadow
.