I have set up and used chroot-ed web trees
with the CERN httpd. There are various advantages and
disadvantages to chroot-ing a web tree. In the early days of the
'web'
this technique provided some valuable extra security. In this
Apache-dominated era there seems to be less need. However the
techique
is still interesting and relevant.
I provide example chroot-ed Linux and Solaris setups, with options to
do a standard compilation (which is marked
non-DSO where necessary), or a
Dynamic Shared Object (DSO) compilation (which is marked
DSO where necessary). The solaris example
with
DSO options is not yet documented, since I haven't tested it
(and
want to play with Solaris 8 as well when I do it :-)
It is relatively simple to set up a chroot-ed apache tree on Linux.
This
example uses Red Hat 6.* and Apache 1.3.12. This example
also
includes PHP 4 (as an apache module), and an installation of
perl 5 in the chrooted tree. Additionally mod_ssl
and mod_perl are installed.
This example assumes that
Red Hat was installed with a decent development environment (ie:
sufficient
include files, libraries and development tools). Note that you will
typically have a complete development environment if you installed the
Red Hat custom (preferred!) configuration and selected the
'development' option; or the server configuration.
MySQL 3.22.27 is not installed in the chroot-ed tree, but is
added
here for completeness.
Standard Disclaimer
I am not an expert (IANAE ? :-), especially for issues related to
encryption (openssl, mod_ssl and company). I am human and I make
mistakes.
Please let me know if you find any, or if you have any other
constructive
suggestions.
This how-to is provided in the hope that it will help you, and that
you
may learn something from it. I could always just provide an RPM, but
it
is far more interesting (I think) to know that you can construct a
modern
web server from scratch, yourself. But it is up to you to learn and
understand the issues, the problems and the risks of running a web
server
in today's internet!
The Solaris Example
The Solaris example for chroot-ing a web tree is very similar to the
Linux
case. Of course, if you don't have a current GNU development
environment
installed then it will be not be as easy as the Linux case.
The Solaris example is
documented here,
in a separate web document (but note that DSO options, mod_perl
and mod_ssl are not yet documented).
- To discover necessary shared libraries use the tool:
ldd
- In these examples the users have 'prompts' like the
following:
root user:
ROOT#
ordinary user:
$
- I nearly always compile and install software as an
'ordinary user' rather than as root. This helps me to avoid
accidentally stomping on the file system (especially with software
I am unfamiliar with). It also helps to alert me about makefiles
that
want to do dangerous things, like 'setuid' on installed binaries;
or install files in unusual places.
In these examples I compile and install as user
softs:softs
Just make sure that the software owner is NOT
the same user
as the apache tree user id (user id 888 in these examples).
- The default Red Hat root environment has the
interactive
switch '-i' set on the commands: 'cp', 'mv' and 'rm'. If your root
environment does not have this, then you are advised to
set
them. To check:
ROOT# alias |grep '\-i'
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'
- You should keep your configuration simple -- do not install
modules
that you will not use or do not need. A standard non-DSO apache
configuration with perl installed is adequate for many people...
- An important note about DSO
and mod_ssl:
If you plan to compile everything as DSO
modules and you will be building mod_ssl then you really
should
build your apache tree in the following order. mod_ssl
significantly modifies the apache build tree, and in my experience
with
the versions mentioned in this how-to it is easier to proceed in this
order:
- Build Apache
- Build and add mod_ssl to Apache
- Build and add php and/or mod_perl to Apache
- You should jot down somewhere how you compiled your tree, in
case
you have to redo it (print these pages out and annotate them).
- The final chroot-ed tree with everything weights in at about
23 MBytes, including
about 8 MB each for shared libraries and for perl. Following are
file size summaries in kilobytes for a DSO-based install:
ROOT# pwd
/www
ROOT# du -s .
22737 .
ROOT# du -s *
6832 apache
0 bin
1 dev
7 etc
6679 lib
1 tmp
9215 usr
1 webhome
ROOT# du -s apache/*
600 apache/bin
3 apache/cgi-bin
125 apache/conf
1560 apache/htdocs
133 apache/icons
392 apache/include
3925 apache/libexec
64 apache/man
29 apache/var
ROOT# du -s usr/*
8410 usr/Local
336 usr/bin
340 usr/lib
128 usr/share
You will need to pick up the source files for any packages you
intend
to integrate into your chroot-ed tree. Many of these source files
can be extracted from the corresponding linux distribution SOURCE
cdroms
as
SRPMs (RPM source packages) or tarball (.tar.gz) files.
(This is very handy if you have limited bandwidth).
For a Red Hat
system you install the source (as root):
ROOT# rpm -i /path/to/SRPMfile.src.rpm
and pick the source out of the
/usr/src/redhat/SOURCES/ directory.
But for these examples I indicate where to go to get the sources
on the internet (and the versions that were used for these
examples):
Package |
Version |
Source |
Documentation |
Apache |
1.3.12 |
|
|
MySQL |
3.22.27 |
|
www.mysql.com/documentation/ |
PHP |
4.0.2 |
|
|
Perl |
5.00503 |
|
|
mod_perl |
1.24 |
|
|
Hello.pm |
|
|
|
mod_ssl |
2.6.6-1.3.12 |
|
|
OpenSSL |
0.9.5a |
|
|
RSAref |
2.0 |
|
|
Prepare a Chroot-ed File System
-
Set up the tree anywhere (preferably another disk
or
a non-system partition to discourage others from making
hard links to files outside your web tree),
but use a symlink (eg /www) to reference it.
ROOT# mkdir /export/misc/www
ROOT# ln -s /export/misc/www /www
-
Create the basic directories; bin will
be a
link to usr/bin
!! NOTE the lack of leading slashes in this
example,
except where I copy files from the regular file system. Do NOT mix
up your
chroot-ed tree with your real '/'!
You have been
warned!
I have indicated the chroot-ed files in
magenta
ROOT# cd /www
ROOT# mkdir -p usr/bin usr/lib
lib
etc tmp dev webhome
ROOT# ln -s usr/bin bin
-
/tmp is given special perms.
ROOT# chmod 777 tmp
ROOT# chmod +t tmp
-
Make the special device /dev/null
ROOT# mknod -m 666 dev/null
c 1 3
-
Set up the timezone info for YOUR timezone
(this example uses MET):
ROOT# mkdir -p
usr/share/zoneinfo
ROOT# cp -pi /usr/share/zoneinfo/MET
usr/share/zoneinfo/
ROOT# cd etc
ROOT# ln -s
../usr/share/zoneinfo/MET localtime
ROOT# cd ..
-
You will find that perl and/or mod_perl will
complain
about the lack of locale settings. To fix this install
your
locale files in the chroot-ed tree:
ROOT# set |grep LANG
LANG=en_US
ROOT# mkdir /www/usr/share/locale
ROOT# cp -a /usr/share/locale/en_US
/www/usr/share/locale/
-
Now copy in the shared libraries that provide a
very
basic chroot-ed file system
ROOT# cp -pi /lib/libtermcap.so.2 /lib/ld-linux.so.2
/lib/libc.so.6 lib/
-
Test your tree ('cat' will be needed by
'apachectl'
later, but is not strictly necessary):
ROOT# cp -pi /bin/ls /bin/sh /bin/cat
bin/
ROOT# chroot /www /bin/ls -l /
lrwxrwxrwx 1 0 0 7 Jan 29 09:24 bin -> usr/bin
drwxr-xr-x 2 0 0 1024 Jan 29 09:28 dev
drwxr-xr-x 2 0 0 3072 Jan 29 13:17 etc
drwxr-xr-x 2 0 0 1024 Jan 29 13:12 lib
drwxrwxrwt 2 0 0 1024 Jan 29 09:23 tmp
drwxr-xr-x 5 0 0 1024 Jan 29 09:23 usr
drwxr-xr-x 2 0 0 1024 Jan 29 10:41 webhome
-
You can remove 'ls'; it was only used for
testing:
ROOT# rm bin/ls
Here we create the user whom apache will run as, and the necessary
naming
services for this configuration.
-
Create a new user that doesn't exist on the
system, and
give the user a unique name (eg: www) and user id
(eg:888). Note that it isn't actually necessary for the
user:group to exist in the real authentication (/etc/passwd
/etc/group)
files. It's up to you..
ROOT# cd /www
ROOT# touch etc/passwd
etc/group
etc/shadow
ROOT# chmod 400 etc/shadow
-
Edit these three files. For the sake of this
example I
am just echoing the data into the files:
ROOT# echo
'www:x:888:888:Web Account:/webhome:/usr/bin/False' >
etc/passwd
ROOT# echo 'www:x:888:' >
etc/group
ROOT# echo 'www:*:10882:-1:99999:-1:-1:-1:134537804'
>
etc/shadow
-
I have given this user no login, and no shell.
Just to
be complete, compile a 'no-go' shell called False:
ROOT# echo 'int main(int argc, char *argv[])
{ return(1); }' > /tmp/False.c
ROOT# cc -o /www/usr/bin/False
/tmp/False.c
-
While we are at it, lets mark the binaries as
execute-only:
ROOT# chmod 111 usr/bin/*
-
Some naming services will be required. With
glibc and
the Name Service Switch libraries the necessary libraries are not
immediately obvious. See 'man nsswitch' for details.
I chose to rely on files and DNS, even though I also run NIS on my
home
machines.
Note: The libresolv library
will
be needed as well (This will become evident when PHP is installed).
ROOT# cp -pi /lib/libnss_files.so.2
lib/
ROOT# cp -pi /lib/libnss_dns.so.2
lib/
-
We will need 3 files to complete the
configuration
for Naming Service. The contents of these files will depend on your
IP and DNS setup. Here we assume that the web server is named
ns.mynet.home with IP address 192.168.196.2
(it is actually also my naming server):
# ---- Contents of
etc/nsswitch.conf ----#
passwd: files
shadow: files
group: files
hosts: files dns
# ---- Contents of
etc/resolv.conf ----#
domain mynet.home
## use the IP address of your naming server
## if bind is not installed on your web server
#nameserver 192.168.196.xxx
## use this if your web server is a (caching) name server
nameserver 127.0.0.1
# ---- Contents of
etc/hosts ----#
127.0.0.1 localhost loopback
192.168.196.2 ns.mynet.home ns www
-
Make the top-level directory for the apache
install
(in this example: /apache); and create a symlink to it in
the
real tree:
ROOT# mkdir /www/apache
ROOT# ln -s /www/apache
/apache
-
I normally compile and install as an ordinary
user
(in this example: softs), rather than as 'root'. Note,
however,
that the installation of apache should be done as root. (See the
'security tips' in the online apache documentation)
In this case I compile sources in
/usr/local/src/chr, which is owned by softs:softs
$ cd /usr/local/src/chr
$ tar zxf /path/to/apache_1.3.12.tar.gz
$ cd apache_1.3.12
-
Edit config.layout so that it includes a
special layout called chroot
# chroot layout.
prefix: /apache
exec_prefix: $prefix
bindir: $exec_prefix/bin
sbindir: $exec_prefix/bin
libexecdir: $exec_prefix/libexec
mandir: $prefix/man
sysconfdir: $prefix/conf
datadir: $prefix
iconsdir: $datadir/icons
htdocsdir: $datadir/htdocs
cgidir: $datadir/cgi-bin
includedir: $prefix/include
localstatedir: $prefix/var
runtimedir: $localstatedir/logs
logfiledir: $localstatedir/logs
proxycachedir: $localstatedir/proxy
-
Now configure and make:
- non-DSO:
$ ./configure --with-layout=chroot \
--enable-module=most --enable-module=so
By enabling the module 'so' you have the
possibility of
extending your Apache installation later via 3rd-party modules
through the
DSO+APXS mechanism.
- DSO:
$ ./configure --with-layout=chroot \
--enable-module=most --enable-shared=max
$ make
ROOT# make install ## I am root!
-
Copy the other shared libraries that will be
needed by
Apache as configured in this example. NOTE that other
configurations
may require other libraries (use ldd to find out).
ROOT# cd /www
ROOT# cp -pi /lib/libm.so.6 /lib/libcrypt.so.1
/lib/libdb.so.3
lib/
ROOT# cp -pi /lib/libdl.so.2
lib/
-
Do a quick test to see that it worked. The main
fields
to edit in the configuration file
/www//apache/conf/httpd.conf
for a quick test are:
User www
Group www
ServerName yourserver.yourdomain.here
Port 8088 ## pick your favourite test port
Here are sample configuration files:
-
Start the daemon (you need to be root):
ROOT# chroot /www /apache/bin/apachectl start
-
Test the URL:
$ lynx -dump
Test the URL if on another port, eg: 8088:
$ lynx -dump
-
Here is a
that removes most of the comments from the generated config files,
for
those who want to simplify the file.
-
This would be a good time to give ownership of
the
htdocs tree to the web tree 'owner':
ROOT# chown -R 888:888
/www/apache/htdocs
MySQL is not installed in the chroot-ed tree; indeed, it should
probably
be installed on another system. But on my home system it is installed
on the
same server as apache.
This example includes creating the user and the place where
the database will reside, and the creation of the initial database.
-
Create the user who will own the mysql database
--
for example, 777:777 in /home/mysql:
ROOT# groupadd -g 777 mysqldba
ROOT# useradd -c "mysql DBA" -d /home/mysql
-u 777 -g 777 -m -n mysql
-
unpack the source and give ownership of the mysql
source
tree to the mysql user:
ROOT# mkdir /usr/local/mysql
ROOT# chown mysql:mysqldba /usr/local/mysql
ROOT# cd /usr/local/src
ROOT# tar zxf /path/to/mysql-3.22.27.tar.gz
ROOT# chown -R mysql:mysqldba
/usr/local/src/mysql-3.22.27
-
Now as the mysql user, make a directory for the
database, and compile and install mysql:
$ mkdir ~/db ## where the DB will reside
$ cd /usr/local/src/mysql-3.22.27
$ ./configure --localstatedir=/home/mysql/db
--prefix=/usr/local/mysql
$ make
$ make install
-
Create the *MySQL* grant tables (necessary only
if you
haven't installed *MySQL* before):
$ ./scripts/mysql_install_db
-
Install and modify the database startup script,
changing the database owner from root to 'mysql':
ROOT# cd /usr/local/src/mysql-3.22.27/
ROOT# cp support-files/mysql.server /etc/rc.d/init.d/
ROOT# chmod 755 /etc/rc.d/init.d/mysql.server
ROOT# [ edit /etc/rc.d/init.d/mysql.server: ]
mysql_daemon_user=mysql ## so we can run mysqld as this user.
ROOT# chkconfig --add mysql.server
## permanently add server to rc scripts
-
It may be necessary to refresh the shared library
cache
after installing mysql:
ROOT# /sbin/ldconfig -nv /usr/local/lib
-
Edit the PATH variable for the mysql owner, and
set up
the 'root' password for the database (read the documentation!)
(and you will probably want to delete the test database and
associated
entries):
$ [ Edit shell login script .bash_profile: ]
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
$ . ~/.bash_profile
## source it!
$ mysqladmin -u root password '2mUch!data'
## pick your own password!
-
Stop the apache daemon, if it is running:
ROOT# chroot /www /apache/bin/apachectl stop
-
You must first compile PHP, then for
non-DSO installs only you must recompile
Apache. (You will need to do this each time you upgrade either
software package for non-DSO installs.)
$ cd /usr/local/src/chr ## I am NOT root!
$ tar zxf /path/to/php-4.02.tar.gz
$ cd php-4.02
- non-DSO:
$ ./configure --with-mysql=/usr/local/mysql \
--with-apache=../apache_1.3.12 --enable-track-vars \
--with-config-file-path=/apache/conf --sharedstatedir=/tmp
- DSO:
$ ./configure --with-mysql=/usr/local/mysql \
--with-apxs=/apache/bin/apxs --enable-track-vars \
--with-config-file-path=/apache/conf --sharedstatedir=/tmp
- DSO:
(or add CFLAGS switch when mod_ssl was also
configured as a DSO module)
$ CFLAGS=-DEAPI ./configure
--with-mysql=/usr/local/mysql \
--with-apxs=/apache/bin/apxs --enable-track-vars \
--with-config-file-path=/apache/conf --sharedstatedir=/tmp
$ make
- non-DSO:
$ make install
- DSO:
ROOT# make install
(You will need to be root for the
DSO 'make install' of PHP, since the
module goes
directly into the module tree: /apache/libexec/ and
additionally
the apache configuration file is altered.)
-
Now for the non-DSO
installation only, recompile Apache, activating the PHP module:
$ cd ../apache_1.3.12/
$ ./configure --with-layout=chroot \
--enable-module=most --enable-module=so \
--activate-module=src/modules/php4/libphp4.a
$ make
ROOT# make install ## I am root!
-
More shared libraries (for PHP) are needed in the
chrooted tree; check with 'ldd':
- For non-DSO:
ldd /apache/bin/httpd
- For DSO:
ldd /apache/apache/libexec/libphp4.so
A little for-loop can be used to copy the needed files
from /lib and from /usr/lib:
ROOT# cd /www
ROOT# for i in libresolv.so.2 libnsl.so.1
libpam.so.0 ; do
> cp -pi /lib/$i /www/lib/ ; done
ROOT# for i in libgd.so.1 libgdbm.so.2 libz.so.1; do
> cp -pi /usr/lib/$i /www/usr/lib/ ;
done
-
If you will be needing mysql, you must install
that
library as well from the place it was compiled into:
ROOT#
cp -pi /usr/local/mysql/lib/mysql/libmysqlclient.so.6
/www/usr/lib/
-
You must edit httpd.conf so that it
recognizes .php files, if
you have not already done so:
ROOT# cd /apache/conf
ROOT# [ edit
/apache/conf/httpd.conf ]
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
-
Restart the daemon:
ROOT# chroot /www /apache/bin/apachectl start
-
For non-DSO installs
you can check for compiled-in PHP:
ROOT# chroot /www /apache/bin/httpd -l | grep php
mod_php4.c
-
Here is a
to test PHP. It should be installed as 'hello.php' (save as type
'text'
from netscape), with a copy or a
symlink as 'hello.phps' for source-code viewing if you wish. Do
not
leave it lying around for the public after you have finished
testing!
You can get away with simply copying
/usr/lib/perl5 into
/www/usr/lib/
; and copying
/usr/bin/perl5.00503 (assuming Red Hat
6.0)
into
/www/usr/bin/. You would
need
to check for, and install any missing shared libraries. You should
also
make a hard link from
usr/bin/perl5.00503
to
usr/bin/perl in
/www as well.
The easy way:
ROOT# cp -a /usr/lib/perl5
/www/usr/lib/perl
ROOT# cp -p /usr/bin/perl5.00503
/www/usr/bin/
ROOT# cd /www/usr/bin
ROOT# ln perl5.00503 perl
Nonetheless (the slightly less easy way :o), I show how to compile
and
install perl. If you are going to install mod_perl then you
really must compile perl here:
-
Make the nessary links to install into the
chroot-ed tree. This example uses /usr/Local inside the
tree. The choice of /usr/Local is deliberate -- do not
confuse it with /usr/local.
Ever fearful :-O, I installed as 'softs':
ROOT# mkdir /www/usr/Local
ROOT# ln -s /www/usr/Local
/usr/Local
ROOT# chown softs:softs
/www/usr/Local
-
Get the source RPM from the redhat sources:
ROOT# rpm -i /path/to/perl-5.00503-2.src.rpm
-
As the owner (softs) of the source tree, unpack
perl.
$ cd /usr/local/src/chr
$ tar zxf /usr/src/redhat/SOURCES/perl5.005_03.tar.gz
-
Red Hat supplies some patches in the SRPM. You
can
apply these patches for this distribution as well. This exemple
illustrates patching perl from a Red Hat 6.0 distribution.
$ cp /usr/src/redhat/SOURCES/perl*.patch .
$ cd perl5.005_03
$ patch -p1 <../perl5-installman.patch
$ patch -p1 <../perl5.005_02-buildsys.patch
$ patch -p1 <../perl5.005_03-db1.patch
-
You need to run Configure, accepting
most of the defaults from the script. You will also
probably
want to specify 'none' for the man pages. A few of the defaults to
change in my example are listed below:
$ ./Configure
- architecture name? i386-linux
- Installation prefix to use? /usr/Local
- Directories to use for library searches? /lib
/usr/lib /usr/Local/lib
- install perl as /usr/bin/perl? n
-
Compile and install it.
$ make
$ make test
$ make install
-
Create symlink to perl in the usr/bin tree.
If you are not installing mod_perl (see ahead), then you could
change
ownership of the perl tree to root (but not necessary as long as the
permissions on the perl tree are read-only for the web-tree
owner:
uid '888' in this example):
ROOT# cd /www/usr/bin
ROOT# ln -s ../Local/bin/perl
perl
-
Check the shared libraries and install any
missing
libraries (depends on your configuration options). No extra
libraries
are needed in this example:
ROOT# ldd
/www/usr/bin/perl
libnsl.so.1 => /lib/libnsl.so.1 (0x4001b000)
libdl.so.2 => /lib/libdl.so.2 (0x40031000)
libm.so.6 => /lib/libm.so.6 (0x40035000)
libc.so.6 => /lib/libc.so.6 (0x40052000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x40147000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
-
Test your installation:
ROOT# chroot /www /usr/bin/perl -v
This is perl, version 5.005_03 built for i386-linux
...
-
Set up the example perl cgi bin script installed
with the apache server:
ROOT# cd /www/apache/cgi-bin
ROOT# chmod ugo+x *
-
Start your apache server, and test the example
perl cgi bin script installed with the server:
ROOT# chroot /www /apache/bin/apachectl start
$ lynx -dump cgi-bin/printenv
While you are at it, check test-cgi for
shell CGI access as well:
$ lynx -dump cgi-bin/test-cgi
-
Finally, REMOVE the execute bit from the example
cgi-scripts, or remove them entirely. Don't let the general public
have access to these scripts:
ROOT# chmod ugo-x
/www/apache/cgi-bin/*
-
This process assumes that your chroot-ed perl
tree
is owned by your source-code owner. It this is not the case then
change ownership:
ROOT# chown -R softs:softs
/www/usr/Local
-
Extract the source code for mod_perl:
$ cd /usr/local/src/chr
$ tar zxf /path/to/mod_perl-1.24.tar.gz
$ cd mod_perl-1.24
-
IMPORTANT: Put /usr/Local/bin first
in the path before starting configuration. This helps to avoid
problems with the configuration finding /usr/bin/perl or
/usr/local/bin/perl first in your environment:
$ which perl
/usr/bin/perl
$ export PATH=/usr/Local/bin:$PATH
## assuming a bourne shell
$ which perl
/usr/Local/bin/perl
-
Now configure mod_perl; configure the Perl-side of
mod_perl, and prepare the mod_perl subdirectory inside apache:
- non-DSO:
$ perl Makefile.PL APACHE_SRC=../apache_1.3.12/src \
DO_HTTPD=1 USE_APACI=1 PREP_HTTPD=1 EVERYTHING=1
- DSO:
$ perl Makefile.PL USE_APXS=/apache/bin/apxs \
EVERYTHING=1
- DSO:
( or add the CFLAGS switch when mod_ssl was also
configured as a DSO module [and respect any message about
apache include files being in unusal places!] )
$ CFLAGS=-DEAPI perl Makefile.PL
USE_APXS=/apache/bin/apxs \
EVERYTHING=1
-
Now make and install mod_perl into the chroot-ed
tree:
$ pwd
/usr/local/src/chr/mod_perl-1.24
$ make
- non-DSO:
$ make install
- DSO:
ROOT# make install
(You will need to be root for the
DSO 'make install' of mod_perl, since the
module goes directly into the module tree: /apache/libexec/
and additionally the apache configuration file is altered.)
-
For the non-DSO
installs
only you must recompile apache and reinstall it:
$ cd /usr/local/src/chr/apache_1.3.12/
$ ./configure --with-layout=chroot \
--enable-module=most --enable-module=so \
--activate-module=src/modules/php4/libphp4.a \
--activate-module=src/modules/perl/libperl.a
$ make
Stop apache if it was
previously running, and install it:
ROOT# chroot /www /apache/bin/apachectl stop
ROOT# make install ## I am root!
-
For non-DSO installs
you can check for compiled-in PHP and mod_perl:
ROOT# chroot /www /apache/bin/httpd -l |
grep -E '(php|perl)'
mod_php4.c
mod_perl.c
-
Test your mod_perl setup with the
.
perl module written by Doug MacEachern. You need to install
it, edit httpd.conf and restart apache:
$ cp -i Hello.pm \
/www/usr/Local/lib/perl5/site_perl/5.005/i386-linux/Apache/
Insert the mod_perl configuration necessary for
Hello.pm into httpd.conf -- example:
SetHandler perl-script
PerlHandler Apache::Hello
### Section 3: Virtual Hosts
ROOT# chroot /www /apache/bin/apachectl restart
$ lynx -dump
Hello, I see you see me with Lynx/2.8.3dev.18 libwww-FM/2.14.
-
If you are finished testing then comment out
this entry in httpd.conf.
Don't leave unnecessary functionality enabled in your apache
configuration.
-
NOTE: If you need to install other perl modules,
you
must put /usr/Local/bin first in your path before running
perl Makefile.PL:
$ export PATH=/usr/Local/bin:$PATH
## assuming a bourne shell
I hope you have read the if you are planning a DSO install of
mod_ssl.
You must compile both openSSL and
mod_ssl. I have also elected
to compile rsaref version 2.0. You should read the
documentation
for mod_ssl
in the to understand
the issues and the options for mod_ssl.
Note that openssl and rsaref provide the
include files,
libraries and tools to allow you to compile mod_ssl and
generate
keys, and therefore they are not part of, nor installed into, the
chroot-ed
tree.
-
Extract the source code for mod_ssl, openssl and
rsaref20:
$ cd /usr/local/src/chr
$ tar zxf /path/to/mod_ssl-2.6.6-1.3.12.tar.gz
$ tar zxf /path/to/openssl-0.9.5a.tar.gz
$ mkdir rsaref-2.0
$ cd rsaref-2.0
$ tar Zxf /path/to/rsaref20.1996.tar.Z
-
Configure and build the RSA Reference library.
Note
that on 64-bit architectures you MUST
read the
documentation in the INSTALL file in the mod_ssl
package
about portability problems/solutions with rsaref.
$ cd /usr/local/src/chr/rsaref-2.0
$ cp -rpi install/unix local
$ cd local
$ make
$ mv rsaref.a librsaref.a
-
Configure and build the OpenSSL library.
$ cd /usr/local/src/chr/openssl-0.9.5a
$ ./config -L/usr/local/src/chr/rsaref-2.0/local
-fPIC
$ make
$ make test
# inspect output for anomolies
- You may want to install the package. Of
course,
it is not installed in the chroot-ed tree. Here I assume that
softs:softs owns the /usr/local/ tree, because the default
install prefix for openssl is /usr/local/ssl. However, it
is not
necessary to install this package; you can operate out of the src
tree
for building mod_ssl (but do NOT run make clean!)
$ make install
-
Configure mod_ssl:
$ cd /usr/local/src/chr/mod_ssl-2.6.6-1.3.12
$ ./configure --with-apache=../apache_1.3.12
-
Go into the apache tree to complete the build.
Run
configure and then make:
$ cd /usr/local/src/chr/apache_1.3.12
- non-DSO:
$ SSL_BASE=../openssl-0.9.5a
RSA_BASE=../rsaref-2.0/local \
./configure --prefix=/apache --with-layout=chroot \
--enable-module=most --enable-module=so --enable-module=ssl \
--disable-rule=SSL_COMPAT --enable-rule=SSL_SDBM \
--activate-module=src/modules/php4/libphp4.a \
--activate-module=src/modules/perl/libperl.a
- DSO:
$ cd src/modules
$ make clean ## seems to be necessary if you
previously compiled in the apache tree
$ cd ../../
$ SSL_BASE=../openssl-0.9.5a
RSA_BASE=../rsaref-2.0/local \
./configure --prefix=/apache --with-layout=chroot \
--enable-module=most --enable-shared=max --enable-shared=ssl \
--disable-rule=SSL_COMPAT --enable-rule=SSL_SDBM
$ make
-
Install apache again. Stop apache if it was
previously running, and then install it:
ROOT# chroot /www /apache/bin/apachectl stop
ROOT# make install ## I am root!
-
For non-DSO installs
you can check for the compiled-in modules:
ROOT# chroot /www /apache/bin/httpd -l |
grep -E '(php|perl|ssl)'
mod_ssl.c
mod_php4.c
mod_perl.c
-
Create the random devices in the chroot-ed tree:
ROOT# cd /www/dev
ROOT# mknod random
c 1 8
ROOT# mknod urandom
c 1 9
-
Merge the default configuration file into your
current
httpd.conf file. I test on a different port from the
standard
port 80 because I usually already have a web server
running on
port 80. But for the secure port (port 443) I have no web server
running, so I use it immediately.
For the default configuration file
the main fields to change for this example follow (and
):
- User www
- Group www
- ServerName yourserver.yourdomain.here
- Port 8088 ## pick a test port
- Listen 8088 ## in 'IfDefine SSL'
section
- Listen 443
## this is the standard secure port!
- _default_:443>
-
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
- # your Hello.pm script for mod_perl testing:
SetHandler perl-script
PerlHandler Apache::Hello
- SSLCertificateFile /apache/conf/server.crt
- SSLCertificateKeyFile /apache/conf/server.key
# in this example I generate the key and crt files into
/apache/conf
-
If you do not already have a server key and
certificate
then create them. In this example I assume that openssl
is in
your path because you have installed it. If not, then you should
add
it to your path (according to this example it is in
/usr/local/src/chr/openssl-0.9.5a/apps).
Note also that I am certifying my own key. Presumably
you will get a Certifying Authority to sign your key if you are
doing any
serious work with your web tree (eg: commericial work):
- ROOT# cd
/www/apache/conf
- # set up a path of random files:
ROOT#
randfiles='/var/log/messages:/proc/net/unix:/proc/stat:/proc/ksyms'
- # generate the server key
ROOT#
openssl genrsa -rand $randfiles -out server.key 1024
- # generate the
(don't add a password when certifying it yourself).
Note that it is important that the Common Name match your
fully-qualified web server name!
ROOT#
openssl req -new -nodes -out request.pem -key server.key
- # sign your own key (validity for one year in this
example):
ROOT#
openssl x509 -in request.pem -out server.crt -req \
-signkey server.key -days 365
- Protect your key and certificate:
ROOT# chmod 400 server.*
- Delete the request file:
ROOT# rm request.pem
- Optionally encrypt your key (you will have to provide the
password
each time your start apache, but you may have a very good reason for
doing this!):
ROOT# mv server.key server.key.unencrypted
ROOT# openssl rsa -des3 -in server.key.unencrypted
-out server.key
ROOT# chmod 000 server.key.unencrypted ## better yet
delete it!
- Oops, you changed your mind. You decide to remove the
encryption
password from your key:
ROOT# openssl rsa -in server.key -out server.key.un
ROOT# mv server.key.un server.key
ROOT# chmod 400 server.key
-
Start apache first without ssl to make
sure
it still works:
ROOT# chroot /www /apache/bin/apachectl start
$ lynx -dump
-
Re-start apache with ssl and test it with
netscape (note that the URL is specified as https):
ROOT# chroot /www /apache/bin/apachectl stop
ROOT# chroot /www /apache/bin/apachectl startssl
$ netscape
-
At this point you probably want to edit your web
server
configuration and set the server on the standard ports 80 and 443 if
your test configuration did not use these ports.
-
See the
'security tips' in the online apache documentation for some help
in
this area. One extra precaution to take is to change the
permissions on
the httpd scripts and binaries:
ROOT# chmod ugo-rw
/www/apache/bin/*
-
You should be very careful when you set about deliberately escaping
from your chroot-ed environment -- you need to assess the risks and
benefits. In the UNIX world there is always more than one way to
accomplish a task, and you should think about other ways of solving
your
problem.
Never the less, I provide an example C-utility that implements a
customised remote-shell command to email a file generated by forms
output
to someone. It might be invoked via a cgi-bin script, or via PHP.
Example:
...
/** construct the file name as $f **/
$cmd = "/bin/mail \"-s Some-subject-line -t webmaster@localhost -f $f\"";
$op = exec( $cmd, $arr, $retval );
...
?>
The file is called wwwmail.c and it
Almost anything can be done this way if you code-up your own small
utility. I have written a similar utility to exec sqlplus macros for
example. But these sorts of utilities are risky, and need to be
carefully evaluated.
For this particular problem (emailing forms-output to someone) you
might
be better off putting files to be mailed in a directory and having a
cron
job pass through every few minutes and process them...
-
Remove temporary links needed for installation of
apache and perl ( remember to put them back if you need to rebuild
or upgrade any package ):
ROOT# rm /apache /usr/Local
-
Automate the startup of Apache by installing a
startup script called httpd in /etc/rc.d/init.d/
Here are two examples:
Then run chkconfig on it to set the runlevel symbolic
links (and verify it with '--list'):
ROOT# chkconfig --add httpd
ROOT# chkconfig --list httpd
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
-
Automate log file trimming. On a Red Hat system
you can specify which log files and which parameters to use in
/etc/logrotate.conf. Here is an
I haven't had time to totally document this, but you can use the RPM
contents from RPMs and create a chroot-ed web tree without
compiling the sources. To this end, I have these scripts. I will
document
this technique more completely later...
-
-
- that will
harvest the RPMs (RPMs are NOT installed on system with this
version!)
- to be placed
in /etc/init.d/ and enabled with
ROOT# chkconfig --add httpd
- called
from /etc/init.d/httpd that does the actual chroot -
modified slightly
by adding path to chroot tree. It also adds the mysql libraries to
the
library path.
Last modified: Wed Jan 5 11:59:32 PST 2005
阅读(892) | 评论(0) | 转发(0) |