Wednesday, December 7, 2011


When you are configuring SPF records in DNS servers you have to clearly define the mail server policy to prevent unauthorized users sending mails to using your domain. Following is the SOFTFAIL vs FAIL comparison on SPF records.

~all ==> Defines the SOFTFAIL
-all ==> defines the FAIL

SOFTFAIL will mark e-mails as spam and forward to the sender while "FAIL" will drop the mail at the mail-server itself in case you are sending unauthorized mail server.

When you start configuring SPF records its good to start with SOFTFAIL once you identified and optimized mail servers you better go with SPF "FAIL".

As a good practice its better to configure both TXT and SPF records.

Monday, November 14, 2011

Routing in Dual Interface Linux Servers

If you have a two interface eth0 and eth1 in a Linux servers. Incoming traffic of eth0 send reply through eth1. Some times this may caused problem. Eg: mail-servers may receive mails through one interface and send through some other interface. There fore its a good practice to keep separate routing table for each interface in a Linux box. And send back the data through same interface it received.

Add two routing tables

Add routing tables on /etc/iproute2/rt_tables file

1 tble_eth1
2 tble_eth2

Incoming data as out put in same interface

Interfaces are and and gw is

ip route add dev eth0 src table tble_eth0
ip route add default dev eth0 src table tble_eth0
ip rule add from table tble_eth0

ip route add dev eth1 src table tble_eth1
ip route add default via dev eth1 src table tble_eth1
ip rule add from table tble_eth1

Run above script when interfaces getting up in a boot.

Thursday, August 25, 2011

Comprehensive SVN Mirror

Subversion is critical for any software development company. Most importantly you might want to have separate mirror in local premises and other one is public place.
Also users should not be able to detect whether either he is using local mirror or public repository. Unless it become annoying. You can redirect users to local mirror using local DNS .

Assume your public SVN is and mirror is domain name will only be used to do the mirroring among servers. Users will be using accessing the svn independent of the location.

Following picture will give you a brief idea about how the replication taken place.

svnslave will redirect commits to master. Master will replicate the slave realtime.

Configurations on Main repo -

Change post-commit and post-revprop-change scripts as follows to replicate all commits and changes to slave.


/usr/bin/svnsync --source-username=svnsync --sync-username=svnsync sync 2>>/var/log/svnsynclog &


/usr/bin/svnsync --source-username=svnsync --sync-username=svnsync $REV 2>>/var/log/svnsynclog &

Configurations on Apache virtual host should be as follows. create svnsync user using following command.

htpasswd -c /etc/apache2/allowed svnsync

---------------- Start Vhost config -----------------------------


SSLProxyEngine on
SSLEngine On

SSLCertificateFile /etc/apache2/example.crt
SSLCertificateKeyFile /etc/apache2/example.key
SSLCertificateChainFile /etc/apache2/chain.crt

DAV svn
SVNPath /home/svn/test
AuthType Basic
AuthName "test master SVN Login"
AuthUserFile /etc/apache2/allowed

Require valid-user

--------- End Vhost Config -------------------------------------------

Configurations on mirror -

Install apache subversion and apache-svn module modules as follows.

apt-get install apache2 subversion libapache2-svn

enable proxy module and ssl. Slave will redirect commit to master repository using SVNMasterURI directive. It need to have proxy modules enabled.

a2enmod proxy
a2enmod proxy_http
a2enmod ssl

Create a slave svn repository.

svnadmin create --fs-type=fsfs /home/svn/test

Change pre-revprop-change as follows to makesure syncing user will alwaylibapache2-svns be svnsync

if [ "$USER" != "svnsync" ]; then
echo >&2 "Only the svnsync user is allowed to change revprops"
exit 1
exit 0 virtual host should be as follows. create svnsync user as
"htpasswd -c /etc/apache2/allowed svnsync" and configure a strong password.

----------- Start Vhost Config ---------------------------------------


# The alias directive used due to local
#users will be refering as

SSLProxyEngine on
SSLEngine On

SSLCertificateFile /etc/apache2/example.crt
SSLCertificateKeyFile /etc/apache2/example.key
SSLCertificateChainFile /etc/apache2/chain.crt

DAV svn
SVNPath /home/svn/test
AuthType Basic
AuthName "test slave SVN Login"
AuthUserFile /etc/apache2/allowed


Require valid-user

# svnsync will not allow if SVNMasterURI directive also there. Therefore
# you need to have seperate location match to have svnsync as follows.

DAV svn
SVNPath /home/svn/test
Order deny,allow
Deny from all
Allow from

-----------End Vhost Config---------------------------------

Now you can initialize slave as follows at the

svnsync --source-username=svnsync --sync-username=svnsync init

Following command will give you the stat of salve. It should return the master repo url.

svn propget svn:sync-from-url --revprop -r 0

Now start syncing the master to slave.

svnsync --source-username=svnsync --sync-username=svnsync sync

If you have a huge master repo, some times slave locks when running the svnsync. You have to remove the lock as follows in which cases.

svn pdel --revprop -r 0 svn:sync-lock file:///home/svn/test

Thursday, July 21, 2011

SVN path based authorization with LDAP authuntication

We can use LDAP for authentication and "AuthzSVNAccessFile" directive with config file for authorizing.

Configuration as follows

#----------------Apache Config ------------------------#

< Location /repo >
DAV svn
SVNPath /path/to/repo/
SVNListParentPath On
SVNAutoversioning On
SVNReposName "User Repo"
SVNPathAuthz off
AuthBasicProvider ldap
AuthBasicAuthoritative on
AuthzLDAPAuthoritative off
AuthType Basic
AuthName "User Login"
AuthLDAPBindDN ""
AuthLDAPBindPassword password
AuthzSVNAccessFile /etc/apache2/svnaccess.conf
Satisfy All
Require valid-user

< /Location >

#--------------------svnaccess.conf file -----------------------

admin = user1, user2

* = rw

* = r

Tuesday, July 19, 2011

How to backup Cisco configurations without a TFTP

"expect" is a nice linux program that can be used to automate interactive applications. There fore you can used it to execute cisco commands through a linux machine.
Best way to backup the cisco config is using "show run" command but the problem was how to save running config into a separate machine. You can use "expect" program to do that.

First you need to install "expect" program. In ubuntu/debian its easy

apt-get install expect

Then change the "router" and "pass" variables of the following script and execute on a crontab.


# ------------------- config --------------------- #
set router
set pass password
set timeout 1000
set filesave [exec date +%m-%d-%Y]

#------------------------------------------------- #

spawn telnet $router
expect "Password:"
send "$pass\n"
expect ">"
send "en\n"
expect "Password:"
send "$pass\n"

log_file $router--$filesave.cfg
send "term len 0\n"
send "show running-config\n"
expect "end\r"
send "\n"
send "exit\n"

This will save the file in IP--date.cfg format

Monday, July 18, 2011

Python script for Birthday Paradox

Probablity of two people have same birthday is .5 .
More information checkout


# Function to calculate the birthday paradox

def calParadox(in_noOfdates,in_noOfBdaysPerYear):
avg =float(1)
avgnext =float(0)
count =1
curNoOfdates =noOfdates=in_noOfdates
avgList = []

# probablity of two people having same birthday should be equel to .5 for more information
# check wikipedia about birthday problem

while avg >float(.5):
curNoOfdates =curNoOfdates-noOfBdaysPerYear
avg =avg * curNoOfdates/noOfdates
count +=1

if (avgList[-2] -.5) < (.5-avg):
count -=1

return count

# Call the function with parameters of no of birthdays and days per year :)
paradoxVal =calParadox(365,1)
print "Birthday paradox is %d" % paradoxVal

Saturday, April 23, 2011

How setup a BGP multihome network without your own public AS & IP prefix list

One of the best ways of doing traffic load-balancing and fail-over together is BGP multi-homing. Because BGP always have to best path to a particular destination and one link failure automatically transfer into other link.

But main blocker of implementing BGP in small companies is inability of having their own AS number and IP address list. If you need your own AS number and IP prefix list you have to go through the Regional Internet Registry that allocates IP and AS numbers like APNIC doing in Asia pacific reign.

Following I have explain how to set up a BGP multihomed network without your own public AS or ip prefix list. Set up describe simply as follows. you have to have two BGP peers with two ISPs (ISP1 and ISP2) by peering with your private AS number (EBGP). Also you don't advertise any prefixes (Obviously you don't have). And ask both ISPs to advertise their global BGP routing tables to your end.

Once you get both BGP routing tables on your router you obviously you have the best paths in the routing tables itself. One limitation of this setup is you can't load-balance traffic like web server, mail server traffic that DNS pointed to since you don't have your own IP addresses. In such cases you have to use one of both ISPs IP addresses. This set up is better where you have multiple links from multiple ISPs and you need to get optimal use of the bandwidth.

Following is the configuration as per the Diagram 1.

Client config

router bgp 65550
bgp log-neighbor-changes
neighbor remote-as 100
neighbor ebgp-multihop 10
neighbor update-source f0/0
neighbor soft-reconfiguration inbound
neighbor remote-as 200
neighbor ebgp-multihop 10
neighbor update-source f0/1
neighbor soft-reconfiguration inbound

ISP1 config

router bgp 100
bgp log-neighbor-changes
neighbor remote-as 65550
neighbor ebgp-multihop 10
neighbor update-source f0/0
neighbor soft-reconfiguration inbound
neighbor default-originate

ISP2 config

router bgp 200
bgp log-neighbor-changes
neighbor remote-as 65550
neighbor ebgp-multihop 10
neighbor update-source f0/1
neighbor soft-reconfiguration inbound
neighbor default-originate

F0/0 ip address is a public IP given by ISP1, same as F0/1 is public ip of ISP2. Once you done this configuration your peers should be up and running. This is same as setting up normal BGP peers. Make sure ISP1 and ISP2 advertise the default routes as well. By this point you have to make sure peers are up and running and you are getting BGP updates from both ISPs with default routes.

you can make sure whether peers are running by following commands on client and you will see output like following.

show ip bgp summery

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 4 100 1370 1373 174 0 0 21:51:15 150543 4 200 1355 1355 174 0 0 22:27:24 110435

Also following commands may help to check the BGP routes and updates
show ip bgp
show ip route bgp
sh ip bgp neighbors received-routes

There is a possibility that you re advertising the updates comming from one ISP to other. You can limit it by configuring a filter list at client side.

ip as-path access-list 1 permit ^$
router bgp 65550
neighbor filter-list 1 out
neighbor filter-list 1 out

Also you can use prefix list to filter the unwanted BGP prefixes coming from ISP1 and ISP2.

Second phase is how to send the upload traffic. Most of the time Client LAN is on private ip range there fore you have to nat the LAN traffic to access the Internet.Upload Traffic that goes to ISP1 has to be nat into F0/0 ip ( and ISP2 traffic has to be nat into F0/1 ip ( In any case if you have done static NAT and unknowingly if ISP1 get the packets with source address as ISP2 IP then ISP1 will block the traffic.
To overcome this problem you have to do the natting based on the outgoing interface. As a example Traffic goes to ISP1 has to be nat into F0/0 IP address dynamically.

Following is the configuration

ip nat pool isp1natpool netmask
ip nat inside source route-map NAT2ISP1 pool isp1natpool overload

route-map NAT2ISP1 permit 10
match ip address 180
match interface f0/0

access-list 180 permit ip any

int f0/0
ip nat outside

int f1/0
ip nat inside

Likewise you need to done the natting for ISP2 as well.

ip nat pool isp2natpool netmask
ip nat inside source route-map NAT2ISP2 pool isp2natpool overload

route-map NAT2ISP2 permit 10
match ip address 185
match interface f0/1

access-list 185 permit ip any

int f0/1
ip nat outside

Now your primary setup is done. you have failover and load-balanced multihomed network. Assume one link goes down all the BGP route will be removed from the routing table and all traffic goes through the other path. Best path to particular destination will be select from the BGP table.

Assume you need to set particular destination always through ISP1. This can be done by setting local preference higher.

router bgp 65550
neighbor route-map set-isp1-local-pref in

route-map set-isp1-local-pref permit 10
match ip address prefix-list ISP1_IN_LOCAL_PREF
set local-preference 120

ip prefix-list ISP1_IN_LOCAL_PREF seq 5 permit

This set up is successfully tested with IOS version c1841-ipbase-mz.124-15.T12.bin. If you encounter any problem while configuring please let me know.