Got the initial restricted file list setup; some things are missing because they may expose a security hole, and they need a further, more detailed wrapper (like mount, find, etc etc), because they expose both harmless read-only, and extremely damaging write functions.

This commit is contained in:
2012-08-06 18:28:07 -04:00
parent 0f0f68a38d
commit cea08e9d74
4 changed files with 252 additions and 47 deletions

View File

@@ -12,14 +12,15 @@ fi
# Cleanup old junk # Cleanup old junk
rm -rf ${DISCOROOT}/scratchfs rm -rf ${DISCOROOT}/scratchfs
rm -rf ${DISCOROOT}/restricted/* rm -rf ${DISCOROOT}/restricted/*
rm -rf ${DISCOROOT}/munge/*
# Prepare all the mountpoint directories # Prepare all the mountpoint directories
mkdir -p ${DISCOROOT}/chroot mkdir -p ${DISCOROOT}/chroot
mkdir -p ${DISCOROOT}/execs/bin #mkdir -p ${DISCOROOT}/proc/proc
mkdir -p ${DISCOROOT}/proc/proc #mkdir -p ${DISCOROOT}/sysfs/sys
mkdir -p ${DISCOROOT}/sysfs/sys
mkdir -p ${DISCOROOT}/rootfs mkdir -p ${DISCOROOT}/rootfs
mkdir -p ${DISCOROOT}/scratchfs mkdir -p ${DISCOROOT}/scratchfs
mkdir -p ${DISCOROOT}/munge
mkdir -p ${DISCOROOT}/dev/dev mkdir -p ${DISCOROOT}/dev/dev
mkdir -p ${DISCOROOT}/restricted/bin mkdir -p ${DISCOROOT}/restricted/bin
@@ -28,35 +29,34 @@ mkdir -p ${DISCOROOT}/restricted/bin
mkdir -p ${DISCOCFG}/restricted.d mkdir -p ${DISCOCFG}/restricted.d
for file in $(cat ${DISCOCFG}/restricted.d/* 2>/dev/null | grep -v "^#") for file in $(cat ${DISCOCFG}/restricted.d/* 2>/dev/null | grep -v "^#")
do do
mkdir -p ${DISCOROOT}/restricted/bin$(echo $file | dirname $file) if [ ! -e ${DISCOROOT}/restricted/bin/$(basename $file) ]; then
ln -s $file ${DISCOROOT}/restricted/bin/$file ln -s $file ${DISCOROOT}/restricted/bin/$(basename $file)
fi
done done
# Setup some more restricted execution stuff, but only if we actually have $NOOP # Setup some more restricted execution stuff, but only if we actually have $NOOP
if [ "$NOOP" != "" ]; then if [ "$NOOP" != "" ]; then
# Munge up /etc/profile
mkdir -p ${DISCOROOT}/munge/etc
cp /etc/profile ${DISCOROOT}/munge/etc/profile
echo "export PATH=${DISCOROOT}/restricted/bin" >> ${DISCOROOT}/munge/etc/profile
# Make default wrapper
echo -e "#!/bin/bash\necho \"info: Would execute \$0 \$@\"" > ${DISCOROOT}/restricted/bin/_disco_restricted_cmd
chmod +x ${DISCOROOT}/restricted/bin/_disco_restricted_cmd
# Now link everything to the default wrapper
for dir in $(echo $PATH | sed s/":"/" "/g) for dir in $(echo $PATH | sed s/":"/" "/g)
do do
for file in ${dir}/* for file in ${dir}/*
do do
if [ "$file" != "/bin/bash" ] && [ -x $file ] && [ ! -x ${DISCOROOT}/restricted${file} ] ; then FNAME=$(basename $file)
mkdir -p $(dirname ${DISCOROOT}/restricted/${file}) if [ "$FNAME" != "bash" ] && [ -x $file ] && [ ! -x ${DISCOROOT}/restricted/bin/$FNAME ] ; then
echo -e "#!/bin/bash\necho \"info: Would execute \$0 \$@\"" > ${DISCOROOT}/restricted${file} ln -s ${DISCOROOT}/restricted/bin/_disco_restricted_cmd ${DISCOROOT}/restricted/bin/${FNAME}
chmod +x ${DISCOROOT}/restricted${file}
fi fi
done done
done done
# Here we play a pretty lame trick on the user. /bin/bash will always exist
# (unfortunately), but we can force everything else to our rbash wrapper,
# forcing restricted execution. The user can get around this by calling
# /bin/bash directly, but that's on the user. TNMP, RTFM!
#ln -s /bin/bash ${DISCOROOT}/restricted/bin/rbash
#for dir in /usr/bin /usr/local/bin /usr/sbin;
#do
# mkdir -p ${DISCOROOT}/restricted/${dir}
# echo "#!/bin/bash --restricted\neval \$@" > ${DISCOROOT}/restricted/${dir}/bash
# chmod +x ${DISCOROOT}/restricted/${dir}/bash
#done
fi fi
# We need SOME special files in /dev like /dev/null, so make them here # We need SOME special files in /dev like /dev/null, so make them here
@@ -69,26 +69,25 @@ chmod 666 ${DISCOROOT}/dev/dev/null
mount --bind -o ro / ${DISCOROOT}/rootfs 2>&1 | grep -v "seems to be mounted read-write" mount --bind -o ro / ${DISCOROOT}/rootfs 2>&1 | grep -v "seems to be mounted read-write"
mount -o remount,ro ${DISCOROOT}/rootfs mount -o remount,ro ${DISCOROOT}/rootfs
# Setup filesystem layers. The read/write ones go on the top, with scratchfs ALWAYS on top.
FSLAYERS="${DISCOROOT}/scratchfs=rw"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/munge=ro"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/dev=rw"
#FSLAYERS="${FSLAYERS}:${DISCOROOT}/proc=ro"
#FSLAYERS="${FSLAYERS}:${DISCOROOT}/sysfs=ro"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/rootfs=ro"
# Union
unionfs -o cow,dev,dirs=$FSLAYERS ${DISCOROOT}/chroot
# Duplicate /proc and /sys if they already exist # Duplicate /proc and /sys if they already exist
mount | grep " on /proc" >/dev/null 2>&1 mount | grep " on /proc" >/dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
mount -t proc -o ro none ${DISCOROOT}/proc/proc mount -t proc -o ro none ${DISCOROOT}/chroot/proc
fi fi
mount | grep " on /sys" >/dev/null 2>&1 mount | grep " on /sys" >/dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
mount -t sysfs -o ro none ${DISCOROOT}/sysfs/sys mount -t sysfs -o ro none ${DISCOROOT}/chroot/sys
fi fi
# Setup filesystem layers. The read/write ones go on the top, with scratchfs ALWAYS on top.
FSLAYERS="${DISCOROOT}/scratchfs=rw"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/dev=rw"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/restricted=ro"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/execs=ro"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/proc=ro"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/sysfs=ro"
FSLAYERS="${FSLAYERS}:${DISCOROOT}/rootfs=ro"
# Here we go
unionfs -o cow,dev,dirs=$FSLAYERS ${DISCOROOT}/chroot
exit 0 exit 0

View File

@@ -10,25 +10,21 @@ fi
umount ${DISCOROOT}/chroot umount ${DISCOROOT}/chroot
umount ${DISCOROOT}/proc/proc umount ${DISCOROOT}/proc/proc
#Unmount the proc/sys mirrors if they were mounted
mount | grep " on /${DISCOROOT}/proc/proc" >/dev/null 2>&1
if [ $? -eq 0 ]; then
mount -t proc -o ro none ${DISCOROOT}/proc/proc
mount -t sysfs -o ro none ${DISCOROOT}/sysfs/sys
fi
mount | grep " on /${DISCOROOT}/sysfs/sys" >/dev/null 2>&1
if [ $? -eq 0 ]; then
mount -t sysfs -o ro none ${DISCOROOT}/sysfs/sys
fi
umount ${DISCOROOT}/sysfs/sys
umount ${DISCOROOT}/rootfs umount ${DISCOROOT}/rootfs
mount | grep $DISCOROOT > /dev/null 2>&1 mount | grep $DISCOROOT > /dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
# Sometimes required # Sometimes required
umount ${DISCOROOT}/rootfs umount ${DISCOROOT}/rootfs
fi fi
#Unmount the proc/sys mirrors if they were mounted
mount | grep " on ${DISCOROOT}/proc/proc" >/dev/null 2>&1
if [ $? -eq 0 ]; then
mount -t proc -o ro none ${DISCOROOT}/proc/proc
fi
mount | grep " on ${DISCOROOT}/sysfs/sys" >/dev/null 2>&1
if [ $? -eq 0 ]; then
mount -t sysfs -o ro none ${DISCOROOT}/sysfs/sys
fi
rm -rf ${DISCOROOT}/scratchfs/* ${DISCOROOT}/scratchfs/.unionfs rm -rf ${DISCOROOT}/scratchfs/* ${DISCOROOT}/scratchfs/.unionfs
rm -rf ${DISCOROOT}/dev/* rm -rf ${DISCOROOT}/dev/*

View File

@@ -0,0 +1,64 @@
/bin/arch
/bin/basename
/bin/cat
/bin/chgrp
/bin/chmod
/bin/chown
/bin/cp
/bin/cpio
/bin/cut
/bin/dash
/bin/date
/bin/dd
/bin/df
/bin/dmesg
/bin/dnsdomainname
/bin/domainname
/bin/dumpkeys
/bin/echo
/bin/ed
/bin/egrep
/bin/false
/bin/fgrep
/bin/findmnt
/bin/grep
/bin/gtar
/bin/gunzip
/bin/gzip
/bin/hostname
/bin/ipcalc
/bin/keyctl
/bin/link
/bin/ln
/bin/loadkeys
/bin/ls
/bin/lsblk
/bin/mkdir
/bin/mknod
/bin/mktemp
/bin/mv
/bin/netstat
/bin/nisdomainname
/bin/ping
/bin/ping6
/bin/ps
/bin/pwd
/bin/readlink
/bin/rm
/bin/rmdir
/bin/sed
/bin/sleep
/bin/sort
/bin/sync
/bin/tar
/bin/touch
/bin/tracepath
/bin/tracepath6
/bin/traceroute
/bin/traceroute6
/bin/true
/bin/uname
/bin/unlink
/bin/usleep
/bin/ypdomainname
/bin/zcat

View File

@@ -0,0 +1,146 @@
/usr/bin/attr
/usr/bin/base64
/usr/bin/bashbug-32
/usr/bin/bc
/usr/bin/bunzip2
/usr/bin/bzcat
/usr/bin/bzcmp
/usr/bin/bzdiff
/usr/bin/bzgrep
/usr/bin/bzip2
/usr/bin/bzip2recover
/usr/bin/bzless
/usr/bin/bzmore
/usr/bin/chacl
/usr/bin/chage
/usr/bin/chattr
/usr/bin/chcon
/usr/bin/chfn
/usr/bin/chvt
/usr/bin/clear
/usr/bin/cmp
/usr/bin/crontab
/usr/bin/cut
/usr/bin/diff
/usr/bin/diff3
/usr/bin/dig
/usr/bin/dir
/usr/bin/dircolors
/usr/bin/dirname
/usr/bin/du
/usr/bin/expand
/usr/bin/expr
/usr/bin/file
/usr/bin/find-repos-of-install
/usr/bin/fmt
/usr/bin/fold
/usr/bin/free
/usr/bin/funzip
/usr/bin/getent
/usr/bin/getfacl
/usr/bin/getfattr
/usr/bin/gethostip
/usr/bin/getkeycodes
/usr/bin/getopt
/usr/bin/gpasswd
/usr/bin/gpg
/usr/bin/gpg2
/usr/bin/gpgconf
/usr/bin/gpg-error
/usr/bin/gpgkey2ssh
/usr/bin/groups
/usr/bin/gunzip
/usr/bin/gzip
/usr/bin/head
/usr/bin/hexdump
/usr/bin/host
/usr/bin/hostid
/usr/bin/iconv
/usr/bin/id
/usr/bin/install
/usr/bin/install-catalog
/usr/bin/iostat
/usr/bin/join
/usr/bin/last
/usr/bin/lastlog
/usr/bin/locale
/usr/bin/localedef
/usr/bin/locate
/usr/bin/logger
/usr/bin/lsattr
/usr/bin/lscpu
/usr/bin/lsusb
/usr/bin/md5sum
/usr/bin/mkfifo
/usr/bin/mkisofs
/usr/bin/needs-restarting
/usr/bin/nslookup
/usr/bin/ntpstat
/usr/bin/openssl
/usr/bin/passwd
/usr/bin/paste
/usr/bin/pidstat
/usr/bin/pr
/usr/bin/printenv
/usr/bin/printf
/usr/bin/pstree
/usr/bin/quota
/usr/bin/rdate
/usr/bin/readelf
/usr/bin/readlink
/usr/bin/rename
/usr/bin/rpm2cpio
/usr/bin/rpmdb
/usr/bin/rpmdumpheader
/usr/bin/rpmquery
/usr/bin/rpmsign
/usr/bin/rpmverify
/usr/bin/rsync
/usr/bin/scp
/usr/bin/script
/usr/bin/scriptreplay
/usr/bin/seq
/usr/bin/sha1sum
/usr/bin/sha224sum
/usr/bin/sha256sum
/usr/bin/sha384sum
/usr/bin/sha512sum
/usr/bin/showkey
/usr/bin/shred
/usr/bin/shuf
/usr/bin/size
/usr/bin/split
/usr/bin/sqlite3
/usr/bin/ssh-keygen
/usr/bin/stat
/usr/bin/sum
/usr/bin/tac
/usr/bin/tail
/usr/bin/tailf
/usr/bin/tee
/usr/bin/test
/usr/bin/tr
/usr/bin/tree
/usr/bin/truncate
/usr/bin/tsort
/usr/bin/tty
/usr/bin/ul
/usr/bin/unexpand
/usr/bin/uniq
/usr/bin/unlzma
/usr/bin/unzip
/usr/bin/unzipsfx
/usr/bin/updatedb
/usr/bin/uptime
/usr/bin/users
/usr/bin/uuidgen
/usr/bin/vmstat
/usr/bin/w
/usr/bin/wc
/usr/bin/whatis
/usr/bin/whereis
/usr/bin/which
/usr/bin/who
/usr/bin/whoami
/usr/bin/wnck-urgency-monitor
/usr/bin/zip