One site that I manage that has a lot of complex disease-related data that is given out for free to the public directly via the web site and also via an iOS app.  The entire site is dynamic and derived from multiple back end sources and subsequently causes a bit of a hit to render the information together.  We have often seen other entities (IPs originating from China & Germany recently) decide they want to “scrape” the entire site for all of the content without throttling their connections.  Due to our limited resources (only two front-end application servers), when someone hits us this way, this effectively creates a minor DoS for us.   The best place to try to control for these sort of scenarios would of course be at the load balancer device, but I don’t have control of configuration of them and so I have had to try to take matters into my own hands.

While there are quite a number of ways to cap someone’s impact on your server (mod_bw, mod_ratelimit, IP Tables, etc), most often, these are rendered fairly useless by the client’s IP being replaced by the IP of the LTM (traffic manager / load balancer).

Here’s how I effectively was able to limit other entities ability to hit our site beyond what it could handle.

Step 1:  Install mod_security (and mod_unique if not already loaded) – my mod_security was version 2.7 on CentOS

Step 2: Create a basic config for mod security
########## MOD SEC Basic Config File ###########
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so
SecRuleEngine On
SecDataDir /tmp
SecTmpDir /tmp
SecDebugLog /var/log/httpd_logs/modsec_debug.log
SecDebugLogLevel 0
##########################################

Step 3: Add the specific connection limiting configuration anywhere inside the VirtualHost directives of the site you are trying to protect:

####### SPECIFIC rate limiting for this site inside apache VirtualHost #########
<LocationMatch “^/(?!(?:jpe?g|png|bmp|gif|css|js|svg))(.*)”>
#counts everything but images and such
SecAction initcol:ip=%{X-Forwarded-For},pass,nolog,id:4444446
SecAction “phase:5,deprecatevar:ip.mysiteconncounter=1/1,pass,nolog,id:4444447”
SecRule IP:MYSITECONNCOUNTER “@gt 150” “id:4444448,phase:2,pause:300,deny,status:509,setenv:RATELIMITED,skip:1,nolog”
SecAction “id:4444449,phase:2,pass,setvar:ip.mysiteconncounter=+1,nolog”
Header always set Retry-After “15” env=RATELIMITED
</LocationMatch>
ErrorDocument 509 “Rate Limit Exceeded”
############## End rate limit configuration for virtual host here ###########

Step 4: Restart apache!

Some additional notes:
* You can limit what portion of your site is watched in the LocationMatch (instead of the whole site like I did)
* With Mod Security 2.7, I guess you need to add unique rule ID’s to each rule.  For these numbers I chose arbitrarily 4444446 – 4444449
* Change the “@gt 150” to a lower number if you want to lower the threshold for number of connections (each second the number of connections decreases by 1 for each IP) or the speed to which it deprecates the IP connection stat (1/1)
* If you would like to protect multiple sites (additional VirtualHosts on the same server), use a different variable for collecting IPs. In my case above I used “mysiteconncounter” so make sure it is something different, otherwise they will stomp on each other.
* You could probably return a different error code rather than 509 as it is only really partially supported out there.

 

We ended up getting a new Challenger 3000 Liebert (Emerson Power) HVAC unit in our data center recently.  We typically monitor everything using the Nagios system for our servers and we were pleased to find that inside the Liebert toward the top was a component that they refer to as the “Unity” module.  After reading some online user guides I was able to bind an IP to it and start querying it via SNMP.  Hint: the default username and password to get in to the web interface were both “Liebert”.  After looking around for a bit, I realized there weren’t any stock commands in Nagios via the check_snmp plugin to handle this, so I added some of my own.  Using snmpwalk, I was able to determine which of the OIDs I was interested in and made some custom command definitions.

Here’s the command definitions:

##########################################
# ‘snmp_lbenv_humidity’ command definition – consider anything under 21 percent critical
define command {
command_name    snmp_lbenv_humidity
command_line    $USER1$/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.5028 -l ‘\Return Humidity\’ -u ‘\%\’ -c @0:20.9 -w @21:35
}

# ‘snmp_lbenv_returnairtemp’ command definition – critical at 24 or more degrees Celcius
define command {
command_name    snmp_lbenv_returnairtemp
command_line    $USER1$/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.4291 -w 23 -c 24 -l ‘\Return Air Temp\’ -u ‘\Celcius\’
}

# ‘snmp_lbenv_hvacstatus’ command definition
define command {
command_name    snmp_lbenv_hvacstatus
command_line    $USER1$/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.4123 -l ‘\HVAC Status\’ -u ‘\Normal vs Abnormal\’ -s ‘”Normal Operation”‘
}

##########################################

I also set up nagiograph plugin in order to give me a quick historical overview of the changes in temperature and humidity.

HVAC

Pretty neat way to monitor the Liebert without having to set up anything additional!

My old wireless router had started having trouble and the wireless chipset was beginning to get flaky.  I’d been running DD-WRT on it for about a year and a half without any problems, but lately it started having issues only with wireless connections.  Being the cheapskate I am, I ordered a refurb E2500 Cisco from Amazon for under $40 and in a few days it showed up in the mail.  I had already looked up the router in the DD-WRT router database and pulled down the mini firmware in order to overwrite the stock firmware.  (Unfortunately, what I would later read in the forum posts is that the firmware version dd-wrt.v24-18625_NEWD-2_K2.6_mini-e2500.bin would basically brick the router.)  So do yourself a favor and use the 18710 version right off the bat  (dd-wrt.v24-18710_NEWD-2_K2.6_std_usb_nas-e2500.bin).

Even though I had properly followed the 30-30-30 power cycling procedure and updated the firmware with the one recommended in the router database, my router was caught in a continuous reboot cycle.  Every so often I could ping the router for a little while and if I timed it right, I could successfully TFTP up the original stock firmware, however after manually power cycling, it would go back to it’s constant reboot cycle on its own.  Believe me, I worked on it for quite a few hours and then gave up on it.  Then as luck would have it a few days later, I read a post that someone had left it unplugged for a day and the router no longer went through the automatic reboot and stayed solid, but they couldn’t get to the GUI DD-WRT interface.  I had the same results, and left the router unplugged for two days, and when I tired was able to telnet to the router and fix it using these steps:

Telnetting to the E2500 router
I had to set my laptop’s NIC card manually first to 192.168.1.100/24 and then was able to telnet to the router at 192.168.1.1

Then, as you can see above, I performed an “erase linux” and “erase nvram” and then power cycled the router.   At this point I could get to the Management Mode Firmware Upgrade Utility by going to http://192.168.1.1

Firmware upgrade management interface - cisco E2500
Thank goodness for the firmware upgrade management interface – cisco E2500

Now believe me, I really thought hard about loading up the stock firmware, but hey, I might as well try DD-WRT again.  Using the management interface I uploaded  newer fixed version of the DDWRT firmware (version 18625).

Of course waiting during the firmware upload is the worst part
Of course waiting during the firmware upload is the worst part for me. I’ve spent too many sleepless hours back in the day waiting around for hours while uploading images to old cisco routers over xmodem protocols to enjoy this sort of thing anymore.

Luckily this time the firmware took and after a single *yay* power-cycle, I was presented with the standard, change your password page for DD-WRT!

Yay!  The default change your user and password page for DD-WRT
Yay! The default change your user and password page for DD-WRT

Then all I had to do was go thought and put back in all my settings… and enjoy my new router with much better working wireless.