<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-11812054</id><updated>2011-11-02T03:26:14.370-07:00</updated><category term='Cross-Platform'/><category term='if-map'/><category term='AppleScript'/><category term='tnc'/><category term='Networking'/><category term='omapd'/><category term='Mac OS X'/><category term='dhcp'/><category term='LLDP'/><category term='ifmapdev'/><category term='Source Code'/><category term='Programming'/><category term='tcg'/><category term='Open Source'/><title type='text'>*NIX Trix</title><subtitle type='html'>Hey Rocky, watch me pull a rabbit out of my hat.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11812054.post-6158197274277279137</id><published>2010-05-19T10:26:00.000-07:00</published><updated>2010-05-19T10:26:32.797-07:00</updated><title type='text'>Building omapd on Ubuntu Lucid Lynx</title><content type='html'>As a follow-up to &lt;a href="http://nixtrix.blogspot.com/2010/05/if-map-with-isc-dhcp-and-omapd.html" alt="IF-MAP with ISC DHCP and omapd"&gt;my post on ISC DHCP and omapd integration&lt;/a&gt; I've put together this post which contains instructions on getting the latest SVN versions of omapd to build.&lt;br /&gt;&lt;br /&gt;For Ubuntu 10.04 (Lucid Lynx) the process is pretty straight forward:&lt;br /&gt;&lt;br /&gt;* Install Lucid Lynx&lt;br /&gt;* sudo apt-get install subversion&lt;br /&gt;* sudo apt-get install g++&lt;br /&gt;* sudo apt-get install libqt4-dev&lt;br /&gt;* svn checkout http://omapd.googlecode.com/svn/trunk omapd&lt;br /&gt;* cd omapd&lt;br /&gt;* ./certgen.sh&lt;br /&gt;* qmake&lt;br /&gt;* make&lt;br /&gt;* ./omapd&lt;br /&gt;&lt;br /&gt;That's it.&lt;br /&gt;&lt;br /&gt;For older versions of Ubuntu you'll need to build Qt from scratch, so it's a bit more involved but I'll update this post later for Karmic Koala users.  You need Qt 4.6.2 at a minimum to build the latest omapd sources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11812054-6158197274277279137?l=nixtrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/6158197274277279137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11812054&amp;postID=6158197274277279137' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/6158197274277279137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/6158197274277279137'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/2010/05/building-omapd-on-ubuntu-lucid-lynx.html' title='Building omapd on Ubuntu Lucid Lynx'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11812054.post-4143716348410433017</id><published>2010-05-16T06:40:00.000-07:00</published><updated>2010-05-17T17:53:35.227-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='omapd'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='tnc'/><category scheme='http://www.blogger.com/atom/ns#' term='tcg'/><category scheme='http://www.blogger.com/atom/ns#' term='if-map'/><category scheme='http://www.blogger.com/atom/ns#' term='ifmapdev'/><category scheme='http://www.blogger.com/atom/ns#' term='dhcp'/><title type='text'>IF-MAP with ISC DHCP and omapd</title><content type='html'>If you're an IT admin and you haven't heard about IF-MAP yet, chances are you will soon.&lt;br /&gt;&lt;br /&gt;IF-MAP is an open standard being championed by the Trusted Computing Group.  The 'MAP' in IF-MAP stands for Metadata Access Point and the standard defines a way for devices on the network to share information about events happening on the network.&lt;br /&gt;&lt;br /&gt;This is a huge boon for network security.  It lays the groundwork for multi-layer security that actually works (finally).&lt;br /&gt;&lt;br /&gt;For example, at Interop 2010 the Trusted Computing Group was demoing a 2-layer security system wherein the card swipe system would prevent you from being able to gain access to a PC if you weren't card-swiped into the building... even if you knew the credentials!&lt;br /&gt;&lt;br /&gt;So how does IF-MAP work?&lt;br /&gt;&lt;br /&gt;There's a central server called the MAP server that listens for devices to publish updates, and for subscribers to request updates.  That's all.  Yes, it's that simple.&lt;br /&gt;&lt;br /&gt;The amazing thing about IF-MAP is that it's vendor agnostic.  A device that wishes to consume data only needs to subscribe to the data it cares about.  A device that publishes data doesn't need to concern itself with the consumers.&lt;br /&gt;&lt;br /&gt;So I think this stuff is really great, and I'm excited that there's an Open Source implementation of IF-MAP called omapd.&lt;br /&gt;&lt;br /&gt;I got omapd up and running (a post for another time) but it doesn't really do anything useful by itself.&lt;br /&gt;&lt;br /&gt;One of the most exciting applications (in my  mind) is being able to publish DHCP lease information, so I decided to see what it would take to make ISC DHCP able to publish lease aquisitions and to delete those entries upon release or expiration.&lt;br /&gt;&lt;br /&gt;I used Ubuntu 10.04 'Lucid Lynx' for the project.&lt;br /&gt;&lt;br /&gt;To keep things simple, I'm going to assume that you already have an omapd installation up and running.&lt;br /&gt;&lt;br /&gt;First, you need to install ISC DHCP, Perl's SOAP::Lite module, and curl:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install dhcp3-server&lt;br /&gt;sudo apt-get install libsoap-lite-perl&lt;br /&gt;sudo apt-get install curl&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We're going to be using the ISC DHCP "on &lt;event&gt;event" triggers to call a script whenever a lease is committed, released, or expired.  Lucid Lynx has app-armor enabled by default, so these triggers will fail unless we tweak the apparmor settings to allow dhcpd to execute external scripts.&lt;br /&gt;&lt;br /&gt;To keep things simple I have disabled the apparmor checks for dhcpd:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo ln -s /etc/apparmor.d/usr.sbin.dhcpd3 /etc/apparmor.d/disable/&lt;br /&gt;sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.dhcpd3&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The default location for the DHCP server configuration file is /etc/dhcp3/dhcpd.conf.&lt;br /&gt;&lt;br /&gt;Here's what mine looks like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ddns-update-style none;&lt;br /&gt;&lt;br /&gt;authoritative;&lt;br /&gt;&lt;br /&gt;default-lease-time 30;&lt;br /&gt;&lt;br /&gt;max-lease-time 30;&lt;br /&gt;&lt;br /&gt;log-facility local7;&lt;br /&gt;&lt;br /&gt;stash-agent-options true;&lt;br /&gt;&lt;br /&gt;subnet 10.0.0.0 netmask 255.255.255.0 {&lt;br /&gt;option subnet-mask 255.255.255.0;&lt;br /&gt;option routers 10.0.0.1;&lt;br /&gt;option domain-name-servers 8.8.8.8, 8.8.4.4;&lt;br /&gt;range 10.0.0.2 10.0.0.254;&lt;br /&gt;&lt;br /&gt;on commit {&lt;br /&gt;set clientIP = binary-to-ascii(10, 8, ".", leased-address);&lt;br /&gt;set clientMAC = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));&lt;br /&gt;&lt;br /&gt;execute("/usr/local/libexec/publish-ip-mac.pl", "commit", clientIP, clientMAC);&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;on release {&lt;br /&gt;set clientIP = binary-to-ascii(10, 8, ".", leased-address);&lt;br /&gt;set clientMAC = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));&lt;br /&gt;&lt;br /&gt;execute("/usr/local/libexec/publish-ip-mac.pl", "release", clientIP, clientMAC);    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;on expiry {&lt;br /&gt;set clientIP = binary-to-ascii(10, 8, ".", leased-address);&lt;br /&gt;&lt;br /&gt;if(exists agent.remote-id) {&lt;br /&gt;set clientMAC = binary-to-ascii(16, 8, ":", substring(option agent.remote-id, 2, 6));&lt;br /&gt;&lt;br /&gt;execute("/usr/local/libexec/publish-ip-mac.pl", "expiry", clientIP, clientMAC);  &lt;br /&gt;} else {&lt;br /&gt;execute("/usr/local/libexec/publish-ip-mac.pl", "expiry", clientIP);    &lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The above configuration is pretty straight forward.  There's a single scope, a global lease time of 30 seconds (for testing), and the on event triggers that I mentioned.&lt;br /&gt;&lt;br /&gt;One thing to note here is that you can put the on event triggers in the global scope.  They will work just as well there, just like other ISC DHCP configuration options.&lt;br /&gt;&lt;br /&gt;Notice that the on expiry event doesn't use the clientMAC variable like on commit and on release.  This is because an expiration event doesn't get triggered by the client, so there is no packet to pull that information out of.  To work around that my hook script caches any incoming commit requests and when an expiry comes in it grabs the MAC address from the cache so the entry can be properly deleted on the IF-MAP server.&lt;br /&gt;&lt;br /&gt;Everything else is fairly straight forward.  When a lease is committed, or released the DHCP server executes publish-ip-mac.pl and passes 3 parameters: type, IP address, and MAC address (2 in the case of expiry - type and IP address).&lt;br /&gt;&lt;br /&gt;One thing to note about the execute command with dhcpd - The documentation mentions that you don't want long-executing scripts to be called because it can cause performance delays with the DHCP server.  I solve that by forking as soon as the script has started executing.&lt;br /&gt;&lt;br /&gt;Here's an example shell that you can reuse for other purposes with these on event hooks:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;my $type = shift;&lt;br /&gt;my $ip   = shift;&lt;br /&gt;my $mac  = shift;&lt;br /&gt;&lt;br /&gt;# Fork so we can return control&lt;br /&gt;# to the dhcp server ASAP.&lt;br /&gt;my $pid = fork();&lt;br /&gt;&lt;br /&gt;# If we're the child, do whatever we need to do&lt;br /&gt;if($pid == 0) {&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I'm still working on the script that handles the publishing and deletion of entries.  Ideally I'd like to have the entire script driven by a nice clean SOAP interface, but I've had some troubles with the WSDL definition file, so I cut some corners on the publish and delete by calling out to curl.  It's not pretty, but it gets the job done.&lt;br /&gt;&lt;br /&gt;Here's the full publish-ip-mac.pl script:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/perl&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;use Data::Dumper qw(Dumper);&lt;br /&gt;use Fcntl qw(:flock);&lt;br /&gt;use SOAP::Lite &lt;br /&gt;    # For debugging&lt;br /&gt;    #+trace=&amp;gt;'all';&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;sub request_publish;&lt;br /&gt;sub request_delete;&lt;br /&gt;&lt;br /&gt;my $leaseFile = "/tmp/ifmap-leases";&lt;br /&gt;my $lockFile  = "/tmp/ifmap-lease-lock";&lt;br /&gt;&lt;br /&gt;my $leases;&lt;br /&gt;&lt;br /&gt;my $type = shift;&lt;br /&gt;my $ip   = shift;&lt;br /&gt;my $mac  = shift;&lt;br /&gt;my $ifmapServer = "https://127.0.0.1:8081";&lt;br /&gt;&lt;br /&gt;# Fork so we can return control&lt;br /&gt;# to the dhcp server ASAP.&lt;br /&gt;my $pid = fork();&lt;br /&gt;&lt;br /&gt;# If we're the child them&lt;br /&gt;# attempt to publish this&lt;br /&gt;# information to the MAP&lt;br /&gt;# server. &lt;br /&gt;if($pid == 0) {&lt;br /&gt;    # Wait for the lease lock&lt;br /&gt;    open(LOCKFH, "&amp;gt; $lockFile");&lt;br /&gt;    flock(LOCKFH, LOCK_EX);&lt;br /&gt;&lt;br /&gt;    # Thaw the leases out&lt;br /&gt;    if(-f $leaseFile) {&lt;br /&gt; $leases = do $leaseFile;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    # If $leases-&amp;gt;{$ip} eq $mac, then we're&lt;br /&gt;    # already published, so do nothing&lt;br /&gt;    # rather than beat on the MAP server.&lt;br /&gt;    if($type eq "commit") {&lt;br /&gt; if(defined($leases-&amp;gt;{$ip}) and defined($mac)) {&lt;br /&gt;     if($leases-&amp;gt;{$ip} eq $mac) {&lt;br /&gt;  exit(0);&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    my $soap = SOAP::Lite&lt;br /&gt; -&amp;gt;readable(1)&lt;br /&gt; -&amp;gt;proxy('https://127.0.0.1:8081');&lt;br /&gt;        # Use the below with the WSDL interface.&lt;br /&gt;        # and remove the proxy line.&lt;br /&gt; #-&amp;gt;service('file:ifmap.wsdl')&lt;br /&gt; #-&amp;gt;endpoint("https://127.0.0.1:8081");&lt;br /&gt;&lt;br /&gt;    my $serializer = $soap-&amp;gt;serializer();&lt;br /&gt;&lt;br /&gt;    $serializer-&amp;gt;register_ns('http://www.trustedcomputinggroup.org/2006/IFMAP/1', 'ifmap');&lt;br /&gt;&lt;br /&gt;    $serializer-&amp;gt;register_ns('http://www.trustedcomputinggroup.org/2006/IFMAP-METADATA/1', 'meta');&lt;br /&gt;&lt;br /&gt;    my $newSession = SOAP::Data-&amp;gt;name("ifmap:new-session");&lt;br /&gt;&lt;br /&gt;    my $soapReply = $soap-&amp;gt;call($newSession);&lt;br /&gt;    &lt;br /&gt;    my $sessionId   = $soapReply-&amp;gt;valueof('//session-id');&lt;br /&gt;    my $publisherId = $soapReply-&amp;gt;valueof('//publisher-id');&lt;br /&gt;&lt;br /&gt;    printf("Session ID: $sessionId\n");&lt;br /&gt;    printf("Publisher ID: $publisherId\n");&lt;br /&gt;&lt;br /&gt;    my $sessionHeader = &lt;br /&gt; SOAP::Header&lt;br /&gt; -&amp;gt;name("ifmap:session-id")&lt;br /&gt; -&amp;gt;value($sessionId);&lt;br /&gt;    &lt;br /&gt;    if($type eq "commit") {&lt;br /&gt; # Check to see if this IP is already published.&lt;br /&gt; if(defined($leases-&amp;gt;{$ip}) and defined($mac)) {&lt;br /&gt;     # We have a stale lease in our&lt;br /&gt;     # cache, so send a delete request&lt;br /&gt;     if($leases-&amp;gt;{$ip} ne $mac) {&lt;br /&gt;  request_delete($sessionId, $ip, $leases-&amp;gt;{$ip});&lt;br /&gt;  &lt;br /&gt;  delete $leases-&amp;gt;{$ip};&lt;br /&gt;     }     &lt;br /&gt; }    &lt;br /&gt;   print "Doesn't exist!\n";&lt;br /&gt;   # This is a new lease, so publish it.&lt;br /&gt;   request_publish($sessionId, $ip, $mac);&lt;br /&gt;&lt;br /&gt;   $leases-&amp;gt;{$ip} = $mac;&lt;br /&gt;    } elsif($type eq "release" or $type eq "expiry") {&lt;br /&gt; # If we weren't provided a MAC address&lt;br /&gt; # then pull it out of the leases cache&lt;br /&gt; # if it exists there.&lt;br /&gt; if(!defined($mac)) {&lt;br /&gt;     # This should probably only ever happen&lt;br /&gt;     # with the "expiry" event.&lt;br /&gt;     if(defined($leases-&amp;gt;{$ip})) {&lt;br /&gt;  $mac = $leases-&amp;gt;{$ip}      &lt;br /&gt;     } else {&lt;br /&gt;  # Store something in $mac&lt;br /&gt;  # since request_delete &lt;br /&gt;  # expects it.&lt;br /&gt;  $mac = "00:00:00:00:00:00";&lt;br /&gt;     }    &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; # Delete the session.&lt;br /&gt; request_delete($sessionId, $ip, $mac); &lt;br /&gt; &lt;br /&gt; # Delete the cache entry.&lt;br /&gt; if(exists($leases-&amp;gt;{$ip})) {&lt;br /&gt;     delete $leases-&amp;gt;{$ip};&lt;br /&gt; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    # Save the updated lease cache.&lt;br /&gt;    open(FH, "&amp;gt; $leaseFile");&lt;br /&gt;    print FH Dumper($leases);&lt;br /&gt;    close(FH);&lt;br /&gt;&lt;br /&gt;    # Closing a locked file handle&lt;br /&gt;    # unlocks it.&lt;br /&gt;    close(LOCKFH);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub request_publish {&lt;br /&gt;    my ($sessionId, $ip, $mac) = @_;&lt;br /&gt;&lt;br /&gt;    printf("Request publish.\n");&lt;br /&gt;    &lt;br /&gt;my $publishCommand = &amp;lt;&amp;lt;END;&lt;br /&gt;curl --insecure -X POST -H 'Content-type: text/xml' -d '&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;env:Envelope &lt;br /&gt;  xmlns:env="http://www.w3.org/2003/05/soap-envelope" &lt;br /&gt;  xmlns:ifmap="http://www.trustedcomputinggroup.org/2006/IFMAP/1" &lt;br /&gt;  xmlns:meta="http://www.trustedcomputinggroup.org/2006/IFMAP-METADATA/1"&amp;gt;&lt;br /&gt;  &amp;lt;env:Header&amp;gt;&lt;br /&gt;    &amp;lt;ifmap:session-id&amp;gt;$sessionId&amp;lt;/ifmap:session-id&amp;gt;&lt;br /&gt;  &amp;lt;/env:Header&amp;gt;&lt;br /&gt;  &amp;lt;env:Body&amp;gt;&lt;br /&gt;    &amp;lt;ifmap:publish&amp;gt;&lt;br /&gt;      &amp;lt;update&amp;gt;&lt;br /&gt;        &amp;lt;link&amp;gt;&lt;br /&gt;          &amp;lt;identifier&amp;gt;&lt;br /&gt;            &amp;lt;mac-address value="$mac"/&amp;gt;&lt;br /&gt;          &amp;lt;/identifier&amp;gt;&lt;br /&gt;          &amp;lt;identifier&amp;gt;&lt;br /&gt;            &amp;lt;ip-address value="$ip" type="IPv4"/&amp;gt;&lt;br /&gt;          &amp;lt;/identifier&amp;gt;&lt;br /&gt;        &amp;lt;/link&amp;gt;&lt;br /&gt;        &amp;lt;metadata&amp;gt;&lt;br /&gt;          &amp;lt;meta:ip-mac cardinality="singleValue"/&amp;gt;&lt;br /&gt;        &amp;lt;/metadata&amp;gt;&lt;br /&gt;      &amp;lt;/update&amp;gt;&lt;br /&gt;    &amp;lt;/ifmap:publish&amp;gt;&lt;br /&gt;  &amp;lt;/env:Body&amp;gt;&lt;br /&gt;&amp;lt;/env:Envelope&amp;gt;' $ifmapServer&lt;br /&gt;END&lt;br /&gt;`$publishCommand`;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sub request_delete {&lt;br /&gt;    my ($sessionId, $ip, $mac) = @_;&lt;br /&gt;&lt;br /&gt;    printf("Request publish.\n");&lt;br /&gt;&lt;br /&gt;my $deleteCommand = &amp;lt;&amp;lt;END;&lt;br /&gt;curl --insecure -X POST -H 'Content-type: text/xml' -d '&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;env:Envelope &lt;br /&gt;  xmlns:env="http://www.w3.org/2003/05/soap-envelope" &lt;br /&gt;  xmlns:ifmap="http://www.trustedcomputinggroup.org/2006/IFMAP/1" &lt;br /&gt;  xmlns:meta="http://www.trustedcomputinggroup.org/2006/IFMAP-METADATA/1"&amp;gt;&lt;br /&gt;  &amp;lt;env:Header&amp;gt;&lt;br /&gt;    &amp;lt;ifmap:session-id&amp;gt;$sessionId&amp;lt;/ifmap:session-id&amp;gt;&lt;br /&gt;  &amp;lt;/env:Header&amp;gt;&lt;br /&gt;  &amp;lt;env:Body&amp;gt;&lt;br /&gt;    &amp;lt;ifmap:publish&amp;gt;&lt;br /&gt;      &amp;lt;delete filter="meta:ip-mac"&amp;gt;&lt;br /&gt;        &amp;lt;link&amp;gt;&lt;br /&gt;          &amp;lt;identifier&amp;gt;&lt;br /&gt;            &amp;lt;mac-address value="$mac"/&amp;gt;&lt;br /&gt;          &amp;lt;/identifier&amp;gt;&lt;br /&gt;          &amp;lt;identifier&amp;gt;&lt;br /&gt;            &amp;lt;ip-address value="$ip" type="IPv4"/&amp;gt;&lt;br /&gt;          &amp;lt;/identifier&amp;gt;&lt;br /&gt;        &amp;lt;/link&amp;gt;&lt;br /&gt;      &amp;lt;/delete&amp;gt;&lt;br /&gt;    &amp;lt;/ifmap:publish&amp;gt;&lt;br /&gt;  &amp;lt;/env:Body&amp;gt;&lt;br /&gt;&amp;lt;/env:Envelope&amp;gt;' $ifmapServer&lt;br /&gt;END&lt;br /&gt;print `$deleteCommand`; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And finally, here's what the output from /var/log/syslog looks like:&lt;br /&gt;&lt;br /&gt;Lease commit:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;May 16 23:25:15 ubuntu dhcpd: DHCPDISCOVER from 00:15:60:c8:16:44 via eth1&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: DHCPOFFER on 10.0.0.2 to 00:15:60:c8:16:44 (Open1x-PC) via eth1&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: execute_statement argv[0] = /usr/local/libexec/publish-ip-mac.pl&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: execute_statement argv[1] = commit&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: execute_statement argv[2] = 10.0.0.2&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: execute_statement argv[3] = 0:15:60:c8:16:44&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: DHCPREQUEST for 10.0.0.2 (10.0.0.1) from 00:15:60:c8:16:44 (Open1x-PC) via eth1&lt;br /&gt;May 16 23:25:16 ubuntu dhcpd: DHCPACK on 10.0.0.2 to 00:15:60:c8:16:44 (Open1x-PC) via eth1&lt;br /&gt;May 16 23:25:19 ubuntu dhcpd: DHCPINFORM from 10.0.0.2 via eth1&lt;br /&gt;May 16 23:25:19 ubuntu dhcpd: DHCPACK to 10.0.0.2 (00:15:60:c8:16:44) via eth1&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lease release:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;May 16 23:25:25 ubuntu dhcpd: execute_statement argv[0] = /usr/local/libexec/publish-ip-mac.pl&lt;br /&gt;May 16 23:25:25 ubuntu dhcpd: execute_statement argv[1] = release&lt;br /&gt;May 16 23:25:25 ubuntu dhcpd: execute_statement argv[2] = 10.0.0.2&lt;br /&gt;May 16 23:25:25 ubuntu dhcpd: execute_statement argv[3] = 0:15:60:c8:16:44&lt;br /&gt;May 16 23:25:26 ubuntu dhcpd: DHCPRELEASE of 10.0.0.2 from 00:15:60:c8:16:44 (Open1x-PC) via eth1 (found)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lease expiry:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;May 16 23:26:19 ubuntu dhcpd: execute_statement argv[0] = /usr/local/libexec/publish-ip-mac.pl&lt;br /&gt;May 16 23:26:19 ubuntu dhcpd: execute_statement argv[1] = expiry&lt;br /&gt;May 16 23:26:19 ubuntu dhcpd: execute_statement argv[2] = 10.0.0.2&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In a future post I'll discuss how to set up omapd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11812054-4143716348410433017?l=nixtrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/4143716348410433017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11812054&amp;postID=4143716348410433017' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/4143716348410433017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/4143716348410433017'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/2010/05/if-map-with-isc-dhcp-and-omapd.html' title='IF-MAP with ISC DHCP and omapd'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11812054.post-5014812991399127704</id><published>2010-03-07T04:18:00.000-08:00</published><updated>2010-03-07T04:55:47.766-08:00</updated><title type='text'>Open1X XSupplicant finally comes to Vista/Windows 7</title><content type='html'>It's gone unsupported far too long, but XSupplicant finally works with wireless* on Windows Vista and Windows 7.&lt;br /&gt;&lt;br /&gt;I managed to authenticate with WPA-PSK and 802.1X enabled networks, key, and get a DHCP address.  Not too shabby.&lt;br /&gt;&lt;br /&gt;The trouble with Vista and 7 is that the NDIS stack was rewritten, which meant protocol driver work to be able to properly receive wireless events and ethernet frames.  Additionally, Microsoft has done some things that make it extremely difficult to get at the underpinnings required to make keying and other important driver calls.&lt;br /&gt;&lt;br /&gt;In short, a lot of stuff changed between XP and Vista/7 that have caused a lot of heartburn for the project.&lt;br /&gt;&lt;br /&gt;One more thing of note... those of us that used to work on the project full time for our day jobs no longer do so.  The time we put into the project these days is far less than we used to be able to (and far less than we'd like).&lt;br /&gt;&lt;br /&gt;Finally, I can't take credit for any of the Vista/7 work (unless you count my heckling Chris while he chased down annoying bugs).&lt;br /&gt;&lt;br /&gt;Nightly builds are located here:&lt;br /&gt;&lt;br /&gt;http://www.open1x.org/build/nightly/windows&lt;br /&gt;&lt;br /&gt;The specific build that I am testing with as of this post is:&lt;br /&gt;&lt;br /&gt;http://www.open1x.org/build/nightly/windows/xsupplicant-setup-v2.2.nightly.183.exe&lt;br /&gt;&lt;br /&gt;* Known Issues (based on testing with 2.2 nightly build revision 183):&lt;br /&gt;&lt;br /&gt;Update your wireless drivers.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Vista's stock IPW 3945 driver did not work for me.  Intel's version 12.4.4.5 works for me.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Windows 7's stock IPW 3945 driver worked for me.  YMMV.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There are currently interface enumeration issues, so if you have more than one wireless card you may see some strange behavior.&lt;br /&gt;&lt;br /&gt;You will need to reboot your system if you do update your wireless drivers.  XSupplicant isn't currently catching wireless events properly, so your card might show up but it probably won't work.&lt;br /&gt;&lt;br /&gt;Don't be surprised if the service and/or UI crash... a lot.  This stuff is extremely beta.&lt;br /&gt;&lt;br /&gt;I couldn't get the IPW 3945 working at all on Vista Home Basic on my HP.  I'm not sure why, but I'll need to try Home Premium on it and see if it works, since IPW 3945 + Dell D620 works with Home Premium.&lt;br /&gt;&lt;br /&gt;My Setup:&lt;br /&gt;&lt;br /&gt;Dell Latitude D620&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows Vista Home Premium w/SP2&lt;/li&gt;&lt;li&gt;Windows 7 Home Premium&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Intel PRO/Wireless 3945ABG&lt;/li&gt;&lt;/ul&gt;HP/Compaq nc6320&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows Vista Home Basic w/SP2&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Intel PRO/Wireless 3945ABG&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11812054-5014812991399127704?l=nixtrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/5014812991399127704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11812054&amp;postID=5014812991399127704' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/5014812991399127704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/5014812991399127704'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/2010/03/open1x-xsupplicant-finally-comes-to.html' title='Open1X XSupplicant finally comes to Vista/Windows 7'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11812054.post-1296666295658487140</id><published>2009-09-05T00:02:00.001-07:00</published><updated>2009-09-05T13:36:20.497-07:00</updated><title type='text'>DD-WRT OpenVPN Persistent Routed Split Tunnel Howto</title><content type='html'>&lt;div style="text-align: left;"&gt;The purpose of this howto is to explain how to get OpenVPN working with a routed tun setup.  The goal is to have a permanent point-to-point link connecting several networks together through a central VPN server that manages the routing table propagation.  We don't want to NAT the routes, either, so this post explains how to disable that.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I used dd-wrt build 12533 (vpn generic) on a Linksys WRT310N v1.0.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Go here, and find your model: http://www.dd-wrt.com/dd-wrtv3/dd-wrt/hardware.html&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Download the mini and vpn versions.  You *must* install the mini version first, then upgrade from that to the vpn build.  It has to do with how Linksys' firmware loader handles loading images over 3MB.  The mini build overcomes this restriction, so get it installed first.  There are plenty of documents on the dd-wrt site and on the net explaining this issue in detail, so I won't discuss it any further.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm going to assume that you're familiar enough with linksys and/or dd-wrt to get it installed and running, so I won't explain the process in detail, but here are the steps I generally take to prep my hardware:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Upgrade to latest Linksys firmware, then reset to factory defaults.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Install dd-wrt mini via web interface, then reset to factory defaults. (I use the 30-30-30 method here).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Install dd-wrt vpn via web interface, then reset to factory defaults.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The dd-wrt boards generally recommend doing a 30-30-30 reset on the system after each update, but I only do it after the initial dd-wrt load, then I use the factory reset software option when upgrading my firmwares.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you don't know what the 30-30-30 reset method is, go google it.  It's basically just holding down the reset button to do a hard reset (though diehards might disagree with me), so if you've ever restored a linksys to factory state with that little reset button in the back, that's pretty much it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ok, on with the configuration.  At this point I'm going to assume that you have the vpn build installed and are ready to configure it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For my configuration, the server is servicing 192.168.0.0/20.  My network is 192.168.16.0/20 and there are other 192.168.x.0/20 networks hosted by other clients which will be connecting to the VPN as well.  For simplicity sake I will only show how to configure a single client, but I'll touch on the points that are relevant to consider when handling multiple permanent VPN links in this scenario.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, I configured my router (LAN-side) for the appropriate local subnet (192.168.16.0/20).  Since my router gets a DHCP address on the WAN-side, I won't go into configuration here and will assume that your router is configured to reach the Internet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since OpenVPN is an SSL-based VPN we'll need to generate certificates.  This is the most complicated part of the process.  I'm not going to go into how to generate the server certificate, but I will explain how I generate my client certificates.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OpenVPN is going to be running on embedded hardware, and modifying the dd-wrt installation post-install is a bit of a pain in the butt, we're going to use certificates that don't have a passphrase so that the setup will be simpler.  As always, keep your private key private.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've named my router Crete, so let's generate a certificate:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&gt; openssl genrsa -out crete.key&lt;/div&gt;&lt;div&gt;&gt; openssl req -new -key crete.key -out crete.csr -days 730&lt;/div&gt;&lt;div&gt;&gt; openssl ca -policy policy_anything -out crete.pem -infiles crete.csr&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The data in the certificate doesn't matter *EXCEPT* for the CN field.  This matters very much for reasons we'll get into later.  Since my router is named Crete, I'm going to put "Crete" in my CN field.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, remember to *NOT* put a passphrase on your certificate, but you will need to provide the CA's passphrase to sign the certificate.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are the details for my signed certificate:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Check that the request matches the signature&lt;/div&gt;&lt;div&gt;Signature ok&lt;/div&gt;&lt;div&gt;Certificate Details:&lt;/div&gt;&lt;div&gt;        Serial Number: 5 (0x5)&lt;/div&gt;&lt;div&gt;        Validity&lt;/div&gt;&lt;div&gt;            Not Before: Sep  4 10:44:22 2009 GMT&lt;/div&gt;&lt;div&gt;            Not After : Sep  4 10:44:22 2010 GMT&lt;/div&gt;&lt;div&gt;        Subject:&lt;/div&gt;&lt;div&gt;            countryName               = US&lt;/div&gt;&lt;div&gt;            stateOrProvinceName       = UT&lt;/div&gt;&lt;div&gt;            localityName              = Murray&lt;/div&gt;&lt;div&gt;            organizationName          = OpenSEA&lt;/div&gt;&lt;div&gt;            organizationalUnitName    = Open1X&lt;/div&gt;&lt;div&gt;            commonName                = Crete&lt;/div&gt;&lt;div&gt;            emailAddress              = terry.simons@gmail.com&lt;/div&gt;&lt;div&gt;        X509v3 extensions:&lt;/div&gt;&lt;div&gt;            X509v3 Basic Constraints: &lt;/div&gt;&lt;div&gt;                CA:FALSE&lt;/div&gt;&lt;div&gt;            Netscape Comment: &lt;/div&gt;&lt;div&gt;                OpenSSL Generated Certificate&lt;/div&gt;&lt;div&gt;            X509v3 Subject Key Identifier: &lt;/div&gt;&lt;div&gt;                XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX&lt;/div&gt;&lt;div&gt;            X509v3 Authority Key Identifier: &lt;/div&gt;&lt;div&gt;                keyid:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Certificate is to be certified until Sep  4 10:44:22 2010 GMT (365 days)&lt;/div&gt;&lt;div&gt;Sign the certificate? [y/n]:y&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1 out of 1 certificate requests certified, commit? [y/n]y&lt;/div&gt;&lt;div&gt;Write out database with 1 new entries&lt;/div&gt;&lt;div&gt;Data Base Updated&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ok, we're ready to configure the VPN.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Go to Services-&gt;VPN and enable the OpenVPN Client.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enter in the relevant information.  For my purposes I'm using UDP TUN with LZO compression.  Everything else is default.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You'll need to copy and paste in the certificates now.  The CA certificate which was used to sign your client certificate, your client certificate, and your private key.  My files are named cacert.pem, crete.pem, and crete.key.  When you paste them into the UI, you *only* need the data in between (and including) the BEGIN and END lines.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, I include an extra line after the END just because I've seen some things get picky about certificates that way.  I don't know if it's strictly necessary on this setup.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Go ahead and save this and head over to the Administrations-&gt;Commands window.&lt;br /&gt;&lt;br /&gt;Here's the most simple setup:&lt;br /&gt;&lt;br /&gt;# Accept any tunnel traffic destined for Crete&lt;br /&gt;iptables -I INPUT 1 -i tun+ -j ACCEPT&lt;br /&gt;&lt;br /&gt;# Accept any traffic leaving Crete and heading for any tunnel&lt;br /&gt;iptables -I OUTPUT 1 -i tun+ -j ACCEPT&lt;br /&gt;&lt;br /&gt;# Accept any traffic that needs to be forwarded to or from the tunnel on behalf of another host.&lt;br /&gt;iptables -I FORWARD 1 -i tun+ -j ACCEPT&lt;br /&gt;&lt;br /&gt;The above lines make it so we'll accept any input or output from the tunnel, and we'll forward anything that we need to that is tunnel related.  The above rules are very insecure, but you can use them to troubleshoot if you have issues.&lt;br /&gt;&lt;br /&gt;I'm going to go off of a stricter set of rules for my configuration:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Paste this in the Commands box:&lt;br /&gt;&lt;br /&gt;# DROP any traffic coming from any tunnel that purports to be us.&lt;br /&gt;&lt;/div&gt;iptables -I INPUT 1 -i tun+ -s 192.168.16.0/20 -j DROP&lt;br /&gt;&lt;br /&gt;# Accept any other tunnel traffic.&lt;br /&gt;iptables -I INPUT 2 -i tun+ -j ACCEPT&lt;br /&gt;&lt;br /&gt;# Forward traffic through the tunnel for 172.16.16.0/24 hosts (this is our tunnel address space).&lt;br /&gt;iptables -I FORWARD 1 -o tun0 -s 172.16.16.0/24 -j ACCEPT&lt;br /&gt;&lt;br /&gt;# Forward traffic through the tunnel for any of our subnet.&lt;br /&gt;iptables -I FORWARD 2 -o tun0 -s 192.168.16.0/20 -j ACCEPT&lt;br /&gt;&lt;br /&gt;# Drop any other traffic trying to go through the tunnel.&lt;br /&gt;iptables -I FORWARD 3 -o tun0 -j DROP&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;# Turn off NAT on the tunnel, since we want to route directly.&lt;br /&gt;iptables -D POSTROUTING -t nat -o tun0 -j MASQUERADE&lt;br /&gt;&lt;br /&gt;Note that if we add more tunnels to different places in the future, the above rules will prevent the other tunnels from talking to each other.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Click Save Firewall&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The INPUT chain configuration says to accept packets inbound from the tunnel interface that are destined for the router (Crete), but to drop any other traffic.  If you'd rather not have people poking at your router remotely you can leave this line out, but you'll probably still want to block anyone claiming to be 192.168.16.0/20 (or whatever your subnet is).&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The FORWARD chain configuration says to accept packets that are destined to be forwarded on beyond Crete.  This means the systems behind the router on 192.168.16.0/20, but not including Crete.  We also explicitly include the tunnel interfaces (172.16.16.0/24) but exclude everything else.  This prevents addresses we don't trust from using our tunnel.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Strictly speaking, at this point if your server is configured you should be able to establish a tunnel and pass traffic, but this wasn't good enough for me.  The problem is that the default OpenVPN configuration on dd-wrt brings up a NAT that tunnels all traffic out the tunnel interface, but I want only traffic destined for systems on the other side of the tunnel to traverse the tunnel.  Everything else should be routed out my WAN interface.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order to accomplish this we turn off NAT with the final iptables line.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That's it.  Now it's time to discuss the server configuration.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here it is:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;port 1194&lt;/div&gt;&lt;div&gt;proto udp&lt;/div&gt;&lt;div&gt;dev tun&lt;/div&gt;&lt;div&gt;ca /etc/ssl/CA/cacert.pem&lt;/div&gt;&lt;div&gt;cert /etc/ssl/CA/server_cert.pem&lt;/div&gt;&lt;div&gt;key /etc/ssl/CA/server_key.pem&lt;/div&gt;&lt;div&gt;dh /etc/ssl/CA/dh1024.pem&lt;/div&gt;&lt;div&gt;server 172.16.16.0 255.255.255.0&lt;/div&gt;&lt;div&gt;ifconfig-pool-persist ipp.txt 60&lt;/div&gt;&lt;div&gt;keepalive 10 30&lt;/div&gt;&lt;div&gt;comp-lzo&lt;/div&gt;&lt;div&gt;persist-key&lt;/div&gt;&lt;div&gt;persist-tun&lt;/div&gt;&lt;div&gt;status status.log&lt;/div&gt;&lt;div&gt;verb 3&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;client-to-client&lt;/div&gt;&lt;div&gt;client-config-dir ccd&lt;/div&gt;&lt;div&gt;route 192.168.16.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.32.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.64.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.96.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.128.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.192.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.224.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.240.0 255.255.240.0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;push "route 192.168.0.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.16.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.32.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.64.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.96.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.128.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.192.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.224.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;push "route 192.168.240.0 255.255.240.0"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's break this down into manageable chunks:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pretty self explanatory.  These options mirror the client settings.  UDP port 1194 with a tun interface.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;port 1194&lt;/div&gt;&lt;div&gt;proto udp&lt;/div&gt;&lt;div&gt;dev tun&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Server certificate configuration, again you'll need to figure this step out on your own:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ca /etc/ssl/CA/cacert.pem&lt;/div&gt;&lt;div&gt;cert /etc/ssl/CA/server_cert.pem&lt;/div&gt;&lt;div&gt;key /etc/ssl/CA/server_key.pem&lt;/div&gt;&lt;div&gt;dh /etc/ssl/CA/dh1024.pem&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next up we configure the tun server subnet.  This is arbitrary.  It's just a subnet used by the server to establish the point-to-point links.  Just make sure it's an RFC 1918 address space (unless you want to use real space) that you aren't using for your clients.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;server 172.16.16.0 255.255.255.0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Set up a persistent pool:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ifconfig-pool-persist ipp.txt 60&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This just causes everybody to get the same tunnel addresses every time they connect.  It's not strictly required for the setup unless you think you have a need.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The keepalive command dictates how a client handles a dropped connection.  This means they'll try pinging the server every 10 seconds and if the connection is down for 30 seconds they will try to re-establish the link.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;keepalive 10 30&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we turn on compression.  Again this mirrors the client configuration.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;comp-lzo&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm not sure what these persistent options do.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;persist-key&lt;/div&gt;&lt;div&gt;persist-tun&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Configure the status log and verbosity level:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;status status.log&lt;/div&gt;&lt;div&gt;verb 3&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the rest of this is purely routing magic for our clients and server to be able to communicate with each other.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is where the interesting things happen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, we need to let other clients communicate with each other:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;client-to-client&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And we also need to set up a client configuration directory:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;client-config-dir ccd&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The client configuration directory is where the CN that you configured in your certificate becomes relevant.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You need to create a file that is named whatever is in your certificate's CN field.  My router is named Crete, so I'll create a file named Crete in the ccd directory.  Inside the file is the following configuration line:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;iroute 192.168.16.0/20&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;NOTE WELL:  The iroute command *MUST* be in the client configuration directory file.  I'll explain why in a moment, and yes, the route appears to be redundant because of the route 192.168.16.0/20 directive in the main server configuration, but it's not.  I'll explain why.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally the route entries.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The normal "route" entries are route directives for the server.  This tells the server to create routing entries for these networks.  You might be wondering how the server knows where the other side of the route is.  That will become clear in a moment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;route 192.168.16.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.32.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.64.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.96.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.128.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.192.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.224.0 255.255.240.0&lt;/div&gt;&lt;div&gt;route 192.168.240.0 255.255.240.0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, we push the routes out to all of the clients that connect.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What's actually going on here is that the openvpn server uses the client configuration directory entry to determine who owns which subnet.  So in my case Crete owns the 192.168.16.0/20 subnet.  The server uses that information to construct its local route.  It also uses this information to know *NOT* to push the 192.168.16.0/20 route out to Crete when it does the push.  This is important because if the route does accidentally get pushed to the client it will appear to have died.  I thought I had found a bug in OpenVPN on dd-wrt when I first experienced this, but I realized that it was a misconfiguration on my part… so be careful here.  If you've managed to lose connectivity to your router and you think this might be the cause, unplug it from the WAN, reboot it, and you should be able to talk to it again.  You can disable the OpenVPN client (your certificates and configuration won't be purged) and you can plug the router back.  Once you have your client configurations set up properly you should be able to connect.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Verify you can ping the remote tunnel endpoint and that they can ping you.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One other note about routes.  You *MUST* ensure that any routers behind the respective networks have routes back to the VPN client for this to work.  If your VPN client is your router, then you don't have to do anything extra.  If you have enterprise-grade equipment servicing routes that are being pushed by the VPN server then the routers managing those networks need to route the various remote networks back to the VPN router.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11812054-1296666295658487140?l=nixtrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/1296666295658487140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11812054&amp;postID=1296666295658487140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/1296666295658487140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/1296666295658487140'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/2009/09/dd-wrt-openvpn-persistent-openvpn.html' title='DD-WRT OpenVPN Persistent Routed Split Tunnel Howto'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11812054.post-117074414831527597</id><published>2007-02-05T22:34:00.000-08:00</published><updated>2007-02-06T23:43:51.062-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='LLDP'/><category scheme='http://www.blogger.com/atom/ns#' term='Source Code'/><category scheme='http://www.blogger.com/atom/ns#' term='Networking'/><category scheme='http://www.blogger.com/atom/ns#' term='Cross-Platform'/><title type='text'>IEEE 802.1AB - LLDP and the OpenLLDP Project</title><content type='html'>One of the most useful tools in troubleshooting and maintaining a large-scale enterprise network is the Cisco Discovery Protocol CDP.  Any network admin worth a grain of salt that has had exposure to Cisco gear in any capacity knows about this protocol.  Unfortunately, CDP is proprietary to Cisco, which doesn't lend well to multi-vendor environments. Although, I know of one vendor (HP) that has licensed the protocol for use in their gear.&lt;br /&gt;&lt;br /&gt;Other vendors have their own discovery protocols as well.  Foundry uses the Foundry Discovery Protocol (FDP).  Extreme has Extreme Discovery Protocol (EDP), Enterasys also has CDP, but the C stands for Cabletron...  Nortel also has its own NDP.  Any wagers as to what the "N" stands for?&lt;br /&gt;&lt;br /&gt;As you might guess, none of these protocols interoperate with each other... or if they do it is limited at best.  I have heard that Foundry can understand Cisco's Discovery Protocol, but not speak it.  All of the protocols are roughly similar.  They provide information about their upstream neighbors.  Unfortunately, both sides need to speak the same protocol to be of any worthwhile purpose.&lt;br /&gt;&lt;br /&gt;Enter IEEE 802.1AB.  Also known as the Link Layer Discovery Protocol (LLDP).  This standard, which was ratified in 2005, is intended to provide a vendor-neutral solution to the discovery protocol game.&lt;br /&gt;&lt;br /&gt;Interestingly enough, many of the big players are beginning to push LLDP.  HP has actually dropped support for the licensed Cisco Discovery Protocol in favor of LLDP.  Extreme, Avaya, and Mitel are all coming on board too.  Cisco even mentions LLDP on their website, though it's apparent by at least one whitepaper that they intend to push CDP in favor of LLDP for the foreseeable future.&lt;br /&gt;&lt;br /&gt;Cisco's main argument is that LLDP isn't as robust as CDP... although, this shouldn't be a problem since LLDP specifies the ability to publish organizational extensions, which should allow Cisco (and others) to extend the protocol anyway they see fit.  I suspect the real issue here is that Cisco doesn't want to spend the money required to untangle the mess they've made with CDP... but that's a story for another post.  If you don't believe me, try turning CDP off in your network for a few months... but don't call me when you try to span a new VLAN and can't figure out for the life of you why your trunks aren't behaving.&lt;br /&gt;&lt;br /&gt;LLDP is interesting not only for the inter-vendor aspects, but also because it defines a mechanism to identify end-stations.  When I heard about LLDP I was extremely excited... The thought of being able to console into a switch and dump the interface information and see that a rogue Linux box is enough to make any network administrator squeal with delight.&lt;br /&gt;&lt;br /&gt;It is for this very reason that Jason Peterson and I have formally begun work on an open source LLDP project called &lt;a href="http://openlldp.sourceforge.net/"&gt;OpenLLDP&lt;/a&gt;.  Our goal is to provide an LLDP agent for a minimum of Mac OS X, Linux, and Windows.&lt;br /&gt;&lt;br /&gt;We've been hacking on the project for a few months now.  The code in CVS is more a proof of concept than a functional agent at this point, but we're making steady progress.  Some of the code was borrowed from the venerable &lt;a href="http://www.open1x.org/"&gt;Open1X&lt;/a&gt; project.  Kudos to Chris Hessing for being an awesome mentor and friend the past few years.  My Network-and-Code-Fu would be virtually non-existent without him.&lt;br /&gt;&lt;br /&gt;Stay tuned for more news on the OpenLLDP project!&lt;br /&gt;&lt;br /&gt;- Terry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11812054-117074414831527597?l=nixtrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/117074414831527597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11812054&amp;postID=117074414831527597' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/117074414831527597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/117074414831527597'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/2007/02/ieee-8021ab-lldp-and-openlldp-project.html' title='IEEE 802.1AB - LLDP and the OpenLLDP Project'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11812054.post-113524648655147177</id><published>2005-12-22T02:14:00.000-08:00</published><updated>2007-02-06T22:40:43.242-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='AppleScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>How to Learn : Mac OS X : AppleScript</title><content type='html'>So you want to learn AppleScript?  You've seen it do some amazing things, or you're just curious about it's capabilities, but you're not sure where to look for more information.  You could just google it.  Maybe that's how you found this site. ;)  Keep reading.&lt;br /&gt;&lt;br /&gt;A colleague of mine, who is quite tech savvy approached me about Mac OS X after aquiring a new Powerbook. &lt;br /&gt;&lt;br /&gt;He was mostly interested in learning about Mac OS X.  Coming up to speed on a new operating system can be painful, especially when you don't know where to start.  I threw out the names of a few applications that I thought were generally useful and asked him about what he was trying to accomplish.&lt;br /&gt;&lt;br /&gt;Partway through our conversation he asked me "What do you know about AppleScript?", to which I replied that I had done a bit of HyperCard back in the "good old days", and a bit of AppleScript more recently.  I asked him if he had anything specific in mind.&lt;br /&gt;&lt;br /&gt;His asked, "Is AppleScript at all useful?".&lt;br /&gt;&lt;br /&gt;This begs the question... "Well, what do you want to do with it?".&lt;br /&gt;&lt;br /&gt;Most often I find that people simply say, "I don't know", when they should be asking "What &lt;i&gt;CAN&lt;/i&gt; I do with it?".&lt;br /&gt;&lt;br /&gt;My friend and colleague was asking me whether AppleScript was useful because he really didn't know anything about it.  Without knowing what he wanted to do, I couldn't really answer his question.  Instead of trying to give him examples of how AppleScript is widely useful and trying to bestow upon him the virtuous wonder that is Mac OS X ;), I introduced him to what AppleScript can do so he could decide for himself whether AppleScript was useless or not.&lt;br /&gt;&lt;br /&gt;In this "How to Learn" article, I want to use the above example as a way to teach about a technology without ever looking at a code example. Looking at code might teach you how to ask the finder to open a new window, but it doesn't teach you how to find information... that's what this article is all about.&lt;br /&gt;&lt;h3&gt;I still haven't found what I'm looking for!&lt;/h3&gt;My goal here is to point out what you need in order to make an informed decision about a specific technology - AppleScript in this case.&lt;br /&gt;&lt;br /&gt;So let's get started.&lt;br /&gt;&lt;br /&gt;What are you looking for?&lt;br /&gt;&lt;br /&gt;Your answer can most likely be found in the Script Editor library.  Well, what is Script Editor, and where is it located?&lt;br /&gt;&lt;br /&gt;Script Editor is an Apple Application for composing AppleScripts.  It has existed, in one form or another, since early versions of Mac OS. &lt;br /&gt;&lt;br /&gt;Script Editor is located in "/Applications/AppleScript/" on Mac OS X by default.&lt;br /&gt;&lt;br /&gt;First, an exercise that can certainly be used with any Apple-shipped products, and will also be the case for any decent 3rd party Mac OS X software:&lt;br /&gt;&lt;br /&gt;Open Script Editor and check out "Help-&gt;Script Editor Help".&lt;br /&gt;&lt;br /&gt;Apple's Help is an amazing reference utility that is often underutilized.  It's much better than any other help system that I have ever seen. &lt;br /&gt;&lt;br /&gt;The first help topic is "Learn about Script Editor", which will give you an overview of what Script Editor is, and what it can do.  Consider it a first-step in learning whether AppleScript is useful.  The help gives you some basics, as well as helpful hints on where to get more information.&lt;br /&gt;&lt;br /&gt;The second AppleScript suggestion I have, and arguably the most important, helps answer that fundamental question posed earlier.  What can AppleScript do?  Now, this question can certainly be answered by looking at the language, but there is an easier way. &lt;br /&gt;&lt;br /&gt;Chances that you will want to use AppleScript with another application in the system are good.  In order to do that, you need to know what actions the application exports.  It isn't super obvious where this information is kept, and it took me a little bit of time to dig the pearl out of the oyster of information that is the Internet.&lt;br /&gt;&lt;br /&gt;Each AppleScriptable Application contains a set of actions, or verbs, that it recognizes.  These actions, or at least the Apple specific ones, are stored in a library that is easily accessible (but not obvious) from Script Editor.&lt;br /&gt;&lt;br /&gt;To access the library, open Script Editor and choose "Window-&gt;Library", or use the shortcut (Command-Shift-L).  This library contains all of the information you need to interact with any of the AppleScript ready Applications.  You can also add new libraries for other applications.&lt;br /&gt;&lt;br /&gt;The AppleScript library for a given application should contain pretty much everything you need to know about scripting against that application.  It's a complex, but succinct, application specific API reference.&lt;br /&gt;&lt;br /&gt;That should be enough to get you started learning what AppleScript can do for you.  If this article was helpful, please leave a comment!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11812054-113524648655147177?l=nixtrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nixtrix.blogspot.com/feeds/113524648655147177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11812054&amp;postID=113524648655147177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/113524648655147177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11812054/posts/default/113524648655147177'/><link rel='alternate' type='text/html' href='http://nixtrix.blogspot.com/2005/12/how-to-learn-mac-os-x-applescript.html' title='How to Learn : Mac OS X : AppleScript'/><author><name>Terry Simons</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
