Browsing articles tagged with " networking"

External notification script patch for Observium

I’ve written a patch for Observium¬† that defines a couple of additional configuration options. When set, these allow Observium to call an additional external script for notifications in addition to the default mail notification method. This is useful for SMS notifications, although it could be used for any notification via a script or command. It expects the script to accept the notification text from STDIN, and respects the per-device notifications-disabled setting on the device configuration tab.


The following configuration options are defined:

$config['alerts']['script']['enable'] = TRUE|FALSE;
$config['alerts']['script']['file'] = "/path/to/script-file";



*** includes/functions.php.dist 2012-11-23 05:52:27.769189651 +0000
--- includes/functions.php      2012-11-25 10:19:48.309370976 +0000
*** 707,712 ****
--- 707,726 ----
+   if ($config['alerts']['script']['enable'] && $config['alerts']['script']['file'] && !get_dev_attrib($device,'disable_notify'))
+   {
+     if (!get_dev_attrib($device,'disable_notify'))
+     {
+       $script = popen($config['alerts']['script']['file'], "w");
+       if($script){
+         fwrite($script, $message."\r\n");
+       }else{
+         echo "Notification Script Error!\n";
+       }
+       pclose($script);
+     }
+   }

  function formatCiscoHardware(&$device, $short = false)

WebDAV revisited

In my previous endeavour with WebDAV, I ended up using a complicated lighttpd/apache proxy system to get the permissions right. This did work well enough, but it had a few limitations. In involved modifying the registry on the client systems and it required a new lighty instance running for each share with different permissions to the last (which wasn’t terribly efficient). Additionally, lighty’s mod_webdav lacked support for a few vital operations which made working with the shares a bit difficult, not to mention there were some MIME-type conflicts between lighty/apache/the webDAV client that made working with certain types of files near impossible.

I have since revised some of the methods I’ve used to implement the WebDAV server. For a start, I managed to resolve the XP SP2/Vista/7 basic vs DIGEST authentication method hacks to not need registry editing – it turns out, by default, if the share is SSL encrypted, basic authentication should be fine. I also decided on a new approach. Using Apache, PHP5, suPHP and eZ Component’s WebDAV module, I was able to implement a sturdier WebDAV solutions that still solved the problems.

First things first, Apache, PHP5, mod_php, mod_suphp all needed to be installed and configured. Once that was done, ez Component’s WebDAV module needed to be installed – on Fedora, this is php-ezc-Webdav in the Yum repositories. Then I needed to make a couple of scripts to handle authentication and module loading. These are modified right from the ezc-Webdav documentation. These scripts need to go in Apache’s DocumentRoot.


require_once "/usr/share/pear/ezc/Base/base.php";

 * Autoload ezc classes
 * @param string $className
function __autoload( $className )
    ezcBase::autoload( $className );

You may need to alter the path to base.php above.


class ldapAuthenticator extends ezcWebdavDigestAuthenticatorBase
                   implements ezcWebdavAuthorizer

    public function authenticateAnonymous( ezcWebdavAnonymousAuth $data )
        return false;

    public function authenticateBasic( ezcWebdavBasicAuth $data )
        $username = $data->username;
        $password = $data->password;

	if(strstr($username, '\\')){
		$username = strstr($username, '\\');
		$username = preg_replace("^.", '', $username);

	$ldap = ldap_connect("", 389);
	$bind = @ldap_bind($ldap);
	$search = ldap_search($ldap, "dc=company,dc=tld", "(&(objectClass=shadowAccount)(uid=".$username."))", array("dn"));
	$data = ldap_get_entries($ldap, $search);
	$dn = $data[0]['dn'];

	if(!$dn){ return false; }

	$bind = @ldap_bind($ldap, $dn, $password);
	$search = ldap_search($ldap, "dc=company,dc=tld", "(&(objectClass=shadowAccount)(uid=".$username."))", array("dn"));
	$data = ldap_get_entries($ldap, $search);

	if(!$bind){ return false; }

	return true;

    public function authenticateDigest( ezcWebdavDigestAuth $data )
        $username = $data->username;

	error_log("User attempted unsupported DIGEST authentication: ".$username);

	return false;

    public function authorize( $user, $path, $access = ezcWebdavAuthorizer::ACCESS_READ )
        return true;

You will need to modify the authenticateBasic function. The one above is to authenticate with an LDAP backend.


require_once 'autoload.php';
require_once 'authenticator.php';

$server = ezcWebdavServer::getInstance();

$server->options->realm = "CCPG Solutions Ltd WebDAV";

$server->auth = new ldapAuthenticator();

$backend = new ezcWebdavFileBackend(

$server->handle( $backend );

In this one, you will need to modify the share path (in $backend) and the realm.

Then you need to change the owning uid/gid (chown user:group sharename.php) of the sharename.php file to the user/group you want to use for read/write permissions of the files. You can make as many sharename.php files for each share (or combination of share/permissions) you need.

With all that done, you should be able to go ahead and map the share using the URL

The eZ Component’s WebDAV module seems pretty in-depth – the above is really just a very basic usage of it’s capabilities, but it does work pretty well. The only other thing you may have to do, depending how pedantic your Windows boxes are going to be, is disable the DIGEST authentication headers altogether. To do this, edit /usr/share/pear/ezc/Webdav/servers.php (or wherever your Webdav/server.php is located) and comment the following lines in the createUnauthenticatedResponse function:

$wwwAuthHeader['digest'] = 'Digest realm="' .$this->options->realm . '"'
 . ', nonce="' . $this->getNonce() . '"'
 . ', algorithm="MD5"';

Save the file and exit. That’s all it takes. With all that done, your users should be able to map the share in Windows, authenticate via LDAP and read/write files with the permissions of the PHP script owner.

Palm Centro Bluetooth Enabler

Script Information
I recently owned a Palm Centro (although I no longer do and now I do yet again), which is a nice device except for the part where it lacks Wifi connectivity. To combat this problem, I put together a script that allows me to connect to the computer from the Centro using bluetooth, and have my computer act as a router for the unit, allowing it to get on the internet over the bluetooth connection.

It uses AppleScript and Perl, and has three parts. It can be easily modified to work on Linux.


set mypath to POSIX path of (path to me)
set interfaces to do shell script "/bin/bash '" & mypath & "Contents/Resources/Scripts/'"
set ttys to do shell script "/bin/bash '" & mypath & "Contents/Resources/Scripts/'"

set interfacedialog to display dialog "Which interface is connected to the internet?

(Interfaces on this system: " & interfaces & ")" default answer "en1"

set syncttydialog to display dialog "Which serial port is the Bluetooth PDA sync port?

(Ports on this system: " & ttys & ")" default answer "Bluetooth-PDA-Sync"

set sharettydialog to display dialog "Which serial port is the Bluetooth modem sharing port?

This should have been added by you before running this script. If you haven't done this, click cancel, open Bluetooth preferences, go to advanced, and add a new, non-secure port of type Modem, then re-run this enabler and put it's name in this dialog.

Ports on this system: " & ttys & ")" default answer "sharing-port"

set theinterface to the text returned of interfacedialog
set thesynctty to the text returned of syncttydialog
set thesharetty to the text returned of sharettydialog

display dialog "The enabler will now run, starting a PPP server on " & thesynctty & " and " & thesharetty & ", directing packets between them, using " & theinterface & " as a default gateway. It will enable kernel-level packet forwarding and NAT.

This needs to be run each time the system is booted before the Palm will be able to connect, and not more than once.

It will require your password to run, and it may take a short time to complete. Configuration instructions for your handheld will be displayed when it is complete."

do shell script "sudo /usr/sbin/pppd /dev/tty." & thesynctty & " 115200 noauth local
  passive proxyarp asyncmap 0 silent persist : &" with administrator privileges
do shell script "sudo /usr/sbin/sysctl -w net.inet.ip.forwarding=1" with administrator privileges
do shell script "sudo /usr/sbin/natd -same_ports -use_sockets -log -deny_incoming -interface " & theinterface with administrator privileges
do shell script "sudo /sbin/ipfw add divert natd ip from any to any via " & theinterface with administrator privileges
do shell script "sudo /usr/sbin/pppd /dev/tty." & thesharetty & " 115200 noauth local passive proxyarp asyncmap 0 silent persist : &" with administrator privileges

display dialog "The enabler has run. You can now try to connect from your Palm. Your Palm should be paired to this computer.

The Palm should be configured with a connection profile set to 'Connect to PC via Bluetooth', and the device should be set to your computer. Under details, you will need to set the spped to 115,200 bps, and the Flow Ctl to automatic.

You will also need to create a new network profile, set to use the connection you just created. No username or password is necessary. Under details, the idle timeout should be set to never, and under advanced, specify an IP address of You may use whatever DNS servers you like, reccomended are and

Once this is configured you should be able to connect."


ifconfig | perl -e 'while($line=<STDIN>){($int)=$line=~/^(\w+\d):/;if($int ne "" && $int ne "lo0" && $int ne "gif0" && $int ne "stf0"){$allints .= $int." ";}} $allints =~ s/\ $/\n/; print $allints'


ls -1 /dev/tty.* | perl -e 'while($line=<STDIN>){($int)=$line=~/\/dev\/tty\.(.+)$/; $ints.=$int." "}$ints=~s/\ $/\n/;print $ints;'


Script Information

iptables-config is a fairly simple, straightforward BASH script for quickly setting up an iptables firewall on a single server to block all but specified ports, and has the ability to block certain IPs, IP blocks, or ranges of IPs. It is configured by default to allow pings. Take a look below. Simply download, modify the variables to suit your setup, and then run the script. Hasn’t been updated in a little over a year (hence why it’s in this section), but I have plans for it soon to be rc-ified and maybe a bit more .. modular. As soon as I get some free time. ^_^

Script Source


# iptables-config by cmantito ( //

# added a rule to allow incoming pings, so that is fixed [27/04/2006]
# next version will be rc-script-ish and slightly more flexible...eventually

# IPTABLES parameters config
incoming="iptables -A INPUT"
outgoing="iptables -A OUTPUT"
forwarding="iptables -A FORWARD"
tcp="-p TCP"
udp="-p UDP"
icmp="-p icmp"
accept="-j ACCEPT"
drop="-j DROP"
reject="-j REJECT"
forward="-j FORWARD"

# TCP: Allowed Ports
TCP_ACCEPT_PORTS="22 23 25 80 143 548 587 993 3306 3690 6667 6697 9999 48240 48241 48242 48243 48244"
# Blackholed IPs

# UDP: Allowed Ports
# Blackholed IPs

# Clear existing rules.
iptables --flush

# Set REJECT rules

for ip in $TCP_REJECT_IPS ; do
   $incoming $tcp -s $ip $reject

for ip in $UDP_REJECT_IPS ; do
   $incoming $udp -s $ip $reject

# Set DROP rules

for ip in $TCP_DROP_IPS ; do
   $incoming $tcp -s $ip $drop

for ip in $UDP_DROP_IPS ; do
   $incoming $udp -s $ip $drop

# Set ACCEPT rules.

for port in $TCP_ACCEPT_PORTS ; do
   $incoming $tcp --dport $port $accept

for port in $UDP_ACCEPT_PORTS ; do
   $incoming $udp --dport $port $accept

# ACCEPT ICMP pings.

$incoming $icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED $accept

# Add more rules here.

# Allow all outgoing traffic, established sessions.

$incoming -m state --state RELATED,ESTABLISHED $accept
$forwarding -i eth0 -m state --state RELATED,ESTABLISHED $accept
$outgoing -m state --state NEW,RELATED,ESTABLISHED $accept

# Set an implicit DENY

$incoming $reject
$forwarding $reject

# Show em all.
iptables -L


Script Information

routersh was a shell script designed for personal use as a login script that allows for management of iptables rules, route rules, and network interfaces, in a ‘linux box as a router’ environment. There is no support for it, but feel free to download it and customise it as you feel fit.

Script Source

use Switch;


sub main {

    $ENV{'PATH'} = "/bin:/sbin:/usr/sbin:/usr/bin";

    my $hostname = `hostname --fqdn`;

    fancyPrint($hostname."\n\n", 32, 1, 4);

    fancyPrint("Routing\n", 36, 4);
    fancyPrint("\t[1]", 33, 1); print " Start routing\n";
    fancyPrint("\t[2]", 33, 1); print " Stop routing\n";
    fancyPrint("\t[3]", 33, 1); print " Show routes\n";
    fancyPrint("\t[4]", 33, 1); print " Edit port forwards\n";
    print "\n";
    fancyPrint("Access Point\n", 36, 4);
    fancyPrint("\t[5]", 33, 1); print " SNMP AP Config\n";
    print "\n";
    fancyPrint("Network Interfaces\n", 36, 4);
    fancyPrint("\t[6]", 33, 1); print " Show interfaces\n";
    print "\n";
    fancyPrint("Clients\n", 36, 4);
    fancyPrint("\t[7]", 33, 1); print " Show DHCP leases\n";
    fancyPrint("\t[8]", 33, 1); print " Show all active clients\n";
    print "\n";
    fancyPrint("Other\n", 36, 4);
    #fancyPrint("\t[S]", 33, 1); print " Launch shell\n";
    fancyPrint("\t[X]", 33, 1); print " Exit to shell\n";

    print "\nPlease make a selction [1-7, S, X]: ";
    $choice = ;
    $choice = lc($choice);

        case "x" {
        case "s" {
        case "1" {
            $run = `/etc/rc.d/iptables start 2>&1`;
            if($run =~ /FAIL/i){
                fancyPrint("Start routing failed! Press RETURN.", 37, 41, 1);
                fancyPrint("Routing started. Press RETURN.", 30, 42, 1);
            $wait = ;
        case "2" {
            $run = `/etc/rc.d/iptables stop 2>&1`;
            if($run =~ /FAIL/i){
                fancyPrint("Stop routing failed! Press RETURN.", 37, 41, 1);
                fancyPrint("Routing stopped.  Press RETURN.", 30, 42, 1);
            $wait = ;
        case "3" {
            fancyPrint("Press 'q' to return. Press RETURN to continue.", 30, 42, 1);
            $wait = ;
            system("/sbin/route -e -n | /bin/less");
        case "4" {
            print "What you like to add or delete a port forward? (add/del): ";
            $pfDo = ;

            if(lc($pfDo) eq "add"){
                print "TCP or UDP? (tcp/udp): ";
                $proto = ;

                if(lc($proto) eq "tcp"){ $proto = "tcp"; }
                elsif(lc($proto) eq "udp"){ $proto = "udp"; }
                else{ main(); }

                print "Destination port (WAN): ";
                $dPort = ;

                print "Destination IP (LAN): ";
                $dIP = ;

                print "New destination port (LAN): ";
                $newdPort = ;

                open(FORWARDS, ">>/etc/ipForwards.conf");
                print FORWARDS $proto.",".$dPort.",".$dIP.",".$newdPort."\n";

                system("/usr/sbin/iptables -A PREROUTING -t nat -p ".$proto." --dport ".$dPort." -i wan0 -j DNAT --to ".$dIP.":".$newdPort);
                system("/usr/sbin/iptables -A FORWARD -p ".$proto." -d ".$dIP." --dport ".$newdPort." -i wan0 -o lan0 -j ACCEPT");
                system("/usr/sbin/iptables -A FORWARD -p ".$proto." -s ".$dIP." --sport ".$newdPort." -i lan0 -o wan0 -j ACCEPT");

            }elsif(lc($pfDo) eq "del"){
                open(FORWARDS, "){
                    $forwards[$count] = $line;
                    print $count.": ".$line."\n";
                print "Number of forward to remove: ";
                $rmPort = ;
                if($rmPort eq ""){ main(); }
                ($proto, $dPort, $dIP, $newdPort) = split(/,/, $forwards[$rmPort]);
                system("/usr/sbin/iptables -D PREROUTING -t nat -p ".$proto." --dport ".$dPort." -i wan0 -j DNAT --to ".$dIP.":".$newdPort);
                system("/usr/sbin/iptables -D FORWARD -p ".$proto." -d ".$dIP." --dport ".$newdPort." -i wan0 -o lan0 -j ACCEPT");
                system("/usr/sbin/iptables -D FORWARD -p ".$proto." -s ".$dIP." --sport ".$newdPort." -i lan0 -o wan0 -j ACCEPT");

                delete $forwards[$rmPort];

                open(FORWARDS, ">/etc/ipForwards.conf");
                foreach $newLine(@forwards) {
                    if($newLine ne ""){
                        print FORWARDS $newLine."\n";
        case "5" {
        case "6" {
            fancyPrint("Press 'q' to return. Press RETURN to continue.", 30, 42, 1);
            $wait = ;
            system("/sbin/ifconfig | /bin/less");
        case "7" {
            my @leases;
            my $x;

            open(DHCP, "/var/state/dhcp/dhcpd.leases");
            while($line = ){
                if($line =~ /^lease (.+) \{/){
                    $ipAddr = $1;
                if($line =~ /^\s+hardware ethernet (.+);/){
                    $macAddr = $1;
                if($line =~ /^\s+client-hostname "(.+)";/){
                    $clientName = $1;
                if($line =~ /^}/){
                        $clientName = "";
                    $leases[$x][0] = $clientName;
                    $leases[$x][1] = $ipAddr;
                    $leases[$x][2] = $macAddr;
                    $clientName = "";
                    $ipAddr = "";
                    $macAddr = "";
            fancyPrint("Hostname", 4);
            print "\t";
            fancyPrint("Assigned IP", 4);
            print "\t\t";
            fancyPrint("MAC Address", 4);
            print "\n";
            my %shownLease;
            for($q = 0; $q <= $#leases; $q++){
                if($shownLease{$leases[$q][2]} < 1){
                    print $leases[$q][0]."\t\t";
                    print $leases[$q][1]."\t\t";
                    print $leases[$q][2]."\n";
                    $shownLease{$leases[$q][2]} = 1;
            fancyPrint("Press RETURN to continue.", 30, 42, 1);
            $wait = ;
        case "8" {
            system("/sbin/arp -n -i lan0");
            fancyPrint("Press RETURN to continue.", 30, 42, 1);
            $wait = ;
        else {


sub clearScreen {
    print "\e[2J";

sub moveCursor {
    my ($x, $y) = @_;

    print "\e[".$y.";".$x."H";

sub fancyPrint {
    my ($text) = shift(@_);

    $printStr = "\e[";
    for($i = 0; $i <= $#_; $i++){
        $printStr .= $_[$i];
        if($i < $#_){
            $printStr .= ";";
            $printStr .= "m";

    $printStr .= $text."\e[0m";
    print $printStr;