Archive

Archive for June, 2009

myping.py

June 28, 2009 Leave a comment

A ping script using python thread. Examples of usage:

myping.py -n 192.168.1 -s 10 -e 150
  Scans 192.168.1.10 – 192.168.1.150
myping.py -n 172.16.0 -g
  Scans 172.16.0.0/24 subnet and returns active hosts only

[ direct link: http://rc3.fileave.com/myping.py.txt ]

#!/usr/bin/env python
DEBUG=False
import os
import re
import time
from threading import Thread

class pingtest(Thread):
	def __init__ (self,ip):
		Thread.__init__(self)
		self.ip = ip
		# -1 means not found, any other number indicates 
		#the index of the found pattern
		self.status = -1 
	def run(self):
		pingaling = os.popen("ping -q -c 2 -w 3 "+self.ip,"r")
		while 1:
			line = pingaling.readline()
			if not line: break
			igot = re.findall(pingtest.lifeline,line)
			if igot:
				self.status = int(igot[0])

def usage():
	print('''\
	usage 1:
	myping.py -n network_adr [ -s start -e end -g ]
	for example: myping -n 192.168.1 -s 10 -e 150

	usage 2:
	myping.py -f ip_list_file [ -g ]
	''')
if __name__=="__main__":
	import sys
	if (len(sys.argv)) < 2:
		usage()
		sys.exit()
	else:
		import getopt
		try:
			opts, args = getopt.getopt( sys.argv[1:], 'n:s:e:f:hg' )
		except getopt.GetoptError, err:
			usage()
			print str(err)
			sys.exit(1)

		#variables initialize:
		S=1
		E=254
		N=''
		FILE=''
		GOODONLY=False
		for o, a in opts:
			if DEBUG: print o
			if o == '-h':
				usage()
				sys.exit(0)
			elif o=='-g':
				GOODONLY=True
			elif o=='-n':
				N=a
			elif o=='-s':
				try:
					S=int(a)
				except Exception:
					print("int argument expected")
			elif o=='-e':
				try:
					E=int(a)
				except Exception:
					print("int argument expected")
			elif o=='-f':
				FILE=a
			else:
				assert False, "unhandled option"

		if len(N) > 0 and len(FILE)>0:
			usage()
			print("Please do not specify -n and -f at the same time")
			sys.exit(1)
		elif len(N)==0 and len(FILE)==0:
			usage()
			print("Please specify option -n or -f")
			sys.exit(1)
		else:
			pinglist = []
			pingtest.lifeline = re.compile(r"(\d) received")
			report = ("No response","Partial Response","Alive")
			print "***ping started: " + time.ctime()
			if len(N)>0:
				for host in range(S,E):
					ip = N + '.'+ str(host)
					current = pingtest(ip)
					pinglist.append(current)
					current.start()
			elif len(FILE)>0:
				try:
					f=open(FILE)
					for ip in f:
						current=pingtest(ip.strip())
						pinglist.append(current)
						current.start()
					f.close()
				except IOError, err:
					print( str(err) )
			for pingle in pinglist:
				pingle.join()
				if GOODONLY:
					if pingle.status == 2: 
						print "Status from ",pingle.ip,\
							 ": ",report[pingle.status]
				else:
					print "Status from ",pingle.ip,": ",report[pingle.status]
			print "***ping finished: "+time.ctime()

 

If you have fping installed, you can achieve the similar results with the following perl one-liner

perl -e 'for (1..254) { print "192.168.1.$_\n" }' | fping -a -q 2>/dev/null

Advertisements
Categories: Networking, Programming, python

Display disk usage in colors

June 28, 2009 Leave a comment
#!/bin/bash
LIMIT=85
usage() {
  echo "usage:"
  echo -e "\t$0 threshold [ other df options ]"
  echo -e "\t$0 -H : for help with usage of this script"	
}
if [ $# -lt 1 ]; then
  echo "**displaying disk usage with default threshold=$LIMIT, \
see mydf -H for usage**"
else
  if [[ $1 =~ ^[0-9]{1,3}$ ]]; then  
    LIMIT=$1
  else 
    usage
    exit 0
  fi
fi
shift
df -P $* | awk "BEGIN{FS=\"[ %]+\"} {
  if (NR==1) print \$0; 
  else if (\$5 > $LIMIT) print \"33[31m\"\$0\"33[0m\"; 
  else print \"33[32m\"\$0\"33[0m\"}"

 

Note: this script has been tested under ubuntu, opensuse, gentoo and freebsd. Example usages:
mydf
  displays df in colors with default threshold of 85%
mydf 75 -h
  displays df in colors with threshold of 75% and capacity units in human-readable format.

[ direct link: http://rc3.fileave.com/mydf.sh ]

Screenshot from my own desktop:

mydf.sh example output screenshot

mydf.sh example output screenshot

Categories: Bash, linux, Programming

Protect sensitive data using symmetric and asymmetric encryptions

June 28, 2009 7 comments

I have created this script to solve the problem of encrypting large data file which can not be encrypted using asymmetric method alone.
[ Direct Link: http://rc3.fileave.com/encdec.sh ]

#!/bin/bash
###############################################################################
# This script is inspired by 
# http://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php
# and http://www.simplehelp.net/2009/02/19/adding-encryption-to-protect-your-backups-on-linux/
# Public/private key scheme works great if it can encrypt large files but unfortunately only
# file upto 1024 bytes can be encrypted using a public key. secret key scheme can deal with
# big files but the same key is used for encrypting and decrypting. Therefore the best practice 
# to do is to combine these two methods together: encrypt data with the secret key (not to be
# confused with private key) then encrypt the secret key with public key. problem solved.
#### encrypt procedures
# [ 1 ] create a 1000-byte random key
# [ 2 ] encrypt the destination (either a file or folder) then remove the original secret key
# [ 3 ] encrypt the scret key generated at step 1 with the public key
# [ 4 ] now the secret key and the data file are both encrypted


#### decrypt procedures
# [ 1 ] decrypt secret key with the private key
# [ 2 ] decrypt the data file with the decrypted secret key
# [ 3 ] delete secret key

#in order to use this script, a pair of public/private keys need to be created first:
# for example:
# $ mkdir ~/.ssl
# $ cd ~/.ssl
# $ openssl genrsa -out private.pem 1024 
# $ chmod 600 private.pem
# $ openssl rsa -in private.pem -out public.pem -outform PEM -pubout
# 
# the private key privated.pem should be stored in a secure location as once it's compromised,
# all the efforts to protect sensitive data will be useless.
# $Id: encdec.sh,v 1.1 2009/04/27 05:05:03 rico Exp $

declare -rx SCRIPT=${0##*/}
TMP=`mktemp -u -p . XXX`
TMP=${TMP##*/}
KEY=secret.$TMP.key
DEBUG=1

usage() {
    printf "usages:\n"
    printf "\t%s enc datafile public_key [ output_path ]\n" $SCRIPT 
    printf "\t%s enc datadir/ public_key [ output_path ]\n" $SCRIPT 
    printf "\t%s dec datafile.bf private_key [ output_path ]\n" $SCRIPT
}

if [ $# -lt 3 ]; then
    usage
    exit
fi

case $1 in
    enc)
        TIME_START=$(date "+%s")
        TARGET=$2
        TARGET=${TARGET%/}    #remove trailing / if any
        PUB_KEY=$3
        [ $# -gt 3 ] && OUT_DIR=$4 || OUT_DIR=.
        OUT_DIR=${OUT_DIR%/}    #remove trailing / if any
        ID=`mktemp -u -p . XXXX`
        ID=${ID##*/}
        OUTPUT=$OUT_DIR/${TARGET##*/}.bf.$ID
        [ ! -f $PUB_KEY -o ! -d $OUT_DIR ] && \
		printf "Check if $PUB_KEY or $OUT_DIR/ exists\n" && exit 151
        #make sure the key is only readable by the script owner
        touch $KEY && chmod 600 $KEY
        KEY=$OUT_DIR/secret.key.$ID
        ENC_KEY=$OUT_DIR/secret.key.rsa.$ID
        dd if=/dev/random of=$KEY bs=100 count=1
        #/usr/local/bin/genpass 40 > $KEY
        #encrypt the key
        G1="openssl rsautl -encrypt -inkey $PUB_KEY -pubin -in $KEY -out $ENC_KEY"
        [ $DEBUG -eq 1 ] && echo $G1
        eval $G1
        G="tar -zcf - $TARGET|openssl enc -blowfish -pass file:$KEY|dd of=$OUTPUT"
        [ $DEBUG -eq 1 ] && echo $G || echo "Encrypting ..."
        eval $G && rm -f $KEY
        TIME_END=$(date "+%s")
        SECONDS_SPENT=$(expr $TIME_END - $TIME_START)
        printf "Encryption Summary:\n"
        printf "\tData: %s\n" $OUTPUT
        printf "\tEncrypted Key: %s\n" $ENC_KEY
        printf "\tTotal Time Elapsed: $SECONDS_SPENT seconds.\n"
        exit 0
        ;;
    dec)
        TIME_START=$(date "+%s")
        TARGET=$2
        ID=${TARGET##*.}
        PRIV_KEY=$3
        [ $# -gt 3 ] && OUT_DIR=$4 || OUT_DIR=.
        #remove trailing / if any
        OUT_DIR=${OUT_DIR%/}
        [ ! -f $PRIV_KEY ] && printf "Missing valid private key.\n" && exit 152
        if [ ! -d $OUT_DIR ]; then
            if [ -f $OUT_DIR ]; then
                printf "$OUT_DIR exists and it's a file!\n"
                exit 155
            else
                printf "Creating non-existing directory $OUT_DIR\n" && mkdir $OUT_DIR
            fi
        fi
        [ ! -f $TARGET ] && printf "$TARGET does not exist or is not a file" && exit 153
        ORIG_DIR=$(dirname $TARGET)
        ENC_KEY=$ORIG_DIR/secret.key.rsa.$ID
        KEY=$OUT_DIR/secret.key.$ID
        [ ! -f $ENC_KEY ] && printf "Encrypted secret key $ENC_KEY is missing, \
		it should be in the same path as $TARGET" && exit 154
        G="openssl rsautl -decrypt -inkey $PRIV_KEY -in $ENC_KEY -out $KEY"
        [ $DEBUG -eq 1 ] && echo $G
        eval $G
        chmod 600 $KEY
        G1="dd if=$TARGET|openssl enc -d -blowfish -pass file:$KEY|tar xzf - -C $OUT_DIR"
        [ $DEBUG -eq 1 ] && echo $G1 || echo "Decrypting ..."
        eval $G1 && rm -f $KEY
        TIME_END=$(date "+%s")
        SECONDS_SPENT=$(expr $TIME_END - $TIME_START)
        printf "Decryption Summary:\n"
        printf "\tData Location: %s\n" $OUT_DIR
        printf "\tEncrypted Key: %s\n" $ENC_KEY
        printf "\tTotal Time Elapsed: $SECONDS_SPENT seconds.\n"
        exit 0
        ;;
    *)
        usage
        exit 152
esac

[ Edit 7.20.2009: I have uploaded a newer version of this script at http://rc3.fileave.com/encdec1.2.sh ]

Categories: cipher, Programming, Security

Reloading a bg process without terminating

June 11, 2009 Leave a comment

Ever wonder how /etc/init.d/scriptname reload works? I haven’t figured out yet. But I have achieved something similar through the following example:

1. make a folder called trap

2. create main.sh under that folder with the following code

#!/bin/bash
SCRIPT=${0##*/}
[ -f data ] && step=`cat data` || step=1
if [ $# -eq 1 -a "$1" == "reload" ]; then
	if [ -f $SCRIPT.pid ]; then
		c="kill -USR1 `cat $SCRIPT.pid`"
		echo $c
		eval $c
	fi
	exit
elif [ $# -eq 1 -a "$1" == "stop" ]; then
	if [ -f $SCRIPT.pid ]; then
		kill -TERM `cat $SCRIPT.pid`
		rm -f $SCRIPT.pid
	fi
	exit
fi

init=0
function on_sigusr1()
{
	#todo: validate content in file data
	step=`cat data`
	init=0
}
echo $$>$SCRIPT.pid
while true; do
	trap on_sigusr1 SIGUSR1
	init=$((init+1))
	echo "$init"
	sleep $step
done

3. under the same folder create a text file named data

4. inside the current terminal run main.sh script

5. you should be able to see sequential numbers starting from 1 scrolling up the screen one number per second

6. now open another terminal, cd to trap/, issue the following commands:

echo “.5” > data
./main.sh reload

7. you should be able to see the numbers scroll twice as faster (change .5 to 2 will make the scrolling slower)

8. to terminate the program, simply run
./main.sh stop
from the second terminal

I didn’t add validation for the intervals but you should now get the idea how the program behaves.

Categories: Bash, linux, Programming

Easy Copy/Rename with Bash

June 11, 2009 1 comment

Instead of
cp a_very_long_file_name.ext a_very_long_file_name.ext.bak
cp a_very_long_file_name.ext{,.bak}

Instead of
mv foldername/ foldername.old/
mv foldername{,.old}/

I forgot where I got this tip but it’ll definitely save you a lot of typing. You fingers will thank you for that. Happy scripting.

#!/usr/bin/env python
import telnetlib,time,random,smtplib
from subprocess import Popen
from email.MIMEText import MIMEText
PORT=110

def testhost(host):
result=”
count=0
while count < 3:
try:
tn=telnetlib.Telnet(host,PORT)
except Exception:
return “bad”
result=tn.read_until(‘Dovecot ready.’,5)
index=result.find(‘ready.’)
tn.close()
if index < 0:
count+=1
SLEEP=random.randint(5,10)
print( “count %d, sleeping for %d seconds now” % (count,SLEEP) )
time.sleep( SLEEP )
else:
return ‘good’
return ‘bad’

def rpr(sub,msg):
FROM=’noreply@25os.net’
TO=[‘ricoc@aweb.com’]
message=MIMEText(msg)
message[‘Subject’]=”%s” % sub
message[‘From’]=’Notification’
message[‘Reply-to’]=’noreply@25os.net’
message[‘To’]=TO[0]
server=smtplib.SMTP(‘localhost’)
server.sendmail(FROM, TO, message.as_string())
server.close()

def main():
#    IPS=[ ‘69.48.143.47’, ‘69.48.143.66’, ‘69.48.143.83’ ]
HOSTS={ ‘srv_1’: ‘69.48.143.47’,
‘srv_2’: ‘69.48.143.83’,
‘srv_5’: ‘69.48.143.66’ }
restarted_hosts=”
for hn,ip in HOSTS.items():
if testhost(ip) == ‘bad’:
Popen( [ “/usr/local/bin/killvm”, hn ] )
time.sleep(2)
Popen( [ “/usr/local/bin/startvms”, hn ] )
#simulate machine restart
print(“%s restarted\n” % ip)
restarted_hosts+=”%s\n” % ip
if restarted_hosts:
rpr(“Virtualbox guest restarted”, restarted_hosts)

if __name__==’__main__’:
Read more…

Categories: Bash, linux, Tip