# ( http://www.fsf.org/licenses/gpl.txt )
# first Release: 2004-07-30
-# latest update: 2006-07-17
+# latest update: 2007-02-24
#
# The latest version of the script is available at
# http://www.fuschlberger.net/programs/ssh-scp-chroot-jail/
# Features:
# - enable scp and sftp in the chroot-jail
# - use one directory (default /home/jail/) as chroot for all users
+# - create new accounts
+# - move existing accounts to chroot
################################################################################
# Check if we are called with username or update
echo "Checking distribution... "
if [ -f /etc/debian_version ];
then echo " Supported Distribution found"
- echo -e " System is running Debian Linux\n"
+ echo " System is running Debian Linux"
DISTRO=DEBIAN;
elif [ -f /etc/SuSE-release ];
then echo " Supported Distribution found"
- echo -e " System is running SuSE Linux\n"
+ echo " System is running SuSE Linux"
DISTRO=SUSE;
elif [ -f /etc/fedora-release ];
then echo " Supported Distribution found"
- echo -e " System is running Fedora Linux\n"
+ echo " System is running Fedora Linux"
DISTRO=FEDORA;
elif [ -f /etc/redhat-release ];
then echo " Supported Distribution found"
- echo -e " System is running Red Hat Linux\n"
+ echo " System is running Red Hat Linux"
DISTRO=REDHAT;
-else echo -e " failed...........\nThis script works best on Debian, Red Hat and SuSE Linux!\nLet's try it nevertheless....\n"
+else echo -e " failed...........\nThis script works best on Debian, Red Hat, Fedora and SuSE Linux!\nLet's try it nevertheless....\nIf some program files cannot be found adjust the respective path in line 98\n"
#exit 1
fi
# Specify the apps you want to copy to the jail
if [ "$DISTRO" = SUSE ]; then
- APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/netcat /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd /usr/lib/ssh/sftp-server"
+ APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/netcat /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
elif [ "$DISTRO" = FEDORA ]; then
- APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/nc /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd /usr/libexec/openssh/sftp-server"
+ APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/nc /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
elif [ "$DISTRO" = REDHAT ]; then
- APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/nc /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd /usr/libexec/openssh/sftp-server"
+ APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/nc /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
elif [ "$DISTRO" = DEBIAN ]; then
- APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd /usr/lib/sftp-server"
+ APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd"
else
- APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /usr/sbin/unix_chkpwd /usr/lib/misc/sftp-server"
+ APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /usr/sbin/unix_chkpwd"
fi
# Check existence of necessary files
+echo "Checking for which... "
+if ( test -f /usr/bin/which ) || ( test -f /bin/which ) || ( test -f /sbin/which ) || ( test -f /usr/sbin/which );
+ then echo " OK";
+ else echo " failed
+
+Please install which-binary!
+"
+exit 1
+fi
+
echo "Checking for chroot..."
if [ `which chroot` ];
then echo " OK";
else echo " failed
+chroot not found!
Please install chroot-package/binary!
"
exit 1
echo "Checking for sudo..."
if [ `which sudo` ]; then
+ echo " OK";
+else
+ echo " failed
+
+sudo not found!
+Please install sudo-package/binary!
+"
+exit 1
+fi
+
+echo "Checking for dirname..."
+if [ `which dirname` ]; then
+ echo " OK";
+else
+ echo " failed
+
+dirname not found!
+Please install dirname-binary (to be found eg in the package coreutils)!
+"
+exit 1
+fi
+
+echo "Checking for awk..."
+if [ `which awk` ]; then
echo " OK
";
else
echo " failed
-Please install sudo-package/binary!
+awk not found!
+Please install (g)awk-package/binary!
"
exit 1
fi
+# get location of sftp-server binary from /etc/ssh/sshd_config
+# check for existence of /etc/ssh/sshd_config and for
+# (uncommented) line with sftp-server filename. If neither exists, just skip
+# this step and continue without sftp-server
+#
+if (test ! -f /etc/ssh/sshd_config &> /dev/null); then
+ echo "
+File /etc/ssh/sshd_config not found.
+Not checking for path to sftp-server.
+ ";
+else
+ if !(grep -v "^#" /etc/ssh/sshd_config | grep -i sftp-server &> /dev/null); then
+ echo "Obviously no sftp-server is running on this system.
+";
+ else SFTP_SERVER=$(grep -v "^#" /etc/ssh/sshd_config | grep -i sftp-server | awk '{ print $3}')
+ fi
+fi
+
+#if !(grep -v "^#" /etc/ssh/sshd_config | grep -i sftp-server /etc/ssh/sshd_config | awk '{ print $3}' &> /dev/null); then
+APPS="$APPS $SFTP_SERVER"
+
# Get accountname to create
CHROOT_USERNAME=$1
fi
# Exit if user already exists
-id $CHROOT_USERNAME > /dev/null 2>&1 && { echo "User exists."; echo "Exiting."; exit 1; }
+#id $CHROOT_USERNAME > /dev/null 2>&1 && { echo "User exists."; echo "Exiting."; exit 1; }
+if ( id $CHROOT_USERNAME > /dev/null 2>&1 ) ; then {
+echo "
+-----------------------------
+User $CHROOT_USERNAME exists.
+
+Are you sure you want to modify the users home directory and lock him into the
+chroot directory?
+Are you REALLY sure?
+Say only yes if you absolutely know what you are doing!"
+ read -p "(yes/no) -> " MODIFYUSER
+ if [ "$MODIFYUSER" != "yes" ]; then
+ echo "
+Not entered yes. Exiting...."
+ exit 1
+ fi
+}
+else
+ CREATEUSER="yes"
+fi
# Create $SHELL (shell for jailed accounts)
if [ -f ${SHELL} ] ; then
- echo "$SHELL exists. Don't want to overwrite it.
-Please delete it before running the script."
+ echo "
+-----------------------------
+The file $SHELL exists.
+Probably it was created by this script.
+
+Are you sure you want to overwrite it?
+(you want to say yes for example if you are running the script for the second
+time when adding more than one account to the jail)"
+read -p "(yes/no) -> " OVERWRITE
+if [ "$OVERWRITE" != "yes" ]; then
+ echo "
+Not entered yes. Exiting...."
exit 1
+fi
else
echo "Creating $SHELL"
echo '#!/bin/sh' > $SHELL
fi
# make common jail for everybody if inexistent
-if [ ! -d $JAILPATH ] ; then
- mkdir -p $JAILPATH
- echo "Creating $JAILPATH"
+if [ ! -d ${JAILPATH} ] ; then
+ mkdir -p ${JAILPATH}
+ echo "Creating ${JAILPATH}"
fi
-cd $JAILPATH
+cd ${JAILPATH}
# Create directories in jail that do not exist yet
-JAILDIRS="dev etc etc/pam.d bin home sbin usr usr/bin"
+JAILDIRS="dev etc etc/pam.d bin home sbin usr usr/bin usr/lib"
for directory in $JAILDIRS ; do
if [ ! -d "$JAILPATH/$directory" ] ; then
mkdir $JAILPATH/"$directory"
# Create new account, setting $SHELL to the above created script and
# $HOME to $JAILPATH/home/*
+if [ "$CREATEUSER" != "yes" ] ; then echo "
+Not creating new User account
+Modifying User \"$CHROOT_USERNAME\"
+Copying files in $CHROOT_USERNAME's \$HOME to \"$HOMEDIR\"
+"
+usermod -d "$HOMEDIR" -m -s "$SHELL" $CHROOT_USERNAME && chmod 700 "$HOMEDIR"
+fi
+
+if [ "$CREATEUSER" = "yes" ] ; then {
echo "Adding User \"$CHROOT_USERNAME\" to system"
useradd -m -d "$HOMEDIR" -s "$SHELL" $CHROOT_USERNAME && chmod 700 "$HOMEDIR"
+
# Enter password for new account
-passwd $CHROOT_USERNAME
+if !(passwd $CHROOT_USERNAME);
+ then echo "Passwords are probably not the same, try again."
+ exit 1;
+fi
echo
+}
+fi
# Create /usr/bin/groups in the jail
echo "#!/bin/bash" > usr/bin/groups
# check if file exists (ie we are not called for the first time)
# if yes skip root's entry and do not overwrite the file
if [ ! -f etc/passwd ] ; then
- grep /etc/passwd -e "^root" > etc/passwd
+ grep /etc/passwd -e "^root" > ${JAILPATH}/etc/passwd
fi
if [ ! -f etc/group ] ; then
- grep /etc/group -e "^root" > etc/group
+ grep /etc/group -e "^root" > ${JAILPATH}/etc/group
# add the group for all users to etc/group (otherwise there is a nasty error
# message and probably because of that changing directories doesn't work with
# winSCP)
- grep /etc/group -e "^users" >> etc/group
+ grep /etc/group -e "^users" >> ${JAILPATH}/etc/group
fi
# grep the username which was given to us from /etc/passwd and add it
echo "Adding User $CHROOT_USERNAME to jail"
grep -e "^$CHROOT_USERNAME:" /etc/passwd | \
sed -e "s#$JAILPATH##" \
- -e "s#$SHELL#/bin/bash#" >> etc/passwd
+ -e "s#$SHELL#/bin/bash#" >> ${JAILPATH}/etc/passwd
# if the system uses one account/one group we write the
# account's group to etc/group
-grep -e "^$CHROOT_USERNAME:" /etc/group >> etc/group
+grep -e "^$CHROOT_USERNAME:" /etc/group >> ${JAILPATH}/etc/group
# write the user's line from /etc/shadow to /home/jail/etc/shadow
-grep -e "^$CHROOT_USERNAME:" /etc/shadow >> etc/shadow
+grep -e "^$CHROOT_USERNAME:" /etc/shadow >> ${JAILPATH}/etc/shadow
+chmod 600 ${JAILPATH}/etc/shadow
# endif for =! update
fi
if [ -e ${HOME}/ldlist2 ]; then
rm ${HOME}/ldlist2
fi
-for libs in `cat /root/ldlist`; do
+for libs in `cat ${HOME}/ldlist`; do
frst_char="`echo $libs | cut -c1`"
if [ "$frst_char" = "/" ]; then
- echo "$libs" >> /root/ldlist2
+ echo "$libs" >> ${HOME}/ldlist2
fi
done
-for lib in `cat /root/ldlist2`; do
+for lib in `cat ${HOME}/ldlist2`; do
mkdir -p .`dirname $lib` > /dev/null 2>&1
# If the files in the chroot are on the same file system as the original
/bin/rm -f ${HOME}/ldlist
/bin/rm -f ${HOME}/ldlist2
-# Necessary files that are not listed by ldd
+# Necessary files that are not listed by ldd.
+#
+# There might be errors because of files that do not exist but in the end it
+# may work nevertheless (I added new file names at the end without deleting old
+# ones for reasons of backward compatibility).
+# So please test ssh/scp before reporting a bug.
if [ "$DISTRO" = SUSE ]; then
cp /lib/libnss_compat.so.2 /lib/libnss_files.so.2 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
elif [ "$DISTRO" = FEDORA ]; then
- cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/ld-linux.so.2 /lib/ld-ldb.so.3 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
+ cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/ld-linux.so.2 /lib/ld-ldb.so.3 /lib/ld-lsb.so.3 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
cp /lib/*.* ${JAILPATH}/lib/
+ cp /usr/lib/libcrack.so.2 ${JAILPATH}/usr/lib/
elif [ "$DISTRO" = REDHAT ]; then
cp /lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/ld-linux.so.2 /lib/ld-lsb.so.1 /lib/libnss_dns.so.2 /lib/libxcrypt.so.1 ${JAILPATH}/lib/
# needed for scp on RHEL
cp /etc/DIR_COLORS ${JAILPATH}/etc/
fi
+# Don't give more permissions than necessary
+chown root.root ${JAILPATH}/bin/su
+chmod 700 ${JAILPATH}/bin/su
+
exit