Dustin Larmeir

Cloud Sales Engineer | Security Solutions Architect | Linux Fanatic

A few mod_security tips

ModSecurityLogo

Introduction

The mod_security WAF is an open source web application firewall platform that highly tunable, scalable, and battle tested. WAFs are a requirement for various regulatory compliance frameworks and they are also a crucial part of a defense-in-depth strategy with the goal being to drive up the skill level of the attacker and block automated bot attacks. While mod_security was not designed to protect a larger network like a dedicated WAF appliance or Nextgen UTM, it can be leveraged through a reverse proxy to protect multiple web servers running behind it. This WAF platform is not for the faint of heart however as you must have some deep level Linux administration skills to make adjustments to the WAF and to properly handle exceptions to rulesets that have been developed. Luckily, OWASP has created the CRS (Core Rule Set) and it provides a great start towards blocking common attacks such as XSS, SQL Injection, CSRF, and others.

Installation

The basic installation of mod_security is pretty simple so I won’t spend a lot of time on this one. The major Linux Distros already have a version available in their mirrors and so you should search with your favorite package management tool and install it.

If you’re doing the install in Ubuntu just run the following command:

# apt-get install libapache2-mod-security2

Pretty simple! You can also verify that the module is enabled with a quick apachectl command:

# apache2ctl -t -D DUMP_MODULES | grep security
 security2_module (shared)

Basic Rulesets

Once you finish the installation there is no protection occurring on your web server. There are a few things you must finish up before mod_security will bring effective protection to your server.

Here’s a quick list:

  • Installation of a core set of rules ( I.e. OWASP CRS, Comodo WAF, or commercial feeds such as Trustwave’s Service)
  • Adjustment of the main mod_security.conf file (the core rule sets handle most of this for you)
  • Setting the SecRuleEngine from DetectionOnly to On in the modsecurity.conf ( you will want to wait to do this  – see going live below )

Testing and Validation

When you finish the installation of the core rule sets the SecRuleEngine will be in Detection mode by default. You should do some extensive QA testing on your site and watch the Apache error log to see if any WAF block IDs start to show up. If you do see blocks then it’s a great time to go and make adjustments ( I.e. Exceptions, Rule Adjustments, Disabling Rules, Etc.)

This article on the Trustwave’s site has a great write up on this topic: https://www.trustwave.com/Resources/SpiderLabs-Blog/ModSecurity-Advanced-Topic-of-the-Week–(Updated)-Exception-Handling

The Testing and Validation process is the hardest part of WAF implementation since you will have to troubleshoot and false positive blocks are normal with all WAF platforms. In a nutshell, DetectionOnly is a learning mode where you can grab the event ID’s and make adjustments without production impact.

Here’s an example of a rule bypass for a specific script:

<LocationMatch "/somepath/wafexample.php">
  SecRuleRemoveById 970903

This will allow a given rule to not apply to a specific script.

Going Production

Once you are ready to bring the WAF live and you have sufficiently tested the site or application then it’s time to make the following adjustment in your mod_security.conf.

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
#SecRuleEngine DetectionOnly 
SecRuleEngine On

As you can see with the example above I just commented out the DetectionOnly directive and added SecRuleEngine On. Once the Apache server is restarted the WAF will be 100% live.

Important Tip!

If you’re going to be pushing updates to the site on a regular basis and want to avoid false positive blocks you can bypass the WAF by adding your IP Address to a whitelist. The WAF my nature will interfere with the development process so why bother with it? This also allows you to avoid putting unnecessary exceptions in place.

For the IP whitelist I added a file called modsecurity_crs_10_whitelist.conf and created the following rule:

SecRule REMOTE_ADDR "^10\.0\.1\.11$" phase:1,log,allow,ctl:ruleEngine=Off,id:999945

When connecting from this IP it may throw up warnings in the event of a block but it will not enforce. This is great when you are using a blogging platform such as wordpress or a dynamic content site.

Conclusion

While I am no expert with mod_security I just thought it might be useful to share my experiences with it. It is a solid platform to help mitigate the risks of human coding errors but should not be a replacement for good development security practices.

-Dustin

Restricting wp-admin by IP through CloudFlare’s Proxy

Cloudflare-logo-horizontal
I’m a firm believer in the concept of “if you don’t need to expose it you shouldn’t.” When I think of WordPress’s admin interface that is exactly what comes to my mind so I always lock them down. I use CloudFlare for most of my WordPress deployments since it helps with SSL offloading, some basic bot blocking, and has a robust CDN capability. One of the lessons I learned from CloudFlare is that it is just a giant proxy so you need to account for X-Forwarded-For headers to obtain the real IP addresses of your visitors. To facilitate a simple block on an IP basis on the server you need to include X-Forwarded-For on your .htaccess rules as the example shows below:

#Cloudflare IP
SetEnvIf X-FORWARDED-FOR your.ip.address allow
SetEnvIf X-FORWARDED-FOR some.other.ip.address allow
SetEnvIf X-FORWARDED-FOR another.ip.address allow
order deny,allow
deny from all
allow from env=allow

Just drop this in the wp-admin directory and it will look at the real IP being passed through CloudFlare to prevent unauthorized access.

-Dustin

Ubuntu 14.04 Apache Hardening Script 1.0

hardened_apache
I’m always automating things for myself because I hate performing repetitive tasks over and over again. With that, I present to you a very basic Apache hardening script that you can run on a fresh install of Ubuntu 14.04 LTS.

In a nut shell it does the following:

  • Prints information about the server.
  • Disables the Directory Indexing Module
  • Disables Mod Status
  • Adjusts Server Tokens to Prod
  • Turns off the Server Signature
  • Ensures Trace Enable is Off
  • If the Ubuntu Distro Apache page exists it removes it automatically. I am going to incorporate more features later but this script does work.

The source code is posted below:

#!/bin/bash
##############################################
# Ubuntu Hardening Script for Apache Servers #
#     THIS IS FOR FRESH INSTALLS ONLY        #
#       11/21/2015 - Dustin Larmeir          #
#       Tested on Ubuntu 14.04 LTS           #
##############################################


####################
# Apache Hardening #
####################

# Start Script
echo "*** Starting Hardening Script ***"
echo ""
date
cat /etc/lsb-release 
apache2ctl -v
sleep 2
echo ""

# Disable Directory Index Module
echo "*** Disabling Directory Indexing ***"
a2dismod autoindex
sleep 1
echo ""

# Disable Apache Status Module
echo "*** Disabling Mod_Status ***"
a2dismod status
sleep 1
echo ""

# Getting rid of nasty and revealing Server Tokens
echo "*** Adjusting ServerTokens to Prod ***"
ServerTokens=Prod
sed -i 's/ServerTokens .*/ServerTokens '${ServerTokens}'/' /etc/apache2/conf-enabled/security.conf 
sleep 1
echo "Done"
echo ""

# Getting rid of nasty and revealing Server Signatures
echo "*** Removing Server Signatures ***"
ServerSignature=Off
sleep 1
sed -i 's/ServerSignature .*/ServerSignature '${ServerSignature}'/' /etc/apache2/conf-enabled/security.conf
echo "Done"
echo ""

# Disable Trace Enable
echo "*** Ensuring Trace Enable = Off ***"
TraceEnable=Off
sleep 1
sed -i 's/TraceEnable .*/TraceEnable '${TraceEnable}'/' /etc/apache2/conf-enabled/security.conf
echo "Done"
echo ""

# Remove Default Site Files
echo "*** Removing Default Distro Index.html ***"
defaultpage=$(cat /var/www/html/index.html | grep -i "Apache2 Ubuntu Default Page" | tail -n1)
pagexists=$(echo "$defaultpage" | awk '{print $3}')
   if [ "$pagexists" = "Default" ]; then
      rm /var/www/html/index.html
   else
      echo "Default Page Already Removed"
   fi
sleep 1
echo "Done"
echo ""

# Restart Apache
service apache2 restart
#lsof -i :80 | awk '{print $1,$9,$10}' | uniq
echo ""
echo "*** Hardening Completed ***"
echo "If you notice any issues with this script please email dustin@larmeir.com"

#rm apache_harden.sh
########################
# End Apache Hardening #
########################

If you have any questions about the script or want to contribute to some of my hardening projects let me know!
-Dustin

Quick Ping Packetloss Script

This is not my finest work but I needed to put a ping packet loss test script together in a pinch that would log the result and run until I stopped it.

Here’s what I came up with:

#!/bin/bash
# Very Basic Ping Script
 
# Enter the domain to be monitored here
domain=somedomain.com
 
while :
do
 
# Line Separation
echo "###############################">>ping.log;
 
# Date Stamp Log
echo `date` >>ping.log
 
# ping starget host for 5 ping intervals
ping -c5 $domain | grep loss | awk '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10}' >>ping.log
 
# optional (enable verbose ouput to console)
# cat ping.log
 
        sleep 1
done

The ping.log it generates looks like this:

$ cat ping.log 
###############################
Tue Nov 10 05:05:44 CST 2015
5 packets transmitted, 5 packets received, 0.0% packet loss 
###############################
Tue Nov 10 05:05:49 CST 2015
5 packets transmitted, 5 packets received, 0.0% packet loss 
###############################
Tue Nov 10 05:05:54 CST 2015
5 packets transmitted, 5 packets received, 0.0% packet loss 
###############################
Tue Nov 10 05:05:59 CST 2015
5 packets transmitted, 5 packets received, 0.0% packet loss 

Not fancy but it works…

Toshiba Satellite C55D-B510 Hard Drive Upgrade

satellite-C55D-B5102-600-01

The Toshiba Satellite C55D-B510 is a low price system that runs great as an entry level laptop. A friend of mine recently purchased one for school and asked me to take a look at why it was performing super slow.

After investigating further aside from the bloatware issues, the laptop had a 5400 RPM Toshiba drive in it. I was unpleasantly surprised to find that this speed of SATA drive was still on the market! Luckily I just happened to have a 7200 RPM drive laying around that was brand new as I recently replaced my own laptop hard drive with a SSD. I figured since I had to pop the hood on this machine that I might as well take pictures and document it. Below are the steps to pull the drive and replace it!

Step 1. Remove the bottom cover – This process was fairly easy. Just simply remove the two screws that hold in the battery, pull the battery away from the laptop, and then remove the rest of the screws ( they are a small phillips head type screw). Start at the bottom right corner with the laptop upside down and the the battery bay facing away from you and gently pry the corners away from the chassis. Beware, if you feel to much resistance STOP and look for a screw you may have missed (it’s easy to do!).

IMG_0815

 

Step2. Locate the Hard Drive – The Hard Drive is located on the bottom left and is in a blue soft plastic enclosure. It’s held in my two tabs at the front that are sticking into two slots while the drive itself is held in by the sata power and sata connector ports.

IMG_0811

 

Step 3. Removing the Hard Drive – Simply pull the tabs up gently and release them from the slots. Then slightly pull up on the front of the drive and gently pull it away from the sata power and connector ports.

IMG_0814

 

Step 5. Remove the blue harness  – Take off the harness from the drive by simply slipping it off. The place it on the new drive and follow these steps in reverse!

 

IMG_0818

 

Step 6. Completion – Once everything is reassembled you have been upgraded!

It’s a pretty simple procedure and as you can see from the shot of the motherboard on step 2 you can also easily upgrade the memory on this system. By default it comes with 4GB of RAM in a single DIMM so you can easily add another. If you plan on going through this trouble I would definitely recommend a SSD if it is in the budget as an SSD will have a great impact on performance. Hope this helps someone out there!

-Dustin

 

Macrium Reflect – A Great Tool For Managing Disks and Backups

logo

I have recently needed to perform a few disk migrations via clones and I always need a solid backup solution for my Windows desktop machines. Macrium reflect always gets the job done!

The free version located here is a very feature rich offering and I could easily see myself paying for the full product license.

A few successful projects I have completed with this software are:

  • Creation of backup images.
  • Disk to Disk clones
  • Backups sent to network devices.

This review is short and sweet but it does not give this product the justice it deserves. If you are looking to clone a disk or backup your systems definitely take the time to check this software out!

– Dustin

 

Enabling Promiscuous Mode For A Vswitch On Vsphere 6

logo

I run a VMWare based infrastructure for my personal hosting projects and love it because of the Vswitch capabilities.

Since I am a firm believer in following security best practices on these type of deployment I have a NIDS service in path that is collecting information about threats that are being leveraged against my public facing services. To facilitate the monitoring of the traffic with my NIDS platform I have to be able to collect traffic data from the Vswitch and the simplest way to facilitate this is enabling promiscuous mode on the private Vswitch.

Here’s a quick walkthrough on how to complete this:

Step 1. Log into Vsphere and click on the host –> configuration –> and the corresponding Vswitch properties ( I.e. the screenshots below are for Vswitch 3)

Screen Shot 2015-07-18 at 6.26.26 AM

 

Step 2. On the next screen highlight the Vswitch and click –> Edit

Screen Shot 2015-07-18 at 6.26.48 AM

 

Step 3. From the Edit screen click –> Security

Screen Shot 2015-07-18 at 6.27.12 AM

 

Step 4. Check the Promiscuous Mode box and select “Accept” from the dropdown menu. Click –> OK

Screen Shot 2015-07-18 at 6.27.26 AM

You now have Promiscuous mode enabled on the Vswitch and can configure an NIDS system to monitor the ingress and egress traffic on the Vswitch.

If you have any comments or questions feel free to leave feedback below!

– Dustin

Quick and dirty nginx installation on CentOS 7

nginx

CentOS 7 is a great Linux distribution but one thing it does lack is an official Nginx package in the default distribution mirrors. There are a few methods of working around this including the use of EPEL but for this tutorial I will use Nginx’s official repository for the installation.

Let’s get started!

Step 1.
Establishing a connection to the repository via yum is simple. simply create and edit a new repository file as shown below:

vi /etc/yum.repos.d/nginx.repo

add the following:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

Step 2.
Next we will install the nginx server by running the following yum installation command:

yum install nginx

You will have to acknowledge the install but you can make this silent by adding a -y to the installation command if you wish.

Step 3.
One the installation is completed you can start the nginx server by running the following command:

service nginx start

Step 4.
You will probably want nginx to auto start at boot time. In CentOS 7 you will use the following systemd command to do this:

systemctl enable nginx

Step 5.
You can verify it is properly enabled by running the following command in systemd:

systemctl is-enabled nginx

If the output says “enabled” then nginx is properly set to start on boot.

Troubleshooting.
Here’s a few examples of useful commands to help you in the event you are having issues with your nginx server.

Check the sanity of a config file:

[example@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Check the status of the nginx server:

[example@proxy ~]# service nginx status
Redirecting to /bin/systemctl status nginx.service
nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled)
Active: active (running) since Sun 2015-02-15 11:15:22 CST; 25min ago
Docs: http://nginx.org/en/docs/
Main PID: 28703 (nginx)
CGroup: /system.slice/nginx.service
├─28703 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
└─28704 nginx: worker process

Feb 15 11:15:22 proxy.01.example.com nginx[28699]: nginx: the configuration...
Feb 15 11:15:22 proxy.01.example.com nginx[28699]: nginx: configuration fil...
Feb 15 11:15:22 proxy.01.example.com systemd[1]: Started nginx - high perfo...
Hint: Some lines were ellipsized, use -l to show in full.

In the event these two check out and it’s still not working you probably have a connectivity issue. The default policies on CentOS 7 have http blocked so that would be a great place to start assuming connectivity has been verified.

On a parting note one last step I would recommend when tidying up the install would be to disable the version header. You can edit the nginx.conf and add the following directive to do this:

server_tokens off;

This guide was meant to be very basic and I plan on doing a deeper dive into virtual hosts, proxies, and addition configurations in a future post.

Hope you enjoy!
– Dustin

18 Months Of Training Progress

As many of you know I started a health and fitness journey on April the 16th 2013. This video is a progress update of the last 18 months of work!

A little script I wrote in PHP for GeoIP lookups

Being fully transparent I am a system admin by trade so my code is not the greatest. That being said, I figured I would release a little bit of PHP code I wrote for a tool I have created as it is useful for pulling GeoIP data and displaying it in HTML.  It uses PHP Curl, gethostbyname, JSON decode, and the Telize.com JSON GeoIP webservice.

Enjoy!

 // PHP GeoIP Lookup Script - 11/15/2014 by Dustin Larmeir (dustin@larmeir.com)
// Form Input
$INPUT = $_POST['INPUT'];

// Grabs the domain name via the input form and converts it to a IP address
$hostname = $_POST['INPUT'];
$ipaddress = gethostbyname($hostname);

// Grabs IP address from form (basic method)
$url = "http://www.telize.com/geoip/".$ipaddress;
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$geoip_json=curl_exec($ch);
// Closing
curl_close($ch);

// get the results and json_decode the answer
$geoip_data = (json_decode($geoip_json, true));

// Echo output from JSON decoding and PHP arrays
echo "IP Address: "; echo($geoip_data["ip"]);
echo "Organization: "; echo($geoip_data["isp"]);
echo "City: "; echo($geoip_data[city]);
echo "State: "; echo($geoip_data[region]);
echo "Country: "; echo($geoip_data[country]);
echo "Time Zone: "; echo($geoip_data[timezone]);
echo "";

?>

Page 1 of 33

Powered by WordPress & Theme by Anders Norén