Skip to content

Instantly share code, notes, and snippets.

@AitorATuin
Last active October 1, 2015 19:25
Show Gist options
  • Save AitorATuin/9726836 to your computer and use it in GitHub Desktop.
Save AitorATuin/9726836 to your computer and use it in GitHub Desktop.
Little script based on ArchWiki [https://wiki.archlinux.org/index.php/nginx#Installation_in_a_chroot] that aims to create a chroot environment for nginx
#!/bin/sh
function usage() {
echo -e "Little script to create a chroot environment for nginx installations (under archlinux)."
echo -e "\t ATuin"
echo -e "\t GNU GPL 3.0 . No warranties at all. Use at your own risk."
echo -e
echo -e "" echo usage: $0 [directory]
echo -e "\n\t\t --help :: show detailed help on how to setup the chroot environment"
exit 1;
}
function help() {
JAIL=$1
echo -e ""
echo -e ""
echo -e "After you have created the chroot environment successful you must be aware of the following:"
echo -e "\t- You need to have mounted both tpmfs fs under CHROOT/run and CHROOT/tmp"
echo -e "\t You can mount manually with the following commands:"
echo -e "\t\t # mount -t tmpfs none $JAIL/run -o 'noexec,size=1M'"
echo -e "\t\t # mount -t tmpfs none $JAIL/tmp -o 'noexec,size=100M'"
echo -e "\t NOTE: It's important to set the size to avoid DOS attacks due to not available memory!!!"
echo -e "\t You may want to add the following lines into /etc/fstab so every time the machine reboots those directories are mount for you."
echo -e "\nFILE: /etc/fstab"
echo -e "------------------\n"
echo -e "tmpfs /srv/http/run tmpfs rw,noexec,relatime,size=1024k 0 0"
echo -e "tmpfs /srv/http/tmp tmpfs rw,noexec,relatime,size=102400k 0 0"
echo -e
echo -e "EOF\n"
echo -e "\t- You need to configure nginx in order to run under the chroot environment. You need to cretate this file /etc/systemd/system/nginx.service"
echo -e "\nFILE: /etc/systemd/system/nginx.service"
echo -e "---------------------------------------"
echo -e "
[Unit]
Description=A high performance web server and a reverse proxy server
After=syslog.target network.target
[Service]
Type=forking
PIDFile=$JAIL/run/nginx.pid
ExecStartPre=/usr/bin/chroot --userspec=http:http $JAIL /usr/bin/nginx -t -q -g 'pid /run/nginx.pid; daemon on; master_process on;'
ExecStart=/usr/bin/chroot --userspec=http:http $JAIL /usr/bin/nginx -g 'pid /run/nginx.pid; daemon on; master_process on;'
ExecReload=/usr/bin/chroot --userspec=http:http $JAIL /usr/bin/nginx -g 'pid /run/nginx.pid; daemon on; master_process on;' -s reload
ExecStop=/usr/bin/chroot --userspec=http:http $JAIL /usr/bin/nginx -g 'pid /run/nginx.pid;' -s quit
[Install]
WantedBy=multi-user.target
EOF
"
echo -e ""
echo -e "Now you can remove yout unchrooted nginx installation if you want, if you dediced to keep it be sure that when you run nginx is the chrooted the one that is executed:"
echo -e "You should be able to see the chroot environment under /prod/{PID}/root"
echo -e ""
echo -e "For the moment, this script cant manage actualizations in your nginx distribution, its in the TODO list."
echo -e ""
echo -e "This script is based in the guide on the ArchLinux Wiki [https://wiki.archlinux.org/index.php/nginx#Installation_in_a_chroot]"
}
function create_dev() {
DEV=$1
$MKDIR -p $DEV
$MKNOD -m 0666 $DEV/null c 1 3
$MKNOD -m 0666 $DEV/random c 1 8
$MKNOD -m 0444 $DEV/urandom c 1 9
}
function copy_libraries {
JAIL=$1
ldlib=$(ldd /usr/bin/nginx|grep ld-linux|sed -s 's/(.\+)//g')
[ -f $ldlib ] && {
echo "[$JAIL/lib] * Copying $ldlib $JAIL/lib"
$CP $ldlib $JAIL/lib
} || {
echo "[$JAIL/lib][ERROR] Cant found ld-linux library!"
}
for lib in $(ldd /usr/bin/nginx | grep /usr/lib | sed -sre 's/(.+)(\/usr\/lib\/\S+).+/\2/g'); do
echo "[$JAIL/usr/lib] * Copying $lib to $JAIL/usr/lib"
$CP $lib $JAIL/usr/lib
done
echo "[$JAIL/usr/lib] * Copying $JAIL/usr/lib/libnss_*"
$CP /usr/lib/libnss_* $JAIL/usr/lib
}
function copy_config_files {
JAIL=$1
DIRS="services localtime nsswitch.conf nscd.conf protocols hosts ld.so.cache ld.so.conf resolv.conf host.conf nginx"
for dir in `echo $DIRS`; do
echo "[$JAIL/etc/$dir] * Copying from /etc/$dir to $JAIL/etc/$dir"
$CP -rfvL /etc/$dir $JAIL/etc/
done
$TOUCH $JAIL/etc/shells
$TOUCH $JAIL/run/nginx.pid
}
function fix_permissions {
JAIL=$1
echo "[$JAIL] * Setting permissions."
$CHOWN -R root:root $JAIL/
$CHOWN -R http:http $JAIL/www
$CHOWN -R http:http $JAIL/etc/nginx
$CHOWN -R http:http $JAIL/var/{log,lib}/nginx
$CHOWN http:http $JAIL/run/nginx.pid
$FIND $JAIL/ -gid 0 -uid 0 -type d -print | xargs $CHMOD -rw
$FIND $JAIL/ -gid 0 -uid 0 -type d -print | xargs $CHMOD +x
$FIND $JAIL/etc -gid 0 -uid 0 -type f -print | xargs $CHMOD -x
$FIND $JAIL/usr/bin -type f -print | xargs $CHMOD ug+rx
$FIND $JAIL/ -group http -user http -print | xargs $CHMOD o-rwx
$CHMOD +rw $JAIL/tmp
$CHMOD +rw $JAIL/run
$SETCAP 'cap_net_bind_service=+ep' $JAIL/usr/bin/nginx
}
function create_directories {
JAIL=$1
DIRS="etc/nginx/logs usr/lib/ usr/bin usr/share/nginx var/log/nginx var/lib/nginx www/cgi-bin run tmp dev"
for dir in `echo $DIRS`; do
echo "[$JAIL/$dir] * Creating $JAIL/$dir"
$MKDIR -p $JAIL/$dir
done
CWD=`pwd`
cd $JAIL
$LN -s usr/lib lib
$LN -s usr/lib lib64
cd $CWD
}
function populate_directories {
JAIL=$1
DIRS="/usr/share/nginx::usr/share/nginx /usr/share/nginx/html::www /usr/bin/nginx::usr/bin /var/lib/nginx::var/lib/nginx"
for dir in `echo $DIRS`; do
orig=${dir%%::*}
dest=${dir##*::}
echo "[$JAIL/$dest] * Populating $JAIL/$dest from $orig"
$CP -r $orig $JAIL/$dest
done
}
function create_groups_and_users {
JAIL=$1
USERFILE=$JAIL/etc/passwd
SHADOWFILE=$JAIL/etc/shadow
GSHADOWFILE=$JAIL/etc/gshadow
GROUPSFILE=$JAIL/etc/group
echo "[$USERFILE] * Creating users [httpd | nobody]"
$CAT > $USERFILE <<EOF
http:x:33:33:http:/:/bin/false
nobody:x:99:99:nobody:/:/bin/false
EOF
$CAT > $SHADOWFILE <<EOF
http:x:14871::::::
nobody:x:14871::::::
EOF
$CAT > $GSHADOWFILE <<EOF
http:::
nobody:::
EOF
$CAT > $GROUPSFILE <<EOF
http:x:33:
nobody:x:99:
EOF
}
function create_chroot() {
JAIL=$1
echo "[$JAIL] * Creating chroot into $JAIL"
echo "[$JAIL] * Creating required directories"
create_directories $JAIL
echo "[$JAIL/dev] * Populating dev"
create_dev $JAIL/dev
echo "[$JAIL] * Populating other directories"
populate_directories $JAIL
echo "[$JAIL] * Copying required libraries"
copy_libraries $JAIL
echo "[$JAIL/etc] * Copying required config files"
copy_config_files $JAIL
echo "[$JAIL/etc] * Creating users and groups"
create_groups_and_users $JAIL
echo "[$JAIL] * Fixing permisions"
fix_permissions $JAIL
}
DEFAULT_JAIL=/srv/http
MKNOD=`which mknod`
MKDIR=`which mkdir`
CHMOD=`which chmod`
TOUCH=`which touch`
FIND=`which find`
CHOWN=`which chown`
SETCAP=`which setcap`
CP=`which cp`
CAT=`which cat`
LN=`which ln`
[ "$1" == "--help" ] && {
help $DEFAULT_JAIL
exit 0
}
[ ! -z $1 ] && {
[ -d $1 ] && {
# Custom directory
create_chroot $1
echo "CHROOT CREATED SUCCESSFULLY"
help $1
exit 0
} || {
usage
}
} || {
# Default directory
create_chroot $DEFAULT_JAIL
echo "CHROOT CREATED SUCCESFULLY"
help $DEFAULT_JAIL
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment