Category Archives: Tools

Script for Verifying Authoritative Name Servers

As organizations tighten their web server security, attackers are looking for new weak links.  One of these weak links are DNS hosting companies and domain registrars.   Even though your own security may be top notch, are you sure that your domain registrar is equally bullet proof?   If the hacker can convince your registrar to change name servers to those under the hacker’s control, the hacker can start doing all kinds of nasty stuff.

Other than shopping around for DNS hosting companies and registrars that have strong security practices including (but not limited to) two-factor authentication, what else can be done?

Monitoring; If you can quickly detect that someone has made an unauthorized change to your name servers or other DNS records, you can minimize the damage by acting quickly and taking control back away from them.

Below is a script that will check your DNS records against a while list of allowed entries:


//Change this:
//Domain you wish to verify
$domain = "";
//Valid DNS hosts for your domain (detect change at registrar)
$authWhitelist= array("","");
//Valid A records (detect change at DNS host)
$aRecordWhitelist= array("","");

require_once 'Net/DNS2.php';

function lookupAuthorities($domain,$server)
 $serverIP = gethostbyname($server);

 $resolver = new Net_DNS2_Resolver( array('nameservers' => array($serverIP)) );

 $resp = $resolver->query($domain, 'A');

 $servers= array();

 foreach($resp->authority as &$record)
 //keep for later
 $name = $record->name;


 $result = (object) [
 'name' => $name,
 'servers' => $servers,

 return $result;

function lookupAuthoritativeNameservers($domain)
 $authorities =lookupAuthorities($domain,"");

 if($authorities->name != $domain)
 $authorities = lookupAuthorities($domain,$authorities->servers[0]);
 return $authorities->servers;


function lookupARecords($domain,$authNameserver)
 $serverIP = gethostbyname($authNameserver);

 $resolver = new Net_DNS2_Resolver( array('nameservers' => array($serverIP)) );

 $resp = $resolver->query($domain, 'A');

 $servers= array();

 foreach($resp->answer as &$record)


 return $servers;


$authServers = lookupAuthoritativeNameservers($domain);


$aRecords = lookupARecords($domain,$authServers[0]);

$aRecordDiff = array_diff($aRecords,$aRecordWhitelist);

if(count($authDiff)>0 || count($aRecordDiff)>0)
 echo ($domain . " Fail (See offending entries below)\n");
 if(count($authDiff)>0) print_r($authDiff);
 if(count($aRecordDiff)>0) print_r($aRecords);

 echo($domain . " Pass\n");


Script will return “Pass” if everything is ok.  If any of the results is not specified on the white list script will show “Fail” including a list of all offending entries.

You can either run this as a cron job and include an email notification by tweaking this script, or you can check it periodically by a tool such as PRTG.

fio: Linux hard drive benchmark

I’m always on a lookout for good hard drive benchmark tools. fio is pretty good, especially because it’s easy to setup and execution is pretty self-explanatory:

fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=test --bs=4k --iodepth=64 --size=1G --readwrite=randrw --rwmixread=0

The only parameter that does need bit of explanation is –rwmixread parameter:

  • 0 means 0 read, 100 write.
  • 100 means 100 read, 0 write.
  • 50 is half and half

PHP URL include vulnerability detection and workaround

Some exploits never get old.  One such example is an exploit that takes advantage of PHP URL include vulnerability.   It’s particularly nasty because it lets the attackers execute arbitrary PHP code without leaving any trace on the server it self.  The whole exploit executes in memory and vanishes once the attacker got what they were after.    With no back doors left behind, there are only two ways to find out.  You can either spot the suspicious entry in your log files, or you can run a script that checks whether your server is vulnerable to the attack in the first place.


if [ -z "$1" ]; then

        echo "Error, must specify domain name"

        exit 0


#do not change this is one of the rare cases, when it serves an actual function.

wget -q -O test http://$1/?-d%20allow_url_include%3DOn+-d%20auto_prepend_file%3D

grep "This domain is established to be used for illustrative examples" test > /dev/null

if [ $? -eq 0 ]; then


        echo "$1 is VULNERABLE add the following to .htaccess file and retry"


        echo "RewriteEngine on"

        echo "RewriteCond %{QUERY_STRING} ^[^=]*$"

        echo "RewriteCond %{QUERY_STRING} %2d|- [NC]"

        echo "RewriteRule .? – [F,L]"




        echo "$1 is OK"


When you run this tool, you will see this if the web site you are scanning is vulnerable:

# ./ is VULNERABLE add the following to .htaccess file and retry

RewriteEngine on
RewriteCond %{QUERY_STRING} ^[^=]*$
RewriteCond %{QUERY_STRING} %2d|- [NC]
RewriteRule .? – [F,L]

I should add that the proper way is to patch PHP to a version that doesn’t have the vulnerability. The .htaccess fix works, but as you can imagine, it’s a bandaid solution. If you have this vulnerability, chances are you also have many more like it.

Safe Ceph Utilization Calculator

The only way I’ve managed to ever break Ceph is by not giving it enough raw storage to work with. You can abuse ceph in all kinds of ways and it will recover, but when it runs out of storage really bad things happen. It’s surprisingly easy to get into trouble. Mainly because the default safety mechanisms (nearfull and full ratios) assume that you are running a cluster with at least 7 nodes. For smaller clusters the defaults are too risky. For that reason I created this calculator. It calculates how much storage you can safely consume.

Gb`’b4&^faQ? -> Beep It Over

Remember when this happened?  You needed to tell someone over the phone a complicated string like: Gb`’b4&^faQ?

The conversation probably went something like this:

Alice: Upper case G, lower case b, slanted single quote, non slanted single quote …

Bob: What the hell are you talking about?!?!  What’s a slanted quote?!

Alice:  Why don’t I beep it over to you.  Ready?

Bob: <Gets his decoder ready> …. Ready!

Alice: <Presses a button><BeepSchrrrrrBeepBeep .. .modem kind of a noise>

Bob: ok got it  <sees Gb`’b4&^faQ?>

You can also beep things over with


Let’s encrypt is awesome

It used to be that if you wanted to encrypt using SSL you have couple of choices.  You can either self sign for $0 and get a narly warning message every time you or your users visit the site.  Or you could pay $60+/year for SSL certificate.

Let’s encrypt gives you a 3 month (indefinitely renewable) certificate for free.  The best part isn’t the cost though.  The best part is that the setup is so easy.  You can get SSL certificate for your apache site right from command line with 3 button presses.  You can’t do that even if you pay $200 for commercial SSL.  It will take you at least 30 minutes to do it.

There must be a catch right?  Not really, although right now my Blackberry doesn’t recognize the cert.  That will change with time though.  It’s only because let’s encrypt is too new.

Changing Ceph Configuration on all Nodes

One question regarding Ceph that comes up frequently is:  Where do you change ceph.conf file?  On admin node?  On each node manually?  Or will it magically replicate on it’s own?

The answer is that you change the the ceph.conf only in one place.  You change it on the admin node and use ceph-deploy to deploy the changes on all other nodes

For example: if you have a cluster consisting of n0, n1 and n2, you would do it like this

#login to admin node
cd my-cluster 
ceph-deploy --overwrite-conf admin n0 n1 n2