Tag Archive for: chroot

LAMP Server Setup Pt. 4

11 May
May 11, 2010

Now that we have a secure Apache HTTP server installation, we need to setup PHP. I will use PHP 5.2.13 for this tutorial, not 5.3 as I’ve found that breaks a lot of web applications.

For this, I will be compiling in the Suhosin patch and extension, and enabling various database and other modules that come in handy when working with PHP. I’ve found that I need these to be able to use various software packages.

The first step is to go to PHP.net and get the url for the download. For PHP 5.2.13 that url is http://ca.php.net/distributions/php-5.2.13.tar.bz2

# Setup a work directory
mkdir /root/phptemp; cd /root/phptemp
wget http://ca.php.net/distributions/php-5.2.13.tar.bz2
tar -jxvf php-5.2.13.tar.bz2

#Now we need to grab the latest Suhosin and hardened PHP patches
wget http://download.suhosin.org/suhosin-patch-5.2.13-0.9.7.patch.gz
wget http://download.suhosin.org/suhosin-0.9.31.tgz
tar -xvzf suhosin-0.9.31.tgz
gunzip suhosin-patch-5.2.13-0.9.7.patch.gz

#Please note that I skipped the signature testing of the two files. This is optional but recommended that you do not skip
cd php-5.2.13
patch -p 1 -i ../suhosin-patch-5.2.13-0.9.7.patch

The next step involves configuring PHP. You may need to modify some of the paths or install some required software packages

# Configure PHP with common modules
./configure --with-apxs2=/opt/httpd/bin/apxs --prefix=/opt/php --exec-prefix=/opt/php  --with-config-file-path=/opt/php/etc --without-sqlite --with-mysql=/opt/mysql --with-mysqli=/opt/mysql/bin/mysql_config --with-zlib --with-bz2 --with-gd --with-curl --with-openssl --with-mcrypt --with-mhash --enable-mbstring --with-kerberos --with-imap-ssl -with-gettext --with-ttf --enable-exif --with-pear --enable-gd-native-ttf  --with-freetype-dir=/usr/include/freetype2/freetype --with-jpeg-dir=/usr/bin --with-png-dir=/usr/bin --enable-calendar --enable-sockets

# Compile
make

# make test may not work if you are upgrading and have disabled certain functions
make test

# Copy the binaries to their proper directories
make install
make clean

For 64 bit systems the configure code should be like this

./configure --with-apxs2=/usr/local/apache2/bin/apxs --without-sqlite --with-mysql --with-mysqli --with-zlib --with-bz2 --with-gd --with-curl --with-openssl --with-mcrypt --with-mhash --enable-mbstring --with-kerberos --with-imap-ssl --prefix=/usr --with-config-file-path=/etc -with-gettext --with-ttf --enable-exif --with-pear --enable-gd-native-ttf  --with-freetype-dir=/usr/include/freetype2/freetype --with-jpeg-dir=/usr/bin --with-png-dir=/usr/bin --enable-calendar --with-libdir=lib64

Ok, so now PHP is installed/upgraded and now we need to compile and install the Suhosin extension.

cd /root/phptemp;cd suhosin-0.9.31
phpize
./configure
make
make install
vi /etc/php.ini

Find the extensions section (Or just append to the bottom)

extension=suhosin.so

This is not a complete resource for install PHP and Suhosin. I really recommend you read about Suhosin on their website. It is best if you understand this really amazing product.

Now the Suhosin extension is installed, and enabled, but some of the other extensions may or may not of been enabled. Use the above syntax of extension=name.so to enable them, restarted Apache after each one to make sure everything works OK.

PHP can be dangerous if configured improperly, and very useful if configured properly. Here is some common options I use.

Disable some dangerous functions

disable_functions = "apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd, eval, exec, fp, fput, ftp_connect, ftp_exec, ftp_get,ftp_login, ftp_nb_fput,ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, mysql_pconnect, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode,phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid,posix_setuid, posix_setuid, posix_uname, shell_exec, syslog, system, xmlrpc_entity_decode,proc_close, proc_get_status, proc_nice, proc_open, proc_terminate"

I set all of my open_basedir options for each virtual host, but I also set a default option just in case. For my server, I have Apache setup using the webroot /chroot/www with a symlink /www pointing to /chroot/www. In my php.ini file, I set open_basedir = /www as a failsafe.

Load some useful extensions

extension=fileinfo.so
extension=imagick.so
extension=imap.so
extension=suhosin.so
extension=zip.so

LAMP Server Setup Pt. 1 – Installing Apache HTTP Server
LAMP Server Setup Pt. 2 – Installing Mod_Security
LAMP Server Setup Pt. 3 – Installing Mod_Chroot
LAMP Server Setup Pt. 4 – Installing PHP
LAMP Server Setup Pt. 5 – Configuring Apache

LAMP Server Setup Pt. 3

08 May
May 8, 2010

Configuring Apache HTTP Server to run in a chroot jail using mod_chroot is easier that doing it manually, but it still isn’t the simplest process in the world. As of Apache 2.2.10, Apache includes mod_chroot functionality, and to enable it, you only need to set ChrootDir /chroot/httpd and you’re done. Well not quite, you still need to create a chroot jail.

Using a Chrooted environment has several pros and cons.

  • If apache is ever compromised, the attacker will not have access to the entire file system.
  • Poorly written CGI scripts that may allow someone to access your server will not work.
  • There are extra libraries you’ll need to have in the chroot jail for Apache to work.
  • If you use any Perl/CGI features with Apache, you will need to copy the needed binaries, Perl libraries and files to the appropriate spot within the chroot space. The same applies for SSL, PHP, LDAP, PostgresSQL and other third-party programs.

Copy this file to /root/l2chroot.sh and chmod it to 700

#!/bin/bash
# Use this script to copy shared (libs) files to Apache/Lighttpd chrooted
# jail server.
# ----------------------------------------------------------------------------
# Written by nixCraft <http://www.cyberciti.biz/tips/>
# (c) 2006 nixCraft under GNU GPL v2.0+
# -------------------------------------------------------------------------------
# Set CHROOT directory name
BASE="/chroot/httpd"

if [ $# -eq 0 ]; then
  echo "Syntax : $0 /path/to/executable"
  echo "Example: $0 /usr/bin/php5-cgi"
  exit 1
fi

[ ! -d $BASE ] && mkdir -p $BASE || :

# iggy ld-linux* file as it is not shared one
FILES="$(ldd $1 | awk '{ print $3 }' |egrep -v ^'\(')"

echo "Copying shared files/libs to $BASE..."
for i in $FILES
do
  d="$(dirname $i)"
  [ ! -d $BASE$d ] && mkdir -p $BASE$d || :
  /bin/cp $i $BASE$d
done

# copy /lib/ld-linux* or /lib64/ld-linux* to $BASE/$sldlsubdir
# get ld-linux full file location
sldl="$(ldd $1 | grep 'ld-linux' | awk '{ print $1}')"
# now get sub-dir
sldlsubdir="$(dirname $sldl)"

if [ ! -f $BASE$sldl ];
then
  echo "Copying $sldl $BASE$sldlsubdir..."
  /bin/cp $sldl $BASE$sldlsubdir
else
  :
fi

This script takes a file as input and will copy the dependencies to our chroot jail

Now we create the chroot environment

J=/chroot/httpd
mkdir /chroot;mkdir $J
cd $J
mkdir -p $J/bin
mkdir -p $J/usr/sbin
mkdir -p $J/var/run
chown -R root.root $J/var/run
mkdir -p $J/tmp
chmod 1777 $J/tmp
mkdir -p $J/var/lib/php/session
chown root.apache $J/var/lib/php/session
mkdir $J/www
chown root:root $J/www


If you have SELinux you must disable it for apache

setsebool httpd_disable_trans 1

You need to edit the init script to reflect these changes (/etc/init.d/httpd)

Find the line that read as follows:

# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"}

Add following line (set ROOT to $J):

ROOT=/chroot/httpd

Now, make the init script immutable so only superuser can change it

chattr +i /etc/init.d/httpd

You need to make a symlink

/bin/ln -s $J/var/run/httpd.pid /var/run/httpd.pid

Configuring

And you need to modify the httpd.conf file (Which we don’t have yet, I include it for people using this as a standalone guide)

PidFile                                 /var/run/httpd2.pid
ChrootDir                               /chroot/httpd
LockFile                                /var/run/httpd.lock
CoreDumpDirectory                       /var/run
ScoreBoardFile                          /var/run/httpd.scoreboard

Fixing PHP mail()

Although PHP isn’t installed, we still need this

View my guide to fixing PHP mail functionality

You may want to wait until PHP is installed to do that.

LAMP Server Setup Pt. 1 – Installing Apache HTTP Server
LAMP Server Setup Pt. 2 – Installing Mod_Security
LAMP Server Setup Pt. 3 – Installing Mod_Chroot
LAMP Server Setup Pt. 4 – Installing PHP
LAMP Server Setup Pt. 5 – Configuring Apache

LAMP Server Setup Pt. 2

05 May
May 5, 2010

Mod_Security is a great module for Apache 2 which adds many new security features and fixes a number of exploits. It’s also quite easy to install.

Installation Requirements

  • ModSecurity 2.x works only with Apache 2.0.x or higher. Version 2.2.x is highly recommended
  • Make sure you have mod_unique_id installed
    mod_unique_id is packaged with Apache httpd
  • libapr and libapr-util
    http://apr.apache.org/
  • libpcre
    http://www.pcre.org/
  • libxml2
    http://xmlsoft.org/downloads.html
  • liblua v5.1.x
    This library is optional and only needed if you will be using the new Lua engine.
    http://www.lua.org/download.html

    Note that ModSecurity requires the dynamic libraries. These are not built by default in the source distribution, so the binary distribution is recommended
  • libcurl v7.15.1 or higher
    If you will be using the ModSecurity Log Collector (mlogc) to send audit logs to a central repository, then you will also need the curl library.
    http://curl.haxx.se/libcurl/
mkdir /root/modsec_tmp;cd /root/modsec_tmp
wget http://www.modsecurity.org/download/modsecurity-apache_2.5.12.tar.gz
tar -xvzf modsecurity-apache_2.5.12.tar.gz
cd modsecurity-apache_2.5.12.tar.gz/apache2
./configure --with-apxs=/opt/httpd/bin/apxs
make
make install

Mod_Security is now compiled as a module, but not enabled. To do that, we’ll have to add this to the Apache config file (Which we haven’t made yet).

# You may need to include these files first
LoadFile /usr/lib/libxml2.so
LoadFile /usr/lib/liblua5.1.so

# Load the module with
LoadModule security2_module modules/mod_security2.so

LAMP Server Setup Pt. 1 – Installing Apache HTTP Server
LAMP Server Setup Pt. 3 – Installing Mod_Chroot
LAMP Server Setup Pt. 4 – Installing PHP
LAMP Server Setup Pt. 5 – Configuring Apache

LAMP Server Setup Pt. 1

04 May
May 4, 2010

I’ve decided to write a “simple” guide to installing Apache with mod_security, mod_chroot and mod_ssl, PHP with suhosin and common addons, and MySQL. The common LAMP server with a few security modifications :)

This will be unique in that we are installing everything in the /opt directory, mainly to make updating/removing super easy. No trying to track down files, you just remove a directory. I’ve found this way works best.

This is the first part, the rest are coming in the next few days. Let me know if you are having any troubles.

# Download and extract the package
wget http://mirror.csclub.uwaterloo.ca/apache/httpd/httpd-2.2.15.tar.gz
tar -xvzf httpd-2.2.15.tar.gz
cd httpd-2.2.15

# Configure it with options
./configure --prefix=/opt/httpd --sysconfdir=/opt/httpd/etc --enable-ssl --enable-rewrite --enable-so

# Compile and Install it
make
make install

# Link to /etc
ln -s /opt/httpd/etc /etc/httpd2

Now for the explanation. The first command uses wget to fetch the httpd source code. You should go to the Apache website and make sure you are downloading the most recent version of their software (Excluding developmental releases) for security and performance reasons.

Next we extract the source using tar and change into the source directory

The next line is the interesting one. We configure it with any options that we want. I’ve chosen to install it into the /opt/httpd directory, although you can put it wherever you’d like. I’ve enabled SSL, mod_rewrite, and shared modules. This allows us to load dynamic modules without recompiling (Like mod_security and php). You can always run ./configure –help to see which options you can enable or disable. I HIGHLY recommend you do this so you can at least see what’s available. If you know what you are doing, there are lots of modules you do not need.

You then compile the source code and install it into the proper directories (Make & make install).

And I like creating a symlink in /etc/httpd2 to my configuration directory for ease of use.

Now we create an init script to run the web server. Copy this into /etc/init.d/httpd (I did not write this, I copied it from a distribution install on CentOS 5.4. I’ll probably make my own in the future.

#!/bin/bash
#
# httpd        Startup script for the Apache HTTP Server
#
# chkconfig: - 85 15
# description: Apache is a World Wide Web server.  It is used to serve \
#              HTML files and CGI.
# processname: httpd
# config: /etc/httpd/conf/httpd.conf
# config: /etc/sysconfig/httpd
# pidfile: /var/run/httpd.pid

# Source function library.
. /etc/rc.d/init.d/functions

#if [ -f /etc/sysconfig/httpd ]; then
#        . /etc/sysconfig/httpd
#fi

# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"}

# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""

# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
# with the thread-based "worker" MPM; BE WARNED that some modules may not
# work correctly with a thread-based MPM; notably PHP will refuse to start.

# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/opt/httpd/bin/apachectl
httpd=${HTTPD-/opt/httpd/bin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
RETVAL=0

# check for 1.3 configuration
check13 () {
        CONFFILE=/opt/httpd/etc/httpd.conf
        GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
        GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
        GONE="${GONE}AccessConfig|ResourceConfig)"
        if LANG=C grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then
            echo
            echo 1>&2 " Apache 1.3 configuration directives found"
            echo 1>&2 " please read /usr/share/doc/httpd-2.2.15/migration.html"
            failure "Apache 1.3 config directives test"
            echo
            exit 1
        fi
}

# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure.  So we just do it the way init scripts
# are expected to behave here.
start() {
        echo -n $"Starting $prog: "
        check13 || exit 1
        LANG=$HTTPD_LANG daemon $httpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}

# When stopping httpd a delay of >10 second is required before SIGKILLing the
# httpd parent; this gives enough time for the httpd parent to SIGKILL any
# errant children.
stop() {
        echo -n $"Stopping $prog: "
        killproc -d 10 $httpd
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
reload() {
    echo -n $"Reloading $prog: "
    if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
        RETVAL=$?
        echo $"not reloading due to configuration syntax error"
        failure $"not reloading $httpd due to configuration syntax error"
    else
        killproc $httpd -HUP
        RETVAL=$?
    fi
    echo
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status $httpd
        RETVAL=$?
        ;;
  restart)
        stop
        start
        ;;
  condrestart)
        if [ -f ${pidfile} ] ; then
            stop
            start
        fi
        ;;
  reload)
        reload
        ;;
  graceful|help|configtest|fullstatus)
        $apachectl $@
        RETVAL=$?
        ;;
  *)
        echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"
        exit 1
esac

exit $RETVAL

Now you could run /etc/init.d/httpd to start your server but we haven’t configured the server or installed any modules. Those are coming up next!

LAMP Server Setup Pt. 2 – Installing Mod_Security
LAMP Server Setup Pt. 3 – Installing Mod_Chroot
LAMP Server Setup Pt. 4 – Installing PHP
LAMP Server Setup Pt. 5 – Configuring Apache

Fixing PHP mail() when using mod_chroot

28 Apr
April 28, 2010

If you are using mod_chroot or Apache’s built in chroot functionality (With Apache HTTP Server 2.2.10 or greater), one of the first problems you’ll have is a non working mail() function. Although mail() isn’t the best option for PHP, a lot of applications use it, so here is how to fix it.

cp /bin/sh $J/bin
/root/l2chroot.sh $J/bin/sh
mkdir /root/mini_sendmail
cd /root/mini_sendmail

# Verify this is the latest version at (http://www.acme.com/software/mini_sendmail/)
wget http://www.acme.com/software/mini_sendmail/mini_sendmail-1.3.6.tar.gz
tar -xvzf mini_sendmail-1.3.6.tar.gz
cd mini_sendmail-1.3.6

Now you need to edit mini_sendmail.c, finding this line:

username = getlogin();

and replacing it with

username = "0";//getlogin();

If you don’t disable username autodetection, it won’t work

# Compile it now
make
cp mini_sendmail $J/usr/sbin/mini_sendmail

And now we edit php.ini to reflect this (/opt/php/etc/php.ini)

Find the below line:

;sendmail_path = sendmail -t -i

and replace it with

/usr/sbin/mini_sendmail -t -i

Restart Apache and you’ll have a working PHP mail() function using mini_sendmail. This isn’t the only way to fix the problem, and has a few problems like it won’t try to resend if there was an error, no spool, etc.