Minified Chroot for WordPress & Joomla with PHP FPM on Debian 9 Stretch

For months i was giving up on this project and used Debootstrap to get a 300Mb+ minbase version of debian, but…

…i finally got it working and here is the code for a chroot under 50Mb.

Colleagues argued that it was a waste of time since Mb’s are cheap but it makes a big difference on our backup server, and when a site gets compromised it’s nice to know that they have nowhere to hide ;)

#!/usr/bin/env bash

WWW="/var/www/xn--1ca.se"

##### Zone info
ZONEINFO="/usr/share/zoneinfo"
[[ ! -d "${WWW}/${ZONEINFO}" ]] && {
        mkdir -p ${WWW}${ZONEINFO}
        rsync -a ${ZONEINFO}/Europe ${WWW}${ZONEINFO}
        rsync -a ${ZONEINFO}/UTC ${WWW}${ZONEINFO}
}

##### /etc
[[ ! -d "${WWW}/etc" ]] && {
    mkdir ${WWW}/etc
    cp /etc/ld.so.cache /etc/resolv.conf /etc/nsswitch.conf /etc/passwd /etc/group /etc/hosts /etc/networks /etc/protocols /etc/services /etc/localtime ${WWW}/etc/
}

##### /dev
[[ ! -d "${WWW}/dev" ]] && {
    mkdir ${WWW}/dev
    mknod -m 666 ${WWW}/dev/null c 1 3
    mknod -m 666 ${WWW}/dev/zero c 1 5
    mknod -m 444 ${WWW}/dev/random c 1 8
    mknod -m 444 ${WWW}/dev/urandom c 1 9
}

##### Libs
libnss_dns=$(find /lib /usr/lib -name libnss_dns.so.2)
if [[ -n "$libnss_dns" ]]
    then [[ ! -f ${WWW}/${libnss_dns} ]] && cp $libnss_dns ${WWW}/$(dirname $libnss_dns)
    else echo "Error: Cant find important file libnss_dns.so.2 !!!"
fi

###### Copy commands and dependensies
cpDep () {
    [[ -f ${WWW}/${1} ]] && \
        echo "$1 already exist in chroot" && return 1 

    [[ ! -d ${WWW}/$(dirname $1) ]] && \
        mkdir -p ${WWW}/$(dirname $1)

    cp $1 ${WWW}/${1}

    # Linked libraries
    for DEP in $(ldd $1 | grep '=>' |cut -d'>' -f2 | awk '{print $1}') ; do
        [[ ! -d ${WWW}/$(dirname $DEP) ]] && \
            mkdir -p ${WWW}/$(dirname $DEP)
        cp $DEP ${WWW}/${DEP}
    done
    
    # And lib64
    for DEP in $(ldd bin/bash |grep lib64 | awk '{print $1}') ; do
        [[ ! -d ${WWW}/$(dirname $DEP) ]] && \
            mkdir -p ${WWW}/$(dirname $DEP)
        cp $DEP ${WWW}/${DEP}
    done


}

cpDep /bin/bash
cpDep /bin/ls
cpDep /usr/bin/dig

And in case it isn’t working, here is a debug script

Look for “File not found”

#!/usr/bin/env bash

[[ -z "$1" ]] && echo "Need domain as first argument..." && exit 1

declare DOMAIN=$1
declare ARGS

for pid in $(ps waux | grep "$DOMAIN" | grep 'php-fpm' | awk '{print $2}')
    do ARGS="$ARGS -p $pid"
done

if [[ -z "$ARGS" ]]
then echo "Could not find PHP-FPM process ids of $DOMAIN"
else echo "Dumping session to /tmp/strace.txt, reload webpage and then press CTRL+C"
    strace $ARGS &> /tmp/strace.txt
fi

Published by Nimpen J. Nordström

System Developer and Network Security Enthusiast

Leave a comment

Your email address will not be published. Required fields are marked *