Monday, December 22, 2008

How do I start chrooted httpd with Centos OR Redhat

Red Hat / CentOS: Chroot Apache 2 Web Server

by Vivek Gite [Last updated: December 22, 2008]

A chroot on Red Hat / CentOS / Fedora Linux operating changes the apparent disk root directory for the Apache process and its children. Once this is done attacker or other php / perl / python scripts cannot access or name files outside that directory. This is called a "chroot jail" for Apache. You should never ever run a web server without jail. There should be privilege separation between web server and rest of the system. In this quick tutorial, you will learn about securing an Apache 2 web server under Red Hat Enterprise Linux / CentOS Linux using mod_chroot.

Requirements

  1. Server: Apache 2 Web server
  2. Jail directory: /httpdjail
  3. User / Group: apache / apache (never ever run chroot using root user)
  4. Virtual domain directory for all domain inside jail: /home/httpd
  5. Instructions are tested under CentOS / RHEL 5.x

More about Jail directory: /httpdjail

Create a jail directory as follows:
# J=/httpdjail
# mkdir $J

  1. Do not create /dev directory
  2. Do not create special device files inside jail.
  3. Do not copy shell or any other executable files inside jail.
  4. if possible mount $J using a separate partition with nosuid, nodev and noexec options. This will improve security as user will not able to run suid enabled programs and device files inside a jail.

Install Apache, PHP and MySQL

Install required packages, enter:
# yum install mysql mysql-server httpd php-mysql php-par php-xml php-mysql php-cli php-imap php-gd php-pdo php-dv php-mbstring php-common php-ldap php httpd-devel

Now, create required directory inside a jail:
# mkdir -p $J/var/run
# chown -R root.root $J/var/run
# mkdir -p $J/home/httpd
# mkdir -p $J/var/www/html

Install mod_chroot

mod_chroot makes running Apache in a secure chroot environment easy. You don't need to create a special directory hierarchy containing /dev, /lib, /etc. mod_chroot allows you to run Apache in a chroot jail with no additional files. The chroot() system call is performed at the end of startup procedure - when all libraries are loaded and log files open. Download mod_chroot using wget command:
# cd /opt/
# wget http://core.segfault.pl/~hobbit/mod_chroot/dist/mod_chroot-0.5.tar.gz

Untar it:
# tar -zxvf mod_chroot-0.5.tar.gz
Compile and install mod_chroot for using apxs, enter:
# cd mod_chroot-0.5
# apxs -cia mod_chroot.c

Configure Apache mod_chroot

Open /etc/httpd/conf/httpd.conf file, type:
# C=/etc/httpd/conf/httpd.conf
# vi $C

Set PidFile path in which the server should record its process identification number when it starts. Find line that reads as follows:

PidFile run/httpd.pid

Replace with:

PidFile /var/run/httpd.pidM

Next add ChrootDir directive, enter:

ChrootDir /httpdjail

Find line that read as follows:

ServerRoot "/etc/httpd"

Append following lines:

LockFile /var/run/httpd.lock
CoreDumpDirectory /var/run
ScoreBoardFile /var/run/httpd.scoreboard

Make sure mod_chroot.so line exists. For example, 64 bit Linux should have line as follows:

LoadModule chroot_module      /usr/lib64/httpd/modules/mod_chroot.so

32 bit Linux config line:

LoadModule chroot_module      /usr/lib/httpd/modules/mod_chroot.so

Save and close the file.

Disable SELinux for Apache

You need to disable SELinux for apache, enter:
# setsebool httpd_disable_trans 1
See article "disable SELinux for only Apache / httpd in Linux" for further details.

Patch up /etc/init.d/httpd.conf

Open /etc/init.d/httpd.conf file, enter:
# vi /etc/init.d/httpd.conf
Find out 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=/httpdjail

Find stop() that read as follows:

stop() {
echo -n $"Stopping $prog: "
killproc -d 10 $httpd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

Replace it as follows (you need to link /var/run/httpd.pid to $J/var/run/httpd.pid; so that stop operation works):

stop() {
/bin/ln -s $ROOT/var/run/httpd.pid /var/run/httpd.pid
echo -n $"Stopping $prog: "
killproc -d 10 $httpd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

Save and close the file. Set immutable permission on /etc/init.d/httpd so that file cannot be modified, updated by yum, deleted or renamed, no link can be created to this file and no data can be written to the file. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute:
# chatter +i /etc/init.d/httpd.conf

How do I start chrooted httpd?

Type the following command:
# /etc/init.d/httpd start
You should not see any error in /var/log/httpd/error_log file:

[Sun Dec 21 18:43:09 2008] [notice] core dump file size limit raised to 18446744073709551615 bytes
[Sun Dec 21 18:43:09 2008] [notice] SELinux policy enabled; httpd running as context root:system_r:initrc_t
[Sun Dec 21 18:43:09 2008] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Sun Dec 21 18:43:09 2008] [notice] Digest: generating secret for digest authentication ...
[Sun Dec 21 18:43:09 2008] [notice] Digest: done
[Sun Dec 21 18:43:10 2008] [notice] mod_chroot: changed root to /httpdjail.
[Sun Dec 21 18:43:10 2008] [notice] Apache/2.2.3 (CentOS) configured -- resuming normal operations

How do I stop chrooted httpd?

# /etc/init.d/httpd stop

How do I restart chrooted httpd?

# /etc/init.d/httpd restart

No comments: