Setting Up Private Internet Access on Mint

Illustration

When I published post about OpenVPN on CentOS most common comment was "How to do that on some more user-friendly distribution. Well, you don’t get much more friendlier than Mint 16 (Petra).

Before starting with anything we need to install OpenVPN package. This is done via Menu, Administration, Software Manager. Just type OpenVPN and install first thing you get back (yep, this is great piece of security advice ;)).

First we can do the easy stuff. Download PIA’s OpenVPN configuration files and extract it to directory of your choice. I kept them in /home/MyUserName/pia.

Next easy step is setting up DNS resolving. For that we go to Menu, Preferences, Network Connections. Just click edit on connection you are using and go to IPv4 Settings tab. Change Method to Automatic (DHCP addresses only). Under DNS servers enter 209.222.18.222 209.222.18.218 (PIA’s DNS).

All other commands are to be executed in terminal and most of them require root privileges. It might be best if you just become root for a while:

su - root

Next step is getting configuration in place (replace username and password with yours):

cp /home/MyUserName/pia/ca.crt /etc/openvpn/ca.crt
cp /home/MyUserName/pia/crl.pem /etc/openvpn/crl.pem
cp /home/MyUserName/pia/US\ Midwest.ovpn /etc/openvpn/client.conf

sed -i "s*ca ca.crt*ca /etc/openvpn/ca.crt*" /etc/openvpn/client.conf
sed -i "s*crl-verify crl.pem*crl-verify /etc/openvpn/crl.pem*" /etc/openvpn/client.conf

echo "auth-user-pass /etc/openvpn/login.pia" >> /etc/openvpn/client.conf
echo "mssfix 1400" >> /etc/openvpn/client.conf

echo "^^username^^" > /etc/openvpn/login.pia
echo "^^password^^" >> /etc/openvpn/login.pia

chmod 500 /etc/openvpn/login.pia

Now we can test our connection (after we restart network in order to activate DNS changes):

/etc/init.d/networking restart
openvpn --config /etc/openvpn/client.conf

Assuming that this last step ended with Initialization Sequence Completed, we just need to verify whether this connection is actually used. I found whatismyipaddress.com quite helpful here. If you see some mid-west town on map, you are golden (assuming that you don’t actually live in US mid-west :)).

Now you can stop test connection via Ctrl+C in order to properly start it. In addition, you can specify it should start on each system startup:

service openvpn start
echo "AUTOSTART=all" >> /etc/default/openvpn

Lastly you can think about firewall and disabling default interface when VPN is not active. Of course, in order for things to work, we still need to allow port 1194 toward our VPN server and DNS:

ufw default deny incoming
ifw default deny outgoing
ufw allow out on tun0
ufw allow out 1194/udp
ufw allow out on eth0 to 209.222.18.222 port 53 proto udp
ufw allow out on eth0 to 209.222.18.218 port 53 proto udp
ufw enable

And that is all.

PS: It is not a déjà vu, article is really close to how it was set on CentOS.

[2016-10-01: Removed auth-nocache directive as it didn’t play nice with auth-user-pass.]

Growing a ZFS Pool

Illustration

As I was building my media server, I decided I must have support for both network file sharing and DAAP protocol. That way I could (comfortably) listen to my media collection using both my PC and my mobile phone. That simple requirement and fact that I had some experience with FreeNAS 0.7 drove me to NAS4Free.

I installed it in VirtualBox with two virtual drives; one 512 MB and another 2 GB. On smaller one I did embedded install of NAS4Free. Second one I formatted as ZFS (a.k.a. single *nix file system that doesn’t suck on power loss) and assigned to a single ZFS virtual device which was in turn assigned to a single ZFS pool. Both DAAP and samba were then forwarded to this share for their consumables.

Since I naively allocated only 2 GB I soon stumbled upon topic of this blog post. How do I increase my ZFS volume?

Increasing virtual disk is really easy and there is probably handful tools for every disk type (VHD in my case). I decided to use VirtualBox built-in vboxmanage tool (found in VirtualBox’s directory; don’t forget to turn off virtual machine):

VBoxManage.exe modifyhd "D:\Media.vhd" --resize 8192
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

While this was simple enough, it didn’t resolve anything. Next boot-up showed that ZFS still assumed 2 GB as size of a pool (at Disks, ZFS, Pools). If there was only a way for ZFS to recognize disk was bigger…

Fortunately there was just such a command. I went to Advanced, Command and executed following line:

zpool online -e Media-Pool ada1

Media-Pool was name of ZFS pool I was increasing and ada1 was actual physical disk that pool was located on. And that was it, my disk was increased painlessly and without any need for copying data around (except for backup purpose, of course). While it was nowhere close to comfort of using mouse to perform this task in Disk Management, it wasn’t too bad either.

PS: This post assumes that you know how to use NAS4Free. If you don’t use it, do try it out. You’ll love it.

PPS: Essentially same procedure works for FreeNAS or any other situation where you have virtualized disk drive with ZFS pool on it.

[2018-07-22: NAS4Free has been renamed to XigmaNAS as of July 2018]

Syntactic Sugar Does Make a Difference

Most of the days I have my life split between Java and C#. Work on one during the day, enjoy the other during the night. Some things I like in one language, some I prefer in other; it all depends on situation. But there is one feature I miss daily in Java. It is the var keyword.

Simplest scenario would be:

var x = new Something();

In this case var does not signify some new data type but it simply says to compiler to infer most appropriate type on its own. It is not variant data type by any stretch of imagination (check [dynamic](http://msdn.microsoft.com/en-us/library/vstudio/dd264736.aspx) for that) because var still statically assigns a type. Finally compiled code is actually equivalent to:

Something x = new Something();

In this, most basic scenario, it is already quite helpful in avoiding repetition. But it gets better. If you are dealing with loop, you don’t need to remember which kind of collection you are going in:

foreach (**var** item in foo.getItems()) {
    item.doSomething();
}

Assuming getItems() returns IList<MyItem>, this code might get compiled as:

foreach (**MyItem** item in foo.getItems()) {
    item.doSomething();
}

As long as MyItem type contains doSomething(), everything just works. If getItems() returns list of String, compile will fail (doSomething() is not a method of a String, at least not in current Java/C# version). If you ever refactor your code to use some other class, compile will still work as long as it contains same methods used elsewhere in code.

And that is the case where I miss it in Java the most. If I work with someone else’s classes and it is obvious that some sort of collection is returned, why cannot language figure out this for me? Why do I need to tell it, for even most basic cases, what exactly I need? Just so it can triumphantly say that my type doesn’t match what it expects? If compiler is smart enough to tell me my return type sucks, it should be smart enough to fill the data type itself.

While this var keyword does save me some typing its primary benefit comes from a more relaxed workflow. It helps me get over gritty, boring, ultimately unimportant, details into the code that actually matters. It preserves my flow of thoughts and it does make me more productive.

I see this feature as a major reason why I find C# more comfortable language than Java. It is not (just) about this particular syntactic sugar. It is about a philosophy. While Java prefers cleanliness of language, C# makes work easy.

PS: And don’t let me get started about how var is used with anonymous types, a distant dream in Java.

Installing KitKat on Nexus 4 From a Factory Image.

Illustration

Nexus 4 owners are a bit itchy these days. KitKat is out but nobody got it as an update yet. However, we are step closer to that since Google posted official factory images. If you are prepared to lose all your data, you might as well update OS yourself. I will describe this procedure on Windows and on non-developer’s computer.

NOTE: THIS PROCEDURE WILL DELETE ALL THE CONTENT ON YOUR PHONE.

We’ll definitely need to download Google’s USB drivers. Once you download and unpack the archive, you’ll need to go to Device Manager and find your Nexus device with an exclamation point next to its name. Right-click, Update Driver Software, and select location where you unpacked the driver zip file. Your device should then be named Android ADB Interface.

And we definitelly need ADB and Fastboot tools. While we can get them in Google SDK, I found that Minimal ADB and Fastboot works nicely and it is less fuss to install on a non-developer computer. Just execute installation and do standard Next, Next, Finish dance routine.

Last, but not the least, we need factory image itself. Once downloaded, I usually just unpack it in same directory as Minimal ADB and Fastboot (C:\Program Files (x86)\Minimal ADB and Fastboot on my computer) to avoid setting up the paths (yep, pure laziness).

Next order of business is enabling USB debugging. This means going to Settings, About phone and clicking Build Number 7 times. Your Nexus 4 will pronounce you a developer and you will get additional Developer options in Settings. There you must turn on USB debugging. As soon as that is done, device will ask you for confirmation.

Once allowed, we can go start Minimal ADB and Fastboot command line (or just reuse one automatically started after setup). There we will first check whether device is visible:

adb devices
 * daemon not running. starting it now on port 5037 *
 * daemon started successfully *
 List of devices attached
 04caa50d9f0c7784        device

Assuming device is visible, we’ll reboot into bootloader:

adb reboot-bootloader

Device will go down and you will be presented with a nice screen that probably says LOCK STATE - locked in the last line. We can change that with a simple unlock command:

fastboot oem unlock
...
OKAY [ 30.008s]
finished. total time: 30.009s

Moment of truth is upon us. Now we run update itself:

flash-all.bat
 sending 'bootloader' (2203 KB)...
 OKAY [  0.072s]
 writing 'bootloader'...
 OKAY [  0.333s]
 finished. total time: 0.409s
 rebooting into bootloader...
 OKAY [  0.003s]
 finished. total time: 0.005s
 < waiting for device >
 sending 'radio' (45537 KB)...
 OKAY [  1.437s]
 writing 'radio'...
 OKAY [  2.578s]
 finished. total time: 4.018s
 rebooting into bootloader...
 OKAY [  0.002s]
 finished. total time: 0.003s
 < waiting for device >
 archive does not contain 'boot.sig'
 archive does not contain 'recovery.sig'
 archive does not contain 'system.sig'
 --------------------------------------------
 Bootloader Version...: MAKOZ30d
 Baseband Version.....: M9615A-CEFWMAZM-2.0.1700.97
 Serial Number........: 04caa50d9f0c7784
 --------------------------------------------
 checking product...
 OKAY [  0.002s]
 checking version-bootloader...
 OKAY [  0.003s]
 checking version-baseband...
 OKAY [  0.002s]
 sending 'boot' (6336 KB)...
 OKAY [  0.202s]
 writing 'boot'...
 OKAY [  0.365s]
 sending 'recovery' (6884 KB)...
 OKAY [  0.238s]
 writing 'recovery'...
 OKAY [  0.411s]
 erasing 'system'...
 OKAY [  0.568s]
 sending 'system' (700500 KB)...
 OKAY [ 22.124s]
 writing 'system'...
 OKAY [ 42.031s]
 erasing 'userdata'...
 OKAY [  0.810s]
 formatting 'userdata' partition...
 Creating filesystem with parameters:
     Size: 14129561600
     Block size: 4096
     Blocks per group: 32768
     Inodes per group: 8144
     Inode size: 256
     Journal blocks: 32768
     Label:
     Blocks: 3449600
     Block groups: 106
     Reserved block group size: 847
 Created filesystem with 11/863264 inodes and 95427/3449600 blocks
 sending 'userdata' (137438 KB)...
 writing 'userdata'...
 OKAY [ 12.716s]
 erasing 'cache'...
 OKAY [  0.043s]
 formatting 'cache' partition...
 Creating filesystem with parameters:
     Size: 587202560
     Block size: 4096
     Blocks per group: 32768
     Inodes per group: 7168
     Inode size: 256
     Journal blocks: 2240
     Label:
     Blocks: 143360
     Block groups: 5
     Reserved block group size: 39
 Created filesystem with 11/35840 inodes and 4616/143360 blocks
 sending 'cache' (10984 KB)...
 writing 'cache'...
 OKAY [  1.042s]
 rebooting...

 finished. total time: 80.594s
 Press any key to exit...

Congratulations! Your device is a KitKat.

After this I prefer to make myself a developer and enable USB debugging once more. In a new Minimal ADB and Fastboot command line (because flash-all batch closed our last one), reboot to bootloader and lock it again:

adb reboot-bootloader

fastboot oem lock
 ...
 OKAY [  0.010s]
 finished. total time: 0.011s

Simple power button press later and our device is exactly where we started; minus lost data and plus an android version.

Rolling Your Own

Illustration

Probably every programmer had a phase when he started to develop his own encryption algorithm. It was probably early in his professional life when he learnt about XOR and the magic it does. Most programmers soon after realize that they are not cryptographers and that their algorithm is shitty at the best. Those who don’t usually work on DRM later (and those things are never broken, are they?)

Professional programmers know that any person can invent a security system so clever that she or he can’t think of how to break it. They heavily rely on a published standards and make their applications work accordingly. Cryptographers take care of encryption algorithms, programmers take care of implementation part and the world is a more secure place.

But it makes me wonder, are we approaching this all wrong? In a spy-happy world where NSA seems to influence security standards and where bulk decryption seems to be a reality, I would argue that own encryption has some benefits.

Since bulk collection relies on all data being in similar format, anything you can do to foil this actually makes you invisible. Let’s assume that AES is broken (don’t worry; it is not). Anyone relying on standard AES would be affected. But if some wise-ass just did XOR with 0xAA there is high probability that his data would skip the collection.

Mind you stupid encryption is still stupid. And if you are targeted by NSA there is high probability that they will get the data regardless of what you do. If you are using some homegrown encryption, it will be broken. However, they will be unable to take this data in an automatic manner. Enough people doing this would mean they need to dedicate human resources for every shitty algorithm out there. And you are probably not important enough to warrant such attention.

Probably smarter choice would be using two encryption algorithms, back to back. You can use Rijndael to encrpyt data once, then use another key (maybe derived via Tiger) with a Twofish. I am quite comfortable saying that this encryption will not be broken by any automatic means. System might have huge gaping holes, but it will require human to find them.

Of course, once you start doing your “twist” on encryption method you suddenly become completely incompatible with all other “twists” out there. Implementations will become slower (yep, double encrypting stuff costs). Implementing two encryption algorithms will not really protect you against targeted attach where e.g. trojan can get used to steal your password and circumvent all that encryption. Nobody will bother to do cryptoanalysis on your exact combination so you are pretty much flying in the dark. And probably another bad thing or two I forgot.

However, there is something attractive in rolling your own encryption using standardized cipher blocks for data you deem important (e.g. password storage). Not only that it is an interesting defense but it also gives you an enjoyment of doing something you know you shouldn’t.

PS: Never take cryptography advice from a random guy on the Internet.