Getting IPv6 working on the UK Mobile Network

One problem with mobile data here in the UK is that everything is NATed to death. Most consumer mobile data connections do not support static IP‘s and those that do are expensive. Also, the UK is lagging behind most of the world in providing access to the IPv6 internet. It’s not that IPv6 is new either, it’s been around for 10 years but no, here in the UK they want to try not fork out the cash to replace older kit that can only handle IPv4 & it’s not exactly rocket science either.

Ok, my home network is IPv6 enabled. I have a /64 subnet routed to home out of my /48 allocation at my ISP (they support IPv6 natively). If you don’t know what this is don’t worry – l this means is that on the IPv6 internet I actually have more static IP’s on my home network than the old legacy internet put together. In fact the legacy has about 4 billion & I have 1.8*1019. Now you see the main selling point of IPv6 – there’s room for every single device that’s networkable to have just one IP address and be accessible from anywhere – obviously behind a firewall.

Anyhow, the problem I had to solve was this: I’ve got a fair few machines on my network and at times I need to be able to ssh into them remotely. Currently I can do this by either ssh into my firewall by it’s IPv4 address and then onto the internal machine or I could setup a VPN – but why should I when I’m fully IPv6 enabled?

Setting up a Tunnel Broker

Well there is a way. When native IPv6 isn’t available, one option is to use a tunnel broker. A broker sets up a tunnel between your device and an endpoint at the broker. IPv6 is then encapsulated in an IPv4 packet, sent through the tunnel to the broker, then sent out from there as IPv6. Now there are plenty out there like Hurricane Electric and SixXS but as I need to use this on a 3G device they won’t work as they require a static IPv4 address and we don’t have that – we’re behind a NAT, so the only available option is Gogo6 (which owns Freenet6). They are also a broker but they support NAT traversal which is what we need.

So, on my Linux Mint laptop it’s a simple case of installing the Gogo6 client:

sudo apt-get install gogoc
sudo /etc/init.d/gogoc stop
sudo /etc/rc5.d/S20gogoc

Now you might wonder why we stop then delete a file after installation. This is because when it installs it starts the service and we don’t want it running just yet. Also the rc5.d file means it starts on boot which we don’t want – we want to use this on 3G remember.

As it stands that’s all there is to do – by default it’s configured to use an anonymous account so the next time you’re on 3G you simply:

sudo /etc/init.d/gogoc start

and you’ll find you are now on the IPv6 internet. When you go offline just stop gogoc:

sudo /etc/init.d/gogoc stop

Getting a more permanent static IPv6 address

With an anonymous connection you’ll get an IP address out of a pool but if you want a static address you’ll need to register an account and edit /etc/gogoc/gogoc.conf

In that file:

  1. edit the lines with userid= and passwd= with you’re account’s username and password.
  2. The line server= needs to be their endpoint. Here you register against a specific one, so as I used amsterdam set this to amsterdam.freenet6.net
  3. Finally change the auth_method= line from anonymous to one of the other methods listed just above that line.

Now that last step might take some work to get working. any should always work but it risks sending your password in the clear but you might want to play with that later.

That’s it. When you start gogoc you’ll get a new IP address which will be permanent. You’ll also get a dns entry setup as well, username.broker.freenet6.net so now you can get into your laptop.

Tunneling an entire network

There is a final option available but out of scope here, and thats connecting an entire network to the tunnel. Thats simply a case of changing the host_type= line from host to router. Then you’re local network will get an IPv6 address with your laptop as the router.

How well does it work

Well I’ve tested it on T-Mobile UK and it works pretty well. I can access my home servers directly and as I use the non-anonymous option I can actually ssh from home to the laptop via it’s 3G connection.

I’ve even tried setting up a proxy on an Apache server which is accessible from the legacy IPv4 internet and it connects to the laptop’s Apache server fine – although sluggish but remember this is over 3G.

At some point I’ll try it on other operators (I also use GiffGaff & 3).

Next I need to figure out how to get this working on Android so that I can get my Nexus 4 & Nexus 7 3G online – both supports IPv6 when on the WiFi at home, just would be nice when out and about.

 

Getting SSHD to run on boot

By default the sshd service is not installed in the debian distrubution used on the Raspberry PI. For most uses this isn’t really necessary but if you are intending to use the pi without a screen then you need some way to get into it over the network.

All you need to do is to install ssh & tell debian to run it on boot:

sudo apt-get install ssh
sudo update-rc.d ssh defaults

Now, as long as you know the IP address (or you give it a static one) then you can now ssh into it.

Generating private keys with openssl

Keys are the basis of public key algorithms and PKI. Keys usually come in pairs, with one half being the public key and the other half being the private key. With OpenSSL, the private key contains the public key information as well, so a public key doesn’t need to be generated separately.

Public keys come in several flavors, using different cryptographic algorithms. The most popular ones associated with certificates are RSA and DSA, and this  article will show how to generate each of them.

Generating an RSA key

A RSA key can be used both for encryption and for signing and generating a key is quite easy, all you have to do is the following:

  openssl genrsa -des3 -out privkey.pem 2048

That will generate a private key with is password protected (it will prompt you for the password during generation). If you don’t want it password protected (usually for server side use) then leave the -des3 parameter out, i.e.:

  openssl genrsa -out privkey.pem 2048
 The number 2048 is the size of the key, in bits. Today, 2048 or higher is recommended for RSA keys, as fewer amount of bits is considered insecure.

Generating a DSA key

A DSA key can be used for signing only. This is important to keep in mind to know what kind of purposes a certificate request with a DSA key can really be used for.

Generating a key for the DSA algorithm is a two-step process. First, you have to generate parameters from which to generate the key then to generate the key itself.

  openssl dsaparam -out dsaparam.pem 2048
  openssl gendsa -des3 -out privkey.pem dsaparam.pem

Again like RSA, 2048 is the size of the key, in bits with anything smaller than 2048 being insecure in todays standards.

Also the -des3 parameter will prompt you for a pass phrase – for server use leave it out:

  openssl dsaparam -out dsaparam.pem 2048
  openssl gendsa -out privkey.pem dsaparam.pem

Performing remote Maven 3 builds with NetBeans 7.0

This article covers how to get NetBeans to use a Maven installation on a remote server. This has been tested with Maven 3.0.2 but should work on any other version. It may also work for other IDE’s like Eclipse if you can get them to use an alternate maven installation other than the internal one.

Sometimes you may want to run maven on a remote machine from inside the NetBeans IDE. For me this is down to available memory on the local machine is limited enough on large projects that both NetBeans and Maven compete slowing the local machine down as it swaps the IDE in and out of main memory.

Another instance may be to perform builds on a standard OS (Linux in this case) rather than the OS running the IDE (OSX here).

Now this is pretty easy to implement. Here I have the IDE running on OSX and the builds on Linux (Ubuntu 10.10) but if you can get the prerequisites running in theory any OS should work.

Prerequisites

  • ssh access to both machines with public key authentication working
  • sshfs configured for mounting drives (you can use nfs or smb if you wish)
  • maven 3.0.2 installed on both machines – both machines need the same version

Setting up the environment

In this example:

  • sabrina – The local machine running NetBeans. It’s running OS X
  • kira – The remote machine which will run the builds. It’s running Ubuntu 10.10

Shared filesystems

The remote needs to have access to the local project directories for maven to work. As I have all development under a dev directory under home, on the remote machine I simply create a dev directory and then mount the local host from it using sshfs

<br />
peter@kira:~$ mkdir dev<br />
peter@kira:~$ sshfs peter@sabrina:dev dev<br />

If you have a custom settings.xml file, make sure it’s also present on the remote’s .m2 directory, i.e.

<br />
sabrina:~ peter$ scp .m2/settings.xml peter@kira:.m2<br />

Finally NetBeans needs access to the built artifacts, so to do this we mount the remotes .m2/repository locally. I use .m2/remoterepo for this

<br />
sabrina:~ peter$ mkdir .m2/remoterepo<br />
sabrina:~ peter$ sshfs peter@kira:.m2/repository .m2/remoterepo<br />

Maven

Next install your maven installation on both machines. I keep mine in the same place, but thats optional. For the purposes of this article I’m going to use /usr/local/apache/apache-maven-3.0.2

Next on the machine running NetBeans you need to create a duplicate installation /usr/local/apache/apache-maven-3.0.2-remote We need to have a copy for NetBeans to recognise it as a valid environment later on.

Now in this new installation we need to replace the /usr/local/apache/apache-maven-3.0.2-remote/bin/mvn script with the following:

<br />
#!/bin/bash<br />
#<br />
# Enable NetBeans 7.0 beta to run maven on a remote host</p>
<p># Pass the maven args as is<br />
MVN_ARGS=&quot;$@&quot;</p>
<p># The current directory, NetBeans does a cd so this will be the project<br />
# directory.<br />
#<br />
# If you need to translate the path between local and remote machines then<br />
# pass the output of pwd through sed first<br />
REMOTE_PROJECT_DIR=$(pwd)</p>
<p># Execute maven on remote host<br />
REMOTE_USER=peter<br />
REMOTE_HOST=kira</p>
<p># Location of remote maven installation<br />
REMOTE_MAVEN_HOME=/usr/local/apache/apache-maven-3.0.2</p>
<p># JAVA_HOME on remote machine<br />
REMOTE_JAVA_HOME=/usr/lib/jvm/java-6-openjdk/</p>
<p># ======================================<br />
# DO NOT EDIT ANYTHING BEYOND THIS POINT<br />
# ======================================</p>
<p># Remote mvn command<br />
REMOTE_MVN=$REMOTE_MAVEN_HOME/bin/mvn</p>
<p># Build the commands to run remotely<br />
CMD=&quot;cd ${REMOTE_PROJECT_DIR};&quot;<br />
CMD=&quot;${CMD}export JAVA_HOME=${REMOTE_JAVA_HOME};&quot;<br />
CMD=&quot;${CMD}$REMOTE_MVN ${MVN_ARGS}&quot;</p>
<p># Now run the remote build<br />
echo<br />
echo ------------------------------------------------------------------------<br />
echo Executing remote build on $REMOTE_HOST as $REMOTE_USER<br />
echo Remote command: $CMD<br />
echo ------------------------------------------------------------------------<br />
echo<br />
exec ssh ${REMOTE_USER}@${REMOTE_HOST} &quot;${CMD}&quot;<br />

In this script you need to ensure that the settings are correct:

  • REMOTE_USER and REMOTE_HOST point to your remote host,
  • REMOTE_MAVEN_HOME is the location of where maven is installed on the remote host,
  • REMOTE_JAVA_HOME is the location of the JDK on the remote host.

Now you may need to alter the line defining REMOTE_PROJECT_DIR. Shown above it gets set to the directory containing the maven project on the local host. If this differs on the remote then you need to either change to translate this to the location on the remote.

For example I have my NetBeans projects under a directory called dev in my home directory. As this is OS X that becomes /Users/peter/dev however on Linux the path is /home/peter/dev

I get around this by on the remote simply creating a symlink for /Users pointing to /home but you could modify the script to do that for you.

Configuring NetBeans

The last step is getting NetBeans to use the new remote.

Start NetBeans and enter preferences Then the Miscellaneous tab and finally Maven:

  • Under Maven Home select Browse and select the dummy remote installation, in my case /usr/local/apache/apache-maven-3.0.2-remote
  • Under Local Repository select Browse and point it at .m2/remoterepo
  • Select OK

Now if you try to run any build you’ll now see it run on the remote machine and as far as NetBeans is concerned it’s running locally. For example in the NetBeans output window you should see something like the following:

<br />
cd /Users/peter/dev/misc/example; JAVA_HOME=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home /usr/local/apache/apache-maven-3.0.2-remote/bin/mvn --batch-mode --lax-checksums --fail-fast --no-plugin-updates --batch-mode clean</p>
<p>------------------------------------------------------------------------<br />
Executing remote build on 192.168.30.108 as peter<br />
Remote command: cd /Users/peter/dev/misc/example;export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/;/usr/local/apache/apache-maven-3.0.2/bin/mvn --batch-mode --lax-checksums --fail-fast --no-plugin-updates --batch-mode clean<br />
------------------------------------------------------------------------</p>
<p>Command line option -npu is deprecated and will be removed in future Maven versions.<br />
Scanning for projects...<br />
------------------------------------------------------------------------<br />
Reactor Build Order:<br />

Future invocations

Once setup, whenever you restart either machines you simply need to mount each others drives before starting NetBeans as all the rest should then be setup.

<br />
sabrina:~ peter$ sshfs peter@kira:.m2/repository .m2/remoterepo<br />
peter@kira:~$ sshfs peter@sabrina:dev dev<br />

ssh-askpass on OSX 10.5

I’ve been playing with NetBeans 6.7M3 and the latest Mercurial plugin and found that I couldn’t push to a remote repository via ssh. All netbeans would return was:

Mercurial Push
--------------
INFO Pushing To: ssh://pmount@lego.office.gameaccount.com/hg/ga4Partner ...
ERROR Command failed:
Command: [/usr/local/bin/hg, outgoing, -v, --template=rev:{rev}\nauth:{author}\ndesc:{desc}\ndate:{date|hgdate}\nid:{node|short}\n\nendCS:\n, --repository, /Users/peter/dev/gameaccount/maven/ga4Partner, ssh://pmount@lego.office.gameaccount.com/hg/ga4Partner]
Output: [running ssh pmount@lego.office.gameaccount.com “hg -R hg/ga4Partner serve --stdio”, remote: ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory, remote: Host key verification failed., abort: no suitable response from remote hg!]
INFO: End of Mercurial Push

Here the remote server is trying to prompt for the login password but fails because OSX 10.5 does not have the ssk-askpass command.

After some searching on the net (ok Google who else) I found Mercurial Push from IntelliJ where someone had a similar position with IntelliJ. By creating the following script mercurial in NB6.7M3 works flawlessly:

sabrina:~ peter$ sudo vi /usr/libexec/ssh-askpass
#! /bin/sh  
  
#  
# An SSH_ASKPASS command for MacOS X  
#  
# Author: Joseph Mocker, Sun Microsystems  
  
#  
# To use this script:  
#     setenv SSH_ASKPASS "macos-askpass"  
#     setenv DISPLAY ":0"  
#  
  
TITLE=${MACOS_ASKPASS_TITLE:-"SSH"}  
  
DIALOG="display dialog \"$@\" default answer \"\" with title \"$TITLE\""  
DIALOG="$DIALOG with icon caution with hidden answer"  
  
result=`osascript -e 'tell application "Finder"' -e "activate"  -e "$DIALOG" -e 'end tell'`  
  
if [ "$result" = "" ]; then  
    exit 1  
else  
    echo "$result" | sed -e 's/^text returned://' -e 's/, button returned:.*$//'  
    exit 0  
fi  

sabrina:~ peter$ sudo chmod +x /usr/libexec/ssh-askpass