Wednesday, December 7, 2011

my solaris 9 zone is a punk

i have a love/hate relationship with my non-enterprise use of zones to emulate a lot of solaris instances. i do.
 
# ssh host
unable to initialize mechanism library [/usr/lib/gss/gl/mech_krb5.so]

excuse me?

workaround:
Edit /etc/ssh/ssh_config and add the following

Host *
StrictHostKeyChecking no
GSSAPIKeyExchange no
GSSAPIAuthentication no

Edit /etc/ssh/sshd_config and add the following

GSSAPIAuthentication no
GSSAPIKeyExchange no
GSSAPIStoreDelegatedCredentials no

svn client on suse 9.2 install

Sometimes I need to install svn clients.  Sometimes this has to be done by scratch 
by source on SuSE 9.2 Pro systems.
Most will come pre-loaded with OpenSSL libs and sometimes with berkleydb.

The below will use downloaded apr libs; and not system local libs.
My compile takes place in /usr/local.
in tmp

# get and extract subversion sources
wget http://subversion.tigris.org/downloads/subversion-xxx.tar.gz
wget http://subversion.tigris.org/downloads/subversion-deps-xxx.tar.gz
tar xvfz subversion-xxx.tar.gz
tar xvfz subversion-deps-xxx.tar.gz

# get and extract latest version of apache portable runtime
wget http://apache.ibiblio.org/apr/apr-xxx.tar.gz
wget http://apache.ibiblio.org/apr/apr-util-xxx.tar.gz
tar xjvf apr-xxx.tar.gz
tar xjvf apr-util-xxx.tar.bz2

# build apache portable runtime
cd apr-xxx
./buildconf
./configure
make && make check
sudo make install
cd ../apr-util-xxx
./buildconf --with-apr=../apr-xxx
./configure --with-apr=/usr/local/apr/bin/apr-1-config
make && make check
sudo make install

# build subversion
cd ../subversion-xxx
rm -r apr apr-util
sudo chkconfig svn off
sudo rm -f /usr/local/lib/libsvn*
./configure --with-apr=/usr/local/apr/bin/apr-1-config      \
            --with-apr-util=/usr/local/apr/bin/apu-1-config \
            --disable-mod-activation                        \
            --with-ssl
make && make check
sudo make install

# link svn binaries

host:/usr/bin # ln -s /usr/local/bin/svnadmin ./svnadmin
host:/usr/bin # ln -s /usr/local/bin/svndumpfilter ./svndumpfilter
host:/usr/bin # ln -s /usr/local/bin/svnlook ./svnlook
host:/usr/bin # ln -s /usr/local/bin/svnserve ./svnserve
host:/usr/bin # ln -s /usr/local/bin/svnsync ./svnsync
host:/usr/bin # ln -s /usr/local/bin/svnversion ./svnversion
a new development...
wget http://apache.deathculture.net/subversion/subversion-1.7.2.tar.gz
tar xvfz subversion-1.7.2.tar.gz
cd subversion-1.7.2/
./get-deps.sh 
./configure --without-serf --without-neon
make && make install
which svn
svn
in case suse (here's looking at you stock install sles11) is a punk...
apr
./configure --enable-share

apr-util
./configure --with-apr=/usr/local/apr

svn
./configure --without-berkeley-db \
--with-apr=/usr/local/apr \
--with-apr=/usr/local/apr \
--without-apxs \
--without-neon \
--without-serf

Tuesday, October 11, 2011

let's send fakemail!

telnet yourmailhost.yourdomain 25
Once connected, helo . Often you'll need to identify your sending host if you've restricted sending host.
helo yourmachine.yourdomain
Tell the system who is sending the mail to to whom the message is addressed.
mail from: you@yourdomain
rcpt to: testaddress@yourdomain
Place content in the body of the message by entering data on a single line, and terminating the data stream by entering a period (.) on single line.
data 

some test text

. 
End the session my typing quit on a single line or using the control-sequence identified by the mail host.

Wednesday, October 5, 2011

scrambled mysql databases for breakfast

I really don't like corrupt databases. They just ruin my day and I really hate scrambled mysql databases for breakfast. However, sometimes corrupt databases are really just the result of problematic indexes. To check those indices... Stop the mysql database daemon...
/etc/init.d/mysqld stop
Don't forget to lsof and check for any hanging processes or inode access.
lsof |grep mysql
Then go to the directory in which you have your mysql database files, say
/var/lib/mysql
Within the directory, check the tables:
myisamchk *.MYI
Then repair the tables:
myisamchk -r *.MYI
After all is said and done, restart mysql...
/etc/init.d/mysqld start
A caveat, however, you need to have as much disk space free on the disk on which you have your database that you're doing your repairs. So, if you have a 50GB database, you'll need to have at least 50GB free. Oh yes. However, if you want to play it fast and loose and do a live check, use mysqlcheck.
mysqlcheck db
Then repair the database tables:
mysqlcheck -r db

Friday, September 30, 2011

what to do when your ipv4 forwarder has a scrambled arp cache

I have various network segments doing all kinds of things. As opposed to routing all of them, I place them being boxes that shape traffic and the like. ipv4 forwarding is my friend, mostly. Except when its cascading switches go weird.

So, to figure out where a specific host is connected, I issue:

arp -a | grep ethX

That's nice. If I see incomplete entries, that means that the MAC address of said machine is in a weird state. If I know that the system is sitting on a specific interface and not the reported one, it does me good to flush the entire arp cache. But! There's no command in Linux to flush the cache itself. You have to do it quick and dirty via a script or the command line using the -d switch. Plop this in or on either on your boxes that use /proc/net/arp:

for i in `awk -F ' ' '{ if ( $1 ~ /[0-9{1,3}].[0-9{1,3}].[0-9{1,3}].[0-9{1,3}]/ ) \
 print $1 }' /proc/net/arp` ; do arp -d $i ; done

And now the cache is clear and life goes on.

Tuesday, August 30, 2011

wget is my friend

sometimes you need yank a site and edit it and really don't feel like doing it live. one way to get the content is cp'ing the directory and do whatever to it. other times wget is a quick and dirty if you're particularly lazy or if your content is all over the place. here's the command line i typically use for wget:
wget --random-wait -r -p -e robots=off -U mozilla http://your.site.org <- yanks *
wget --random-wait -r --no-parent -p http://your.site.org/content/dir <- grabs a dir

some useful swtiches per man:
-p ; include all files, including images.
-e robots=off ; do not obey server-side robots.txt 
-U mozilla ; browser identity.
--random-wait ; number of seconds to wait, thus avoiding server black list.
--limit-rate=15k ; throttle the download rate.
-b ; continue application in background.
-o ; output log (as opposed to scrolling on screen).

Monday, August 15, 2011

reassociate vmware images

so i got the grand idea to scp some vmware images from a dead nas to another living nas. since the dead one was dead, there really wasn't a good way to move the images in the usual vmware way.

so, i proceeded to set up another iscsi device on that nas, got it mounted right with all the correct data. neat.
my vmware esx server still reported that its images were "Unknown Host" of course. but blast it, what were the names of these systems before? my vsphere console server was down. crud.

easy, i went here:
esxserver:/etc/vmware/hostd/vmInventory.xml

and there they were.

all i needed to do to reassociate them was to change the /vmfs/volume/path to the correct one. i rebooted the vmware esx server and all was cool.

Tuesday, July 26, 2011

instant root shell to change that pesky forgotten root password via grub

forget knoppix. just do it natively. oh, this only works if grub's not passworded. usually isn't.
* press esc at the grub prompt
* highlight the line that begins with kernel XXX , press e
* go to the very end of the line, add rw init=/bin/bash
note:  that is if bash is in /bin ; if not try /usr/bin or /usr/local/bin
* press enter, then press b to boot system
note:  system should now boot as root shell sans password.
* type passwd username.  set password.
* type reboot

Friday, July 22, 2011

using ssh to restrict commands by key

as we all know, if you have ssh access to a box, you can run arbitrary commands via one liners using the -C switch. neat. or not.
but! you can also have the sysadminly joy of restricting what an ssh client connection can do if you do not want said connection to have unfettered shell access.

anyway. here was the probem:
one day i was getting sort of tired of renaming pems and moving them around between systems. believe me, it was a drag. i wanted a one-liner, so i made one.

i plopped an ssh key for the robot account (robot@mordor) via which i wanted to do all these mundane tasks and then prepended its definition in authorized_keys2 on the client box with the a specific command string.

here's a snippet of authorized_keys2:
command="/usr/local/bin/secretcommands $SSH_ORIGINAL_COMMAND" ssh-rsa == robot@mordor

what this does is restrict robot@mordor to only be able to issue that specific command. no interactive shell, no nothing, just the command. but. in my case, i really needed that robot to be able to do more than one thing. so! i made my command a menu of choices - secretcommands. now, robot@mordor can do only what is on the menu of choices - like look at messages or rename things.

to allow robot@mordor to scp things, i needed to also explicitly place the client system's scp command in the same authorized_keys2 file:
command="/root/bin/scp-wrapper" ssh-rsa == robot@mordor

here's secretcommands:
#!/bin/sh
; secretcommands
case "$1" in
 messages)
  /bin/cat /var/log/messages
  ;;
 delicious)
  /usr/local/bin/rename.sh /etc/secretplaceforsecretthings/crl.pem
  ;;
 help)
  echo 'messages and delicious' 1>&2
  exit 1
 ;;
 *)
  echo 'please do not do that' 1>&2
  exit 1
  ;;
esac

here's the scp command per the snail book:
#!/usr/bin/env perl
# from http://www.snailbook.com/faq/restricted-scp.auto.html

# location of the server-side scp we want to run
$scp_server = "/usr/bin/scp";

sub fail {
    my ($msg) = @_;
    print STDERR "$0: ", $msg, "\n";
    exit 1;
}

# This just makes me feel better.

$TRUE  = (0 == 0);
$FALSE = (0 == 1);

# Since this script is called as a forced command, need to get the
# original scp command given by the client.

($command = $ENV{SSH_ORIGINAL_COMMAND})
    || fail "environment variable SSH_ORIGINAL_COMMAND not set";

# Split the command string to make an argument list, and remove the first
# element (the command name; we'll supply our own);

@scp_argv = split /[ \t]+/, $command;

# Complain if the command is not "scp".

fail "account restricted: only scp allowed (\"$scp_argv[0]\")"
    unless $scp_argv[0] eq "scp";

# Wipe the environment as a security precaution.  This might conceivably
# break something, but if it does you can filter the environment more
# selectively here.

%ENV = ();

# Ensure that either -t or -f is on the command line, to enforce running
# scp in server mode.

$ok = $FALSE;
foreach $arg (@scp_argv) {
    if ($arg eq '-t' || $arg eq '-f') {
        $ok = $TRUE;
        last;
    }
}

fail "Restricted; only server mode allowed."
    unless $ok;

# if we're OK, run our desired "scp" with arguments.

shift(@scp_argv);
exec($scp_server, @scp_argv);

the rename script in secretcommands:
#!/bin/sh
# rename.sh
for file in ${@}; do
    if [ -e $file ]; then
        timestamp=`ls -l --time-style=+%Y%M%d-%k%M%S $file |cut -d' ' -f6`
        basename=`echo $file|cut -d'.' -f1`
        ext=`echo $file | cut  -d'.' -f2-`
        mv -v $file $basename.$ext.$timestamp
    fi
done

here's what it would look like in a one liner:
mordor$ /usr/bin/ssh -i /home/robot/.ssh/id_rsa_nothere.secretcommand -l root nothere delicious
delicious.

multiple pub keys

i usually have a myriad of keys for different automated processes. i really like backing up stuff using unattended rsync scripts; and since you can wrap rsync in ssh, having multiple keys is a good idea - plus the security aspect is cool, too.

my nomenclature for keys is the following:
id_typeofencryption_clientboxname.application

here's how to create an additional key and place it on the target (client) box:
# ssh-keygen -t rsa -b 2048 -f id_rsa_client.rsync
# ssh user@client <- it is a good idea to see if you can connect to the client before the next step
# cat id_rsa_client.rsync.pub | ssh user@client 'sh -c "cat >> .ssh/authorized_keys2"'
# ssh -l user -i id_rsa_client.rsync client

got it?

this is particularly useful if you want to run a specific command when a client connects; say, update files, move things around. neato.

who the heck has been goofing with my nfs exported data?

if you work in a big linux shop, you'll probably find yourself wondering who is altering and maybe deleting nfs data. nfs, as a general rule, does not have logging. if you daemonize the below, you'll get all the logs you want, and more.

#!/usr/bin/perl

$PIDFILE = "/var/run/nfs-remove-monitor.pid";
$LOGFILE_BASE = "/var/log/nfs-remove-monitor";
$EXIT = 0;
$SIG{CHLD} = IGNORE;

if ( -e $PIDFILE ) {
        $PID = `cat $PIDFILE`;
        `kill -HUP $PID`;
        $DATE=`date +%F`;
        chomp $DATE;
        unlink "$LOGFILE_BASE.$DATE.log";
        unlink "$LOGFILE_BASE.$DATE.log.bz2";
        rename "$LOGFILE_BASE.log", "$LOGFILE_BASE.$DATE.log";
        unless (fork()) {
                sleep 5;
                `bzip2 -9 $LOGFILE_BASE.$DATE.log`;
                exit;
        }
}

open PID, ">$PIDFILE";
print PID $$;
close PID;

open LOG, ">$LOGFILE_BASE.log";
$STDOUT = select LOG;
$|=1;
select $STDOUT;

open TCPDUMP, "tcpdump -vvvvvv -l -i any -s 0 tcp 2>/dev/null |";
$STDOUT = select TCPDUMP;
$|=1;
select $STDOUT;

$SIG{HUP} = sub { $EXIT = 1; };

while ($line = ) {
        if ($line =~ /remove/) {
                print LOG $line;
        }
        last if $EXIT;
}

close TCPDUMP;
close LOG;

don't forget to rotate your logs...

who have been my nfs clients?

sure, you can plod through /var/log/messages to maybe see who has connected to your nfs server. why not just look at rmtab?

#!/usr/bin/perl

$|=1;

use strict;

use Net::DNS;
use Data::Dumper;

use constant DEBUG=>0;

sub logmsg
{
    print STDERR scalar(localtime), " $0 pid $$ ", @_, "\n";
}

sub dnsLookup($)
{
    chomp();
    my $queryname = shift;
    logmsg("Checking queryname $queryname...") if DEBUG==1;
    my $res   = Net::DNS::Resolver->new;
    my $query = $res->search($queryname);
    if ($query) {
        foreach my $rr ($query->answer) {
            if ($rr->type eq "A" ) {
              return $rr->address;
            } 
            if ($rr->type eq "PTR") {
              return $rr->ptrdname;
            }
        }
    } else {
        return $res->errorstring;
    }
}

open fRMTAB, "/var/lib/nfs/rmtab" || die "Unable to open rmtab for reading: $!";
while() {
        my($host,$mount,$count) = split /:/, $_;
        if ( $host =~ m/\d+\.\d+\.\d+\.\d+/ ) {
                print dnsLookup($host), "\n";
        }
}
close fRMTAB;

Friday, July 15, 2011

aix, nfs insecurity and vmount

if you're on an aix box and see this when you're trying to do a mount from your nice linux server:
"vmount: Operation not permitted."

all is not lost.

"but, i set that export as insecure because that pesky firewall sometimes munges
things," you might say.
that setting is: insecure (within the parens in exports)

whatever. ibm says:

AIX versions 4.x and 5.x
Sometimes Linux NFS servers will do port checking and require that 
the NFS client use a reserved port.

     nfso -o nfs_use_reserved_ports=1

If the mount is going to be permanent, then the change needs to survive across a
 reboot. The nfs option must be changed permanently. On AIX 4.x and 5.1, the 
command above should be added to the startup scripts (possibly /etc/rc.nfs). On AIX 
5.2 and above, the change can be made permanent by adding the -p flag.

     nfso -p -o nfs_use_reserved_ports=1

yeah, that works.

Tuesday, July 12, 2011

tcpping and smokeping

sometimes you just need to measure network latency to specific services between sites. a common thing to do is to do an icmp (ping) test between systems. however, oftentimes your ping tests are dropped. this is what firewalls do from time to time.
a better thing to do is to initiate a half-open scan - just like what nmap does to map services. tcptraceroute or hping3 are terrific tools in this regard.
however (there's always a however) graphs and warnings and the like would be good things™ to have. smokeping with tcpping offers both the latter and former, respectively.

getting them to work together is another kettle of fish, entirely.

tcpping is nothing more than a wrapper script written to have tcptraceroute feed its data to smokeping. the wrapper script is below - don't forget to chmod +x it. if you're on an ubuntu or debian system, you'll need both tcptraceroute and bc. apt-get them. i like to put tccping in /usr/local/bin (because that's where i put all me-made things).

however, smokeping (if it is a really old version) doesn't always have TCPPing.pm (as you may find) thus enabling you to use this coolio probe. you can check this out by going here:
/usr/share/perl5/smokeping/Smokeping/probes/
ls the directory. if TCPPing.pm isn't there, drop in the below TCPPing.pm . Then issue:
smokeping -makepod Smokeping::probes::TCPPing
just remember that you'll need all the modules in the pm prior to doing the make pod and running smokeping and averting a myriad of errors. you can grab each of them (if you haven't them already) by issuing:
perl -MCPAN -e "install IPC::Open3" <- for instance.
now, configure smokeping appropriately. under Probes, add:
+TCPPing
binary = /usr/bin/local/tcpping
forks = 5
offset = 50%
step = 300
timeout = 15
and, as an example here's a stanza for checking both icmp and samba
++ fileservers

menu = fileservers
title = fileservers connectivity

+++ fileservold

menu = fileservers - fileserver10 (icmp)
title = fileservers - fileserver10 (icmp) - 10.0.0.10
host = 10.0.0.10


+++ fileservoldsmb

menu = fileservers - fileservold10 (smb)
title = fileservers - fileserver10 (smb) - 10.0.0.10
probe = TCPPing
host = 10.0.0.10
port = 139
tcpping
#!/bin/sh
#
# tcpping: test response times using TCP SYN packets
#          URL: http://www.vdberg.org/~richard/tcpping.html
#
# uses tcptraceroute from http://michael.toren.net/code/tcptraceroute/
#
# (c) 2002-2005 Richard van den Berg  under the GPL
#               http://www.gnu.org/copyleft/gpl.html
#
# 2002/12/20 v1.0 initial version
# 2003/01/25 v1.1 added -c and -r options
#                 now accepting all other tcptraceroute options
# 2003/01/30 v1.2 removed double quotes around backquotes
# 2003/03/25 v1.3 added -x option, courtesy of Alvin Austin 
# 2005/03/31 v1.4 added -C option, courtesy of Norman Rasmussen 
# 2007/01/11 v1.5 catch bad destination addresses
# 2007/01/19 v1.6 catch non-root tcptraceroute


ver="v1.6"
format="%Y%m%d%H%M%S"
d="no"
c="no"
C="no"
ttl=255
seq=0
q=1
r=1
w=3
topts=""

usage () {
 name=`basename $0`
 echo "tcpping $ver Richard van den Berg "
 echo
 echo "Usage: $name [-d] [-c] [-C] [-w sec] [-q num] [-x count] ipaddress [port]"
 echo
 echo "        -d   print timestamp before every result"
 echo "        -c   print a columned result line"
 echo "        -C   print in the same format as fping's -C option"
 echo "        -w   wait time in seconds (defaults to 3)"
 echo "        -r   repeat every n seconds (defaults to 1)"
 echo "        -x   repeat n times (defaults to unlimited)"
 echo
 echo "See also: man tcptraceroute"
 echo
}

_checksite() {
 ttr=`tcptraceroute -f ${ttl} -m ${ttl} -q ${q} -w ${w} $* 2>&1`
 if echo "${ttr}" | egrep -i "(bad destination|got roo)" >/dev/null 2>&1; then
  echo "${ttr}"
  exit
 fi
}
 
_testsite() {
 myseq="${1}"
 shift
 [ "${c}" = "yes" ] && nows=`date +${format}`
 [ "${d}" = "yes" ] && nowd=`date`
 ttr=`tcptraceroute -f ${ttl} -m ${ttl} -q ${q} -w ${w} $* 2>/dev/null`
 host=`echo "${ttr}" | awk '{print $2 " " $3}'`
 if echo "${ttr}" | egrep "\[(open|closed)\]" >/dev/null 2>&1; then
  rtt=`echo "${ttr}" | awk '{print $5}'`
 else
  rtt=`echo "${ttr}" | awk '{print $4}'`
 fi
 not=`echo "${rtt}" | tr -d ".0123456789"`
 [ "${d}" = "yes" ] && echo "$nowd"
 if [ "${c}" = "yes" ]; then
  if [ "x${rtt}" != "x" -a "x${not}" = "x" ]; then
   echo "$myseq $nows $rtt $host"
  else
   echo "$myseq $nows $max $host"
  fi
 elif [ "${C}" = "yes" ]; then
  if [ "$myseq" = "0" ]; then
   echo -n "$1 :"
  fi
  if [ "x${rtt}" != "x" -a "x${not}" = "x" ]; then
   echo -n " $rtt"
  else
   echo -n " -"
  fi
  if [ "$x" = "1" ]; then
   echo
  fi
 else
  echo "${ttr}" | sed -e "s/^.*\*.*$/seq $myseq: no response (timeout)/" -e "s/^$ttl /seq $myseq: tcp response from/"
 fi
#       echo "${ttr}"
}

while getopts dhq:w:cr:nNFSAEi:f:l:m:p:s:x:C opt ; do
 case "$opt" in
  d|c|C) eval $opt="yes" ;;
  q|w|r|x) eval $opt="$OPTARG" ;;
  n|N|F|S|A|E) topt="$topt -$opt" ;;
  i|l|p|s) topt="$topt -$opt $OPTARG" ;;
  f|m) ttl="$OPTARG" ;;
  ?) usage; exit ;;
 esac
done

shift `expr $OPTIND - 1`

if [ "x$1" = "x" ]; then
 usage
 exit
fi

max=`echo "${w} * 1000" | bc`

if [ `date +%s` != "%s" ]; then
 format="%s"
fi

_checksite ${topt} $*

if [ "$x" = "" ]; then
 while [ 1 ] ; do
  _testsite ${seq} ${topt} $* &
  pid=$!
  if [ "${C}" = "yes" ]; then
   wait $pid
  fi
  seq=`expr $seq + 1`
  sleep ${r}
 done
else
 while [ "$x" -gt 0 ] ; do
  _testsite ${seq} ${topt} $* &
  pid=$!
  if [ "${C}" = "yes" ]; then
   wait $pid
  fi
  seq=`expr $seq + 1`
  x=`expr $x - 1`
  if [ "$x" -gt 0 ]; then
   sleep ${r}
  fi
 done
fi

exit
TCPPing.pm
package Smokeping::probes::TCPPing;

=head1 301 Moved Permanently

This is a Smokeping probe module. Please use the command 

C

to view the documentation or the command

C

to generate the POD document.

=cut

use strict;
use base qw(Smokeping::probes::basefork);
use IPC::Open3;
use Symbol;
use Carp;

sub pod_hash {
      return {
              name => <<'DOC',
Smokeping::probes::TCPPing - TCPPing Probe for SmokePing
DOC
              description => <<'DOC',
Integrates TCPPing as a probe into smokeping. The variable B must
point to your copy of the TCPPing program. If it is not installed on
your system yet, you can get it from http://www.vdberg.org/~richard/tcpping.
You can also get it from http://www.darkskies.za.net/~norman/scripts/tcpping.

The (optional) port option lets you configure the port for the pings sent.
The TCPPing manpage has the following to say on this topic:

The problem is that with the widespread use of firewalls on the modern Internet,
many of the packets that traceroute(8) sends out end up being filtered, 
making it impossible to completely trace the path to the destination. 
However, in many cases, these firewalls will permit inbound TCP packets to specific 
ports that hosts sitting behind the firewall are listening for connections on. 
By sending out TCP SYN packets instead of UDP or ICMP ECHO packets, 
tcptraceroute is able to bypass the most common firewall filters.

It is worth noting that tcptraceroute never completely establishes a TCP connection 
with the destination host. If the host is not listening for incoming connections, 
it will respond with an RST indicating that the port is closed. If the host instead 
responds with a SYN|ACK, the port is known to be open, and an RST is sent by 
the kernel tcptraceroute is running on to tear down the connection without completing 
three-way handshake. This is the same half-open scanning technique that nmap(1) uses 
when passed the -sS flag.
DOC
                authors => <<'DOC',
Norman Rasmussen 
Patched for Smokeping 2.x compatibility by Anton Chernev 
DOC
        }
}


sub new($$$)
{
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self = $class->SUPER::new(@_);

    # no need for this if we run as a cgi
    unless ( $ENV{SERVER_SOFTWARE} ) {
        my $return = `$self->{properties}{binary} -C -x 1 localhost 2>&1`;
        if ($return =~ m/bytes, ([0-9.]+)\sms\s+.*\n.*\n.*:\s+([0-9.]+)/ and $1 > 0){
            $self->{pingfactor} = 1000 * $2/$1;
            print "### tcpping seems to report in ", $1/$2, " milliseconds\n";
        } else {
            $self->{pingfactor} = 1000; # Gives us a good-guess default
            print "### assuming you are using an tcpping copy reporting in milliseconds\n";
        }
    };

    return $self;
}

sub ProbeDesc($){
    my $self = shift;
    return "TCP Pings";
}

sub probevars {
 my $class = shift;
 return $class->_makevars($class->SUPER::probevars, {
  _mandatory => [ 'binary' ],
  binary => { 
   _doc => "The location of your TCPPing script.",
   _example => '/usr/bin/tcpping',
   _sub => sub { 
    my $val = shift;

           return "ERROR: TCPPing 'binary' does not point to an executable"
                unless -f $val and -x _;

    my $return = `$val -C -x 1 localhost 2>&1`;
    return "ERROR: TCPPing must be installed setuid root or it will not work\n"
     if $return =~ m/only.+root/;

    return undef;
   },
  },
 });
}

sub targetvars {
 my $class = shift;
 return $class->_makevars($class->SUPER::targetvars, {
  port => {
   _doc => "The TCP port the probe should measure.",
   _example => '80',
   _sub => sub {
    my $val = shift;

    return "ERROR: TCPPing port must be between 0 and 65535"
     if $val and ( $val < 0 or $val > 65535 ); 

    return undef;
   },
  },
 });
}

sub pingone ($){
    my $self = shift;
    my $target = shift;
    # do NOT call superclass ... the ping method MUST be overwriten
    my $inh = gensym;
    my $outh = gensym;
    my $errh = gensym;

    my @times; # Result times

    my @port = () ;
    push @port, $target->{vars}{port} if $target->{vars}{port};

    my @cmd = (
                    $self->{properties}{binary},
                    '-C', '-x', $self->pings($target), 
                    $target->{addr}, @port);
    $self->do_debug("Executing @cmd");
    my $pid = open3($inh,$outh,$errh, @cmd);
    while (<$outh>){
        chomp;
        next unless /^\S+\s+:\s+[\d\.]/; #filter out error messages from tcpping
        @times = split /\s+/;
        my $ip = shift @times;
        next unless ':' eq shift @times; #drop the colon

        @times = map {sprintf "%.10e", $_ / $self->{pingfactor}} sort {$a <=> $b} grep /^\d/, @times;
    }
    waitpid $pid,0;
    close $inh;
    close $outh;
    close $errh;

    return @times;
}

1;

Friday, May 13, 2011

i like to see what others type + syslog-ng

Once you've gone through the trouble of patching bash to send output to local5, you might find that you're not using syslog, as assumed in a previous post. Instead, you're using syslog-ng. That's cool.

In your syslog-ng.conf file, you'll need to edit some stanzas, filters and destinations.

Set local5 (bash output) destination, if you want it to go to a file.
# bash destination 
destination d_local5 { file("/var/log/local5"); }; 

# bash filters 
filter f_local5 { facility(local5); }; 

and in messages filter, add local5
filter f_messages {
        level(info,notice,warn)
            and not facility(auth,authpriv,cron,daemon,mail,news,local5);
};
and finally, set the log destination:
# local5
log {
        source(s_all); 
        filter(f_local5);
        destination(d_bash);
};

If you have a remote syslog daemon or logger such as loggly or splunk set up, drop their destination definitions in the log stanza for "local5". e.g.:

# loggy
#
destination d_loggly { tcp("logs.loggly.com" port(XXXXXX)); };

# local5
log {
        source(s_all); 
        filter(f_local5);
        destination(d_local5);
        destination(d_loggly); 
};

On loggly (if you've allowed the destination in your remote device list) or splunk, you should see something akin to:
2011 May 13 16:09:19.000 s_all@host1 bash-ub610: history: [pid:5379 uid:0] exit
2011 May 13 16:09:50.000 s_all@host1 bash-ub610: history: [pid:5584 uid:0] ls -la
2011 May 13 16:09:52.000 s_all@host1 bash-ub610: history: [pid:5584 uid:0] cd /opt/
In your old /etc/syslog.conf or /etc/rsyslog.d/50-default.conf add the following:
auth,authpriv.*;local5.*        @syslogserver
auth,authpriv.*;local5.*        @logs.loggly.com:yourportno

Thursday, May 12, 2011

microsoft dhcp and me

I like to use dhcpd on a Linux box because I can set all kinds of options, like giving search suffixes to my DHCP clients. Microsoft Windows Server iterations have no such option - or so you're told. By default, yes, this isn't an option, but at least in Server 2008, you can add new DHCP options to include the DHCP-supplied option. To do as such:

1.  Open the DHCP mmc
2.  Expand DHCP, select DHCP server name.
3.  Right Click IPv4
4.  Select "Set Predefined Options"
5.  Click Add.

A new window appears

6.  Enter the following:
Name: "Domain suffix search order" (without quotation marks)
Data Type: String
Code: "135" (without the quotation marks)
Description: "List of domain suffixes in order" (without the quotation marks)
String: Enter search suffixes separated by comma with no spaces
 
7.  Click OK.
8.  Close DHCP MMC and restart DHCP Server Service.

Now, re-open the DHCP mmc, scroll to the end of the DHCP options, and the newly created option will appear.

Monday, March 7, 2011

apache & openldap group authentication

For Apache 2.2, check your mod-enabled and mods-available directory. Make certain your ls in mods-available have the following symlinked from mods-enabled; e.g.:

 alias.load -> ../mods-available/alias.load
 auth_basic.load -> ../mods-available/auth_basic.load
 authnz_ldap.load -> /etc/apache2/mods-available/authnz_ldap.load
 authz_default.load -> ../mods-available/authz_default.load
 authz_user.load -> ../mods-available/authz_user.load
 ldap.load -> ../mods-available/ldap.load

In your site-available file, load these two loaded mods, with the following:

 LoadModule ldap_module           /usr/lib/apache2/modules/mod_ldap.so
 LoadModule authnz_ldap_module    /usr/lib/apache2/modules/mod_authnz_ldap.so

In the directory structure where you'd like to have LDAP authentication to take place, add the following stanza:

 AuthBasicProvider ldap
 AuthType Basic
 AuthzLDAPAuthoritative on
 AuthName "restricted site access"
 AuthLDAPURL ldap://www.xxx.yyy.zzz/ou=users,dc=your,dc=com?uid
 AuthLDAPGroupAttribute memberUid
 AuthLDAPGroupAttributeIsDN off
 Require ldap-group cn=agroup,ou=groups,dc=your,dc=com
 Require ldap-user adude anotherdude
 Satisfy any

If you have a round-robin LDAP setup, place the FQDN of your OpenLDAP server in the AuthLDAPURL section. The uid condition means that your authentication control is via uid. AuthLDAPGroupAttribute and its allied Require ldap-group, states that you're checking for membership in a specific group "agroup", and those members have the attribute "memberUid". You can tack on an individual user (or users on the same line), by specifying "Require ldap-user". And, To allow for both groups and users, have the "Satisfy any" directive set; otherwise no one will be able to log on and use your web-resource.

Monday, January 24, 2011

a bind slave configuration on ubuntu is sometimes vexing

while installing a slave dns server with bind on an ubuntu box, i found that the slave zone would not synchronize. logs are your friends. in /var/log/daemon.log , I saw the following:
named[4402]: dumping master file: /etc/bind/tmp-xxxxxxx: open: permission denied
named[4402]: transfer of 'www.xxx.yyy.zzz/IN' from master#53: failed while receiving responses: permission denied
it appears that named was unable to write to /etc/bind/ .
after some digging and using strace, i discovered that ubuntu is shipped with slave zone files residing here:
/var/cache/bind/
in /etc/bind/named.conf the zone definition ought to have the following format:
zone "mydomain.com" IN {
        type slave;
        file "/var/cache/bind/db.mydomain.com";
        masters { www.xxx.yyy.zzz; };
};
(or no path to the file)

and have the correct permissions:
# chown -R bind:bind /var/cache/bind/
# chmod -R g+w /var/cache/bind/
bind also needs permissions to write to various zone files, in:
/etc/default/bind9
add:  ENABLE_ZONE_WRITE=yes
however, my slave zone would still not synchronize. this was due to apparmor (sure, i knew that); edit:
/etc/apparmor.d/usr.sbin.named 

change: /etc/bind/** r,
to: /etc/bind/** rw,
some other excitement is to actually resolve things on the localhost.
/etc/network/interfaces

add:
dns-nameservers 127.0.0.1

and in /etc/bind/named.conf.options include the following stanza:
        forwarders {
                8.8.8.8; <- our friend google for ext lookups
                8.8.8.4; <- our friend google for ext lookups
                10.6.6.6; <- an internal server for internal lookups
        };

Monday, January 17, 2011

ubuntu host, let's rename you, shall we?

easy peasy.

to change an ubuntu system's hostname, do the following:
# /bin/hostname new.name
# vi /etc/hosts
# grep -r old.name /etc
# /etc/init.d/cron restart
on a debian system, do the following:
# /bin/hostname new.name
# vi /etc/hostname
# vi /etc/hosts
# grep -r old.name /etc
# sysctl kernel.hostname=new.name
# /etc/init.d/cron restart