Apache with OpenSSL, MySQL, PHP on OpenSuSE 11.0
The goal of this guide is to setup a minimal OpenSUSE 11.0 system and take advantage of the tools that come shipped with it.
This may also serve as a primer for a myriad of web enabled applications available out there that make use of Apache, MySQL, and PHP. Parts of this document could be used as independent guides for installing and/or configuring each core service.
The document is just a rough guide not a sacred text. Do not blindly execute commands here without understanding them. Also, please keep in mind that your journey doesn’t end here. Observe best practices in tuning and securing your machine after performing the steps discussed in this document.
All steps were done using root via terminal interface. This may work using sudo with administrative privileges and even on a full GUI workstation environment. All packages will be installed and configured using the default shell of OpenSuSE; Bourne Again shell (bash).
Contents |
Pre-requisites and additional assumptions
- Successfully installed, configured, updated base installation of OpenSuSe 11.0
- Most of the procedures here are OpenSuSE-centric (e.g. Yast and Zypper)
- Basic knowledge of Unix and Unix-like environment
- Basic knowledge of computer networks
- Will make use of a dummy SSL certificate
- Actual commands are preceded by the host name and its present working directory e.g.:
linux-iifk:~ #
- To facilitate comparison (confusion), an actual screen output will be shown whenever a command is executed.
- System information
Linux 2.6.25.18-0.2-pae #1 SMP 2008-10-21 16:30:26 +0200 i686 athlon i386
Linux version 2.6.25.18-0.2-pae (geeko@buildhost)
(gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036]
(SUSE Linux) ) #1 SMP 2008-10-21 16:30:26 +0200
MySQL
Install the MySQL database:
linux-iifk:~ # yast2 -i mysql
Let’s configure our MySQL service to start automatically on boot-up:
linux-iifk:~ # chkconfig --add mysql
mysql 0:off 1:off 2:on 3:on 4:off 5:on 6:off
Verify if run levels 3 and 5 are toggled “on” as shown above.
Start the Mysql Service:
linux-iifk:~ # rcmysql start
Creating MySQL privilege database...
Installing MySQL system tables...
OK
Filling help tables...
OK
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h linux-iifk.site password 'new-password'
Alternatively you can run:
/usr/bin/mysql_secure_installation
which will also give you the option of removing the test
databases and anonymous user created by default. This is
strongly recommended for production servers.
See the manual for more instructions.
You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &
You can test the MySQL daemon with mysql-test-run.pl
cd mysql-test ; perl mysql-test-run.pl
Please report any problems with the /usr/bin/mysqlbug script!
The latest information about MySQL is available on the web at
http://www.mysql.com
Support MySQL by buying support/licenses at http://shop.mysql.com
Updating MySQL privilege database...
Looking for 'mysql' in: /usr/bin/mysql
Looking for 'mysqlcheck' in: /usr/bin/mysqlcheck
Running 'mysqlcheck'...
mysql.columns_priv OK
mysql.db OK
mysql.func OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.host OK
mysql.proc OK
mysql.procs_priv OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
Running 'mysql_fix_privilege_tables'...
OK
Starting service MySQL done
Let’s use netstat to check if the MySQL process is running:
linux-iifk:~ # netstat -lpt | grep "mysql"
tcp 0 0 *:mysql *:* LISTEN 2962/mysqld
As shown earlier, you can install and configure your MySQL Database manually or using a script. For this example we’re going to use mysql_secure_installation script. Also, please think of a strong password that contains at least 10 mixed case alpha-numeric characters for your MySQL root password.
linux-iifk:~ # /usr/bin/mysql_secure_installation
A message like this will appear:
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):
Since this is a fresh installation just press enter.
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.
At this point, press enter to confirm the suggested answer (written on caps) for each question. Read them carefully as this may not be applicable for you. For this installation, the suggested answers were all accepted.
Set root password? [Y/n]
New password: (type your password, should be more than 10 characters)
Re-enter new password: (re-type your password)
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n]
... Success!
By default, MySQL comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n]
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MySQL installation should now be secure.
Thanks for using MySQL!
For this setup mysql root is not allowed to login remotely. Let’s verify our database installation and root account using a localhost login.
linux-iifk:~ # mysql -u root -p
Enter password:
A successful login will yield this output:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.0.51a SUSE MySQL RPM
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
To return to your shell, either type \q or exit and press enter. MySQL monitor will bid you farewell with a message “Bye”. :)
mysql> \q
PHP
Installing PHP is simple:
linux-iifk:~ # yast2 -i php5
Install additional modules for PHP (MySQL for this installation):
linux-iifk:~ # yast2 -i php5-mysql
Note: If you need to add other PHP5 modules see additional notes section.
Apache
In this step, Apache 2.2 Server MPM Prefork will be installed.
linux-iifk:~ # yast2 -i apache2
Install PHP module for Apache:
linux-iifk:~ # yast2 -i apache2-mod_php5
As with most Linux distributions, package layout varies. Also, check your config file if the APACHE_MODULES line contains php5:
linux-iifk:~ # less /etc/sysconfig/apache2
Your output should have a line similar to this:
APACHE_MODULES="actions alias auth_basic authn_file authz_host authz_groupfile authz_default authz_user authn_dbm autoindex cgi dir env expires include log_config mime negotiation setenvif ssl suexec userdir php5"
Let’s configure Apache to automatically start at boot time:
linux-iifk:~ # chkconfig --add apache2
apache2 0:off 1:off 2:off 3:on 4:off 5:on 6:off
Verify if run levels 3 and 5 are toggled “on” as shown above.
Starting your httpd server Apache:
linux-iifk:~ # rcapache2 start
Starting httpd2 (prefork) done
To check what version of Apache is installed and important files/directories are located for this box:
linux-iifk:~ # httpd2 -V
Server version: Apache/2.2.8 (Linux/SUSE)
Server built: Sep 25 2008 11:59:55
Server's Module Magic Number: 20051115:11
Server loaded: APR 1.2.12, APR-Util 1.2.12
Compiled using: APR 1.2.12, APR-Util 1.2.12
Architecture: 32-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=128
-D HTTPD_ROOT="/srv/www"
-D SUEXEC_BIN="/usr/sbin/suexec2"
-D DEFAULT_PIDLOG="/var/run/httpd2.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="/var/run/accept.lock"
-D DEFAULT_ERRORLOG="/var/log/apache2/error_log"
-D AP_TYPES_CONFIG_FILE="/etc/apache2/mime.types"
-D SERVER_CONFIG_FILE="/etc/apache2/httpd.conf"
As shown earlier, not only the module of php5 is enabled but ssl as well; “ssl_module (shared)”. The next step would be enabling ssl module with Apache with a bash script called a2enflag.
linux-iifk:~ # a2enflag SSL
The command above modifies your /etc/sysconfig/apache2 file from:
APACHE_SERVER_FLAGS=""
to
APACHE_SERVER_FLAGS=" SSL"
Alternatively, you can use your favorite text editor and type the " SSL" at the APACHE_SERVER_FLAGS line.
Let’s restart Apache:
linux-iifk:~ # rcapache2 restart
Syntax OK
Shutting down httpd2 (waiting for all children to terminate) done
Starting httpd2 (prefork) done
Check if the machine listens for http and https traffic
linux-iifk:~ # netstat -lpt | grep "http"
tcp 0 0 *:www-http *:* LISTEN 3212/httpd2-prefork
tcp 0 0 *:https *:* LISTEN 3212/httpd2-prefork
Configure firewall (Netfilter)
The configuration of Netfilter has been done by most via command line using Iptables. For this installation, the Yast utility will be used for configuring the packet filtering instead of creating a custom iptables script.
linux-iifk:~ # yast2
The blue Yast2 Control Center console appears on your screen. (to navigate just use arrow keys and tab button)
Press arrow down to select Security and Users:
Press tab to select Firewall at the right pane and press enter.
Press arrow down to highlight Allowed Services and press enter. Kindly check if the entry Apache 2 is present on Service to Allow portion.
Press tab (7 times) until you reach Advanced then press enter.
Press tab (2 times) until you you reach the TCP Ports and type 80 443.
Press tab (4 times) until you reach OK and press enter.
Press tab (3 times) until you reach Next.
A configuration summary indicating your changes to your system. Kindly check if:
+ TCP Ports: 443, 80 is shown on Open Services, Ports and Protocol
Press enter or F10 to confirm changes and go back to the main menu of Yast2 Control Center.
Press tab twice again and press enter to quit (F9).
To verify if your system allows http (80) and https (443) traffic to pass through your box:
linux-iifk:~ # iptables -L | less
Check for lines similar to this:
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere tcp dpt:http
Enabling Secure Socket Layer for Apache
Generate a dummy SSL keys for this server using a bash script gensslcert. Please take note that this command will place a file /srv/www/htdocs named CA.crt
linux-iifk:~ # gensslcert
comment mod_ssl server certificate
name
C XY
ST unknown
L unknown
U web server
O SuSE Linux Web Server
CN linux-iifk.site
email webmaster@linux-iifk.site
srvdays 730
CAdays 2190
creating CA key ...
710687 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
..................+++
...........+++
e is 65537 (0x10001)
creating CA request/certificate ...
`/etc/apache2/ssl.crt/ca.crt' -> `/srv/www/htdocs/CA.crt'
creating server key ...
710687 semi-random bytes loaded
Generating RSA private key, 1024 bit long modulus
.................++++++
...++++++
e is 65537 (0x10001)
creating server request ...
creating server certificate ...
Signature ok
subject=/C=XY/ST=unknown/L=unknown/O=SuSE Linux Web Server/OU=web server/CN=linux-iifk.site/emailAddress=webmaster@linux-iifk.site
Getting CA Private Key
Verify: matching certificate & key modulus
Verify: matching certificate signature
/etc/apache2/ssl.crt/server.crt: OK
Proceed to Apache’s virtual hosts directory:
linux-iifk:~ # cd /etc/apache2/vhosts.d/
Copy the vhost-ssl.template file to that that of your machine name. In this example it’s linux-iifk:
linux-iifk:/etc/apache2/vhosts.d # cp vhost-ssl.template linux-iifk.conf
Restart Apache service again
linux-iifk:~ # rcapache2 restart
Syntax OK
Shutting down httpd2 (waiting for all children to terminate) done
Starting httpd2 (prefork) done
Test the server for http connections
Let’s create a test.php file to test our installation
linux-iifk:~ # echo "" >> /srv/www/htdocs/test.php
Open your favorite browser to check your server if it accepts http connection:
http://ip.address.ofyour.box/test.php
The output on your browser will be similar to this:
Please scroll down the output and look for for the MySQL section.
PHP Version 5.2.6
System Linux linux-iifk 2.6.25.18-0.2-pae #1 SMP 2008-10-21 16:30:26 +0200 i686
Build Date Aug 20 2008 18:19:14
--snip --
mysql
MySQL Support enabled
Active Persistent Links 0
Active Links 0
Client API version 5.0.51a
MYSQL_MODULE_TYPE external
MYSQL_SOCKET /var/lib/mysql/mysql.sock
MYSQL_INCLUDE -I/usr/include/mysql
MYSQL_LIBS -L/usr/lib -lmysqlclient
Test server for https connections
https://ip.address.ofyour.box/test.php
Since we have just made a dummy certificate, it should not come as a surprise if you receive warnings when you access the test page.
Below are messages encountered for several browsers and their suggested actions:
a) Firefox: The certificate is not trusted because the issuer certificate is unknown. (Error code: sec_error_unknown_issuer)
-- Click “Add an exception”, “Get Certificate”, “Confirm Security Exception”
b) Opera: The server’s certificate chain is incomplete and the signer(s) are not registered. Accept?
-- Click “Approve”
c) Lynx: SSL error: unable to get local issuer certificate - Continue ? (y)
-- Just press enter until you get the same output as http connection
The output should be the same as the one you saw using http connection.
Worth noting is the inclusion of the hardened php project :)
This server is protected with the Suhosin Patch 0.9.6.2 http://www.hardened-php.net/
Additional notes
- Remove test.php on the www directory after you have tested the system.
- Always restart Apache if you have loaded/removed modules by issuing:
linux-iifk:~ # rcapache2 restart
- This is also true for changes in PHP
- Should you need other modules for PHP like gd just replace php5-mysql in the install command. The command should be:
linux-iifk:~ # yast2 -i php5-gd
- The config file for PHP is /etc/php5/apache2/php.ini
- Log files for Apache are located at /var/log/apache2
- Default data directory for Apache is located at /srv/www/htdocs
You can check which shared modules are present by displaying all the Apache 2 modules by:
linux-iifk:~ # httpd2 -M
Loaded Modules:
core_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
actions_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_file_module (shared)
authz_host_module (shared)
authz_groupfile_module (shared)
authz_default_module (shared)
authz_user_module (shared)
authn_dbm_module (shared)
autoindex_module (shared)
cgi_module (shared)
dir_module (shared)
env_module (shared)
expires_module (shared)
include_module (shared)
log_config_module (shared)
mime_module (shared)
negotiation_module (shared)
setenvif_module (shared)
ssl_module (shared)
suexec_module (shared)
userdir_module (shared)
php5_module (shared)
Syntax OK
- The config file for MySQL is in /etc/my.cnf
- Log and data files are stored for mysql are stored at /var/lib/mysql
- Acessing the MySQL server remotely should have tcp port 3306 open on your firewall
- The command “zypper install” can be used instead of "yast2 -i"
- Please do not forget to lock down your system.
- Many,many,many thanks to OpenSuSE, Apache, PHP, Hardened PHP, MySQL, OpenSSL, Opera, Mozilla, Lynx, Vi, KDE, GNU and all Linux folks.
Further reading
For Yast 2 in text mode: http://www.novell.com/documentation/sled10/sled_deployment_sp1/index.html?page=/documentation/sled10/sled_deployment_sp1/data/cha_yast2.html
For tips/guide using zypper: http://en.opensuse.org/Zypper/Usage
For guides on how to configure/use Apache Version 2.2: http://httpd.apache.org/docs/2.2/
For guides on how to configure MySQL: http://dev.mysql.com/doc/refman/5.0/en/
For info about PHP: http://www.php.net/manual/en/
For info about packet filtering on GNU/Linux: http://www.netfilter.org/
For info about OpenSSL: http://httpd.apache.org/docs/2.2/ssl/ http://www.openssl.org/


Tidak ada komentar:
Posting Komentar