Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1216144
  • 博文数量: 275
  • 博客积分: 6445
  • 博客等级: 准将
  • 技术积分: 2863
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-04 23:22
文章分类

全部博文(275)

文章存档

2024年(4)

2023年(5)

2022年(3)

2021年(18)

2020年(9)

2019年(1)

2018年(13)

2017年(11)

2015年(9)

2013年(2)

2012年(4)

2011年(24)

2010年(114)

2009年(6)

2008年(29)

2007年(13)

2006年(10)

我的朋友

分类: 系统运维

2010-07-13 21:16:01



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:
    1. Build Apache
    2. Build and add mod_ssl to Apache
    3. 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

  1. 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

  2. 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

  3. /tmp is given special perms.
    ROOT# chmod 777 tmp
    ROOT# chmod +t tmp

  4. Make the special device /dev/null
    ROOT# mknod -m 666 dev/null c 1 3

  5. 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 ..

  6. 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/

  7. 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/

  8. 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
  9. 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.
  1. 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

  2. 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

  3. 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

  4. While we are at it, lets mark the binaries as execute-only:
    ROOT# chmod 111 usr/bin/*

  5. 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/

  6. 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

  1. 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

  2. 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

  3. 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

  4. 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!

  5. 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/

  6. 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:
    non-DSO:
    DSO:

  7. Start the daemon (you need to be root):
    ROOT# chroot /www /apache/bin/apachectl start

  8. Test the URL:
    $ lynx -dump
    Test the URL if on another port, eg: 8088:
    $ lynx -dump

  9. Here is a that removes most of the comments from the generated config files, for those who want to simplify the file.

  10. 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.

  1. 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

  2. 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

  3. 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

  4. Create the *MySQL* grant tables (necessary only if you haven't installed *MySQL* before):
    $ ./scripts/mysql_install_db

  5. 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

  6. It may be necessary to refresh the shared library cache after installing mysql:
    ROOT# /sbin/ldconfig -nv /usr/local/lib

  7. 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!

  1. Stop the apache daemon, if it is running:
    ROOT# chroot /www /apache/bin/apachectl stop

  2. 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.)

  3. 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!

  4. 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


  5. 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/

  6. 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


  7. Restart the daemon:
    ROOT# chroot /www /apache/bin/apachectl start

  8. For non-DSO installs you can check for compiled-in PHP:
    ROOT# chroot /www /apache/bin/httpd -l | grep php
    mod_php4.c

  9. 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:

  1. 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

  2. Get the source RPM from the redhat sources:
    ROOT# rpm -i /path/to/perl-5.00503-2.src.rpm

  3. 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

  4. 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

  5. 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

  6. Compile and install it.
    $ make
    $ make test
    $ make install

  7. 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

  8. 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)
  9. Test your installation:
    ROOT# chroot /www /usr/bin/perl -v

    This is perl, version 5.005_03 built for i386-linux
    ...
  10. Set up the example perl cgi bin script installed with the apache server:
    ROOT# cd /www/apache/cgi-bin
    ROOT# chmod ugo+x *

  11. 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

  12. 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/*

  1. 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

  2. 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

  3. 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


  4. 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


  5. 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.)

  6. 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!

  7. 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


  8. 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.
  9. If you are finished testing then comment out this entry in httpd.conf. Don't leave unnecessary functionality enabled in your apache configuration.

  10. 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.

  1. 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

  2. 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

  3. 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

  4. 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

  5. Configure mod_ssl:
    $ cd /usr/local/src/chr/mod_ssl-2.6.6-1.3.12
    $ ./configure --with-apache=../apache_1.3.12

  6. 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

  7. 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!

  8. 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


  9. 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

  10. 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

  11. 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

  12. Start apache first without ssl to make sure it still works:
    ROOT# chroot /www /apache/bin/apachectl start
    $ lynx -dump

  13. 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

  14. 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.

* Some Security Considerations

  1. 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/*

  1. 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...

  1. 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

  2. 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
  3. 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...
  1. that will harvest the RPMs (RPMs are NOT installed on system with this version!)
  2. to be placed in /etc/init.d/ and enabled with
      ROOT# chkconfig --add httpd
  3. 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
阅读(884) | 评论(0) | 转发(0) |
0

上一篇:解密

下一篇:测试机房质量之Ping值测试

给主人留下些什么吧!~~