By properly setting up a new root environment, you can fool the user and make them feel they are logging into a real root environment, rather than a jailed root. the funny part is to make a perfect root environment, with everything setting up, not exposure of the real /etc/passwd and /etc/shadow etc… The way to make a root environment I can think of includes 1. copy all required files (binary files, libraries, configurations …) down to the new root. 2. loopback mount the relevant file systems down to the new root. (the drawback is it will expose the real /etc to the user) 3. set the root path to the root path of a non-global zone. (make sure zone is running if you are running a sparse local zone)
It is fairly simple to get chroot for ftp session, change home directory from /etc/passwd as below,
usertest
:55502:0:comments:/export/home/usertest/newroot/./test:/bin/ksh
/export/home/usertest/newroot/./test is the new home directory, of which, /export/home/usertest/newroot is the new root, and /test is relateive path to the new root.
ftp server will change root to “/export/home/usertest/newroot/” after ftp session established.
Pls make sure you copy some essential required file down to the new root, such as /bin /sbin /etc, etc.
the easy way is to loopback mount those file system as below
cd /export/home/usertest/newroot
mkdir bin sbin etc usr lib
mount -F lofs /bin /export/home/usertest/newroot/bin
mount -F lofs /sbin /export/home/usertest/newroot/sbin
mount -F lofs /usr /export/home/usertest/newroot/usr
mount -F lofs /etc /export/home/usertest/newroot/etc
mount -F lofs /lib /export/home/usertest/newroot/lib
after user logs in via ftp, the session will be limited under the new root (/export/home/usertest/newroot)
pls note: for ftp only, even the new root is total empty, the ftp session is still able to establish. But list functionality from ftp gui client doesn’t work, command line works well.
authentication is based /etc/passwd and /etc/shadow under real root.
it doesn’t matter if you do not change home directory in /etc/passwd
2.1 prepare the new root environment (/export/home/usertest/newroot)
copy all required files/directories down to the new root and test it.
eg: /usr/sbin/chroot /export/home/usertest/newroot /bin/ksh
2.2
inetadm -l telnet > telnet.bak
inetadm -m telnet exec=”/usr/sbin/a.ksh”
svcadm restart telnet
a.ksh
#!/bin/ksh
/usr/sbin/chroot /export/home/usertest/newroot/ /usr/sbin/in.telnetd
pls note, as chroot is explicitly run by a.ksh, the authentication will be based on /etc/passwd and /etc/shadow under new root, namely
/export/home/usertest/newroot/etc/passwd and /export/home/usertest/newroot/etc/shadow
3. rsh
it doesn’t matter if you do not change home directory in /etc/passwd
rsh is using SMF svc:/network/login:rlogin and associated daemon is /usr/sbin/in.rlogind
3.1 prepare the new root
3.2 inetadm -m shell/rlogin exec=”/usr/sbin/b.ksh”
b.ksh
#!/bin/ksh
/usr/sbin/chroot /export/home/usertest/newroot/ /usr/sbin/in.rlogind
pls note, authentication is based on /export/home/usertest/newroot/etc/passwd and /export/home/usertest/newroot/etc/shadow.
authentication is based /etc/passwd and /etc/shadow under real root.
4.1 it is a must to change the home directory as above for ftp.
4.2 prepare the new root and test it.
4.3 download the below packages from sunfreeware.com and install them
gcc
libiconv
openssl
4.4 download openssh source code and save into a temporary directory
modify session.c as stated below
+ #define CHROOT /* to be added (of course without + mark at the beginning) */
/* func */
Session *session_new(void);
***************
*** 1159,1164 ****
— 1161,1171 —-
void
do_setusercontext(struct passwd *pw)
{
+ #ifdef CHROOT /* to be added (of course without + mark at the beginning ) */
+ char *user_dir; /* to be added (of course without + mark at the beginning) */
+ char *new_root; /* to be added (of course without + mark at the beginning) */
+ #endif /* CHROOT */ /* to be added (of course without + mark at the beginning) */
+
char tty=”;
#ifdef HAVE_CYGWIN
if (setlogin(pw->pw_name) < 0)
error(“setlogin failed: %s”, strerror(errno));
+ #ifdef CHROOT /* to be added (of course without + mark at the beginning) */
+ user_dir = xstrdup(pw->pw_dir); /* to be added (of course without + mark at the beginning) */
+ new_root = user_dir + 1; /* to be added (of course without + mark at the beginning) */
+
+ while((new_root = strchr(new_root, ‘.’)) != NULL) { /* to be added (of course without + mark at the beginning) */
+ new_root–; /* to be added (of course without + mark at the beginning) */
+ if(strncmp(new_root, “/./”, 3) == 0) { /* to be added (of course without + mark at the beginning) */
+ *new_root = ”; /* to be added (of course without + mark at the beginning) */
+ new_root += 2; /* to be added (of course without + mark at the beginning) */
+
+ if(chroot(user_dir) != 0) /* to be added (of course without + mark at the beginning) */
+ fatal(“Couldn’t chroot to user directory %s”, user_dir); /* to be added (of course without + mark at the beginning) */
+
+ pw->pw_dir = new_root; /* to be added (of course without + mark at the beginning) */
+ break; /* to be added (of course without + mark at the beginning) */
+ } /* to be added (of course without + mark at the beginning) */
+ new_root += 2; /* to be added (of course without + mark at the beginning) */
+ } /* to be added (of course without + mark at the beginning) */
+ #endif /* CHROOT */ /* to be added (of course without + mark at the beginning) */
+
if (setgid(pw->pw_gid) < 0) {
perror(“setgid”);
exit(1);
4.5
./configure –with-random=/dev/random \
–prefix=/usr/local –libexecdir=/usr/libexec/openssh \
–sysconfdir=/usr/local/etc –mandir=/usr/share/man
4.6
make
4.7
mkdir /var/empty
chown root:sys /var/empty
chmod 755 /var/empty
groupadd sshd
useradd -g sshd -c ’sshd privsep’ -d /var/empty -s /bin/false sshd
4.8
make install
4.9
/usr/local/bin/ssh-keygen -t rsa1 -f /usr/local/etc/ssh_host_key -N
/usr/local/bin/ssh-keygen -t dsa -f /usr/local/etc/ssh_host_dsa_key -N
/usr/local/bin/ssh-keygen -t rsa -f /usr/local/etc/ssh_host_rsa_key -N
4.10
create file /etc/init.d/sshd
#!/bin/sh
pid=`/usr/bin/ps -e | /usr/bin/grep sshd | /usr/bin/sed -e ’s/^ *//’ -e ’s/ .*//’`
case $1 in
’start’)
/usr/local/sbin/sshd;;
’stop’)
if [ "${pid}" != "" ]; then
/usr/bin/kill ${pid}; fi;;
*)
echo “usage: /etc/init.d/sshd (start|stop)”;;
esac
4.11
ln -s /etc/init.d/sshd /etc/rc2.d/S100sshd_chroot
ln -s /etc/init.d/sshd /etc/rc0.d/K100sshd_chroot
4.12
/etc/rc2.d/S100sshd_chroot start