Apache 2.0.59 with SSL, PHP 5.2.1, MySQL 5.0.33 on openSuSE linux 10.x

This article describes the installation of a Apache2 server with PHP5 and MySQL5 support on a SuSE Linux 10.0 Server.

Normally any linux distribution comes with precompiled packages. But we want to compile the whole thing ourself.

System Description:

open SuSE Linux 10.x
Apache 2.0.59
PHP 5.2.1
MySQL 5.0.33

Systemrequirements:

To safe us a lot of work install the follwing packages via SuSE "YaST"

  • autoconf
  • automake
  • bison
  • binutils
  • curl
  • curl-devel
  • cpp
  • flex
  • readline
  • readline-devel
  • gd
  • gmp
  • gd-devel
  • gettext
  • gettext-devel
  • glibc
  • glibc-devel
  • gcc
  • gcc-c++
  • imagemagick
  • imagemagick-devel
  • libmcrypt
  • libmcrypt-devel
  • libxml2
  • libxml2-devel
  • libjpeg
  • libjpeg-devel
  • libpng
  • libpng-devel
  • libstdc++
  • libstdc++-devel
  • make
  • m4
  • mcrypt
  • mhash
  • mhash-devel
  • ncurses
  • ncurses-devel
  • openssl
  • openssl-devel
  • zlib
  • zlib-devel
  • - and all other "YaST" automaticly installes
  • - finally make a online update to have the latest patches/fixes installed!

Compiler flags:

I use this one:

export CFLAGS="-O2 -mpentiumpro -msse -msse2 -msse3 -m3dnow -pipe -s -fomit-frame-pointer"

export CXXFLAGS="-O2 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti"

All scripts are tested under SuSE Linux 10.0

We download all sources to "/usr/local/src" the ssl directory is located at "/usr/local/apache2/ssl" the document root is located at "/usr/local/apache2/htdocs"

Download, compile and install MySQL 5.0.33 database server under user/group "mysql"

$>cd /usr/local/src
$>wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.33.tar.gz/from/http://ftp.gwdg.de/pub/misc/mysql/
$>tar xzvf mysql-5.0.33.tar.gz
$>cd mysql-5.0.33
$>./configure \
   --prefix=/usr/local/mysql \
   --exec-prefix=/usr/local/mysql \
   --enable-assembler \
   --enable-thread-safe-client \
   --enable-local-infile \
   --enable-shared \
   --with-mysqld-user=mysql \
   --with-openssl \
   --with-big-tables \
   --without-docs \
   --without-man \
   --without-bench \
$>make
$>make install
$>groupadd mysql
$>useradd -g mysql mysql
$>cp support-files/my-medium.cnf /etc/my.cnf
$>cd /usr/local/mysql
$>bin/mysql_install_db --user=mysql
$>/usr/local/mysql/bin/mysqld_safe &  we start mysqld to give a password
$>/usr/local/mysql/bin/mysqladmin -u root password 'mysecretpassword'
$>/usr/local/mysql/share/mysql/mysql.server stop  we stop mysqld
$>chown -R root .
$>chown -R mysql var
$>chgrp -R mysql .
$>passwd mysql  enter pawssword for user mysql for shell login

Typical MySQL configuration file "/etc/my.cnf" looks like:

[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-locking
key_buffer = 16K
max_allowed_packet = 1M
table_cache = 4
sort_buffer_size = 64K
net_buffer_length = 2K
thread_stack = 64K
skip-networking
server-id = 1
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[isamchk]
key_buffer = 8M
sort_buffer_size = 8M
[myisamchk]
key_buffer = 8M
sort_buffer_size = 8M
[mysqlhotcopy]
interactive-timeout

Download, compile and install Apache 2.0.55

$>cd /usr/local/src
$>wget http://gd.tuwien.ac.at/infosys/servers/http/apache/dist/httpd/httpd-2.0.55.tar.gz
$>tar xzvf httpd-2.0.55.tar.gz
$>cd httpd-2.0.55
$>./configure \
   --prefix=/usr/local/apache2 \
   --enable-so \
   --enable-auth-digest \
   --enable-rewrite \
   --enable-expires \
   --enable-setenvif \
   --enable-mime \
   --enable-deflate \
   --enable-ssl \
   --with-ssl \
   --enable-headers
   --enable-usertrack \
   --enable-cgi \
   --enable-suexec \
   --enable-headers \
   --enable-info
$>make
$>make install

Next step we change the apache2 configuration file located at "/usr/local/apache2/conf/httpd.conf" and change the document root directory to.

DocumentRoot "/usr/local/apache2/htdocs"

PHP 5 module activation: add this someware under the LoadModule description:

LoadModule php5_module modules/libphp5.so
DirectoryIndex index.html index.htm index.php
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

Basic mod_rewrite rules, you find these settings, only change diffrences:

<Directory "/usr/local/apache2/htdocs">
 Options Indexes Includes FollowSymLinks MultiViews
 AllowOverride All
 Order allow,deny
 Allow from all
</Directory>

Now we activate SSL support (standard port 443), in file "/usr/local/apache2/conf/ssl.conf" change/replace to this settings:

Listen 443
<VirtualHost _default_:443>
 ServerName your.IP.adress or FQDN:443
 SSLEngine on
 SSLCertificateFile /usr/local/apache2/ssl/server.cert
 SSLCertificateKeyFile /usr/local/apache2/ssl/server.key
</VirtualHost>

We generate an SSL certificate for the Webserver:

$>cd /usr/local/apache2/conf
$>mkdir ssl.crt ssl.key
$>openssl req -new -x509 -days 3650 -keyout ./ssl.key/server.key -out ./ssl.crt/server.crt -subj '/mytesthost.domain Certificate'
...
$>cp ssl.key/server.key ssl.key/server.key.org
$>openssl rsa -in ssl.key/server.key.org -out ssl.key/server.key
...
$>chmod 400 ssl.key/server.key
$>chmod 400 ssl.key/server.key.org

Download, compile and install PHP 5.2.1:

Before we start with PHP we must download and compile these separeted library:

  • libiconv-1.11 library

Download, compile and install libiconv:

$>cd /usr/local/src
$>wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.11.tar.gz
$>tar -zxvf libiconv-1.11.tar.gz
$>cd libiconv-1.11
$>./configure --prefix=/usr
$>make
$>make install

Now we are ready to compile PHP5 with Apache2, MySQL5 and the rest:

$>cd /usr/local/src
$>wget http://at.php.net/get/php-5.2.1.tar.gz/from/this/mirror
$>tar xzvf php-5.2.1.tar.gz
$>cd php-5.2.1
$>./configure \
  --with-apxs2=/usr/local/apache2/bin/apxs \
  --with-config-file-path=/usr/local/apache2/conf \
  --with-mysql=/usr/local/mysql  \
  --with-mysql-sock=/tmp/mysql.sock \
  --with-mysqli=/usr/local/mysql/bin/mysql_config  \
  --with-cpdflib=/usr/local \  
  --with-freetype-dir=/usr \
  --with-iconv=/usr \
  --with-jpeg-dir=/usr/lib/ \
  --with-png-dir=/usr/lib/ \
  --with-gettext \
  --with-zlib \
  --with-zlib-dir \
  --with-bz2 \
  --with-ttf \
  --with-curl \
  --with-imagick \
  --with-mhash \
  --with-mcrypt=/usr/lib/libmcrypt \
  --enable-inline-optimization \
  --enable-track-vars \
  --enable-gd \
  --enable-gd-native-ttf \
  --enable-trans-id \
  --enable-ftp \
  --enable-mbstring \
  --enable-exif \
  --with-openssl \
  --disable-ipv6 \
  --disable-debug
$>make
$>make install
$>cp php.ini-dist /usr/local/apache2/conf/php.ini

To get more secure we make some changes at the "/usr/local/apache2/conf/php.ini" file:

mysql.default_socket = /tmp/mysql.sock
short_open_tag = Off
register_globals = Off
allow_url_fopen = Off

Start script for Apache2 and MySQL at boot time?

copy paste the following lines to "/etc/init.d/webstart" , and to a "chmod 0755" to this file:

#! /bin/sh
#
# /etc/init.d/web
#
# (c) komaii
#
### BEGIN INIT INFO
# Provides:       apache mysql
# Required-Start: $local_fs $network $remote_fs
# Required-Stop:  $local_fs $network $remote_fs
# Default-Start:  3 5
# Default-Stop:   3 5
# Description:    starts and stops Apache2 und MySQL 5
### END INIT INFO

case "$1" in
        start)
        /usr/local/apache2/bin/apachectl startssl
        /usr/local/mysql/share/mysql/mysql.server start
                ;;
        stop)
        /usr/local/apache2/bin/apachectl stop
        /usr/local/mysql/share/mysql/mysql.server stop
                ;;
        restart)
        /usr/local/apache2/bin/apachectl restart
        /usr/local/mysql/share/mysql/mysql.server restart
                ;;
esac

At last we add this start script into the runlevel, the easiest way doing it with "chkconfig": in directory "/etc/init.d" do the following "chkconfig --add webstart" . that`s it. now you can see "web 0:off 1:off 2:off 3:on 4:off 5:on 6:off" is on in runlevel 3 and 5.

Testing the system?

First we start Apache2, MySQL server:

$>/etc/init.d/webstart start

Create a file "/usr/local/apache2/htdocs/index.php" and add the following code:

<?php phpinfo(); ?>

Open web browser and type "http://your.IP.adress/index.php" and/or "https://your.IP.adress/index.php". if everything is right you can see a lot of information about your Apache/PHP/MySQL installation.

Download, compile and install phpMyAdmin:

To manage the MySQL datenbase server we use phpMyAdmin which is accessable via browser link "http://localhost/db/":

We install phpMyAdmin to "/usr/local/apache2/htdocs/db" :

$>mkdir /usr/local/apache2/htdocs/db
$>cd /usr/local/src
$>wget http://prdownloads.sourceforge.net/phpmyadmin/phpMyAdmin-2.10.0-rc1-all-languages.tar.gz?download
$>tar zxvf phpMyAdmin-2.10.0-rc1-all-languages.tar.gz
$>cp -Rp phpMyAdmin-2.10.0-rc1-all-languages/* /usr/local/apache2/htdocs/db
$>cd /usr/local/apache2/htdocs/db/
$>cp config.default.php config.inc.php

Configurate phpMyAdmin in file "/usr/local/apache2/htdocs/db/config.inc.php" :

// URL to phpMyAdmin
$cfg['PmaAbsoluteUri'] = 'http://your.IP.adress/db/';

//connection settings
$cfg['Servers'][$i]['connect_type'] = 'socket';
$cfg['Servers'][$i]['extension'] = 'mysqli';

// user na password
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root'; 
$cfg['Servers'][$i]['password'] = 'mysecretpassword';

// PMA settings
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages'; 
$cfg['Servers'][$i]['column_info'] = 'pma_column_info'; 
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['verbose_check'] = FALSE;

// persistent connections
$cfg['PersistentConnections'] = TRUE;

// do not display logo on the left
$cfg['LeftDisplayLogo'] = FALSE;

// show MySQL and PHP info
$cfg['ShowMysqlInfo'] = TRUE;
$cfg['ShowMysqlVars'] = TRUE;
$cfg['ShowPhpInfo'] = TRUE;

// show BLOBs
$cfg['ShowBlob'] = TRUE;

Now we start the script /usr/local/apache2/htdocs/db/scripts/create_tables_mysql_4_1_2+.sql to create the PMA tables..

Download, compile and install modsecurity-apache-1.9.2 Modul::

installation and configuration:

cd /usr/local/src
tar zxvf modsecurity-apache-1.9.2.tar.gz
cd /usr/local/src/modsecurity-apache-1.9.2/apache2
$>/usr/local/apache2/bin/./apxs -cia mod_security.c

Now we must tell Apache howto load the modsecurity-apache Modul.

<IfModule mod_security.c>

    # Enable ModSecurity
    SecFilterEngine On

    # Reject requests with status 403
    SecFilterDefaultAction "deny,log,status:403"

    # Some sane defaults
    SecFilterScanPOST On
    SecFilterCheckURLEncoding On
    SecFilterCheckUnicodeEncoding Off

    # Accept almost all byte values
    SecFilterForceByteRange 1 255

    # Server masking is optional
    # SecServerSignature "Microsoft-IIS/5.0"

    # Designate a directory for temporary files
    # storage. It is a good idea to change the
    # value below to a private directory, just as
    # an additional measure against race conditions
    SecUploadDir /tmp
    SecUploadKeepFiles Off

    # Only record the interesting stuff
    SecAuditEngine RelevantOnly
    # Uncomment below to record responses with unusual statuses
    # SecAuditLogRelevantStatus ^5
    SecAuditLog logs/modsec_audit.log

    # You normally won't need debug logging
    SecFilterDebugLevel 0
    SecFilterDebugLog logs/modsec_debug.log

    # Only accept request encodings we know how to handle
    # we exclude GET requests from this because some (automated)
    # clients supply "text/html" as Content-Type
    SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chain
    SecFilterSelective HTTP_Content-Type "!(^application/x-www-form-urlencoded$|^multipart/form-data;)"

    # Do not accept GET or HEAD requests with bodies
    SecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" chain
    SecFilterSelective HTTP_Content-Length "!^$"

    # Require Content-Length to be provided with
    # every POST request
    SecFilterSelective REQUEST_METHOD "^POST$" chain
    SecFilterSelective HTTP_Content-Length "^$"

    # Don't accept transfer encodings we know we don't handle
    SecFilterSelective HTTP_Transfer-Encoding "!^$"

</IfModule>

<<<------------>>> that`s it <<<------------>>>