Linux, Unix, and whatever they call that world these days

SDR on Raspberry Pi 3 (Hardware)

Illustration

[This is a post 1 in series, for software setup go here]

If you want to explore the radio world around you, enthusiasts long time ago noticed that TV tuners are, with their software-defined radio core, the easiest way to get into it. They are widely available, cheap, and listen-only. This listen-only is a really important stuff as not only you can get yourself in a lot of legal troubles by transmitting willy-nilly, but you can also mostly ignore all that antenna matching stuff and not burn your devices.

One family of tuners captured radio hobbyist hearts all around - RTL. There is a bunch of chips in that family, RTL2832 and RTL2832U being the current favorites. There is not much about those chips to distinguish them from other TV tuners but the fact there were there first and they are well supported by software. If application supports radio on cheap, it will support RTL chipset.

However, the basic TV tuner devices are not know for their frequency stability. Their main purpose is working in a single frequency range so tight regulation was not of a major concern. Because of that you have companies like NooElec that either know which SDR receivers work well and they just resell them or, in some cases, they equip SDR receivers with a better crystal (e.g. 0.5 ppm). And that helps a lot.

There are many models on their pages and , if you go with 0.5PPM TCXO you are in excellent shape. I myself opted for Nano 2+ but Mini+ with its aluminium enclosure sure looked tempting.

If you have a powerful PC to dedicate as the radio receiver, story can end here - download SDR# or Cubic SDR and enjoy. However, I had something else in plan.

As my main PC is a notebook I got bored connecting SDR receiver every night only to disconnect it some time later. And lets not speak about all the driver tricks you usually need to make radio applications recognize it properly in 64-bit Windows 10. Fortunately pretty much all applications that recognize RTL can also work with it over the network. And creating remote RTL-based server is a job best done on Linux.

For remote Linux I gave quite a few thoughts toward Stick computers but decided against them due to a new Raspberry Pi 3. It has more than acceptable specs (doing RTL server is not really processor intensive task) and at $35 it is third of the price. As a bonus it is completely passive so we don’t need to be worried about the fan noise.

Even better, it has a wired ethernet port that gives better network experience and enables us to turn off wireless and get a cleaner radio input. Although with all the 2.4 GHz networks and microwave ovens blasting around, it makes a little difference in the end. And no, this small SDR device is not stable on 2.4 GHz, thanks for asking. Realistically, if you want to go into the GHz range, you need a better radio frontend than a cheap TV card.

For Raspberry Pi you need an SD card that will hold the operating system - any 4 GB or above micro-SD will do. You also need a power supply - just scavenge whatever you have lying around. And finally you might want to think about a case - that you will have to buy.

To sum it up, here is the equipment list assuming you have nothing at all:

DescriptionStoreCost
NooElec NESDR Nano 2+NooElec$30
Raspberry Pi 3 BNewark$30
Raspberry Pi 3 CaseNewark$9
Raspberry Pi 3 Power SupplyNewark$11
Raspberry Pi NOOBS SD CardNewark$14
TOTAL$94

PS: All prices are without tax and shipping, as customary in States. Your total amount will be a smidgen higher.

PPS: I have no connections neither to Newark nor NooElec. In case of Newark (or Element 14), it was the only supplier that had all items in stock at the time. In case of NooElec, their devices seemed to be at a perfect price/performance point.

Ubuntu Under Windows

Illustration

During BUILD conference Microsoft announced it would be possible to run bash shell and Ubuntu binaries on Windows. My personal reaction to this was meeh.

Those familiar with me and blog might know I love some things about Linux - especially bash - and I have more Unix/Linux-based computers than ones running Windows (although the number is close). For server-like tasks - even at home - nothing beats Linux. Yes, learning curve is a bit steep due to heavy reliance on the command line but that becomes a strength once you get used to it. And don’t start me talking about superiority of SSH. Anybody with interest in technology is losing a lot if they don’t at least try Linux.

Reason for my less than warm welcome is because I already have all Linux command-line applications worth running under Windows. If you download Git for Windows, you will get Bash shell and bunch of tools that go with it. Frankly, I rarely go into Windows command-line (or its bastard child PowerShell) anymore. Bash is simply more powerful and more practical. With a few easily remembered commands you can do wonders - especially when filtering files. And anything bigger 95% of time has Windows version too.

I don’t view Ubuntu on Windows as a bad step. But I don’t believe it will bring much to developers who had bash running on Windows, one way or another, for years. Considering it is a Windows Store application I am sure there will be enough gotchas to keep it from being practical…

Of course, details remain to be seen once Windows 10 Anniversary edition is out.

Cloning My Website

One disadvantage of having a reliable hosting provider is that you tend to forget about backups. In my ten years with Plus hosting there was not a single case of data loss. Regardless I wanted to go “better safe than sorry” route and make automated backups. And, while I am at it, I might as well use it to make “production replica” environment for testing.

My website environment is based on CentOS 6, MySQL database, and Apache. Ideally I would need exactly the same environment. But in this case I decided to upgrade all components to latest versions. In case of Linux that meant going with CentOS 7.1 (minimal).

Installation for CentOS is as simple as it gets. I basically click on Next until there is no button to press. :) Only possibility of error is forgetting to enable the Ethernet network adapter - not a catastrophic mistake; just annoying one. Once install was done, additional packages were in order:

yum install httpd mariadb-server php php-mysql rsync

To connect to my website I created new SSH keys:

ssh-keygen -b 4096

I appended newly created .ssh/id_rsa.pub key to .ssh/authorized_keys on my web server. That meant I could login and copy files without any passwords - great for scripting.

Setting up MySQL/MariaDB came next. It is just a basic setup followed by user and database creation:

mysql_install_db
chown -R mysql:mysql /var/lib/mysql/
service mariadb start
chkconfig mariadb on
mysql -e "CREATE USER '^^mydbuser_wp^^'@'localhost' IDENTIFIED BY '^^mydbpassword^^';"
mysql -e "CREATE DATABASE ^^mydatabase_wordpress^^"

For data replication (after making sure /home/myuser directory exists) I created simple /root/replicate.sh script with following content:

#!/bin/bash

ssh ^^myuser^^@^^myhost.com^^ "mysqldump -u ^^mydbuser_wp^^ -p^^mydbpassword^^ --opt ^^mydatabase_wordpress^^" > /var/tmp/mysql.dump
mysql ^^mydatabase_wordpress^^ < /var/tmp/mysql.dump
rm /var/tmp/mysql.dump

scp -r ^^myuser^^@^^myhost.com^^:/home/^^myuser^^/* /home/^^myuser^^
#rsync -avz -e ssh ^^myuser^^@^^myhost.com^^:/home/^^myuser^^ /home/^^myuser^^

First three lines ensure I have a fresh MySQL database import and SCP is tasked with file copy. Better approach would be rsync but I kept getting Out of memory errors. As my site is not huge, I opted for dummy copy instead of troubleshooting.

Once I ran script once to verify all is working as expected, i added it to crontab (crontab -e) so it runs every midnight:

…
00 00 * * * /root/replicate.sh

For Apache I edited /etc/httpd/conf/httpd.conf file to change its root:

…
DocumentRoot "^^/home/myuser/public_html^^"
<Directory "^^/home/myuser/public_html^^">
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>
…
<IfModule mime_module>
    …
    ^^AddType text/html .php .phps^^
</IfModule>
…

Opening filewall was next task:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
service iptables save

And all remaining was to start Apache:

chown -R apache:apache ^^/home/myuser/public_html^^
restorecon -R ^^/home/myuser/public_html^^
service httpd start
chkconfig httpd on

PS: Do notice that I didn’t describe security setup for this machine. Unless there are some mitigating circumstances, you pretty much want your backup as secure as a real thing.

Internal IPv6 Router Advertisement

I have fully functioning IPv6 network at home for a while now. I used to do tunneling but for last year or so, I have native IPv6 to my home router. And everything works really nice. Problem arises when I am not at home and I want to do some IPv6 development and I want some proper (other than link-local) IPv6 addresses assigned. There are many ways to deal with this, but I found that virtual IPv6 router works the best for me.

For this I started with preparation of the VirtualBox machine (any virtualization environment will do) for the 64-bit Linux Red Hat. Only change to the defaults was enabling the second network interface (either Bridged or Internal). That was the network I intend to use for the IPv6 router advertisement.

After installing the CentOS 7.0 Minimal Install Image onto the newly created virtual machine, there are a few manual steps needed.

First was actually enabling DHCP so additional packets can be installed. After verifying which network interfaces are present using the ip addr (I had enp0s3 and enp0s8), I edited both network startup files (/etc/sysconfig/network-scripts/ifcfg-enp0s3 and /etc/sysconfig/network-scripts/ifcfg-enp0s8) by changing the ONBOOT setting to yes followed by a network restart:

service network restart
 Restarting network (via systemctl):    [  OK  ]

With Internet working, I was ready for installing IPv6 Router Advertisement Daemon:

yum install radvd
 …
 Complete!

In /etc/radvd.conf I added the following content:

interface enp0s8
{
    AdvSendAdvert on;
    MaxRtrAdvInterval 5;
    prefix 2001:db8:42::/64;
};

This is followed by service start (and enabling it on boot):

systemctl start radvd.service
systemctl enable radvd.service
…

Now any IPv6 capable network adapter sharing the same network with second VirtualBox network interface will get our defined IPv6 prefix.

PS: Advertisement time is intentionally kept very short. I find it useful to get quick unsolicited router advertisement messages for the demonstration purposes.

Sharp Video Play

Making a minimal C# video player in the Linux ought to be easy. I mean, both platforms are mature and something so basic should not present a problem.

GStreamer C# bindings seemed as a perfect choice at first. All needed was to “make” it. Simple enough - just use autogen.sh followed by make and enjoy the fruits of your labor.

That was a plan until I started the dependency dance. First I had to make GtkSharp myself since my latest library versions were too low for GStreamer. Then I had to get GStreamer. Then I had to get GStreamer plugins. And then I gave up.

Between compiling, downloading, and resolving dependencies I have installed around 50 packages, manually compiled multiple libraries, and I was still on the “just one more” stage. Call me spoiled, but I find this unacceptable.

Fortunately Linux is full of choices and my next try was with the MPlayerControl. It too needed a few packets on the top of a clean Mint 17 installation but nowhere close to the dependency hell:

sudo apt-get install mono-complete monodevelop mplayer git

After that I had to get the latest MPlayerControl source:

git clone https://github.com/majorsilence/MPlayerControl MPlayerControl

And that was it. Shockingly, example within the source was working perfectly albeit it was not the smallest one they could make. I created my own sample form (with a reference to the LibMPlayerCommon) to play a single file as simply as possible:

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using LibMPlayerCommon;

namespace TestMedia {
  public class MainForm : Form {
    private MPlayer mPlayer;

    public MainForm() {
      this.WindowState = FormWindowState.Maximized;
      this.mPlayer = new MPlayer(this.Handle.ToInt32(), MplayerBackends.GL2);

      this.Load += delegate(object sender, EventArgs e) {
      this.Text = this.fileQueue.Peek();
        this.mPlayer.Play("~/somefilename.mp4");
      };
      this.mPlayer.VideoExited += delegate(object sender, MplayerEvent e) {
        this.Close();
      };
    }
  }
}

While GStreamer more complete solution by far, I found MPlayerControl infinitely easier to use and setup.

End-to-end Encryption

Illustration

Well, with all these NSA revelations it had to happen. Not only that Google is thinking about easing encryption in GMail but we got a pretty nice early code drop in a form of a Google Chrome extension.

Extension is called End-To-End and it will help you use OpenPGP encryption for your e-mails. Since it is a really early code drop, Google intentionally made it a bit difficult to install. First of all, you’ll need to compile thing yourself.

For that you would need any Linux machine (e.g. Mint 17). Step-by-step instructions are really good and work flawlessly after you install Git and Subversion:

sudo apt-get install git
sudo apt-get install subversion

After going through all steps, the extension is ready for deployment under /end-to-end/javascript/crypto/e2e/extension. To load it into the Chrome, go to Tools, Extensions, Load unpacked extension. I all went good you will see an additional icon next to the address bar.

Click on that icon will allow you access to Options where you can import key if you already have one (RSA or ECDSA). If you don’t have a key, you can provide your e-mail have one created (only ECDSA). From that moment on you can create a new message by clicking that same magical button.

Currently extension is not really polished. Sending mail still requires a few manual steps, e.g. opening mail window yourself, decryption is not automatic, there is no public key lookup… but this is still probably best solution I have seen for a web mail. Best of all, it works with essentially any web mail - not just GMail.

While there is still a lot of work remaining to make this a comfortable solution, first steps are promising. Mail encryption is a bit hard by design but I could see myself explaining all necessary steps to someone with basic computer knowledge and having them send encrypted e-mail within minutes. To me that means that biggest issue is resolved. All other stuff is just an icing on the cake.

P.S. Those who don’t have a Linux machine (or don’t want to deal with compile) can download unpacked extension here. But do notice that this extension is alpha and I probably won’t bother updating these binaries as the source gets updates.

[2014-12-17: Project source is now available on GitHub.]

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.]

Android X86

Illustration

My Android phone has died on me last week. Suddenly I had an issue. Bunch of stuff I had on it was not available anywhere else. Not on Windows and especially not on crusty Nokia 6300 I used as a replacement. I had to get another Android. My choice fell onto running Android x86 in VirtualBox.

First step was creating virtual machine. Upon creation I selected Linux 2.6, increased memory to 1024, and got 8 GB disk ready. After machine was created, I disabled absolute pointing device (System) and changed network adapter type to PCnet-FAST III (Network).

I started machine with Android x86 live CD (android-x86-4.3-20130725) and went for installation. There I was met with slightly annoying partition creation (New, Primary, Bootable, Write, Quit) and disk format selection (ext3). I installed GRUB and went for writable system partition. One reboot later (don’t forget to remove DVD) and my new Android device is ready.

Before I could do anything I had to go to Machine menu and disable mouse pointer integration (; remember host key for exit) in order to click-through setup options. And then I noticed that my network wasn’t working and screen was a bit weird size-wise. So I rebooted and selected Debug mode upon next boot.

There I went on to edit /android/system/etc/init.sh (remember vi) and I added new line with netcfg eth0 dhcp near the end (just before return 0). For fixing up graphics, solution was in editing /mnt/grub/menu.lst (vi again) and appending vga=842 (34A) to kernel line. This gave me resolution of 1152x864x16 and that one worked perfectly for me.

Short reboot later (reboot -f) my new Android was ready.

Setting Up Private Internet Access on CentOS 6.4

Illustration

I am a big fan of Private Internet Access. It gives you anonymous and secure connection to Internet. I personally value my privacy and thus I find such VPN service very valuable.

Under Windows and huge variety of alternate platforms (Android, iOS, Ubuntu, …) installation is very simple and it hardly ever fails. But some platforms don’t come with instructions. Unfortunately one of them is CentOS. Fortunately, setting it all up is not that hard.

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 System, 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 (Private Internet Access 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

CentOS repositories are not known for their extensive software collection. But we can always add a repository of our choice:

wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -Uvh epel-release-6-8.noarch.rpm

This repository has OpenVPN package that we need:

yum install openvpn

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/US\ Midwest.ovpn /etc/openvpn/client.conf
echo "auth-user-pass /etc/openvpn/login.pia" >> /etc/openvpn/client.conf
echo "username" > /etc/openvpn/login.pia
echo "password" >> /etc/openvpn/login.pia

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

service network 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
chkconfig openvpn on

And that is all.

CentOS 6.4 and VirtualBox Additions

When you install CentOS 6.4 in VirtualBox, quite quickly you might be annoyed by a lack of a mouse integration. Usual cure in form of VM guest additions simply fails with

Building the main Guest Additions module   [FAILED]

Fortunately this message comes with some additional information which points to lack of compiler and kernel headers. Easiest way to install them is in terminal:

su - root
yum install gcc
yum install kernel-devel-`uname -r`

After this you can retry guest additions installation and you should see better results.

PS: This method probably works for RedHat also.