Joining Branch Offices via a VPN to Head Office using Debian and OpenVPN using Pre-Shared Key

Scenario: You have a network at Head Office which has resources (Email, Web, Files, etc) and you would like to link a branch office in at the network level to enable bi-directional communication.

The two subnets are as follows:
Head Office - 10.10.1.0/24
Branch Office - 10.10.2.0/24

Two Debian Machines, One at each site:
HEADOFFICE - 10.10.1.200
BRANCHOFFICE - 10.10.2.200

The Debian Machines can have 1 NIC each, or 2 NICs depending on how you want to configure your network.
1 NIC scenario: I would only like to tunnel traffic destined for the remote network via Debian, and not ALL traffic (e.g. Internet). Internet-bound traffic in each site will go out via their normal router/gateway (.254), and only traffic destined for the opposite network will be sent to the Debian machine. ETH0 has an IP on the LAN, and also has a Default Gateway which points to the LAN's Router/Internet Gateway.
2 NIC scenario: ETH0 would connect to the Internet (either via NAT or with a Public IP), and ETH1 would connect to the LAN. All clients on the LAN would have a default gateway that points to the Debian ETH1 interface. Only traffic destined for the remote network would be accepted, all other traffic (e.g. Internet-bound traffic) would be discarded. Workstations would NOT have internet access. (ETH1 would also require a DHCP-Server running to allocate IPs to workstations. Setting up DHCP3-Server is beyond the scope of this document but may be covered later.)

In my configuration, each Debian machine is behind a NAT on the Local Network and only has 1 NIC, ETH0.

Each Debian Machine needs a Standard System install only. You can use a NetInst disc to install as you need very little software on the machines. Installing Debian is beyond the scope of this document.

Configuration for HEADOFFICE:

  • Step 1: Install OpenVPN and OpenSSH-Server
  • apt-get install OpenVPN OpenSSH-Server

  • Step 2: Set up a static IP address with: nano /etc/network/interfaces
  • iface eth0 inet static
    address 10.10.1.200
    netmask 255.255.255.0
    gateway 10.10.1.254

  • Step 3: Initialise TUN
  • modprobe tun
    echo 'tun' >> /etc/modules

  • Step 4: Configure iptables
  • iptables -A FORWARD -i tun+ -j ACCEPT

  • Step 5: Generate encryption key
  • cd /etc/openvpn/
    openvpn --genkey --secret tun0.key

  • Step 6: Reboot
  • shutdown -r now

  • Step 7: Start openvpn and listen for incoming connections
  • openvpn --port 5000 --dev tun0 --ifconfig 10.99.0.1 10.99.0.2 --verb 1 --secret /etc/openvpn/tun0.key --fragment 1400 --mssfix 1400 --tun-mtu 1450 &

  • Step 8: Add Static Route to remote network for this tunnel
  • route add -net 10.10.2.0 netmask 255.255.255.0 gw 10.99.0.1

  • Step 9: Enable Packet Forwarding
  • echo 1 > /proc/sys/net/ipv4/ip_forward

    Configuration for BRANCHOFFICE:

  • Step 1: Install OpenVPN and OpenSSH-Server
  • apt-get install OpenVPN OpenSSH-Server

  • Step 2: Set up a static IP address with: nano /etc/network/interfaces
  • iface eth0 inet static
    address 10.10.2.200
    netmask 255.255.255.0
    gateway 10.10.2.254

  • Step 3: Initialise TUN
  • modprobe tun
    echo 'tun' >> /etc/modules

  • Step 4: Configure iptables
  • iptables -A FORWARD -i tun+ -j ACCEPT

  • Step 5: Copy the tun0.key file from HEADOFFICE /etc/openvpn/tun0.key to BRANCHOFFICE /etc/openvpn/tun0.key. Using WinSCP.exe is beyond the scope of this document.
  • Step 6: Reboot
  • shutdown -r now

  • Step 7: Establish a connection to the OpenVPN Server at HEADOFFICE
  • openvpn --remote HEADOFFICEPUBLICIPGOESHERE:5000 --port 5000 --dev tun0 --ifconfig 10.99.0.2 10.99.0.1 --verb 1 --fragment 1400 --mssfix 1400 --tun-mtu 1450 --secret /etc/openvpn/tun0.key &

  • Step 8: Add a static route to the HeadOffice Network
  • route add -net 10.10.1.0 netmask 255.255.255.0 gw 10.99.0.2

  • Step 9: Enable Packet Forwarding
  • echo 1 > /proc/sys/net/ipv4/ip_forward

  • Step 10: Test your connection with a ping
  • ping 10.10.1.200

    On windows machines on each side of the connection, you will need to add a static route to the remote network via the LAN IP of each Debian Machine.

  • BRANCHOFFICE TO HEADOFFICE STATIC ROUTE
  • route add -p 10.10.1.0 mask 255.255.255.0 10.10.2.200

  • HEADOFFICE TO BRANCHOFFICE STATIC ROUTE
  • route add -p 10.10.2.0 mask 255.255.255.0 10.10.1.200

    Popup Javascript Confirm Dialog, When user clicks OK Disable Button and post back with ASP.NET, otherwise do nothing

    Quite often at the end of a form you would like to confirm the submit action before posting the form, but also disable the submit button once confirmed so that it can't be clicked again.
    In my case my form sends a message to hundreds of customers and we don't want to accidentally send it until we're ready, and we don't want to accidentally send it multiple times if the user gets impatient waiting for the form to postback.

    Using my code, if the user clicks "btnSend" it will ask them "Are you sure you want to send this message to ALL recipients?".
    If the user clicks "Cancel" the page does nothing, but if they click OK, it will disable the button and continue with the postback.

    Add this code to your button:

    UseSubmitBehavior="false" OnClientClick="return confirmSend();"

    JavaScript Function:

    function confirmSend()
    {
        if (confirm('Are you sure you want to send this message to ALL recipients?')==true)
        {
            var control0 = document.getElementById("ctl00_mainContentPlaceHolder_btnSend");
            control0.disabled=true; control0.value="Processing...";
            __doPostBack('ctl00$mainContentPlaceHolder$btnSend','')
        }
        else
        {
            return false;
        }
    }
    

    If you are not sure of the element name or ID (in this case ctl00_mainContentPlaceHolder_btnSend and ctl00$mainContentPlaceHolder$btnSend), you can always enable Tracing by placing this line of code in your Form Load sub:
    Me.Trace.IsEnabled = True
    Then load the page, and simply find your control in the Tracing output at the bottom.

    Debian Linux Install on Dell Latitude D830

    Installing Linux on the Dell Latitude D830 is a fairly pain free experience, with some messing around needed to get audio working properly (although this will be fixed in the ALSA drivers version 1.0.15 and therefore Linux kernel 2.6.23). Note: I used Sid/Unstable for the installation because I like the balance between stability and new stuff. If you use an older distribution, some of the hardware may not be fully supported.

    Suspend/resume (both suspend-to-ram and suspend-to-disk) using the in kernel uswsusp works without any hitches, and installing the splashy package allows the majority of the boot/shutdown/hibernation messages to be hidden behind a splash screen.

    The Hardware

    The Dell Latitude D830 in question has the following hardware with the following status:

    HardwareStatus
    Intel(R) Core(TM) 2 Duo Processor T7500 (2.2GHz)
    Integrated 2MB/4MB ON-DIE L2 Cache, 800MHz FSB
    Works
    Both cores recognised out of the box. VMX Virtualisation (VT extensions) can be enabled in the BIOS.
    2GB (2x1GB) 667MHz DDR2 SDRAM Works
    All memory recognised out of the box.
    Intel SATA IDE Controller Works
    Recognised by ata_piix module. AHCI can be turned on in the BIOS although this is untested.
    Integrated UMA Base Intel(R) Graphics Media Accelerator X3100 (i965GM) Works
    Open drivers with 3D acceleration. See notes below.
    Integrated Broadcom Gigabit Ethernet Works
    Uses in kernel tg3 driver.
    Integrated Modem Untested
    Intel HD Audio Controller Works
    ALSA drivers 1.0.14 contains a bug. See below.
    Dell(TM) TrueMobile(TM) 360 Bluetooth Module Works
    Tested using the kbluetooth system and a file transfer to a bluetooth mobile phone.
    Intel(R) PRO/Wireless 3945 (802.11 a/g) Works
    Uses ipw3945 driver and closed regulatory daemon. See notes below.
    Hotkeys Partially Working
    Volume control keys can be configured but some Fn keys do not generate scancodes.

    For more details the output of lspci

    00:00.0 Host bridge: Intel Corporation Mobile Memory Controller Hub (rev 0c)
    00:02.0 VGA compatible controller: Intel Corporation Mobile Integrated Graphics Controller (rev 0c)
    00:02.1 Display controller: Intel Corporation Mobile Integrated Graphics Controller (rev 0c)
    00:1a.0 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI #4 (rev 02)
    00:1a.1 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI #5 (rev 02)
    00:1a.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI #2 (rev 02)
    00:1b.0 Audio device: Intel Corporation 82801H (ICH8 Family) HD Audio Controller (rev 02)
    00:1c.0 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 1 (rev 02)
    00:1c.1 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 2 (rev 02)
    00:1c.3 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 4 (rev 02)
    00:1c.5 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 6 (rev 02)
    00:1d.0 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI #1 (rev 02)
    00:1d.1 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI #2 (rev 02)
    00:1d.2 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI #3 (rev 02)
    00:1d.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI #1 (rev 02)
    00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev f2)
    00:1f.0 ISA bridge: Intel Corporation Mobile LPC Interface Controller (rev 02)
    00:1f.1 IDE interface: Intel Corporation Mobile IDE Controller (rev 02)
    00:1f.2 IDE interface: Intel Corporation Mobile SATA IDE Controller (rev 02)
    00:1f.3 SMBus: Intel Corporation 82801H (ICH8 Family) SMBus Controller (rev 02)
    03:01.0 CardBus bridge: O2 Micro, Inc. Cardbus bridge (rev 21)
    03:01.4 FireWire (IEEE 1394): O2 Micro, Inc. Firewire (IEEE 1394) (rev 02)
    09:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5755M Gigabit Ethernet PCI Express (rev 02)
    0c:00.0 Network controller: Intel Corporation PRO/Wireless 3945ABG Network Connection (rev 02)
    

    Display - X3100 & Xorg

    At the time of installation X.org 7.3 had just hit Debian Sid, so without any xorg.conf X11 started with the correct resolution and drivers. However, to configure Compiz-Fusion/Beryl a full xorg.conf is required. Importantly, note the use of "XAANoOffscreenPixmaps" "true" in the Device section, without which Compiz won't work correctly. Unfortunately, this line is the only reason for having an xorg.conf at all.

    
    Section "Device"
            Identifier "Generic Video Card"
            Driver     "intel"
            Option     "monitor-TV" "TVOutput"
            Option     "DRI"   "true"
    	Option	   "XAANoOffscreenPixmaps" "true"
    EndSection
    

    Update (2007-11-07): The X.org 7.3+3 in Debian Sid also works with minimal X.org config files. You can easily generate one by deleting the old /etc/X11/xorg.conf and then running

    # dpkg-reconfigure xserver-xorg
    

    However, for posterity I will attach it here, with the modification made to enable Compiz/Beryl.

    Update (2007-12-01): xserver-xorg-video-intel 2:2.2.0-1 introduces EXA acceleration as the default rather than the older XAA. The EXA acceleration currently has poor performance with glyph (font) rendering so it is possible to revert to the old XAA rendering method using

    
    Section "Device"
            Identifier "Generic Video Card"
            Driver     "intel"
            Option     "monitor-TV" "TVOutput"
            Option     "DRI"   "true"
    	Option	   "AccelMethod" "XAA"
    	Option	   "XAANoOffscreenPixmaps" "true"
    EndSection
    

    This is especially important if running a composited window manager. Here is the full xorg.conf.

    Audio - Intel HDA

    A bug in the ALSA drivers 1.0.14 prevents the auto-detection of the sound card, this fix is in CVS so should be available with the next release of the drivers. However, the patch above does not apply to the Debian supplied ALSA source so you need this patch

    diff -ru a/alsa-kernel/pci/hda/patch_sigmatel.c b/alsa-kernel/pci/hda/patch_sigmatel.c
    --- aalsa-kernel/pci/hda/patch_sigmatel.c	2007-10-08 21:29:47.000000000 +1000
    +++ b/alsa-kernel/pci/hda/patch_sigmatel.c	2007-10-08 21:16:48.000000000 +1000
    @@ -2224,7 +2224,7 @@
     		return -ENOMEM;
     
     	codec->spec = spec;
    -	spec->num_pins = 14;
    +	spec->num_pins = 12;
     	spec->pin_nids = stac9205_pin_nids;
     	spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
     							stac9205_models,
    

    To use the patched driver you need to download alsa-source and module-assistant, unpack the source and patch and then build using module-assistant. It would go something like this.

    # aptitude install module-assistant alsa-source
    # m-a prepare
    # cd /usr/src
    # tar -xvjf alsa-driver.tar.bz2
    # cd /usr/src/modules/alsa-driver
    # patch -p1 < patch_sigmatel_d830.patch
    # m-a -O build alsa
    # m-a install alsa
    

    Alternatively, you can use the package I built for the 2.6.22 kernel, or the source tarball with the patch already applied.

    Update (2007-11-19): The 2.6.23 version of the Linux kernel has a more correct update than the patch above and therefore there is no need to install the alsa-source package or perform any compilation if you are using this (or later?) kernel version. The git commit with the fix is here.

    Wireless - Intel PRO/Wireless 3945

    To enable the wireless networking, it is necessary to install the ipw3945 modules and regulatory daemon. The modules are in ipw3945-modules-kerneltype and the regulatory daemon is ipw3945d. Make sure the non-free repository is enabled to install the daemon.

    The ipw3945 card works perfectly with NetworkManager, however, in order for the wireless switch to work correctly, it's necessary to perform the following steps

    # aptitude install libsmbios-bin
    # ln -s /usr/sbin/dellWirelessCtl /usr/bin/dellWirelessCtl
    # modprobe dcdbas
    

    The second step in the process is to fix an issue where hal is looking for /usr/bin/dellWirelessCtl rather than /usr/sbin/dellWirelessCtl. This problem may be fixed at some point in the future. In addition, this fix will only work until you reboot. To make it permanent, add dcdbas to /etc/modules

    Hotkeys

    To make the volume keys work on, the following scancodes might be useful

    • Mute Volume - 160
    • Decrease Volume - 174
    • Increase Volume - 176

    I usually map these to F13, F14 and F15 using the following .xmodmaprc

    keycode 160 = F13
    keycode 174 = F14
    keycode 176 = F15
    

    and then use the KDE settings to map the keys to functions. Alternatively, you can try using keytouch an application with a bunch of default configurations for hotkeys. The Dell Latitude D800 keyboard seems to match the scancodes on the D830.

    Hardware (BIOS) Clock

    There is an issue with the hardware clock that has the effect of creating a noticeable pause on boot and can lead to some time discrepancy issues. The fix is to add an additional parameter to the hwclock program. When invoking hwclock from the command line, simply add the argument --directisa.

    In order to fix the issue when hwclock is called when booting and shutting down, the files /etc/init.d/hwclockfirst.sh and /etc/init.d/hwclock.sh need to be edited. Find the line that starts with HWCLOCKPARS and replace it with

    HWCLOCKPARS=--directisa

    Introducing hickup - Hashed Incremental Backup

    hickup is a small python script that performs incremental backups to tar files that I wrote in order to back up some of my personal files. Detecting file changes is performed by storing a log file containing hashes of each file. Whilst this makes the script very slow/processor intensive, it also means it works on VFAT file systems, which normal tar backups choke on (because the modification time seems to be damaged in some way).
    hickup only supports backing up one entire directory at a time and does not follow symlinks. When hickup is run for the first time, it performs a hash of all the files in the target folder and then creates a tar of the folder. For more info, check the README .

    If you’re interested, you can get a copy of the current version from here or you can get browse the Mercurial repository here. If you want to hack on hickup, the best way is probably to clone the repository using

    hg pull http://score5.org/projects/hgwebdir.cgi/hickup/

    If you have any comments or questions, feel free to contact me.

    DNS Troubleshooting

    DNS troubleshooting is actually a bit of fun (maybe) and I had to do some of it recently for spectrumautomation.com.au. The end of the story was that the authority records were pointing to the completely wrong place. Although it was fairly easy to see, proving it was the difficult part. So here are some tools I found useful.

    nslookup

    One of the simplest tools out there. Does as its name suggests, DNS lookups.

    dig

    dig lets you grab a whole heap of DNS information, basically the entire DNS response from any server that you want. It's extremely useful to track down the DNS lookup process by basically iterating down from the root server all the way to the final authoritative servers.

    dnstracer

    A cool tool to automatically perform a similar trace as to what can be done by dig, a good way of getting an overall view of how the DNS system is arranged.

    DNS Bajaj

    DNS Bajaj generates a diagram showing the delegation and connection between the DNS servers for a domain, all the way down from the top level domain.

    DNSStuff.com

    DNSStuff.com has a very useful DNS report tool which will give you a wide range of information regarding the DNS information for your domain including failures and warnings with respect to RFCs. They also provide web access to standard tools such as ping, traceroute, dig and whois, although the tools are useful only for a certain amount of tests. I used DNSStuff.com as another test point to avoid caching issues.

    Mercurial - Distributed RCS

    I’ve always used Subversion as my choice of RCS (Revision Control System), but the hassle of setting up a repository for each project just was a bit too much. That, and the fact I often had to re-read the quick start pretty much every time I went to use it meant that it really wasn’t a solution I regularly used. It basically came down to the idea that if something isn’t easy to use, it probably won’t get used.
    Now Subversion is certainly good, but I really need something lighter…and then I started reading about distributed RCS’s which was my introduction to Mercurial.

    I couldn’t be bothered describing all the fundamental differences that are documented everywhere else in comparisons between distributed and centralised RCS models. Here are the benefits that I’ve found though:

    • No need to have a separate repository/folder to the actual project. That is the working directory/repository exists with the project, something that makes file organisation much easier.
    • Mercurial commands just seem easier. With Subversion, I always struggled with creating new repositories. Not so with Mercurial.
    • Mercurial is written in Python, a language I really enjoy writing in, so, good potential for future hacking if necessary.
    • Mercurial can easily be installed locally as a user.

    Creating a Repository

    Whilst in the source folder

    hg init # Create the repository.
    hg add # Add the files in the folder into the repository.
    hg commit # Commit the changes.

    That’s it.

    Cross-Platform Development

    For those who don't know, Qt 4 is offered in two(+) variations. A GPL'd version that requires you release the final application under the GPL as well and a paid development kit that lets you do whatever you like. Part of the license requires that if you use the free tools anywhere in the development process then you need to release GPL'd. So you can't use the free tools and then use the paid-for version in the final release. Since the paid-for version is definitely not cheap, unless you can be certain you're releasing under the GPL, then Qt becomes a difficult choice.

    Okay, I think I've found it. I've been looking for a cross-platform development solution for a while now and I used to use Qt, although I never actually got around to building it on anything other the Linux. But now that I've started working full-time, I needed to find something where I didn't have to worry about the licensing.

    My first instinct was Java, as I wanted something with a fairly quick turnaround. But I just didn't like how it looked on Linux and I basically got confused with all the talk of AWT or Swing or whatever the current flavour is.

    So, I turned to wxWidgets, a cross-platform library that I had looked at years ago, but never really liked. However, I really wanted a faster application turn-around time than C can provide as what I'm building are really just small utilities and so I added Python into the mix and started learning both a toolkit and a language at once wxPython.

    The first tool, a PLC code generator, is coming along nicely and has had a quite quick development cycle. Especially since I am learning both a language and tool-kit in one hit. My final evaluation is that wxPython is truly a powerful tool and my only disappointment is the difficulty I'm experiencing in finding really good documentation with example code. If anyone can point me in the right direction, it would be much appreciated.

    Relatively Simple Remote Assistance over VNC

    I was looking for a simple way of providing remote assistance to someone on a Linux machine, in this particular instance Ubuntu, and here is what I've come up with.

    The first step is to make sure that you have ssh access to the machine in question. There's heaps of tutorials on the web for this, but the easiest way is to just install the openssh-server

    # apt-get install openssh-server

    and edit the config file /etc/ssh/sshd_config. You might need to change the port to prevent it being blocked by ISP's and switch off root logins. Don't forget to fix your firewall rules to allow access as well.

    You'll also need some way of actually finding the box on the net, so set up something like DynDNS so that you can easily find the box on the web. ddclient is a good client to dynamically update, and if on dial-up you can set it so that it triggers whenever a connection is made. It's probably a good idea to make sure all the SSH side of things are working now, as the rest can be done remotely via SSH.

    The idea of providing remote assistance is to allow both users access at the same time, so in order to do this we'll use x11vnc. So on the machine you want to provide assistance to,

    # apt-get install x11vnc

    Finally, on your machine, make sure you have the vncviewer installed,

    # apt-get install xvncviewer

    Once this is done, it's time to start assisting by running

    ssh -L 5900:localhost:5900 user@hostname 'x11vnc -localhost -display :0'

    making sure to replace user and hostname appropriately. If you changed the port SSH is working on earlier, you might also need the -p port option.

    Then, run

    xvncviewer localhost

    and you should get a display of what the other person sees.

    Automated Source Code Processing

    There's a tool called PMD that lets you do all sorts of nifty things to java code, looking for possible bugs, dead code, suboptimal code and overcomplicated expressions. Unfortunately (or fortunately), I don't code in Java, but there is an additional tool in the set, CPD which let's you find duplicate code sections.

    Duplicate code sections are bad, because if you copy and paste something, and there's a bug, then you've copied the bug which might get missed in a bugfix. But all seasoned coders know such things. I always remember the phrase "Code duplication is an error.", and sometimes I even pay attention to it ;-).

    The good thing about CPD is it works with C, C++, Java, JSP and PHP, so it should be a worthy tool to add to a programmers collection.

    Allen-Bradley PLC Control LGPL Libraries for Linux

    I've always played with the idea of one day writing some libraries and maybe even a suite of tools to debug and diagnose problems on Allen-Bradley PLC's. It was never meant to be a commercial venture, but just a set of tools that would be useful at work.

    But the thought of reverse engineering the protocols, and the frustration I know that would go with it, meant that I never really thought it would go past the consideration stage, or maybe a few minutes of mucking around. But today, I saw this post from Ron Gage on slashdot, who happened to mention that he had written some Programmable Logic Control Libraries. Now, to just track them down.

    Here is what I found. Ron Gage has a project on freshmeat for an Allen-Bradley PCMK DH+ Driver. Cool, but it seems like it hasn't been maintained in a while. Maybe a future hobby project? Anyways, further hunting got me to this treasure trove, including an Allen-Bradley Ethernet Library (ABEL), a Real-Time Data Monitor for Control-Logix and a Framework for Data Logging with ABEL.

    I'm currently downloading as I write this, although my currently (heavily) capped Unwired access is slowing me down significantly. Maybe time to SSH into home and have them download there, and I'll grab them when I'm out there tonight.

    Syndicate content