Use chroot with PHP and isolate your website
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

268 lines
6.4 KiB

#!/usr/bin/env bash
## Bash strict mode ####################################
set -o errexit # abort on nonzero exitstatus
set -o pipefail # don't hide errors within pipes
set -o nounset # abort on unbound variable
## Bash color ##########################################
# Set colors
RED='\033[0;31m'
GREEN='\033[00;32m'
YELLOW='\033[00;33m'
LRED='\033[01;31m'
LBLUE='\033[01;34m'
NC='\033[0m' # No Color
## Logs ################################################
readonly SCRIPTNAME="$(basename "$0")"
success() { echo -e "${GREEN}[SUCCESS] $* ${NC}" | logger --tag "${SCRIPTNAME}" --stderr; }
info() { echo -e "${LBLUE}[INFO] $* ${NC}" | logger --tag "${SCRIPTNAME}" --stderr ; }
warning() { echo -e "${YELLOW}[WARNING] $* ${NC}" | logger --tag "${SCRIPTNAME}" --stderr ; }
error() { echo -e "${LRED}[ERROR] $* ${NC}" | logger --tag "${SCRIPTNAME}" --stderr ; }
fatal() { echo -e "${RED}[FATAL] $* ${NC}" | logger --tag "${SCRIPTNAME}" --stderr ; exit 1 ; }
########################################################
## Define variables ###################################
LOCK="/var/lock/${SCRIPTNAME}.lock"
CHROOTPATH="/var/chroot"
ZONEINFO="/usr/share/zoneinfo"
LISTCHROOTFILE="/var/chroot/list"
function _USAGE
{
cat << EOF
Usage :
${SCRIPTNAME} [OPTIONS]
Options :
--install Install chroot on ${WEBCHROOT}
--update Update configuration and binary on chroot
--configure Configure chroot for specific path
--help Display this help
EOF
exit 1
}
function _GET_OPTS
{
_SHORT_OPTS="i:u:c:h";
_LONG_OPTS="install,update,configure,help";
_OPTS=$(getopt \
-o "${_SHORT_OPTS}" \
-l "${_LONG_OPTS}" \
-n "${SCRIPTNAME}" -- "${@}")
if [ "${?}" -ne 0 ]
then
_USAGE
fi
eval set -- "${_OPTS}"
while true ; do
case "${1}" in
--install)
_INSTALL
shift
;;
--update)
_UPDATE
shift
;;
--configure)
_CONFIGURE "${3}"
shift 2
;;
--help)
_USAGE
shift
;;
*) echo "getopt Internal error!" ; exit 1 ;;
esac
done
}
function cpDep
{
if [[ -f "${CHROOTPATH}/${1}" ]]
then
error "$1 already exist in chroot"
return 1
fi
if [[ ! -d "${CHROOTPATH}/$(dirname "${1}")" ]]
then
mkdir -p "${CHROOTPATH}/$(dirname "${1}")"
fi
cp "${1}" "${CHROOTPATH}/${1}"
# Linked libraries
for DEP in $(ldd "${1}" | grep '=>' |cut -d'>' -f2 | awk '{print $1}')
do
mkdir -p "${CHROOTPATH}/$(dirname "${DEP}")"
cp "${DEP}" "${CHROOTPATH}/${DEP}"
done
# And lib64
for DEP in $(ldd bin/bash |grep lib64 | awk '{print $1}')
do
if [[ ! -d "${CHROOTPATH}/$(dirname "${DEP}")" ]]
then
mkdir -p "${CHROOTPATH}/$(dirname "${DEP}")"
fi
cp "${DEP}" "${CHROOTPATH}/${DEP}"
done
}
function _TIMEZONE
{
info "Clone Timezone"
if [[ ! -d "${CHROOTPATH}/${ZONEINFO}" ]]
then
mkdir -p "${CHROOTPATH}${ZONEINFO}"
rsync -azP "${ZONEINFO}/Europe" "${CHROOTPATH}${ZONEINFO}"
rsync -azP "${ZONEINFO}/UTC" "${CHROOTPATH}${ZONEINFO}"
rsync -azP "${ZONEINFO}/Etc" "${CHROOTPATH}${ZONEINFO}"
else
warning "Timezone already exist"
fi
}
function _ETC
{
info "Copy /etc"
if [[ ! -d "${CHROOTPATH}/etc" ]]
then
mkdir "${CHROOTPATH}/etc"
for conf in {ld.so.cache,resolv.conf,nsswitch.conf,passwd,group,hosts,networks,protocols,services,localtime}
do
cp "/etc/${conf}" "${CHROOTPATH}/etc/"
done
fi
info "Create ssl"
mkdir -p "${CHROOTPATH}/etc/ssl"
cp -rf /etc/ssl/certs ${CHROOTPATH}/etc/ssl
}
function _DEV
{
info "Copy /dev"
if [[ ! -d "${CHROOTPATH}/dev" ]]
then
mkdir ${CHROOTPATH}/dev
mknod -m 666 "${CHROOTPATH}/dev/null" c 1 3
mknod -m 666 "${CHROOTPATH}/dev/zero" c 1 5
mknod -m 444 "${CHROOTPATH}/dev/random" c 1 8
mknod -m 444 "${CHROOTPATH}/dev/urandom" c 1 9
fi
}
function _LIB
{
for lib_name in {libnss,libnss_dns,libxml,libcurl,libsqlite3}
do
info "Copy ${lib_name}"
for lib in $(whereis ${lib_name})
do
if echo "${lib}" | grep -q "/usr/lib"
then
mkdir -p "${CHROOTPATH}/$(dirname ${lib})"
cp -f "${lib}" "${CHROOTPATH}/$(dirname ${lib})"
fi
done
done
for lib in $(ls /lib/x86_64-linux-gnu/*dns.* /lib/x86_64-linux-gnu/*dns-*)
do
info "Copy ${lib}"
mkdir -p "${CHROOTPATH}/$(dirname ${lib})"
cp -f "${lib}" "${CHROOTPATH}/$(dirname ${lib})"
done
}
function _BIN
{
for binary in {/bin/bash,/bin/ls,/usr/bin/dig}
do
info "Copy ${binary} and dependencies"
cpDep "${binary}"
done
}
function _INSTALL
{
_TIMEZONE
_ETC
_DEV
_LIB
_BIN
}
function _UPGRADE
{
_LIBNSS
_BIN
}
function _CONFIGURE
{
WEBCHROOT=${1}
info "Create /etc and /tmp"
mkdir -p "${WEBCHROOT}/etc"
mkdir -p "${WEBCHROOT}/tmp"
chmod 777 "${WEBCHROOT}/tmp"
info "Link system folder"
for chrooter in {dev,bin,lib/x86_64-linux-gnu,lib64,usr/bin,usr/lib/x86_64-linux-gnu/,usr/share/zoneinfo/Etc,usr/share/zoneinfo/Europe}
do
mkdir -p "${WEBCHROOT}/${chrooter}"
for binary in $(ls "${CHROOTPATH}/${chrooter}")
do
#info "hardlink ${chrooter}/${binary}"
ln "${CHROOTPATH}/${chrooter}/${binary}" "${WEBCHROOT}/${chrooter}/${binary}"
done
done
info "hardlink libnss"
ln "${CHROOTPATH}/usr/share/zoneinfo/UTC" "${WEBCHROOT}/usr/share/zoneinfo/UTC"
info "hardlink some config"
for chrooter in {ld.so.cache,localtime,networks,nsswitch.conf,protocols,resolv.conf,services}
do
info "hardlink ${chrooter}"
ln "${CHROOTPATH}/etc/${chrooter}" "${WEBCHROOT}/etc/${chrooter}"
done
info "Copy some configurations"
for chrooter in {group,hosts,passwd}
do
info "Copy ${chrooter}"
cp "${CHROOTPATH}/etc/${chrooter}" "${WEBCHROOT}/etc/${chrooter}"
done
info "Create certs path"
mkdir -p "${WEBCHROOT}/etc/ssl/certs"
info "Mount RO certs path"
mount --bind -o ro /etc/ssl/certs "${WEBCHROOT}/etc/ssl/certs"
info "Create session folder"
mkdir -p ${WEBCHROOT}/var/lib/php/sessions
info "Chmod 755 all var"
chmod 755 "${WEBCHROOT}/var/"
info "Add sticky bit"
chmod 1757 "${WEBCHROOT}/var/lib/php/sessions"
echo ${WEBCHROOT} >> ${LISTCHROOTFILE}
}
function _CLEAN
{
rm -f "${LOCK}"
}
if [[ ! -f "${LOCK}" ]]
then
trap _CLEAN EXIT
touch "${LOCK}"
_GET_OPTS "${@}"
_CLEAN
success "Account was successfull chrooted"
else
fatal "Lock already exist"
fi