↓ Archives ↓

VPN (IPsec) tunnel between a pfSense 2.0 router and a FRITZ!Box

We have a pfSense 2.0 router at our coworking space which is hooked up to a pretty fast VDSL line so I thought it would be a fun idea to connect my home network (where I’m using a FRITZ!Box 7390) to the work LAN using a secure and permenent VPN tunnel.

Doing a quick Google search yields results for the 1.2 version of pfSense which is outdated and does not use DynDNS hostnames for both ends, so I did a quick writeup of my own.

Prerequisites

First things first, create permanent hostnames for your pfSense and your FRITZ!Box. If your DSL provider has assigned permanent IP addresses, that’s fine. If they didn’t you’ll probably need something like DynDNS. Last time I checked, you could still get free accounts, otherwise it’s just a few bucks a year – probably a good investment. You’ll need to configure both the pfSense and the FRITZ!Box to update your DynDNS hosts whenever their IP address changes, but that’s pretty straight forward so I won’t cover it here. Fun fact: you can add CNAME records to your company domain pointing to your DynDNS host, so it looks even more professional. We use vpn.launchco.com for instance – how cool is that?

You’ll also need two different primary subnets for your networks, i.e. if your home network lives in 192.168.178.0/24, which is the standard network a FRITZ!Box uses, your work network has to use something else, like 192.168.1.0/24, which is by the way the standard that pfSense uses – so you should be safe if you’re like me a big fan of sticking with sensible vendor defaults.

Now, with the permanent hostnames and subnets in place, let’s get down to business.

Setting up pfSense

We’re using IPsec, so let’s head to VPN -> IPsec first and click the [+] icon on the bottom right to add a new phase 1 entry.

Fill the form in accordance to what you see on the following screenshot:

Screenshot of pfSense configuration phase 1 entry

Obviously, replace your-fritz.dyndns.org with the permanent hostname assigned to your FRITZ!Box as well as your-pfsense.dyndns.org with the one on your pfSense box. The Pre-Shared Key should be a long random string. Don’t worry, you won’t have to remember it. You’ll just save that in the FRITZ!Box later and then you can forget about it.

Next up, we need a phase 2 entry. For that, click the [+] icon next to a label that says Show 0 Phase-2 entries and fill the form like below:

Screenshot of pfSense configuration phase 2 entry

Here, you just need to make sure that you replace 192.168.178.0 with the actual subnet your FRITZ!Box uses. Again, if you’ve sticked with the default when setting up the box, this setting should be right for you.

That should be it for the pfSense. After saving it’ll probably ask you to apply or reload the configuration. This is safe to do now.

Setting up the FRITZ!Box

Now, let’s finish this by configuring a VPN entry in your FRITZ!Box. From my perspective, this part is much easier, because I’m just pasting code instead of fiddling with screenshots – yay!

Fire up your favorite text editor and paste the following code:

Make the necessary modifications according to the comments in the file. Then, open the FRITZ!Box configuration interface in your browser and head to Internet -> Freigaben -> VPN, use the browse button to select the file you just created and click on VPN-Einstellungen importieren.

That’s it – you’re done. In my first trials I had to go back to the pfSense interface and navigate to Status -> IPsec to click on a small [>] (“play”) button to get things rolling. Maybe you need this, maybe it just works without it.

Getting the connection up after a restart of either of the two routers sometimes fails which is most probably due to the fact that DynDNS updates have not yet propagated when the VPN tries to connect. In this case, just be patient; both boxes will keep retrying to open VPN connections and you can always stop/start on both ends yourself. Once a connection is made, the tunnels are usually stable and rock-solid. Enjoy!

Remove diacritics (Umlauts, Accents, Special characters) in JavaScript

So I recently found myself generating permalinks in JavaScript again which can be fun and painful. It seems to be less painful if you just ignore anything that’s not [a-zA-Z0-9] and replace it with a hyphen -.

However, this starts looking ugly rather quickly if you’re from Germany or France for instance, where use of umlauts and accents is very common. Something really nice like
J'ai montré les éléphants à ma sœur
becomes something really ugly like
j-ai-montr-les-l-phants-ma-s-ur.

So as Holger pointed out, I needed a diacritics table which I found here. After some modifications for the German language (e.g. ä -> ae, ß -> ss), I came up with this.

It’s still heavily based on what lehel built, so thank him, not me. I just wanted to put my improved version here, so I don’t forget it.

Update: I have created a Gist for this over at Github so we can continue to update it there…

Switch from Bazaar to Git

Recently I had to switch a project from Bazaar to Git. Fortunately this has become quite easy using the right plugins. Just in case anyone out there needs to do the same: these are the steps if you want to keep your version history.

Git comes with an import plugin, bzr has an export plugin available. On debian based distros you might need to install the latter using

# available in lenny-backports, squeeze and ubuntu since 9.10
sudo apt-get install bzr-fastimport

Assuming you have  Bazaar repository in the folder ./bzr-repo just follow these steps to clone it to a git repoitory in the folder ./git-repo:

BZR=./bzr-repo
GIT=./git-repo

mkdir $GIT
cd $GIT
git init
bzr fast-export ../$BZR/ | git fast-import
git checkout
cd ..

The best part is: If you missed some revisions of Bazaar, e.g. because you forgot to merge an important branch, you can easily repeat the line bzr fast-export ../$BZR/ | git fast-import and Git should be smart enough to only import missing revisions.

How to build an 8 TB RAID5 encrypted time capsule for 500 Euros

So I wanted to buy a NAS that can act as a time capsule for Apple computers and run a proper Linux at the same time. I also wanted to be able to run the occasional Windows or Linux VM and I wanted to have a lot of storage. As I knew the thing was going to be in our coworking space, it also needed to have disk encryption.

Here’s how I built this for just under €500.00 using standard components and free open source software.

Selecting the hardware components

I found the HP ProLiant MicroServer (see Review and more Picures) to deliver great value for the price. At the time of writing, you can buy it for €209.90 if you’re in Germany like me.

The N36L (which I bought) comes with a single 250GB hard drive which obviously did not meet my “a lot of storage” requirement. So I bought 4 identical Seagate Barracuda Green 2000GB SATA drives which would add another €229.92 to the bill if you bought them today. I am not an expert in hard drives, but the Seagate Barracuda brand was familiar and “Green” sounds good as well.

If you don’t want your new server to host virtual machines at some point, you can probably get out your credit card and check out right now. If you’re like me though, you’d add another 2 bars of 4GB Kingston ValueRAM PC3-10667U CL9 (DDR3-1333) to your cart. The two of them together are just €44.24, so it’s no big deal anyways.

All components together will set you off €484.06. The rest is based on open source software (Debian mostly) which is free as in beer. More about that after the break.

Continue reading →

Are you stuck in Debian/MySQL/Charset/Collation hell?

So while Debian still hasn’t changed the MySQL default caracter set and collation to utf8, we all know that the first thing to do on a vanilla Debian MySQL installation is to add the following utf8.cnf file to /etc/mysql/conf.d/:

[mysqld]
default-character-set=utf8
default-collation=utf8_unicode_ci

However, if for some reason you didn’t do that and have used software which hasn’t been consistently explicit about character sets and collations, you end up with a nice mess of character sets and collations.

There is a great post on serverfault which helps you out. It comes down to one command which will take some time based on the size of your database:

mysql -B -N --user=user --password=secret -e "SELECT DISTINCT \
CONCAT( 'ALTER TABLE \`', TABLE_SCHEMA, '\`.\`', TABLE_NAME, '\` CONVERT \
TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;' ) FROM \
information_schema.COLUMNS WHERE TABLE_SCHEMA != 'information_schema';" \
| mysql --user=user --password=secret

Update:

And of course you need to alter the defaults for existing databases as well:

mysql -B -N --user=user --password=secret -e "SELECT DISTINCT \
CONCAT( 'ALTER SCHEMA \`', SCHEMA_NAME, '\` CHARACTER SET utf8 COLLATE \
utf8_unicode_ci;' ) FROM information_schema.SCHEMATA where SCHEMA_NAME \
!= 'information_schema';" | mysql --user=user --password=secret

First steps with Chef

Today, Jens and I got to play with Chef which supposedly is the hot sh$&!t when it comes to infrastructure automation and such. Installing your own Chef server seems hard at first but will work in the end.

If you’re using Debian, the APT sources will save you some headaches. Just add

deb http://apt.opscode.com/ squeeze main

to your /etc/apt/sources.list and do something like

wget -qO - http://apt.opscode.com/packages@opscode.com.gpg.key | sudo apt-key add -
sudo apt-get update

to be sure to be getting what you asked for. Then, a little sudo apt-get install chef will do the trick to set up a client and sudo apt-get install chef-server will supercharge your node with a fully blown chef server, including but not limited to CouchDB, Solr, RabbitMQ and other fancy stuff. (You’ll want to do this on two different nodes, so use Virtual Box or something.)

After you’ve set up two nodes like that, try following the rest of the instructions in this tutorial and do the first cookbook example, then you’ll have come as far as we have today.

I will update this post as we dig deeper – hopefully later this week.

Sparkleshare

Today a release candidate for sparkleshare 0.2 came out. Thanks to @jan for making me notice this great software a few days ago. It’s kind of a dropbox or ubuntu one clone but completely open source. You can use it to store your local data on a public server, your own server, your intranet or wherever you trust to put our data. All you need is a git server, ssh and a certificate to access it. No matter if it’s your local data storage, github or plan.io.

Comparing it to dropbox of course there still are a lot of downsides given its early state. There is no sophisticated encryption, only the data transfer is encrypted using ssl certificates. There is no GUI for easy sharing of data: whoever has access to your git repository can access your data, but no one else. However there are already a few nice features working quite well. Among them the easy GUI-based setup, the automatic syncing and the nice way to access old versions o data: right-click on a file, choose a version and a new file appears with the old date in its file name.

There is the source code for linux and mac versions available, binaries and a windows version are expected at a later point of time. In case you are on Ubuntu or Debian I recommend the following steps for installation after getting and unpacking the source from hbons’ github:

# install dependencies for the build process
sudo apt-get install gtk-sharp2 mono-runtime mono-devel monodevelop \
libndesk-dbus1.0-cil-dev nant libnotify-cil-dev libgtk2.0-cil-dev \
libwebkit-cil-dev intltool libtool python-nautilus libndesk-dbus-glib1.0-cil-dev

# using the prefix you enable the nautilus extension
./configure --prefix=/usr

# compile
make

# use checkinstall instead of make install to install it as a clean debian package
# that can be easily uninstalled using your favorite package manager
sudo checkinstall

# start the service
sparkleshare start

# You possibly have to restart nautilus to enable the plugin
nautilus -q

So go try it out!

Bazaar over chrooted sftp

How to set up bzr for chrooted sftp users

How to restrict a user’s access to sftp://.../var/bzr

For the prototyping editor itself and for a lot of our clients’ projects we are heavy Bazaar users at pidoco° to manage our distributed workflow. When we started some years ago we just installed bzr on one of the test servers where all of the developers had ssh access anyway. We put the repositories in /var/bzr and used sftp to checkout/push/pull source changes. This was handy as a sftp server comes with openssh installed.

As the team grew over the years we got to a point where we wanted to give new developers access to the bzr repositories without giving them full ssh access. However we did not want to have to change all the urls for existing repositories. Luckily this can be achieved easily since Debian Lenny.

Per Server Settings

On our scm server we have a user group called bzr that grants read/write access to most of the repositories (except of some personal or release branches) to all users with bzr access. And now we added the group sftponly. All users in this group will be restricted to sftp access only instead of a full shell.

sudo addgroup sftponly
sudo addgroup bzr

You probably have to add ‘/usr/lib/sftp-server’ to /etc/shells to make it a valid shell, eg. like this:

root@host # echo '/usr/lib/sftp-server' >> /etc/shells

The following settings in /etc/ssh/sshd_config force the internal sftp server to be used by openssh and change the root directory for all users in the group sftponly to /var/chroot. Make sure to restart sshd afterwards.

Subsystem sftp internal-sftp
Match Group sftponly
    ChrootDirectory /var/chroot
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand internal-sftp

Up to now our repositories have been in /var/bzr. These need to be moved to /var/chroot/var/bzr to let the sftponly users access them. /var/chroot needs to have root:root as owner for openssh to work correctly. For the existing ssh users we add a symbolic link to keep the old paths working:

sudo mkdir /var/chroot
sudo chown root:root /var/chroot
sudo mkdir /var/chroot/var
sudo mv /var/bzr /var/chroot/var
sudo ln -s /var/chroot/var/bzr /var/bzr

Per User Settings

giving the user username sftp access, but nor ssh access:

USERNAME=username                                  # give the user a name
sudo adduser ${USERNAME}                           # add user and data to system
sudo usermod -s /usr/lib/sftp-server ${USERNAME}   # disallow ssh/bash, allow ssh/ftp (sftp)
sudo adduser ${USERNAME} bzr                       # allow group access to most bzr folders
sudo adduser ${USERNAME} sftponly                  # disallow access to /, allow access to /var/bzr

This changes user’s shell to sftp-server.

Result

As a result of these settings both normal ssh users as well as restricted users in the sftponly group can use the same url for their shared repositories
bzr checkout sftp://my.domain/var/bzr/my_repository. By using chroot however users in the group sftponly are restricted to using sftp and can only access the folders in the bzr subdirectory.

Sources

In the Debian Administration Weblog you can find information on how to setup an OpenSSH SFTP chroot() with ChrootDirectory and on how to restrict users to SFTP only instead of SSH.

iPad Safari Bug: Touching iFrames

I didn’t want to buy an iPad. But in a recent project for one of our clients we had to optimize a page for the iPad. And that is why I just bought one to fix some bugs we had with that page. After some minutes of searching I came up with a nasty browser bug.

The page we developed contained a slider and an image that you can drag around. Both were implemented using the typical touch events that you know from mobile Safari: touchstart, touchmove, touchend, touchcancel. The page worked on my iPhone and on my iPad as well. But our client put the page into an iFrame in order to include it into his website. And that didn’t work.

After some investigation I discovered that the touch events worked in some situations, but not everywhere on the dom element. It turned out that the position of the iFrame has an impact on the area where the touch events work. Let’s say the iFrame is located 100 pixel below the documents top, then the touch events work anywhere on the image except for the lower 100 pixel. From what I know about browsers my guess is that the ‘cursor’ position is not calculated correctly when passing a touch event into an iFrame.

To get a better understanding, please try this little bug demo on your iPad or iPhone. The sources of the iFrame content look like this:

<html>
  <body>
    <div ontouchstart="alert('touched');"
        style="position:absolute;top:0px;width:200px;height:200px;background:yellow;"></div>
    <div ontouchstart="alert('won't be touched');"
        style="position:absolute;top:200px;width:200px;height:200px;background:red;"></div>
    <div ontouchstart="alert('touched only in upper half');"
        style="position:absolute;top:0px;left:200px;width:200px;height:400px;background:orange;"></div>
  </body>
</html>

And the iFrame sources:

<html>
  <body>
    <iframe style="position:absolute;top:200px;"
        border="0" src="iframecontent.html" width="400" frameborder="0"
        height="400" scrolling="auto"></iframe>
  </body>
</html>

I reported the bug to Apple, but since their bug tracking is not very motivating, I might add the bug to webkit as well. (I didn’t even get an email telling me that the bug was reported.)