Integrating OpenVPN into AOSP Source Tree

2011-06-17 06:11 by Ian

My host-side development environment is Ubuntu 10.10 64-bit. There are two targets:

I will cover the AOSP build first, as there is far less documentation regarding this procedure. These instructions are specific to the Nexus S for the sake of simplicity, but they will be similar for any build target running android 2.3.x.

This is not a trivial task, so I recommend reading this guide completely before deciding you want to undertake the effort. Know going into this that using binaries compiled by someone else is much easier, and you ought to have a good reason for going through all this trouble.

Preparation:

The host development environment must be 64-bit, as the tool chain depends on it. Google recommends Ubuntu 10.10 for this task, but any 64-bit Debian-based distribution should work just as well.

First, setup and update Ubuntu. This will not be covered here, but it should be at least as easy as setting up windows. Install your video card driver right away (I will explain why later). Then, you will need to get some tools. Much of the instructions in this section are refinements from Google's instructions.


Note: If you are running NVidia or ATI proprietary drivers, it is quite likely that the compiler will be unable to find glx.h and/or gl.h when the build system attempts to build the emulator. The proprietary video drivers (for whatever reason) remove/replace these header files with their own versions, and gcc doesn't like it. You might need to install them if your video driver doesn't provide its own versions...


I solved the problem by creating symbolic links to the files that my video driver (ATI in my case) provided, but decided to put in a location that was not standard...


Please also note that compiling android source is cross compilation. This means that you will be building for 32-bit targets on a 64-bit machine. Because of this, you will probably need the 32-bit dev libraries in addition to the 64-bit libraries (for the host-side tools), if there is a difference (example: ncurses). You will know this is the case if your compilation fails with messages such as… “skipping incompatible [library or module name]“ Should this be encountered, note the package name, and use google to chase down the 32-bit development version of the package.

If you intend the results of your work to be placed on a phone, you will also want to setup the permissions for udev. Otherwise, you will have permissions problems trying to use ADB with a USB device.


Now... Let's do this thing....

There are three layers that we are going to be dealing with: The kernel, the OS, and applications. There is no way to accomplish this task without dealing with all three layers. I will begin with...

The AOSP source

Follow Google's instructions for obtaining the source.

The next task will be to build the host-side tools and verify that everything works to this point. The following block of commands is a condensation of the instructions located here. From your working directory, execute these commands…


If the compilation finishes successfully, you will have built a set of binaries that are meant to be run on your development system (the emulator, adb, fastboot, etc). Try to...

...and if that works, your build succeeded. Since the host-side tools won't be changing from one compilation to the next, we should copy them to a location in our path so that we don't ever have to worry about them again….

We're going to leave this alone for now, and proceed to...

Build a kernel

Ok... get the kernel source. This applies only to the Nexus S. Make a new working directory (I did this outside of the ASOP tree)...


Then, enter the root of the source tree...


...and issue the commands to build. I put these lines into a bash script so I don't have to copy-paste them each time I build.


The “herring_defconfig” configuration is specific to the Nexus S. You can modify your kernel build options here. From the root of the kernel source...


Somewhere in that file, add this line...

...to build the tunnel module along with the kernel. You can also use...

...to build tunneling capability directly into the kernel. This will save you some time setting things up at the cost of a larger kernel, and the inability to disable tunneling, should that be desirable.

Once you can get the kernel to build successfully, you will need to place the zImage kernel and the modules into the AOSP tree. First, we should backup the original kernel and wifi module. Assuming you are still in the root of your kernel source, you can do all of this with....


Now, if you compiled tunneling into the kernel, you can skip this step. But if you built it as a module, you will need to first copy it into the AOSP tree...

...and then edit the device_base makefile to include it in the image...

I added these lines to the above file:

These binaries will be picked up by the AOSP build system and integrated into the boot.img. Note that this will not cause the tunnel module to be loaded on boot. In order to do that, you will need to edit the file...

...and add this line before the first service definition. I added this to line 60...


Try a test build on the AOSP tree, and make sure you didn't mess up. You will want to be that you can build and run a crespo image before continuing. Otherwise it will be harder to be sure where you went wrong if the next step causes you to have to chase build errors.

Change directories back into your AOSP tree and build an image for the Nexus S....


Then do the fast boot song-and-dance. If you haven't already done so, reboot into the bootloader and unlock it...


Then, once back at the bootloader, flash your images. This will erase your data and nuke the existing image, so back it all up with clockwork mod if you care about it.


If it all works, that's it for the kernel. Take a break.

Applications

Believe it or not, that was the easy part. The hardest part of this whole process is shoehorning engine support back into the AOSP version of OpenSSL (as of this writing, that is OpenSSL v1.0.0a).

Let's prepare... Create another directory outside of your AOSP tree and get the source code for everything...


At this point I feel compelled to explain some things. If you've followed me this far and have not fully understood what is happening, I am about to lead you straight into hell.
  • I am using someone's pre-compiled busybox binary. I am not using an installer APK. I am not building from source. This binary is large (~1.9MB). But it is quite plush. In my opinion, worth it. You are not required to use this version of busybox. But you must have busybox. OpenVPN cannot work without route AND ifconfig.
  • If you haven't yet noticed, I am using engineering builds for the Nexus S. This is only the case because I don't have to deal with rooting the handset every time I have to re-flash it. If you would rather root the phone in your own way, that should be adequate. But since route and ifconfig must have su to work, OpenVPN will not work without it.
  • If you are reading the documentation that comes with Friedrich Schauffelhut's android port of OpenVPN, you will notice that he tells you to install his port of OpenSSL in place of the existing AOSP version. I am going to tell you not to do this. Instead, we are going to patch the existing version from source files in OpenSSL v1.0.0d. Yeah, I hear you screaming. If you can explain to me how to enable engine support in the AOSP version using more conventional means, I will be happy to hear it.


Let's deal with OpenSSL first, as it is the most work. First, copy these two source files from OpenSSL v1.0.0d into the AOSP tree...


You may now delete the openssl-1.0.0d directory. We have taken what we need from it.

Download my version of android-config.mk and replace the android-config.mk in the AOSP-root/external/openssl directory. My version re-enables engine support and disables GOST.

Download my version of Android.mk and replace the one in AOSP-root/external/openssl/crypto. My version adds the previously omitted source files for the crypto engines.

Download my version of Android.mk for OpenVPN and replace the one in the source that you downloaded. Once you've done that, move the OpenVPN directory into the AOSP-root/external tree.

Download my version of Android.mk for liblzo and replace the one in the source that you downloaded. Once you've done that, move the lzo directory into the AOSP-root/external tree.

Move the busybox-android directory into the AOSP-root/external tree. No modifications are required. There exists an installation script that gets called by the build system that will replace as many of the stock binaries as exist, and adds the new ones to the image automatically.

Now... We added two packages that will not add themselves: OpenVPN and liblzo. Change directories back to your AOSP-root, and...

...and add these lines in the "subdirs" block at roughly line 460. Make certain that
  • ...the paths match what you added in the above steps...
  • ...there is no trailing whitespace after the slashes...
  • ...all lines except the last line have a line-folding "\"...
  • ...The last line does not have a line-folding "\".

Once all that is completed. Attempt to build the image again. If it builds, install it on your handset. Once there...


...and then attempt to...


If you added the appropriate directive to the init.herring.rc file, you should see an error claiming something along the lines of "file exists". If there is no output, the module was loaded.


Setup an OpenVPN server and issue a cert for your handset

If you've already got an OpenVPN setup, you can skip this step. Otherwise, the instructions over at TechRepublic are clear and easy to follow.

I would advise against adding the OpenVPN files to the AOSP tree, as they are sensitive and only good for one handset at a time. Once you have the handset up and running, you can push them to the phone like so...

Once that is done, try....


Hopefully. HOPEFULLY you will see your VPN connection happen, and your handset assigned a private IP. If this is true, you may modify the init.rc files or install management apps to control OpenVPN. You have done all the difficult work.

If you have specific build questions, or you see errors or omissions in the procedure, please let me know in the comments, or contact me directly.

Previous:
Next: