Showing posts with label Apache. Show all posts
Showing posts with label Apache. Show all posts

Sunday, December 26, 2010

Installing and configuring mod_security-Ubuntu 9.04


This how-to is reported to work in Ubuntu 8.04-10.10 as well.

What is mod_security you ask ?


Mod Security can significantly increase the security of your Apache installation.
 
What Is ModSecurity?

ModSecurity is a web application firewall that can work either embedded or as a reverse proxy. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analysis.

It is also an open source project that aims to make the web application firewall technology available to everyone.

Do not think you need this ? Follow along with the examples and decide for yourself (This tutorial assumes you already have Apache and php5 installed).
First, let us look at the default Apache behavior. I will use “ubuntuVPS” as the server of interest.

“Insecure” Example 1 – curl

Use curl to obtain information on the server (bodhi@home is a remote machine connecting to “ubutnuVPS”. You can test all this with any browser if you wish, simply use your server’s home page).
bodhi@home# curl -i ubuntuVPS
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:06:21 GMT
Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.1 with Suhosin-Patch
Last-Modified: Tue, 28 Apr 2009 21:39:54 GMT
ETag: "50d4a-2d-468a44dadbe80"
Accept-Ranges: bytes
Content-Length: 45
Vary: Accept-Encoding
Content-Type: text/html
< html>< body>< h1>It works!< /h1>< /body>< /html>

Looks like this in your browser (the famous It works! page)

See how with a single command we already know the server is Ubuntu running Apache 2.2.11 and PHP 5.2.6 ?

“Insecure” Example 2 – bad .php

For this I will ask you to create a file “/var/www/insecure.php”
Put the following code in the file :
# vim /var/www/insecure.php
< ? $secret_file = $_GET['secret_file'];
include ( $secret_file); ? >;

Note: I had to put a space at the front of the php tag “<; ?”, remove it.

Now what ? Open a browser and enter http://ubuntuVPS/insecure.php?secret_file=/etc/passwd

I shall use curl in this example:
bodhi@home# curl -i "http://ubuntuVPS/insecure.php?secret_file=/etc/passwd"
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:24:11 GMT
Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.1 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-3ubuntu4.1
Vary: Accept-Encoding
Content-Length: 860
Content-Type: text/html
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin
postfix:x:104:107::/var/spool/postfix:/bin/false

YIKES !!!

Install and configure mod_secure

There was a time when installing mod_security was a bit difficult, now it is as easy as :
sudo apt-get -y install libapache-mod-security
The “hard part” is that we need to configure mod_security and obtain a few rules.

Configure mod_security

Using any editor, make a file “/etc/apache2/conf.d/modsecurity2.conf” and put the following contents in the file.
#vim /etc/apache2/conf.d/modsecurity2.conf
< ifmodule mod_security2.c>
Include conf.d/modsecurity/*.conf
< /ifmodule>

Note: I had to add a space at the front of the tag “< ifmodule mod_security2.c>” and “< /ifmodule>”, remove them.

By default, mod_security logs to /etc/apache2/logs, the following commands will put the log in /var/log/apache2/mod_security and create a symbolic link back to /etc/apache2/logs

sudo mkdir /var/log/apache2/mod_security
sudo ln -s /var/log/apache2/mod_security/ /etc/apache2/logs
Download and install rules
Download rules from here

As of this writing, the rule set was “modsecurity-core-rules_2.5-1.6.1.tar.gz”, you may need to adjust accordingly as new rules are released.
sudo mkdir /etc/apache2/conf.d/modsecurity
cd /etc/apache2/conf.d/modsecurity
sudo wget http://www.modsecurity.org/download/modsecurity-core-rules_2.5-1.6.1.tar.gz
sudo tar xzvf modsecurity-core-rules_2.5-1.6.1.tar.gz
sudo rm CHANGELOG LICENSE README modsecurity-core-rules_2.5-1.6.1.tar.gz


Enable mod_security:

sudo a2enmod mod-security
Now restart Apache
That’s it :)

Testing mod_security

“Secure” Example 1 – curl
bodhi@home# curl -i http://ubuntuVPS
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:44:42 GMT
Server: Apache/2.2.0 (Fedora)
Last-Modified: Tue, 28 Apr 2009 21:39:54 GMT
ETag: "50d4a-2d-468a44dadbe80"
Accept-Ranges: bytes
Content-Length: 45
Vary: Accept-Encoding
Content-Type: text/html
< html>< body>< h1>It works!< /h1>< /body>< /html>

Look no more server or php information (Fedora apache 2.2.0 , LOL !!! )

“Secure” Example 2 – bad .php
bodhi@home# curl -i "http://ubuntuVPS/insecure.php?secret_file=/etc/passwd"
HTTP/1.1 501 Method Not Implemented
Date: Tue, 28 Apr 2009 22:47:38 GMT
Server: Apache/2.2.0 (Fedora)
Allow: TRACE
Vary: Accept-Encoding
Content-Length: 291
Connection: close
Content-Type: text/html; charset=iso-8859-1
< !DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
< html>< head>
< title>501 Method Not Implemented< /title>
< /head>< body>
< h1>Method Not Implemented< /h1>
< p>GET to /insecure.php not supported.< br />
< /p>
< hr>
< address>Apache/2.2.0 (Fedora) Server at ubuntuvps Port 80< /address>
< /body>< /html>

Looks like this in your browser:
"501 Method Not Implemented
Method Not Implemented"
GET to /insecure.php not supported.Apache/2.2.0 (Fedora) Server at ubuntuvps Port 80
Ah 501 Error looks much better then the contents of /etc/passwd :)
Where to go from here ?

1. Monitor your logs :
tail /var/log/apache2/mod_security/modsec_audit.log
 
2. Learn / edit your mod_security rules : ModSecurity Reference Manual

3. Delete bad.php, LOL
sudo rm -rf /var/www/insecure.php

I hope you enjoyed and learned from this tutorial :)

Reference:
"This is just a copy cat of the post from http://blog.bodhizazen.net/linux/how-to-mod_security-ubuntu-904/
All credit should go to the respective author. I tried the method in Ubuntu 10.10 and it works fine."

Note:-
Some of the rules may deny the access to you applications (eg: phpmyadmin/drupal etc). Test the rules well before you implement.

Tuesday, December 22, 2009

howto install mod_security2 with apache2 in Ubuntu

here are many significant changes and enhancements in ModSecurity 2.x over the 1.x branch, including:
  • use core rules with various features
  • five processing phases: request headers, request body, response headers, response body, logging
  • per-rule transformation options (previously normalization was implicit and hard-coded). New transformation functions were added.
  • transaction variables. This can be used to store pieces of data, create a transaction anomaly score etc.
  • data persistence. It can be configured any way you want. Most people will want to use this feature to track IP addresses, application sessions, and application users).
  • support for anomaly scoring and basic event correlation (counters can be automatically decreased over time; variables can be expired).
  • support for web applications and session IDs.
  • regular expression back-references (allows one to create custom variables using transaction content).
  • many new functions that can be applied to the variables (where you could use only use regular expressions, previously).
  • XML support (parsing, validation, XPath).

Download mod_security

  • Download source from mod_security2 (you need to sign up to download).
There is currently no binary of mod_security 2.5.6 available for Ubuntu, so you need to compile it yourself.

Step by Step Ubuntu install guide

1) install g++ environment

apt-get install g++ doc-base autoconf automake1.9 bison bison libtool make

2) install preconditions for mod_security2

apt-get install apache2-threaded-dev libxml2-dev libcurl4-gnutls-dev
  • try to run configure with missing libraries or header files
    ./configure --with-apxs2=/usr/bin/apxs2
    
    result:
    checking for strtol... yes
    configure: looking for Apache module support via DSO through APXS
    configure: error: couldn't find APXS
  • install apache apxs
    apt-get install apache2-threaded-dev
  • next error with configure: missing libxml2
    checking for libxml2 config script... no
    configure: *** libxml2 library not found.
    configure: error: libxml2 library is required
  • install libxml2-dev
    sudo apt-get install libxml2-dev
  • next error with configure: missing libcurl
    • this step is optional, only needed if you want to build mlogc, id did it.
      checking for libcurl config script... no
      configure: *** curl library not found.
      configure: NOTE: curl library is only required for building mlogc
  • install libcurl4-gnutls-dev
    sudo apt-get install libcurl4-gnutls-dev

3) final configure works, run make now

cd ~/modsecurity-apache_2.5.6/apache2
./configure --with-apx2=/usr/bin/apxs2

output:
checking for g++... g++
checking for C++ compiler default output file name... a.out
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking how to run the C preprocessor... gcc -E
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln -s works... yes
checking whether make sets $(MAKE)... yes
checking for ranlib... ranlib
checking for perl... /usr/bin/perl
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking for unistd.h... (cached) yes
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking for C/C++ restrict keyword... __restrict
checking for size_t... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for uint8_t... yes
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking for working memcmp... yes
checking for atexit... yes
checking for fchmod... yes
checking for getcwd... yes
checking for memset... yes
checking for strcasecmp... yes
checking for strchr... yes
checking for strdup... yes
checking for strerror... yes
checking for strncasecmp... yes
checking for strrchr... yes
checking for strstr... yes
checking for strtol... yes
configure: looking for Apache module support via DSO through APXS
configure: found apxs at /usr/bin/apxs2
configure: checking httpd version
configure: httpd is recent enough
checking for libpcre config script... /usr/bin/pcre-config
configure: using '-L/usr/lib -lpcre' for pcre Library
checking for libapr config script... /usr/bin/apr-1-config
configure: using ' -luuid -lrt -lcrypt  -lpthread -ldl' for apr Library
checking for libapr-util config script... /usr/bin/apu-1-config
configure: using ' -L/usr/lib -laprutil-1' for apu Library
checking for libxml2 config script... /usr/bin/xml2-config
configure: using '-lxml2' for libxml Library
checking for pkg-config script for lua library... no
configure: optional lua library not found
checking for libcurl config script... /usr/bin/curl-config
configure: using '-lcurl -lgssapi_krb5' for curl Library
configure: creating ./config.status
config.status: creating Makefile
config.status: creating build/apxs-wrapper
config.status: creating t/run-unit-tests.pl
config.status: creating t/run-regression-tests.pl
config.status: creating t/gen_rx-pm.pl
config.status: creating t/csv_rx-pm.pl
config.status: creating t/regression/server_root/conf/httpd.conf
config.status: creating ../tools/rules-updater.pl
config.status: creating mod_security2_config.h
make

4) install mod_security2

i did this manual way to control what is installed,
of course you can use "make install".
cp modsecurity-apache_2.5.6/apache2/.libs/mod_security2.so /usr/lib/apache2/modules
chmod 644 /usr/lib/apache2/modules/mod_security2.so
chown root:root /usr/lib/apache2/modules/mod_security2.so

5) include mod_security2 in the apache2 way

/etc/apache2/mods-available# cat mod_security2.load 
LoadModule security2_module /usr/lib/apache2/modules/mod_security2.so

/etc/apache2/mods-enabled# ln -s ../mods-available/mod_security2.load .

6) load apache2 mod_unique_id

  • run apachectl configtest and find the missing mod_unique_id error
    apachectl configtest
    less /var/log/apache2/error.log
    [Fri Aug 15 11:59:34 2008] [error] ModSecurity: ModSecurity requires mod_unique_id to be installed
  • fix it with a2enmod of make a manual symlink in mods-enabled
    a2enmod mod_unique_id

7) reload apache config

  • reload config and check error.log
    apachectl configtest
    apachectl graceful
    less /var/log/apache2/error.log
after reloading apache, make test to you webserver and check access.log and error.log

8) initial mod_security configuration

After initial installation of mod_security2 you can add mod_security2 rules. For example you can add a core rule, for example add rule to apache conf directory:
/etc/apache2/conf.d/mod_security2# ls
modsecurity_crs_10_config.conf

9) adopt log path

SecAuditLog /var/log/apache2/modsec_audit.log
SecDebugLog             /var/log/apache2/modsec_debug.log

10) example: set higher SecDebugLogLevel

# NOTE Debug logging is generally very slow. You should never
#      use values greater than "3" in production.
#      0 - no logging.
#      1 - errors (intercepted requests) only.
#      2 - warnings.
#      3 - notices // default value.
#      4 - details of how transactions are handled.
#      5 - as above, but including information about each piece of information handled.
#      9 - log everything, including very detailed debugging information.

SecDebugLogLevel        5

related posts

Wednesday, December 9, 2009

Application Server HOW TO

http://confluence.atlassian.com/display/DOC/Configuration+Guide

Using Apache with mod_proxy

This page describes how to integrate Confluence into an Apache website, using mod_proxy. There are some common situations where you might do this:

* You have an existing Apache-based website, and want to add Confluence to the mix (eg. http://www.example.com/confluence).
* You have two or more Java applications, each running in their own application server on different ports, eg. http://localhost:8080/confluence and http://localhost:8081/jira. By setting up Apache with mod_proxy, you can have both available on the regular HTTP port (80), eg. at http://www.example.com/confluence and http://www.example.com/jira. If you are running JIRA and Confluence, we recommend this setup. It allows each app to be restarted, managed and debugged separately.

This page describes how to configure mod_proxy. We describe two options:

* If you want a URL like http://www.example.com/confluence/, go to the simple configuration.
* If you want a URL like http://confluence.example.com/, go to the complex configuration.

Simple configuration
Set the context path

First, set your Confluence application path (the part after hostname and port) correctly. Say you want Confluence available at http://www.example.com/confluence/, and you currently have it running at http://localhost:8080/. The first step is to get Confluence available at http://localhost:8080/confluence/.

To do this in Tomcat (bundled with Confluence), edit conf/server.xml, locate the "Context" definition:
1.

and change it to:
1.

Then restart Confluence, and ensure you can access it at http://localhost:8080/confluence/
Configure mod_proxy

Now enable mod_proxy in Apache, and proxy requests to the application server by adding the example below to your Apache httpd.conf (note: the files may be different on your system; the JIRA docs describe the process for Ubuntu/Debian layout):
01.# Put this after the other LoadModule directives
02.LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
03.LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
04.
05.# Put this in the main section of your configuration (or desired virtual host, if using Apache virtual hosts)
06.ProxyRequests Off
07.ProxyPreserveHost On
08.
09.
10. Order deny,allow
11. Allow from all
12.

13.
14.ProxyPass /confluence http://localhost:8080/confluence
15.ProxyPassReverse /confluence http://localhost:8080/confluence
16.
17. Order allow,deny
18. Allow from all
19.

Note to Windows Users

It is recommended that you specify the absolute path to the mod_proxy.so and mod_proxy_http.so files.
Set the URL for redirection

You will need to modify the server.xml file in your tomcat's conf directory and set the URL for redirection.

Locate this code segment
1.

And append the following segment:
1.

Replace www.example.com with the URL you wish to be redirected to.

Complex configuration

A complex configuration involves using the mod_proxy_html filter to modify the proxied content en-route. This is required if the Confluence path differs between Apache and the application server. For example:
Externally accessible (Apache) URL http://confluence.example.com/
Application server URL http://app-server.internal.example.com:8080/confluence/

Notice that the application path in the URL is different in each. On Apache, the path is /, and on the application server the path is /confluence.
For this configuration, you need to install the mod_proxy_html module, which is not included in the standard Apache distribution.

Alternative solutions are discussed below.
01.# Put this after the other LoadModule directives
02.LoadModule proxy_module modules/mod_proxy.so
03.LoadModule proxy_http_module modules/mod_proxy_http.so
04.LoadModule proxy_html_module modules/mod_proxy_html.so
05.
06.
07. ServerName confluence.example.com
08.
09. # Put this in the main section of your configuration (or desired virtual host, if using Apache virtual hosts)
10. ProxyRequests Off
11. ProxyPreserveHost On
12.
13.
14. Order deny,allow
15. Allow from all
16.

17.
18. ProxyPass / http://app-server.internal.example.com:8080/confluence
19. ProxyPassReverse / http://app-server.internal.example.com:8080/confluence
20.
21. ProxyHTMLURLMap / /confluence/
22.
23.
24. Order allow,deny
25. Allow from all
26.

27.


The ProxyHTMLURLMap configuration can become more complex if you have multiple applications running under this configuration. The mapping should also be placed in a Location block if the web server URL is a subdirectory and not on a virtual host. The Apache Week tutorial has more information how to do this.
More information

* The mod_proxy_html site has documentation and examples on the use of this module in the complex configuration.
* Apache Week has a tutorial that deals with a complex situation involving two applications and ProxyHTMLURLMap.
* Using Apache with virtual hosts and mod_proxy shows how to configure the special case where you want JIRA and Confluence running on separate application servers on virtual host subdomains.

Alternatives

If Tomcat is your application server, you have two options:

* use mod_jk to send the requests to Tomcat
* use Tomcat's virtual hosts to make your Confluence application directory the same on the app server and the web server, removing the need for the URL mapping.

If your application server has an AJP connector, you can:

* use mod_jk to send the requests to your application server.

Wednesday, October 14, 2009

LAMP Server For CentOS/RHEL

This tutorial shows a quick way of installing a LAMP server (Linux + Apache + MySQL + PHP/Perl together commonly known as LAMP Server.) on CentOS and RHEL server systems.
  • Apache Web Server 2.x
  • MySQL Database Server 5.x
  • PHP Scripting Language 5.x
  • phpMyAdmin - Web based MySQL Administration Tool

Install Apache
     Apache is the most popular Web HTTP server for a Linux servers.
# yum install httpd httpd-devel
We might need the httpd-devel libraries to compile and install other modules from the sources, just to be on the safer side. /etc/httpd/conf/httpd.conf - Apache configuration file location.
# /etc/init.d/httpd start

Install MySQL Database Server     MySQL is a widely used open source database server on most Linux servers and can very well integrate to PHP and Apache server on CentOS/RHEL.
# yum install mysql mysql-server mysql-devel

If you attempt to type mysql in command prompt, you will be getting this nasty error.
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’
This is because you are not running the mysqld daemon before launching the mysql client. The file /var/lib/mysql/mysql.sock will be automatically created upon running the first instance of mysql.
To fix:
First start the mysql daemon, then type mysql:
# /etc/init.d/mysqld start
# mysql


Changing MySQL Root Password     By default the root password is empty for the mysql database. It is a good idea to change the mysql root password to a new one from a security point of view.
mysql> USE mysql;
mysql> UPDATE user SET Password=PASSWORD('newpassword') WHERE user='root';
mysql> FLUSH PRIVILEGES;

Once done, check by logging in:
mysql -u root -p
Enter Password:

 
To Create A New MySQL User
     To create a new mysql user 'guest' with 'all privileges' on the database 'demo':
mysql > create database demo
mysql >GRANT ALL PRIVILEGES ON demo.* TO 'guest'@'localhost' IDENTIFIED BY 'guest' WITH GRANT OPTION;
mysql> UPDATE user SET Password=PASSWORD('guest') WHERE user='guest';

That's it! MySQL is ready! Don't forget to remember the root password as we might be using it with phpmyadmin.

Install PHP5 Scripting Language
     Installing PHP5 with the necessary modules is so easy and can be configured for both the Apache and mysql environment.
# yum install php php-mysql php-common php-gd php-mbstring php-mcrypt php-devel php-xml
Don't forget to install php-gd (gd library). It is very important if we plan to run captcha scripts on our server and so as other which are dependent on mysql and other functions.
Restart Apache to load php.
# /etc/init.d/httpd restart

To Test If PHP Is Working Or Not:
Create a file named /var/www/html/test.php with the following phpinfo() function inside php quotes.
// test.php
    phpinfo();
  ?>
Then point your browser to http://ip.address/test.php.
That's it! You should see a php configuration file displaying all kind of paths and installed modules.
Closely observe the installed configuration on your server.
  •   PHP Paths (php.ini path)
      Apache paths and Loaded Modules (mod_security, mod_evasive if installed_
      PHP GD Library
      MySQL paths and other information
Install phpMyAdmin
     phpMyAdmin is a free web based MySQL database Administration Tool. Without phpMyAdmin it is almost impossible to mysql db operations in the command line. phpMyAdmin has become so convenient and it is absolutely sought by most webmasters to be present along with the mysql server.
# yum install phpmyadmin
Point your browser to: http://ip.address/phpmyadmin.
 
Common Errors
    You might encounter the following errors while configuring phpmyadmin.
Forbidden
You don't have permission to access /phpmyadmin/ on this server.

To fix:
Edit the /etc/httpd/conf.d/phpmyadmin.conf and uncomment the line deny from all.
# nano /etc/httpd/conf.d/phpmyadmin.conf

  Order Deny,Allow
  # Deny from all
  Allow from 127.0.0.1
  

Error
The configuration file now needs a secret passphrase (blowfish_secret)

To fix:
# nano /usr/share/phpmyadmin/conf.inc.php
Look for a line and enter any password. Just dont leave it empty!
$cfg['blowfish_secret'] = 'mydpassword'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
It worked for me using the above methods!
Log into the phpmyadmin with the mysql root password we changed while installing the mysql database.

Tuesday, September 22, 2009

Hardening of LAMP Server; Links

A complete Ubuntu LAMP Server hardening 

http://www.freesoftwaremagazine.com/articles/hardening_linux?page=0%2C0


Hardening the apache LAMP server avoiding attacks

http://secure-ubuntu-server.blogspot.com/2009/07/howto-hardening-your-apache-and-php-on_07.html

Activate the AppArmor for apache2

http://samiux.wordpress.com/2009/06/16/howto-security-enhanced-your-ubuntu-9-04-lamp-server-with-apparmor/

Activating the Chrootkits:

http://samiux.wordpress.com/2009/06/13/howto-make-sure-no-rootkit-on-your-ubuntu-9-04-server/

lamp server security Basics:

https://scifi.homelinux.net/mediawiki/index.php/Hardening_a_LAMP_server



#----------------------------BASIC SECURITY RESTRICTIONS------------------------------------

#Enable ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

#Disabling IP Spoofing attacks
echo 2 > /proc/sys/net/ipv4/conf/all/
rp_filter

#Don't respond to broadcast pings
echo "1" > /proc/sys/net/ipv4/icmp_echo_
ignore_broadcasts

#Block source routing
echo 0 >/proc/sys/net/ipv4/conf/all/
accept_source_route

#Kill timestamps. These have been the subject of a recent bugtraq
#thread
echo 0 > /proc/sys/net/ipv4/tcp_
timestamps

#Enable SYN Cookies
echo 1 > /proc/sys/net/ipv4/tcp_
syncookies

#Kill ICMP redirects
echo 0 >/proc/sys/net/ipv4/conf/all/
accept_redirects

#Enable bad error message protection
echo 1 > /proc/sys/net/ipv4/icmp_
ignore_bogus_error_responses

#Allow dynamic ip addresses
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

#Log martians (packets with impossible addresses)
#RiVaL said that certain NICs don't like this. Comment out if necessary.
# echo 1 >/proc/sys/net/ipv4/conf/all/
log_martians

#Set out local port range
echo "32768 61000" >/proc/sys/net/ipv4/ip_local_
port_range

#PING OF DEATH
/sbin/iptables -A FORWARD -p icmp --icmp-type 8 -m limit --limit 3/second -j ACCEPT

#SYN-FLOOD PROTECTION
/sbin/iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
#-----------------------------
-------------------------------------------------

#---------------------------
DENIAL OF SERVICE-----------------------------------

#Reduce DoS'ing ability by timeouts
echo 30 > /proc/sys/net/ipv4/tcp_fin_
timeout
echo 1800 > /proc/sys/net/ipv4/tcp_
keepalive_time
echo 1 > /proc/sys/net/ipv4/tcp_window_
scaling
echo 0 > /proc/sys/net/ipv4/tcp_sack
echo 1280 > /proc/sys/net/ipv4/tcp_max_
syn_backlog
#-----------------------------
----------------------------------------------------------------------

Hardening Linux Web Servers - LAMP Installing & Hardening

Security is a process, not a result. It is a process which is difficult to adopt under normal conditions; the problem is compounded when it spans several job descriptions. All the system level security in the world is rendered useless by insecure web-applications. The converse is also true—programming best practices, such as always verifying user input, are useless when the code is running on a server which hasn’t been properly hardened. Securing forward facing GNU/Linux web servers can seem like a daunting task, but it can be made much easier by breaking the process into manageable portions.
This article will cover installing, configuring and hardening free software web servers and associated software including Apache 2.2.0, MySQL 5.0.18, PHP 5.1.2, Apache-Tomcat 5.5.16 and common Apache modules such as mod_security, mod_ssl, mod_rewrite, mod_proxy and mod_jk. Common security mistakes in web-applications and how to fix them will also be discussed, focusing on PHP and Java environments.
The most common and apt analogy for security is the onion. That is to say it is a layered approach—any one layer is inadequate, the onion is the sum of its layers. With that in mind, this article attempts to bridge the knowledge gap between system administrators and web developers, allowing individuals tasked with security to achieve a layered security solution.
Only a basic understanding of GNU/Linux and common command line tools is assumed.

Note: due to formatting constraints, long lines of code are often broken into several smaller lines using the \ character. This is not a return and when typing in the line you should not hit the enter key, it is just to prevent line wrapping. Output from commands will also be limited to relevant fields, so the output will look slightly different when you run the commands on your system.

"Security is a process, not a result"

Security at the system level

System level security is one of the most crucial layers in any defense. Hardening at the system level is roughly categorized into network security and file system security.
Network level security can be increased by securing common services such as xinetd (otherwise known as the super server) and OpenSSH, by correctly configuring or disabling them and enabling a firewall (in our case, iptables.
File-System security can be increased by: preventing common avenues of attack, such as root kits; enabling intrusion detections systems (IDS) to verify the integrity of key configuration files; by using tools to detect and remove root kits; and by configuring your logging system so that it will log to a remote host, thereby protecting the integrity of your system logs.

Network security
The first thing you need to do to secure a system from network attacks is find out which processes are listening for connections and on which ports. There are several time tested tools available for this: nmap and netstat.

netstat
The following command will show you which ports are being listened on, the IP address of the listening socket, and which program or PID is associated with the socket (note: running as the super-user or root is necessary for the program field to work properly).

$ netstat -l -n -p -t -u -w

(-l is for listening, -n is for IP information and -p is for program/PID information, -t, -u, -w are for tcp, udp and raw socket connections. By setting these flags, I disable displaying information about unix sockets which are not relevant to network security, as they are only used for interprocess communication on the current host.)

The output will look something like this:
Note: Certain columns have been omitted for space
proto Local Address      State    PID/Program name
  tcp   127.0.0.1:8005    LISTEN   4079/java
  tcp   0.0.0.0:8009      LISTEN   4079/java
  tcp   0.0.0.0:3306      LISTEN   18542/mysqld
  tcp   0.0.0.0:80        LISTEN   23736/httpd
  tcp   0.0.0.0:8080      LISTEN   4079/java
  tcp   0.0.0.0:22        LISTEN   11045/sshd
  tcp   0.0.0.0:3128      LISTEN   23283/(squid)
  tcp   127.0.0.1:25      LISTEN   24453/master
  udp   0.0.0.0:3130               23283/(squid)
  udp   0.0.0.0:32870              23283/(squid)
 
Understanding the output from netstat is pretty simple. The first field is the protocol, and you will notice that when the protocol is udp, there is no state (as obviously udp is stateless unlike tcp). The next interesting field is the Address field. 0.0.0.0:80 means that the server will respond to any IPs on port 80, while 127.0.0.1:80 means that the server is only listening to the loop back device.

nmap
Another tool in our arsenal is nmap, the network mapper. nmap is good for determining what ports and services are available on a server from other machines on the network.
(Note: The default option is -sS. However, when the system being scanned is running a firewall, such as iptables, it won’t work, as firewalls that block icmp traffic will also block the subsequent scan and the results will be meaningless. The -P0 option disables pinging the host before scanning it, The -O (as in “oh” rather than zero) is to enable nmap’s operating system detection via the network stack fingerprint.)

$nmap -P0 -O 10.0.2.10
The output will look something like this:
The 1661 ports scanned but not shown below are in 
                                    state: filtered)
  PORT    STATE  SERVICE
  22/tcp  open   ssh
  443/tcp closed https
        
  Device type: general purpose
  Running: Linux 2.6.X
  OS details: Linux 2.6.7 - 2.6.8
  Uptime 40.462 days since Mon Dec 26 10:05:57 2005 
 
 
Now that I know what services are listening on which ports, I can go about securing them. In some cases, the solution will be disabling the unwanted service via inetd; in others, I will use iptables rules to block external access to that port.
In the context of a web server, I would recommended disabling all services managed by inetd (if they aren’t already).
/etc/xinetd.conf (Red Hat): this file usually has some minimalistic configuration of the logging software and then an include statement for all the files under /etc/xinetd.d, which are configuration files for each service run through the super server.
/etc/inetd.conf (Debian): Debian has a much simpler configuration layout—one simple file /etc/inetd.conf containing one line for each service managed by inetd.


iptables


   The venerable iptables has been the standard Linux firewall since the 2.4 kernel. The kernels that come with Red Hat and Debian have the proper modules enabled; however, on Debian systems you may need to install the iptables user land tools. Configuring iptables is fairly simple: iptables has chains, rules and targets. iptables has three built in chains: FORWARD, INPUT, and OUTPUT. To create an effective firewall I will append rules to chains that will be matched by connection type, source or destination address or state. In more advanced configurations, it is favorable to create custom chains and then reference them in the default chains; but, to demonstrate the basic principles, I am just going to append rules to the three default chains. When a connection is being matched against the configured rules, each rule is checked. If it matches, it is executed, if not, the next rule is tested. As such, the rules allowing traffic should be appended first, and the very last line in any chain should be a deny rule. This is the most secure firewall configuration, where everything is dropped except the explicitly allowed connections.

If you use Debian, run:
 
 $apt-get install iptables ( to install iptables )
  $apt-cache search iptables ( to search for packages related to iptables)
  
To get started with iptables I will list the current rule set using the following command:
 
$iptables --list 
 
   Chain  INPUT (policy ACCEPT)
   target     prot   opt     source   destination
   ACCEPT     all       anywhere  anywhere       state RELATED,ESTABLISHED

   Chain FORWARD (policy ACCEPT)
   target     prot   opt     source   destination
   ACCEPT     all       anywhere anywhere         state RELATED,ESTABLISHED

   Chain OUTPUT (policy ACCEPT)
   target     prot   opt     source   destination
   DROP       tcp       anywhere anywhere         tcp dpt:ssh
 
   The partial listing above shows rules that allow incoming traffic that isn’t new; that is to say: the connection has been established from inside the network. IP forwarding follows the same rule, and using ssh to connect out to other hosts is blocked.
The flush command with no options will flush all rules; if a chain is passed, all rules in that chain will be flushed. I’ll flush all rules and begin configuring the firewall.
$iptables -F 
    or 
  $iptables -F INPUT 
  $iptables -F FORWARD
  $iptables -F OUTPUT
  
Next, I am going to append the rules to the appropriate chain. A high level overview of the firewall will be the following:
  1. Allow outgoing connections initiated from the host
  2. Allow inbound ssh connections on port 2
  3. Allow inbound http connections on port 80
  4. Allow inbound https connections on port 443
  5. Block outbound ssh connections
  6. Block everything else

# Enable stateful filtering allowing connections 
 
# initiated on host be allowed.
  $iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
  $iptables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
 
# Allow Incoming SSH, HTTP, HTTPS
  $iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
  $iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
  $iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
 
# Allow Everything from the local host
  $iptables -A INPUT -s 127.0.0.1 -j ACCEPT
 
# Block Outgoing SSH connections
  $iptables -A OUTPUT -p tcp -m tcp --dport 22 -j DROP
 
# Block Everything else
  $iptables -A INPUT -j DROP
  $iptables -A FORWARD -j DROP
 
To save the changes I have made to the firewall rules I use the iptables-save command:
  $iptables-save > /root/firewall

Later if I wanted to restore my saved rules I would run the iptables-restore command:
$iptables-restore -c /root/firewall
 
It’s a very good idea to have these rules applied at boot time; check your distribution’s documentation for this. In general, on Debian systems the network configuration scripts can be used for this, and on Red-Hat systems a startup script in /etc/init.d is appropriate.


"Changing the default port that `OpenSSH` listens on is a good way to avoid brute force attacks"


Hardening SSH


      The OpenSSH package comes installed by default on most distributions. The default configuration on most distributions is pretty lax and favors functionality over security. Allowing root logins, listening on all IPs on port 22, and allowing all system accounts to ssh-in are all potential security holes.
Edit /etc/ssh/sshd_config in your favorite editor and change the following lines.

 # ListenAddress defines the IP address ssh will 
  # listen on
  
  #ListenAddress 0.0.0.0 -> ListenAddress 10.0.2.10 

  #Only accept SSH protocol 2 connections
  #Protocol 2,1 -> Protocol 2     

  #Disable root login
  PermitRootLogin yes -> PermitRootLogin no

  #Disable allowing all system accounts to ssh in, 
  # only allow certain users (space delimited)
  AllowUsers userName1 userName2 userName3

  # Change Default port
  Port 22 -> Port 2200
 
After making the changes, restart the SSH server for the changes to take affect:
 
$ /etc/init.d/ssh restart
 
"Partition for security"
 

File system security

      The UNIX file system has several standard directories: /, /tmp, /var, /usr and /home. The two that present the weakest links for a variety of attacks are /tmp and /var. The two most common attacks are: “Denial of Service”, by causing the root partition to fill up with logs or other junk (assuming all these directories are mounted on one partition); and running rootkits from the /tmp directory.

     One solution to file system Denial of Service attacks is to have these directories mounted on their own partitions, this will prevent the / file system from filling up and stop that avenue of attack.
Rootkits typically write to the /tmp directory and then attempt to run from /tmp. A crafty way to prevent this is to mount the /tmp directory on a separate partition with the noexec, nodev, and nosuid options enabled. This prevents binaries from being executed under /tmp, disables any binary to be suid root, and disables any block or character devices from being created under /tmp.

Edit /etc/fstab with your favorite editor, find the line corresponding to /tmp and change it to look like this one.
 /dev/hda2  /tmp  ext3  nodev,nosuid, noexec  0  0 

Wikipedia [6] defines rootkits as a set of software tools frequently used by a third party (usually an intruder) after gaining access to a computer system. This translates to custom versions of ps that won’t list the irc server the attacker installed, or a custom version of ls that doesn’t show certain files. Tools like chkrootkitfcheck to prevent the successful deployment of rootkits. must be run in combination with IDS systems like

chkrootkit is very simple to run, and doesn’t require any installation or configuration.

It’s a good idea to run chkrootkit at regular intervals, see the script below used by fcheck for inspiration.

# Use the wget utility to download the latest version of chkrootkit

# wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz 
# tar -xzvf chkrootkit.tar.gz 
# cd chkrootkit-version (whatever version is) 
# ./chkrootkit 

The next layer of file system security is maintaining and verifying the integrity of configuration files that are typically located under /etc. Intrusion Detection Systems (IDS) allow us to create cryptographic identifiers of important configuration files and store them in a database. They are then periodically re-created and verified against those stored in the database. If there is a mis-match, the file has been changed, you know your system integrity has been violated and which aspects of it are affected. Two well known IDS packages are tripwire and fcheck, which work equally well. However, fcheck has a much simpler configuration and installation process, which is why I favored it for this article.


fcheck

      Download fcheck (see resources) and unpack it. fcheck is a cross-platform Perl script which runs on UNIX and Windows systems (as long as they have Perl installed).

 $mkdir /usr/local/fcheck
  $cp fcheck /usr/local/fcheck
  $cp fcheck.cfg /usr/local/fcheck 
 
Edit /usr/local/fcheck/fcheck.cfg with your favorite editor and change the following values:


Directory, FileTyper, Database, Logger, TimeZone, and Signature.
  # Directories that will be monitored
  # if there is a trailing / it will be recursive 
  Directory       = /etc/
  Directory       = /bin/
  Directory       = /sbin/
  Directory       = /lib/
  Directory       = /usr/bin/
  Directory       = /usr/sbin/
  Directory       = /usr/lib/
  TimeZone        = PST8PDT # For Pacific Standard
  # Database of file signatures
  DataBase        = /usr/local/fcheck/sol.dbf
  Logger          = /usr/bin/logger -t fcheck 
  # Utility to determin file type
  FileTyper       = /bin/file 
  # What to use to create signatures Database of 
  # file signatures
  $Signature      = /usr/bin/md5sum#
  DataBase        = /usr/local/fcheck/sol.dbf
  Logger          = /usr/bin/logger -tfcheck
  # Utility to determin file type
  FileTyper       = /bin/file  

Also edit the fcheck script and change the path of the configuration file to
/usr/local/fcheck/fcheck.cfg

Then run fcheck for the first time to create the baseline database.

# Options explained:
# c create the database
# a is for all
# d is to monitor directory creation 
# s is to create signatures for all files
# x is for extended permissions monitoring

$ ./fcheck -cadsx 
 
Testing fcheck:
To test that everything has been setup correctly run the following commands and fcheck should alert you to the difference.
$ touch /etc/FOO $ ./fcheck -adsx
  fcheck should display some information about /etc/FOO. $rm /etc/FOO will prevent future messages.

Next, create a short shell script that will be run periodically by cron and check for changes.
"When using the `cron` utility lookout for _symlink attacks_"

Open your favorite editor and create /usr/local/bin/fcheck_script.



#!/bin/bash

  # Use mktemp instead of $$ to prevent sym-link attacks
  FCHECK_LOG=`mktemp`

  # Grep for any changes  
  /usr/local/fcheck/fcheck -adsx | grep -Ev ^PROGRESS: |^STATUS:^$ > $FCHECK_LOG

  # If there were any changes email the sys-admin
  if [-s $FCHECK_LOG ] then
      /usr/bin/mail -s fcheck `hostname` youremail@yourprovider.com  < $FCHECK_LOG
      /bin/rm $FCHECK_LOG
  fi
The cron utility will be used to run periodic checks of the file-system and will compare it to the baseline database. The following command will edit root’s crontab:
$ crontab -e

# Add this line to run the script every 15 minutes 
# using nice lower priority when the system load 
# is high.
*/15 * * * * nice /usr/local/bin/fcheck_script > /dev/null
 
Symlink Attacks
      Side Note: Symlink Attacks running an IDS package usually involve running a script at a pre-configured time using the cron utility. This opens up systems to symlink attacks. Symlink Attacks rely on the attacker knowing that a certain file is going to be created at a certain time with a certain name. A common shell scripting technique that generates some randomness is the use of $$, which is the PID of the running script. However, this is vulnerable to Symlink Attacks because most PIDs are below 35K and most file systems can have 35K files. The correct technique is the use of mktemp, which is a truly random file name.


Install and configure common services

      At this stage, you should have a solid base to build upon. The next step is to compile and install the software servers you will use to serve up your web applications. Installing software from source can be tedious; and there is a great temptation to use the packaged binaries that come with your distribution of choice. I would recommend against this. In a world of zero day exploits, the time it takes the package maintainer to compile and distribute the binaries may be unacceptable. By compiling from the source, you will be in full control of your security situation.


Apache 2.2.0

      Now to start compiling and install the services you will be using. Apache is a good place to start, since other packages have compile time dependencies on it.
"Always verify the `checksums` of packages you download, if there is a mismatch start over and download it again "

# md5sum httpd-2.2.0.tar.gz  
# tar -xzvf httpd-2.2.0.tar.gz 
# ./configure --prefix=/usr/local/apache --enable-ssl --enable-speling --enable-rewrite --enable-proxy  
# make  
# make install 


MySQL 5.0.18

      Download the MySQL binaries from the mysql site (see resources). This is an exception to my mantra of compiling from source—since the binaries come directly from MySQL, as soon as there is an update you can download the latest version.

Note: due to space constraints {.} is shorthand for the version of the tarball.

#  md5sum mysql-{.}-linux-i686-glibc23.tar.gz
#  cp mysql-{.}-linux-i686-glibc23.tar.gz /usr/local
#  tar -xzvf mysql-{.}-linux-i686-glibc23.tar.gz
#  ln -s /usr/local/mysql-{.}-linux-i686-glibc23 /usr/local/mysql
        
#  groupadd mysql
#  useradd -g mysql mysql
#  cd mysql
#  scripts/mysql_install_db --user=mysql
#  chown -R root  .
#  chown -R mysql data
#  chgrp -R mysql .
#  bin/mysqld_safe --user=mysql &
#  cp  support-files/mysql.server /etc/init.d/mysql
     
#Make sure that mysql is started if there is a reboot
  
#  cd /etc/rc3.d/
#  ln -s /etc/init.d/mysql S90mysql
#  ln -s /etc/init.d/mysql K90mysql

#Copy the configuration file
 
#  cp support-files/my-medium.cnf /etc/my.cnf


PHP 5.1.2

 Now download the php package from the php.net site (see resources).
 
#  md5sum php-5.1.2.tar.gz
#  tar -xzvf php-5.1.2.tar.gz
#  ./configure --with-prefix=/usr/local/php --with-apxs2=/usr/local/apache/bin/apxs --with-mysql=/usr/local/mysql
#  make
#  make install
#  cp php.ini-dist /usr/local/php/php.ini


Tomcat 5.5.16

 Apache-Tomcat is also an exception to my always compile rule.
 
#  md5sum apache-tomcat-5.5.16.tar.gz
#  tar -xzvf apache-tomcat-5.5.16.tar.gz
 

mod_jk

 Download mod_jk from the the tomcat project page (see resources).

# tar -xzvf jakarta-tomcat-connectors.tar.gz
# cd jakarta/jk/native 
# ./configure --with-apxs=/usr/local/apache/bin/apxs 
# make 
# make install
 

mod_securitymod_security is the most excellent Apache module written by Ivan Ristic.

# md5sum modsecurity-apache-1.9.2.tar.gz 
# tar -xzvf modsecurity-apache-1.9.2.tar.gz 
# cd modsecurity-apache-1.9.2/apache2 
# /usr/local/apache/bin/apxs -cia mod_security.c
 
Configuring Apache 2.2.0

     By this point, you should have installed all of the services and apache modules needed to host and secure PHP and Java environments. Now it’s time to take a look at properly configuring everything for security.

_Apache 2.2.0_ has the ability to list both statically compiled and shared modules with the `-M` option to `apachectl`

Apache 2.2.0 introduces a new configuration layout and new default options in the httpd.conf file. In previous versions of Apache, there was only one configuration file by default, which was conf/httpd.conf; in the current version, the Apache project has taken another step towards its goal of making configuration more managable and modular. The conf/httpd.conf is the main configuration file with include statements for the various configuration files under conf/extra such as httpd-ssl.conf and httpd-vhosts.conf.


 
 Another new and exciting security feature in Apache 2.2.0 is that the root httpd.conf access is denied to all directories. This can be confusing to users coming from previous versions such as 2.0.55 but it is a great step forward in terms of security.

Here is the configuration directive mentioned above; I would suggest leaving it the way it is. We will allow access for specific virtual-hosts and directories later on.
 
  # Default access control Highly restrictive and applies  to everything below it.
  
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
  
 
Every host, which Apache will be responsible for, will be a virtual host or “vhost”. So, start by uncommenting the Include directives at the bottom of conf/httpd.conf. This is done so that the httpd-vhosts.conf, httpd-ssl.conf and httpd-dedfault.conf are included in the main httpd.conf configuration file.
Yet another cool new feature in Apache 2.2.0 is the ability to see all modules both statically compiled and shared with the -M option to apachectl.

  # Edit /usr/local/apache/conf/httpd.conf

  # Move the LoadModule Statement for mod_security 
  # to the top of all module
  # statements. This is needed to use SecChrootDir

  # Add the following line to load mod_jk
   LoadModule jk_module   modules/mod_jk.so

  # The default User and Group is set to daemon, 
  # create and apache user and group and then 
  # configure apache to run as such.
  User apache
  Group apache
 
# List all modules to verify that mod_jk, mod_security, mod_php, and mod_ssl are correctly installed and loaded.
 
 # /usr/local/apache/bin/apachectl -M 
      
  # Virtual hosts 
  
  Include conf/extra/httpd-vhosts.conf -> Include conf/extra/httpd-vhosts.conf 
     
  # Various default settings
  Include conf/extra/httpd-default.conf -> Include conf/extra/httpd-default.conf 

  # Secure (SSL/TLS) connections
   Include conf/extra/httpd-ssl.conf -> Include conf/extra/httpd-ssl.conf 

 
Now it’s time to descend into the extra directory to configure virtual hosts. Open httpd-vhosts.conf in your favorite editor. Next, configure the document root to be /srv/www/vhost1. Also, add the AddType directive for php. PHP files don’t have to have the .php file extension. In fact, it’s probably a good idea if they are .html files. By using the .php file extention you are advertizing more information about your setup than you need to.
`mod_security` makes `chrooting` Apache easy!

Here is the full vhost configuration stanza. It is annotated with inline comments: please take the time to read through it.

 # Enable mod_security engine
 
  SecFilterEngine On

  # Chroot Apache the easy way just make sure your web content is under the chrooted directory
  # Note: The log directives must also be valid directories releative to the chroot dir.
  # Note: THIS CANNOT GO INSIDE VHOST STANZA as it applies to the entire apache configuration
 
  SecChrootDir /chroot/apache
       
  # Delete the 2nd Vhost stanza as you will only be using one for now
 
    
    ServerAdmin webmaster@mydomain.com
    DocumentRoot /srv/www/vhost1
    ServerName vhost.mydomain.com
    ServerAlias www.mydomain.com
    ErrorLog logs/vhost.mydomain.com-error_log
    CustomLog logs/vhost.mydomain.com-access_log common

    # The PHP engine will interpret all 
    # .php and .html files for php code
 
    AddType application/x-httpd-php .php .phtml .html
    AddType application/x-httpd-php-source .phps

    # Add a local Directory directive to override the global Deny From all in conf/httpd.conf
 
     
      Options FollowSymLinks
      AllowOverride None
      Order deny,allow
      Allow from all
    

    # Restrict Access to sensitive files
 
   
      Deny from all
    
    
    # Configure MOD_JK
 
    JkWorkersFile "/usr/local/apache/conf/workers.properties"
    JkLogFile     "/usr/local/apache2/logs/mod_jk_www.log"
    JkLogLevel info
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
    JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
    JkRequestLogFormat "%w %V %T"
                
    # Any URL that begins with /java/ will be forwarded to the java webapp in tomcat
 
    JkMount /java/* ajp13

    # Enable and configure MOD_SECURITY
                
    # See the mod_security documentation link in resources [3]
    # POST Scanning is disabled by default
 
     SecFilterScanPOST On
                
    # Make sure only content with standard encoding types is accepted
 
    SecFilterSelective HTTP_Content-Type "!(^$|^application/x-www-form-urlencoded$|^multipart/form-data;)"

    # Default Action is to reject request, log, and then return HTTP Response 404 which is 
    # File Not Found. Another option would be 403 which is access denied.
 
    SecFilterDefaultAction "deny,log,status:404"
                
    # Enable URLEncoding validation. This can prevent Cross-Site Scripting attacks 
 
    SecFilterCheckURLEncoding On

    # Catch and Prevent PHP Fatal Errors from  being displayed to the USER
 
    SecFilterSelective OUTPUT "Fatal error:" deny,status:500
    
    # Obviously you have to code up this custom Error Page
 
    ErrorDocument 500 /php-fatal-error.html 
                
    # This can be useful to avoid stack overflow attacks default is 0 255 ie All bytes allowed
 
    SecFilterForceByteRange 32 126



Here is the mod_jk configuration file apache/conf/workers.properties (referenced above):

  worker.list=ajp13
  workers.tomcat_home= /usr/local/java/apache-tomcat-5.5.12
  workers.java_home=/usr/local/java/jdk1.5.0_06
  worker.ajp13.type=ajp13
  worker.ajp13.host=localhost
  worker.ajp13.port=8009
 
 
"Apache can be used to configure other web consoles such as the Tomcat Manager application"
 
The configuration stanza below is a variation on an article: 
 

  ServerAdmin webmaster@zero-analog.com
  DocumentRoot /srv/www/hercules.zero-analog.com
  ServerName hercules.zero-analog.com
  ErrorLog logs/hercules.zero-analog-error_log
  CustomLog logs/hercules.zero-analog-access_log common

  
      Options FollowSymLinks
      AllowOverride None
      Order deny,allow
  

  
      Deny from all
  

  # This whole stanza is really to forward http requests to https:// tomcat manager
  # so appended /html to the rewrite target. since the full path is manager/html 

  
   
       
         RewriteEngine on
         RewriteCond %{HTTPS} !^on$ [NC]
         RewriteRule . \
          https://%{HTTP_HOST}%{REQUEST_URI}/html [L]
        
   
  



# This is the ssl-vhost under extra/httpd-ssl.conf 


  # General setup for the virtual host
  DocumentRoot "/srv/www/outpost.zero-analog.com"
  ServerName hercules.zero-analog.com:443
  ServerAdmin webmaster@zero-analog.com

  ErrorLog /usr/local/apache2/logs/error_log
  TransferLog /usr/local/apache2/logs/access_log

  
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
  
  


  RewriteEngine on
  RewriteRule "^/manager$" "https://outpost.zero-analog.com/manager/html" R,L]


   JkWorkersFile "/usr/local/apache2/conf/workers.properties"
   JkLogFile     "/usr/local/apache2/logs/mod_jk_hercules.log"
   JkLogLevel info
   JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
   JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
   JkRequestLogFormat "%w %V %T"
   JkMount /manager/* ajp13


   #   Enable/Disable SSL for this virtual host.
   SSLEngine on
 
   # List the ciphers that the client is permitted 
   # to negotiate. See the mod_ssl documentation
   # for a complete list.
   SSLCipherSuite  ALL:!ADH:!EXPORT56:RC4+RSA: +HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

   # Server Certificate: Point SSLCertificateFile
   # at a PEM encoded certificate.
    
   SSLCertificateFile /usr/local/apache/conf/server.crt

   # Server Private Key:
   SSLCertificateKeyFile /usr/local/apache/conf/server.key

   SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
   
   
           SSLOptions +StdEnvVars
   
   
   
           SSLOptions +StdEnvVars
   

   BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
 

   # Per-Server Logging:
   # The home of a custom SSL log file. 
   # Use this when you want a compact non-error 
   # SSL logfile on a virtual host basis.
   
   # *** Note there are \ characters in this string. These are not my artificial line-breaks, please include them ***
   
   CustomLog /usr/local/apache2/logs/ssl_request_log %t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"


 
 

Configuring PHP


I have already copied the php.ini to /usr/local/php/php.ini so that it will be read by the PHP engine at startup. By default it’s fairly secure, but there are one or two things you can do to improve security.
"Disable PHP display_errors for security"

# Edit /usr/local/php/php.ini with your favorite editor
 # Since you're are going through the trouble of 
  # hiding PHP files you might as well disable 
  # this as well
   expose_php = On -> expose_php = Off 
        
  # You really don't want users, or worse yet an attacker to see error messages
   display_errors = On -> display_erros = Off 

  # But you do want them logged \
  log_errors = Off -> log_errors = On 
  
  # Log to a file
  ;error_log = filename -> error_log = /var/log/php-err 

     Another option to consider is the Hardened-PHP project (see resources section). This is the brain child of three German developers,who continously perform code audits of popular PHP applications. They also release a patch for the standard PHP code, which fixes bugs and security holes in fringe configuration cases, where the main project developers have not had the time or the desire to find a fix.

Configuring Tomcat

      The main configuration files from Tomcat are under $CATALINA_HOME/conf. The following files are of interest:
  • tomcat-users.xml
  • server.xml
  • web.xml
As you might have guessed, the tomcat-users.xml file contains user access information. It is important to create a custom user with a hard-to-guess password for the manager application.

# Edit tomcat-users.xml with your favorite editor and append the following line.

        roles="admin,manager,tomcat,role1"/> 
 

Another important tenet of security is preventing information leakage. That’s why you enable PHP pages to masquerade as html files. It’s also why you want to disable directory listings in Tomcat. This is achieved by editing the tomcat/conf/web.xml file.

# Open web.xml in your favorite editor and look for the following lines:

    listingsfalse 

  # The default value is true, which enables directory listings, simply change this to false
  # to prevent tomcat directory listings.
 
 
You can also hide JSP files by using a servlet-mapping directive in the webapps web.xml configuration file. The following lines will map all html files to the JSP servlet, which is internal to Tomcat.
Note: The listing above goes in the main tomcat/conf/web.xml, while this listing should go in the web.xml of each application.
You can put it in the main web.xml. However, there may be cases where this is undesirable.
 

    jsp
      *.html
   
I want to restrict access to apache-tomcat to control the flow through Apache. iptables is already blocking port 8080 by default, but following the onion principle I’m going to bound Tomcat to loop-back device. This will prevent direct traffic to Tomcat in case of any unforeseen circumstances such as the iptables rules being flushed.



# Open sever.xml in your favorite editor and look for the following lines:

   maxThreads="150" minSpareThreads="25" 
   maxSpareThreads="75" enableLookups="false" 
   redirectPort="8443" acceptCount="100"
   connectionTimeout="20000" 
   disableUploadTimeout="true" />

 # And change to this:

  
  
     address="127.0.0.1" maxThreads="150" 
     minSpareThreads="25" maxSpareThreads="75"
     enableLookups="false" redirectPort="8443" 
     acceptCount="100"  connectionTimeout="20000" 
     disableUploadTimeout="true" /> 
 

Configuring MySQL


The default MySQL installation is not very secure. This is the case when it is installed manually and also when you use your distribution’s precompiled binaries. The default root password is blank, which means anyone can login is as the DBA. This is understandable, as, obviously, a DBA has to login to set the password. However, it’s too easy to forget that anyone can login as the MySQL root user and anonymous users are also enabled by default.









# Set the root password
mysqladmin -u root -h localhost password subGen1us 
  
# Once this is done, log in as the root user and 
# disable anonymous accounts
mysql -u root -p
  
# Drop the test database which comes installed 
# by default
mysql> drop database test;
        
# Disable anonymous accounts
mysql> use mysql;
       
mysql> delete from db where User=’’;
mysql> delete from user where User=’’;
        
# Change DBA NAME
mysql> update user set user="mydbadmin" \ 
          where user="root";

mysql> flush privileges;

# Make sure to login again to make sure 
# all the changes work

mysql -u mydbadmin -p
password: subGen1us

# Configure /etc/my.cnf for security Uncomment  the following line to disable TCP connections 
# to mysql.  As with tomcat this prevents remote connections event in the even of the firewall
# even in the even of the firewall rules being flushed.
  
skip-networking

Security mistakes in web applications

      Now that you are done with configuration, it’s time to put your web developer hat on. You now have a very solid base upon which to build your web applications. This brings me to the Achilles heal: the web applications themselves.
 

What is Cross Site Scripting (XSS)?


Wikipedia [4] defines the term Cross Site Scripting as inaccurate as it really refers to an entire class of vulnerabilities. In general XSS vulnerabilities come down to an age old security problem: not verifying user input. The most common vector of attack is when data is passed to a processing program such as a PHP or JSP script, and then printed back out to the page without being URLEncoded.
The following (highly contrived) PHP code is vulnerable to XSS. If the database to this PHP script contains javascript, it will be executed.

"Never trust user input, it is the root of all evil"
# Vulnerable Code
                        $userInput = $_GET['input'];
                print $userInput;
        ?>
        
        # Secure Code
                    $userInput = urlencode($_GET['input']);
            print $userInput;
        ?> 
 
 
JSP’s or Java Servlets are no less vulnerable. First of all, it is
important to understand that all JSP’s are compiled to servlets the
first time a JSP is called. So, the two are basically the same thing,
with different source code representations. 
Here is the same vulnerability in the Java world.
Note: JSP’s have access to the same HttpServletRequest object as the servlets they are compiled to.
 So, in a JSP page, this would manifest itself as request.getParameter().

# Vulnerable Code
  public class myServlet extends HttpServlet {
    public static void doGet 
              (HttpServletRequest req, 
               HttpServletResponse res) {
                        
     // Get User Input       
     String userInput = req.getParameter("input");

     // Print User Input to page
     PrintWriter out = response.getWriter();
     out.write("");
     out.write(userInput);
     out.write("");
                        
   }
  }

  # Secure Code
  import java.net.URLEncoder;
  public class myServlet extends HttpServlet {
    public static void doGet 
              (HttpServletRequest req, 
               HttpServletResponse res) {
                        
       // Get User Input       
       String userInput = req.getParameter("input");
       // URLEncode Input
       userInput = 
            URLEncoder.encode(userInput, "UTF-8"); 

       // Print User Input to page
       PrintWriter out = response.getWriter();
       out.write("");
       out.write(userInput);
       out.write("");
                        
   }
  }
 
 
 

What is SQL Injection?

      SQL Injection is the ability to insert and execute arbitrary SQL code through a web-application. Like XSS attacks, it involves mishandling user input. In this case, properly escaping the input that is to become part of the SQL query. The PHP solution is to use the mysql_real_escape_string statement, and the java solution is to use PreparedStatements, with the user input as bind variables.
The following code snippets are from Wikipedia [5]:

# Partial PHP
  $query_result = mysql_query
   ( "select * from users where name = \""
       .
      mysql_real_escape_string($user_name)
       .
      "\"" );

  # Partial Java, ? is the bind variable
  Connection con = (acquire Connection)
  
  PreparedStatement pstmt = 
    con.prepareStatement
       ("SELECT * FROM users WHERE name = ?");
  
  pstmt.setString(1, userInput);
  ResultSet rset = pstmt.executeQuery()


Conclusion

      There is no magic bullet. “Conclusion” is a misleading heading: there is no conclusion when it comes to security. Security holes are constantly found and patched. Attackers change their methods, and security professionals respond; it is a process, rather than a result. When it’s implemented correctly, this process can mitigate or prevent the damage done by attacks.
There is a silver lining: there is an entire community of security professionals sharing their experience, tips and tricks on the web. Sites like Securityfocus.com provide heaps of useful information, and the latest trends in security. It’s also the home of bugtraq, a mailing list of security holes that I highly recommend you subscribe to. Sites like freshmeat.net are the yellow pages of free software projects, listing new releases and updates. All of these sites have RSS feeds, a resource I would also recommend you take advantage of to stay abreast of the latest news.

Resources


Reference

http://fsmsh.com/1255