X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=usr_sbin%2Fmake_chroot_jail;h=083c2d27e6a9338ab7788051a1f28504b327645a;hb=3b7f948896440f41092f14347b17ce114072c569;hp=75cf12c9fd10ff4278045340bd4d6cb0dfe3389e;hpb=e720deae78f1eda5e6f62629606c194f16796762;p=grml-scripts.git diff --git a/usr_sbin/make_chroot_jail b/usr_sbin/make_chroot_jail index 75cf12c..083c2d2 100755 --- a/usr_sbin/make_chroot_jail +++ b/usr_sbin/make_chroot_jail @@ -14,14 +14,14 @@ # ( 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/ # # Feedback is welcome! # -# Thanks for Bugfixes / Enhancements to +# Thanks for Bugfixes / Enhancements to # Michael Prokop , # Randy K., Randy D. and Jonathan Hunter. @@ -29,6 +29,8 @@ # 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 @@ -55,10 +57,10 @@ if [ -z "$1" ] ; then fi echo "Am I root? " -if [ "$(whoami &2>/dev/null)" != "root" ] && [ "$(id -un &2>/dev/null)" != "root" ] ; then +if [ "$(whoami 2>/dev/null)" != "root" ] && [ "$(id -un 2>/dev/null)" != "root" ] ; then echo " NO! -Error: You must be root to run this script." +Error: You must be root to run this script." >&2 exit 1 fi echo " OK"; @@ -67,60 +69,117 @@ echo " OK"; 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 chroot..." +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! +" >&2 +exit 1 +fi + +echo "Checking for chroot..." if [ `which chroot` ]; then echo " OK"; else echo " failed +chroot not found! Please install chroot-package/binary! -" +" >&2 exit 1 fi -echo "Checking for sudo..." +echo "Checking for sudo..." if [ `which sudo` ]; then + echo " OK"; +else + echo " failed + +sudo not found! +Please install sudo-package/binary! +" >&2 +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)! +" >&2 +exit 1 +fi + +echo "Checking for awk..." +if [ `which awk` ]; then echo " OK "; -else +else echo " failed -Please install sudo-package/binary! -" +awk not found! +Please install (g)awk-package/binary! +" >&2 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 2>&1); 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 2&1); 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 2&1); then +APPS="$APPS $SFTP_SERVER" + # Get accountname to create CHROOT_USERNAME=$1 @@ -137,13 +196,45 @@ else 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! +(yes/no) -> " + read MODIFYUSER + if [ "$MODIFYUSER" != "yes" ]; then + echo " +Not entered yes. Exiting...." >&2 + 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) +(yes/no) -> " +read OVERWRITE +if [ "$OVERWRITE" != "yes" ]; then + echo " +Not entered yes. Exiting...." >&2 exit 1 +fi else echo "Creating $SHELL" echo '#!/bin/sh' > $SHELL @@ -152,14 +243,14 @@ else 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" @@ -181,27 +272,49 @@ echo [ -r $JAILPATH/dev/urandom ] || mknod $JAILPATH/dev/urandom c 1 9 [ -r $JAILPATH/dev/null ] || mknod -m 666 $JAILPATH/dev/null c 1 3 [ -r $JAILPATH/dev/zero ] || mknod -m 666 $JAILPATH/dev/zero c 1 5 -[ -r $JAILPATH/dev/tty ] || mknod -m 666 $JAILPATH/dev/tty c 5 0 +[ -r $JAILPATH/dev/tty ] || mknod -m 666 $JAILPATH/dev/tty c 5 0 # if we only want to update the files in the jail # skip the creation of the new account if [ "$1" != "update" ]; then -# Modifiy /etc/sudoers to enable chroot-ing for users +# Modify sudo config to enable chroot-ing for users, # must be removed by hand if account is deleted -echo "Modifying /etc/sudoers" -echo "$CHROOT_USERNAME ALL=NOPASSWD: `which chroot`, /bin/su - $CHROOT_USERNAME" >> /etc/sudoers +SUDOERS="$CHROOT_USERNAME ALL=NOPASSWD: $(which chroot), /bin/su - $CHROOT_USERNAME" +if [ -d /etc/sudoers.d ]; then + echo "Installing sudoers configuration file /etc/sudoers.d/jail-$CHROOT_USERNAME" + echo "$SUDOERS" > "/etc/sudoers.d/jail-$CHROOT_USERNAME" + chmod 0440 "/etc/sudoers.d/jail-$CHROOT_USERNAME" +else + echo "Modifying /etc/sudoers" + echo "$SUDOERS" >> /etc/sudoers +fi # Define HomeDir for simple referencing HOMEDIR="$JAILPATH/home/$CHROOT_USERNAME" # 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." >&2 + exit 1; +fi echo +} +fi # Create /usr/bin/groups in the jail echo "#!/bin/bash" > usr/bin/groups @@ -213,30 +326,31 @@ chmod 755 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 -# to ./etc/passwd replacing the $HOME with the directory as it will then +# to ./etc/passwd replacing the $HOME with the directory as it will then # appear in the jail 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 @@ -245,25 +359,25 @@ fi echo "Copying necessary library-files to jail (may take some time)" # The original code worked fine on RedHat 7.3, but did not on FC3. -# On FC3, when the 'ldd' is done, there is a 'linux-gate.so.1' that +# On FC3, when the 'ldd' is done, there is a 'linux-gate.so.1' that # points to nothing (or a 90xb.....), and it also does not pick up # some files that start with a '/'. To fix this, I am doing the ldd # to a file called ldlist, then going back into the file and pulling # out the libs that start with '/' -# +# # Randy K. # # The original code worked fine on 2.4 kernel systems. Kernel 2.6 -# introduced an internal library called 'linux-gate.so.1'. This -# 'phantom' library caused non-critical errors to display during the -# copy since the file does not actually exist on the file system. -# To fix re-direct output of ldd to a file, parse the file and get +# introduced an internal library called 'linux-gate.so.1'. This +# 'phantom' library caused non-critical errors to display during the +# copy since the file does not actually exist on the file system. +# To fix re-direct output of ldd to a file, parse the file and get # library files that start with / # -if [ -x ${HOME}/ldlist ]; then +if [ -x ${HOME}/ldlist ]; then mv ${HOME}/ldlist ${HOME}/ldlist.bak fi -if [ -x ${HOME}/lddlist2 ]; then +if [ -x ${HOME}/lddlist2 ]; then mv ${HOME}/lddlist2 ${HOME}/lddlist2.bak fi @@ -292,13 +406,13 @@ done 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 @@ -314,12 +428,18 @@ done /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 @@ -335,7 +455,7 @@ fi # needed library just copy all of them) # #cp /lib/*.* ${JAILPATH}/lib/ -#cp /lib/lib64/*.* ${JAILPATH}/lib/lib64/ +#cp /lib/lib64/*.* ${JAILPATH}/lib/lib64/ # if you are using PAM you need stuff from /etc/pam.d/ in the jail, echo "Copying files from /etc/pam.d/ to jail" @@ -351,7 +471,11 @@ cp /etc/login.defs ${JAILPATH}/etc/ if [ -f /etc/DIR_COLORS ] ; then cp /etc/DIR_COLORS ${JAILPATH}/etc/ -fi +fi + +# Don't give more permissions than necessary +chown root.root ${JAILPATH}/bin/su +chmod 700 ${JAILPATH}/bin/su exit