Russ McRee wrote an excellent article about OSSEC for the October 2009 issue of ISSA Journal. (Disclaimer: I contributed to the article.) He then went into some further detail on his blog.
In a recent SANS 401 Mentor session, I used OSSEC in my demo of building a secure webserver using defense-in-depth principles. My rough notes can be found below. All software is freely available and the whole process can be done in under an hour (depending on the speed of your Internet connection). Once completed, OSSEC will be monitoring all system logs (SSH, Apache, mod_security, iptables, Wordpress) and optionally providing Active Response, blocking attacker's source IP addresses.
# Go to http://isoredirect.centos.org/centos/5/isos/i386/, pick a mirror, and then download CentOS-5.4-i386-bin-1of6.iso (you'll only need CD #1)
# Boot a virtual machine from the ISO image -OR- burn the ISO to CD and boot a physical machine from it
# Only install what's absolutely necessary - perform a "Base" install of CentOS 5.4
# Reboot (and remove the CentOS CD)
# When "Setup Agent" appears, select "Firewall Configuration".
# SELinux is in Enforcing mode by default -- leave it that way!
# Go to Customize and allow SSH and HTTP in firewall
# Login as root with the password you specified in the installer
# Install all updates and reboot the machine:
yum -y update && reboot
# Add EPEL repo so that we can install mod_security, alpine, and wordpress
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
# Configure EPEL repo to only update mod_security, lua, alpine, and wordpress packages
vi /etc/yum.repos.d/epel.repo
# add this line in the [epel] section:
includepkgs=mod_security* lua* alpine* wordpress*
# Exit vi by pressing Esc and then typing :wq
# Install blog, web server, and database
yum -y install alpine wordpress mysql-server
# Set services to start on boot and start them now
for i in httpd mysqld
do
chkconfig $i on
service $i start
done
# Secure the database
/usr/bin/mysql_secure_installation
# Follow the prompts and create a new MySQL root password
# Start the MySQL command-line client
mysql -p
# Enter the MySQL root password you just created
# Create a database and user and give user all privileges to DB
create database w0rdpressDB;
grant all privileges on w0rdpressDB.* to w0rdpressUser@localhost identified by 'MyReallyReallyStrongPassphrase';
flush privileges;
exit
# Configure Wordpress to use the database and user we just created
sed -i 's|putyourdbnamehere|w0rdpressDB|g' /etc/wordpress/wp-config.php
sed -i 's|usernamehere|w0rdpressUser|g' /etc/wordpress/wp-config.php
sed -i 's|yourpasswordhere|MyReallyReallyStrongPassphrase|g' /etc/wordpress/wp-config.php
# Finish Wordpress configuration by pointing a browser to:
# http://ip.of.centos.vm/wordpress
# Enter a Blog Title
# Enter "root@localhost.localdomain" (without the quotes) as your email address
# Click "Install Wordpress"
# Login using the randomly generated password
# Once logged in, change your password
# Look at logs in /var/log/httpd/
tail access_log
tail error_log
# Check email with alpine to see Welcome email from Wordpress
alpine
# At this point, we've got a basic Wordpress web server.
# Now let's add some layers of instrumentation to augment our defense-in-depth.
# Configure Wordpress to log to /var/log/messages using the WPsyslog2 plugin
cd /usr/share/wordpress/wp-content/plugins
wget http://www.ossec.net/files/other/wpsyslog2.tar.gz
tar zxvf wpsyslog2.tar.gz
# Wordpress admin interface --> activate WPsyslog2 plugin
# Test logging into Wordpress, creating/deleting posts, verify logging in /var/log/messages:
tail /var/log/messages
# Configure IPTables firewall to log any dropped packets to /var/log/messages
iptables -I RH-Firewall-1-INPUT 11 -j LOG --log-prefix="DROP "
service iptables save
tail -f /var/log/messages
# Launch an nmap scan from another host and watch the dropped packets being added to /var/log/messages
# WAF (Web Application Firewall)
yum -y install mod_security
# Configure WAF for extra logging
# Add the following lines to /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf
SecDataDir /tmp
SecAuditEngine on
SecAuditLog logs/modsec_audit.log
# Restart the web server to activate the mod_security module
service httpd restart
# Test WAF by accessing site by IP address instead of hostname
# Test WAF by trying to do an /etc/passwd attack
# Look at ModSecurity alerts in /var/log/httpd/modsec_audit.log
more /var/log/httpd/modsec_audit.log
# Look at rules in /etc/httpd/modsecurity.d/
# NIDS (Network Intrusion Detection System)
# Install Snort:
rpm -Uvh http://dl.snort.org/snort-current/snort-2.8.5.3-1.RH5.i386.rpm
# Install PulledPork for Snort rules management:
yum -y install perl-libwww-perl
cd /usr/local/src/
mkdir pulledpork && cd pulledpork
wget http://pulledpork.googlecode.com/files/pulledpork-0.3.4.tar.gz
tar zxvf pulledpork-0.3.4.tar.gz
cd pulledpork-0.3.4
# Edit the PulledPork configuration file using vi
vi pulledpork.conf
# and change the following configuration directives
oinkcode=InsertYourOinkcodeHere
tar_path=/bin/tar
rule_path=/etc/snort/rules/
sid_msg=/etc/snort/sid-msg.map
sid_changelog=/var/log/snort/sid_changes.log
#sorule_path=/usr/local/lib/snort_dynamicrules/
config_path=/etc/snort/snort.conf
distro=CentOS-5.0
# Exit vi
# Make pulledpork.pl executable
chmod +x pulledpork.pl
# Execute pulledpork.pl with the new configuration file
./pulledpork.pl -c pulledpork.conf
# Start Snort
service snortd start
# Test Snort with idswakeup and verify logs in /var/log/snort/
# HIDS (Host Intrusion Detection System)
yum -y install gcc
cd /usr/local/src/
mkdir ossec
wget http://www.ossec.net/files/ossec-hids-2.3.tar.gz
tar zxvf ossec-hids-2.3.tar.gz
cd ossec-hids-2.3
./install.sh
# Local installation
# Email to root@localhost
# Enable Active Response, add any IPs to whitelist that you don't want to ever block
# Configure HIDS to monitor WAF logs by editing ossec.conf using vi
vi /var/ossec/etc/ossec.conf
# and copying one of the existing localfile entries and setting:
# log_format to syslog
# location to /var/log/httpd/modsec_audit.log
# Exit vi by pressing Esc and then typing :wq
service ossec start
# Check root email using alpine
alpine
# Test HIDS alerting
# Test OSSEC Active Response using nmap, idswakeup, SSH brute force, Wordpress brute force
What else could we do for more defense in depth?
- Suhosin (PHP Hardening)
- GreenSQL (Database firewall)
- Daemonlogger (full packet capture for forensics purposes)
- Others?