Completed Linksys NSLU2 PPTP VPN Server

NOTE: This guide will work for any system or device you can install Linux on.

“With great power comes great responsibility.” We’ve all heard this dozens of times over by now. WiFi is no different. It can be used for good or bad. Some may call me paranoid. However, I prefer to think of myself as cautiously aware.

I recently got to thinking about about all the benefits (and perils) of the prevalence of public WiFi. There are numerous ways of unknowingly falling prey to those with nefarious motives: rogue access points, man in the middle attacks, and more. I wouldn’t advocate avoiding WiFi altogether (except certainly at various hacker cons). The key lies in being aware of potential pitfalls to better prepare yourself. The more tools in your arsenal the better!

I felt it would be a good idea to protect myself when I’m away from home with a private little VPN tunnel. Of course, I could accomplish this with ease on my home network with a little pfSense magic. However, there’s one problem… my internet at home is awful! Without going into too many details, on a good day I get 1mbps down/20kbps upstream. Suffice it to say, Windstream DSL sucks here! Luckily, my girlfriend’s parents don’t live too far and have some pretty terrific bandwidth courtesy of Time Warner. This got me thinking… Wouldn’t it be great to have a portable solid-state VPN server that’ll fit in your pocket!

Before I get to the meat, I should preface this by saying, “Yes… there are simpler methods to accomplish this.” One alternative would be a router with DD-WRT installed with VPN extensions. However, my girlfriend’s parents router isn’t compatible with the VPN enabled flavor of DD-WRT. As luck would have it, I had an old Linksys NSLU2 USB Network File Server laying around collecting dust. I opted to turn this sub-par underclocked file server into a tiny badass portable VPN server! (I should warn you though, this mod will take the better part of a day, and may not be for the feint of heart.)

You’re going to need a couple of things for this mod: a working Linksys NSLU2, a USB based drive (in this case I used a pico 4GB HP USB stick), and possibly a soldering iron & tweezers (but more on that later.)


  • Installation

First thing is first, you are going to need to download the modified unofficial Debian image that adds support for the IXP4xx microcode at While functional without this modified version the built-in network port on the NSLU2 won’t function, and you would need to use a supported USB network adapter.

You will want to do a little planning for the setup of the network you will be installing this on before you start. While you can always change the IP setup of the NSLU2, it will never be simpler than it is now via the stock GUI. In short, the Debian install will inherit whatever IP/Gateway settings the stock NSLU2 had. In my case the NSLU2 was configured as (for those unfamiliar a /24 means a Subnet Mask of, with the Gateway set to

Installing the modified Debian OS is pretty much dirt simple. Just login to your stock NSLU2 and go to the firmware update tab and select the modified Debian one you downloaded earlier.

Once the device has been rebooted after the firmware update has completed you need to SSH into the NSLU2 with the username of “installer” and a password of “install”. Go through the guided install as normal. The process of installing Debian will take a long time. By a long time, I mean close to 4-5 hours! Eventually, you will be able to setup the root account and any user accounts that you wish. Congratulations! You now have a fully functional Debian computer!


Collage of Debian install

Collage of Debian install images

  • Over-clocking

At this point, the install may or may not get a little tricky depending on how lucky you are. It seems early NSLU2’s, of which mine was one, were under-clocked to 133mhz while the later units operate at 266mhz. If yours turns out to be under-clocked this is the point at which I would recommend over-clocking your unit. While it is fairly simple, it is also a delicate procedure and if you are going to potentially do something to kill the unit this would likely be it.

The ARM based processor used in the NSLU2 is rated at 266mhz while the later units were correctly clocked to this, there are no hardware differences between the 266mhz and the 133mhz versions with the exception of a single resistor. To check what speed your NSLU2 is running at login and type:

>cat /proc/cpuinfo

Now look at the output of the BogoMIPS line. If it reads about ~266 (as in the picture below) you’re all set and you can relax. There’s no de-soldering in your future! However, if, like me, yours reads ~133 then you have one of the early under-clocked units and you will want to over-clock your device. Technically, you don’t have to do this, but it will double over speed of the device which I would say makes it worth the risk.

Getting into your device is a very simple process as there are no screws at all! All you need to do is pinch the grey area on both sides creating a small gap. Repeat this procedure down the length of the grey area and it will eventually separate. Take your time as these small plastic clips truly are the only things holding the halves together.

R83 location

R83 vs my Finger

To re-clock the unit, all you need to do is de-solder the R83 (see photo) resistor. I used some desoldering braid and some tweezers to accomplish this without any trouble. There have been reports that some people have been able to accomplish this with nail clippers or an xacto knife. I’ll warn you… the resistor is super tiny! Don’t get discouraged! It’s really not too difficult to remove and the performance boosts are substantial. Just take your time and be careful. Once you’re done, put the NSLU2 back together, log back in, and check to see what speed it’s running at. It should now be running at the (what should have always been stock) speed of 266mhz!


  • Optimizing the flash drive

Now we can get back to setting up the NSLU2. In my case, I used a pico sized 4GB USB drive. While it’s small and takes virtually no power it has one key disadvantage. You see, USB drives have a limited number of write cycles. To help minimize the number of writes to the drive there are a few modifications you need to make…

I know it’s bad form, but I opted to simply login as root rather than having to add “su” before all of the commands. Of course, should you choose to do this from a user account make sure to remember to adjust the commands accordingly!

First, tell the system that it’s on a flash based device.

>touch /.ext3flash

Then, disable mark lines from being added to syslog every 20 minutes.

>nano /etc/default/rsyslog

Add or edit the line “SYSLOGD=”-m 0“.

>/etc/init.d.rsyslogd restart

Next, minimize swap usage.

>nano /etc/sysctl.conf

Disable the last access timestamp.

>nano /etc/fstab

Add noatime to the /sda2 line as per the example below…

/dev/sda2 / ext3 errors=ro,noatime 0 1

Ensure the bootlog is disabled.

>nano /etc/default/bootlogd

Ensure “BOOTLOGD_ENABLE=no” is set.

Check to skip waiting for user input for a file system check.

>nano /etc/default/rcS

Edit to reflect “FSCKFIX=yes”.

Now you should now be setup to make the most out of your flash drive!


  • Beeping the IP Address (Optional, but recommended)

This is the point at which I opted to create a script to beep out the IP address of the unit in the event I ever forget what it was set to. If you’re like me and occasionally forget what IP address a device is set to this is an invaluable tool. Not to mention it’s handy for knowing when the boot process is finished!

>apt-get install beep
>nano /bin/

# Beep ip address trough internal pc speaker
# Tested on Debian Linux @NSLU2
# Author: Sebastiaan Giebels, 2007
# Retreive dot-separated ipv4 address from the ifconfig information, using grep and cut:
IPADDRESS=`/sbin/ifconfig | grep -A1 “eth0” | grep “inet” | cut -d: -f 2 |cut -d” ” -f1`
# Enable next line for debugging:
#Uncomment this for an example with zeroes in the ip address:
# For all characters in dotted ipv4 address:
for ((a=0; a < ${#IPADDRESS} ; a++))
  # Get the next character to process:
  if [ “.” == “$NUMBER” ]
    # Different note to signal a ‘.’ in the address:
    `/usr/bin/beep -l 20 -f 25 -d 20`
  else if [[ “$NUMBER” -ge “0” && “$NUMBER” -le “9” ]]
      # Beep ‘NUMBER’ times, except for 0 (=beep 10 times):
      if [ “$NUMBER” == “0” ]
      `/usr/bin/beep -l 45 -f 15 -d 150 -r $NUMBER`
  sleep 1

>chmod ugo+x /bin/

Now let’s test it to ensure it works as it should…


Assuming that the test went correctly there’s just one more thing to do, and that is to add the script to the end of the startup script.

>nano /etc/rc.local

Add “/bin/” to the end of the file. Save and exit!


  • A real power button (Optional)

By default the power button is configured to simply reboot the device. However, if you choose, you can change it back to a shutdown button. All you have to do is replace the “-r” with a “-h”.

>nano /etc/inittab

Simply, locate “ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now” and change it to “ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -h now”.


  • Dynamic DNS

Enough prep work! It’s finally time to get into the real meat of things! Being that this is to be a self-contained portable VPN server having a static way of accessing the VPN server from outside is extremely important. To accomplish this you will first need to register an account with a dynamic DNS provider for either a free or paid account. For the purpose of this I used Of course, you are welcome to use others, but there may be some subtle configuration differences.

Now, let’s install SSL and the dynamic DNS client!

>apt-get install ssh libio-socket-ssl-perl
>apt-get install ddclient
>nano /etc/ddclient.conf

The file should look similar to the one below…

# Configuration file for ddclient generated by debconf
# /etc/ddclient.conf
use=web,, web-skip=’IP Address’

You will need to change the “login”, “password”, & “” with the values reflecting your dynamic DNS account and hostname chosen. The “ssl=yes” flag will ensure that login and updates will be performed over an SSL connection so you shouldn’t need to worry as much about someone sniffing that information. Also, the “daemon=300” flag tells the system that it should check to see if an updated IP address is available every five minutes.

>nano /etc/default/ddclient

Edit the file as needed to reflect “run_ipup=flase”, “run_daemon=true”, and “daemon_interval=300”. This tells ddclient to run in daemon mode with an interval of 5 minutes.

>/etc/init.d/ddclient restart [To restart ddclient]
>/etc/init.d/ddclient status [To check the status of ddclient]


  • Force updates (Optional)

The problem with many of the free dynamic DNS providers is that if an IP isn’t updated for a set amount of time the record will go stale and eventually pruned from the database. To ensure this doesn’t happen we can force a bi-monthly update with the following two lines…

>crontab -e
>0 0 1,15 * * /etc/init.d/ddclient -quiet -force

Of course, you can always log into the VPN server and manually issue the following command should the desire or need arise.

>/etc/init.d/ddclient -quiet -force


  • Creating the PPTP VPN server

At long last, we are in the home stretch! Just a few more tweaks and it will be ready for use!

Now, let’s install and configure the VPN server!

>apt-get install pptpd
>nano /etc/pptpd.conf

#Local IP and IP range given to remote clients. Change as necessary.

>/etc/init.d/pptpd restart

Here, you will configure what IP addresses you want the VPN server to dish out to clients, and tell it what IP address it is. Pretty simple!

Now we need to create a user login/passwords for VPN clients to use.

>nano /etc/ppp/chap-secrets

Add a login using the following form…

username pptpd lamepassword *

As always, replace the “username” and “password” with the values you wish to use to be able to establish a VPN tunnel to the device. To enable multiple users simply add new lines with their login information.


  • Enable IP Masquerading

We are almost there! In fact, we could establish a VPN tunnel to our server right now, but it would only provide us access to our internal network. To turn this VPN into a proxy VPN we need to do a few final things.

You can enable IP forwarding immediately by issuing the following…

>echo 1 > /proc/sys/net/ipv4/ip_forward

Unfortunately the aforementioned command is not persistent. To make it stick after a reboot you are going to need to do the follwoing…

>nano /etc/sysctl.conf

Add “net.ipv4.ip_forward=1” to the file.

>nano /etc/

Now add “iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE”.

>chown root /etc/
>chmod 700 /etc/
>nano /etc/network/interfaces

Now, let’s add the new rule to the startup by adding “pre-up /etc/” before the default netowrk interface lines.

There’s just one final thing to do, and that is to ensure the time is correct as the internal clock of the NSLU2 is notoriously bad. Simply install the network time protocol and you will be done!

>apt-get install ntp


  • Almost there…

You’re almost there! Technically, your PPTP VPN server is already complete, but there is one small caveat left to cover… port forwarding. This is where your mileage may vary and I cannot give you step by step instructions. However, you are going to need to forward TCP port 1723 to whatever static internal IP address you gave your VPN server. You will also need to allow the GRE 47 protocol to pass through your firewall. Most home routers will allow GRE47 to passthrough by default, but on others (newer Cisco/Linksys devices) it may be listed as “VPN Passthrough” commonly under the Security tab.


It works!

If all was done correctly you should now be the proud owner of a working portable VPN server! You now have a portable secure VPN tunnel!


Some final notes…

There may come a day when you will need to adjust the IP address to mesh with a differently configured network. When such a day arrives you may need a refresher as to where you need to make those changes.

>nano /etc/network/interfaces [Local IP Address config]

>nano /etc/resolv.conf [DNS config. Below is for Google DNS servers]

nameserver <IMP></IMP>

nameserver <IMP></IMP>

>nano /etc/pptpd.conf [IP range for VPN clients]

>nano /etc/ppp/chap-secrets [VPN usernames & passwords]