May 15, 2014

Consolidation With The Intel NUC

  

NUC-01

As readers of this less-than-often-updated blog are aware, I used my Raspberry Pi in conjunction with an old Linkysys WRT54GL wireless router into a wireless hotspot, complete with its own SMS gateway with the help of a 3G dongle. It worked flawlessly and I did receive emails and comments about how good the guide was (given the amount of detail and inate rambling, it better have been!). On top of that little bit of hardware, I also had an old Windows 7 laptop which was consolidating all the video cams in my home into a single web interface by means of a software called WebcamXP, which is a webcam monitoring tool. Its pretty neat in the way it allows users to specify URLs to their cameras for still shots and then strings them together to form a motion JPG or MJPG for a stream. The reason I used Windows 7 was because the software is purely Windows based. Linux has “mjpg-streamer“, which has two modes, a full video stream and also allows for still images to be taken at any point of time. Reloading the stills very rapidly would form an MJPG stream (like flipping pages of drawings to form a crude animation), pretty much the same thing WebcamXP does but I was too preoccupied with other stuff to actually write the script to reload the stills and also customize the webpages to give the same user interface. Why did I need the same interface? Well because the wife uses the system to view the cams as well and lets just say the less changes I have to instruct her to go through, the better it is for everyone. On top of this, I also had a simple file server running on the Windows laptop where I’d store cartoons and kid’s movies and stuff in lower quality MP4 format (separate from my very high quality mkvs in my DLNA NAS) for my son to stream to his iPad using the older AirVideo Server (AVS) software or played directly to the 55″ LG HDTV (yeah super cool, super big monitor) to which it was hooked up. The AirVideo Server, for all intent and purpose was also a Windows only software.

So the Pi was in my study, the laptop was in the TV console and I had two external USB drives hooked up to the laptop which served to store the cartoons and kid’s movies. Not a very pretty setup let me tell you (but tolerable since everything is hidden behide cabinet doors). Basically I had two very under powered devices, which served their purpose but the need to declutter eventually arose, so I had to look into consolidating the hotspot, webcam monitoring and the file server into a single device. Of course the unified machine would run Linux and be sufficiently powerful enough for the three tasks but also sufficiently powered for me to experiment and do projects on – something I couldn’t really do with the Pi. Don’t get me wrong, the Pi is a great little tool, but for heavy coding and projects, you just need something more powerful. I also needed something relatively small, that could fit inside the TV console, hidden from sight, with a sufficiently good BlueTooth range so I could use a wireless keyboard/trackpad to control it while lounging on the sofa 12 feet away.

After considering all the options, I decided to get an Intel NUC (Next Unit of Computing). I was gunning for the i3 version but the need to be some what future proofed steered me towards the i5 version. Now there are two i5 NUCs, one with a built in SATA connector and drive tray (D54250WYKH) for hooking up an internal 2.5″ disk drive (main disk is an mSATA SSD) and one without D54250WYK. The cost difference was actually quite significant, in the range of about S$200. On top of that I’d still need to get memory and a wireless combo card as the system comes bare. So with wanting to keep costs down, I decided to get the one without the internal SATA – after all I could still hook the USB drives to the many USB 3.0 ports the NUC had. I headed off to Sim Lim Square to see what kind of offers were up for grabs and heres where things get a little fortunate for me. On browsing the shops to compare prices, I came across one shop which had the D54250WYKH for the price of D54250WYK and they were also throwing in a Wireless N/BT combo card for free. I enquired twice on the price wanting to make sure the offer was right, and it was! I didn’t hesitate and got the system immediately with 4GB of memory (thing to note with the NUCs, you need _low_ powered memory – the system won’t even boot if you use regular memory). I later found out that the shop had misprinted the price of the item, but hey – all good for me!

NUC-02

So with the machine settled, I had to decide on the flavor of Linux to run and since I’d be coding and experimenting, I wanted an OS with a good package management system as I didn’t want to waste time on building dependencies for stuff that I needed. That meant almost immediately, that Slackware was out. Slackware is what I call the grand-daddy of the Linux flavors as using it teaches you about the inner workings of the Unix system. If you’ve grown up on Slackware, there isn’t a Unix system out there you can’t handle. Unfortunately, this familiarity comes from having to compile and build almost every single thing from scratch. It doesn’t have a good package management system because even if you do build Slackware packages, each of the dependencies is a separate secondary package which is not checked for when the primary package is being installed, unlike Debian’s apt-get or Red Hat’s yum. Slackware is a great teaching tool and its good hacker’s console, but its time consuming. Ubuntu is by far the most popular and easily installed (and maintained) of the Linux flavors and they had just released their very next LTS (Long Term Support) version, 14.04, so thats what I went with.

Moving the hotspot stuff with the SMS gateway was trivial, given it was essentially installing all the same packages I used on the Pi’s Debian image on Ubuntu – with a few changes to the PHP scripts and the Apache config (due to changes in PHP and Apache itself with the newer versions). All in all nothing really new from the instructions in my earlier posts, so I’m not going through any of that.

Setting up the fileserver was also trivial, as all it required was installing SAMBA and configuring it to read the 1TB SATA drive I put into the NUC (OS was on the mSATA SSD). Optimizing SAMBA for good read/write however was a different story. Using SAMBA with its default settings over my 500Mbps homeplug (which the NUC was connected to) I was getting like 2MB/s transfers (roughly 16Mbps). As you know, homeplugs never give you the speed at which they advertise, its a theoretical speed. You’ll be lucky to get half of what they advertise, more often than not its (at best) around a third due to interference and other factors. Adding in the overheads of the network protocol, disk write speeds and all,  SAMBA should have been giving me maybe between 12 – 15MB/s. As such, 2MB/s was completely unacceptable. Thanks to the fact that we’ve been optimizing SAMBA at work for some of our backblaze like storage arrays, I had a rough idea what to tweak in the config. For those who don’t do the kind of work I do, you could also Google for optimizations (this is a good read). I made the following changes to the smb.conf:

read raw = Yes
write raw = Yes
strict locking = No
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072
min receivefile size = 16384
use sendfile = true
aio read size = 16384
aio write size = 16384

Immediately I got a 5x boost in SAMBA read/write speeds to about 10MB/s – that’s about 80Mbps, which was at least tolerable if nothing else. That done, I needed to get AirVideo Server (AVS) running on the Linux. Fortunately the makers of AVS had created an java version that ran on Linux and I had actually packaged the whole thing (including all its dependencies, libraries, ffmpeg, etc) as a Slackware package for running on the Linux Live version of Slax. Turns out packaging everything was a good idea, since AVS jar file wasn’t compatible with the newer libraries and installing the old libraries would have definitely broken other parts of Ubuntu. So with the Slackware package I created I isolated all the old dependencies and libraries and the older version of java that would run the AVS jar into a separate directory and configured AVS to start only with those files. Pointed the config to the 1TB SATA drive where I transferred all the cartoons and kid’s movies and fired up the iPad to test and everything was running smooth.

So now, I only had the webcam monitoring system to deal with. Doing actual video streaming is extremely bandwidth intensive and viewing such streams over mobile data can deplete your data plan very quickly. Loading JPG stills rapidly one after the other (such that they appear like a continuous video feed, i.e MJPG streams) takes up significantly less bandwidth. So learning from the way WebcamXP did things, I would have to start the actual video streams locally (internal LAN) while setting up the MJPG stream such that it could be accessed externally (internet).

The “mjpg streamer” software I mentioned above would take care of creating the video streams and the stills without me having to write any code of my own. So I would run mjpg streamer for each camera on a different TCP port (eg: 81, 82, 83 …) using the following:

/usr/bin/mjpg_streamer -b -i "input_uvc.so -d /dev/video0 -f 30 -r 320x240" -o "output_http.so -w /var/www/htdocs -p 81"

Where /var/www/htdocs is any web accessible folder path where the stills are generated. With this, I could access “http://localhost:81/?action=snapshot” and view the still of the video stream at any point in time.

All that was required at this juncture, was to have a proxy like system where some script would take care of reloading the stills and to have a html page (an exact copy of the page WebcamXP uses so I don’t have to change the user interface) pointing to that proxy for the links to each of my cameras. Fortunately for me, real brilliant minds (unlike mine) always come up with these ideas before I do and there was a ready PHP camera proxy solution available. The core of the script is this:

$rand = rand(1000,9999);
$url = '<html link to mjpg streamer still>'.$rand;

$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl_handle,CURLOPT_URL,$url);
curl_setopt($curl_handle, CURLOPT_USERPWD, "EXAMPLEUSER:EXAMPLEPASSWORD");
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);

if (empty($buffer))
{
print "";
}
elseif($buffer == "Can not get image.")
{
print "Can not get image.";
}
else
{
header("Content-Type: image/jpeg");
print $buffer;
}

The “html link to mjpg streamer still” is simply:

http://localhost:81/?action=snapshot

That chunk of code repeats for each camera you have, with only the port number (ie:81) changing corresponding to the port numbers you used for each camera. The code just creates a random number appended to the end of the mjpg streamer snapshot link which forces the image reload and overwrite the old still image with a new one (via curl) to create the MJPG stream. From the code, you can see that one can also individually set passwords for access to the camera. The only downside of this script is that the usernames and password are in plain text, but thats still ok to a certain extent. Now assuming you have named the proxy script “camproxy.php”, to access the MJPG stream of each camera, you would call the following URL from your html page and it would show you the MJPG stream of your cam:

http://localhost/camproxy.php?camera=x (where x is the number of your camera  1, 2, 3…)

Cool stuff and the wife didn’t even know I changed anything!

And there you have it – all neat, all tidy and all consolidated, just the way I like things.

UPDATE 1:
AirVideo Server has a spanking new HD version which has an official Linux version – way to go InMethod!

UPDATE 2:
With my newer Sineoji 600Mbps AV2 homeplugs I didn’t see a significant increase in my SAMBA speeds, was more or less hovering around 80 – 90Mbps, but with my latest 1800Mbps AV2 gigabit homeplugs, I’m getting a cool 160 – 180Mbps with SAMBA.

April 23, 2014

VPNs

  

VPN

That picture up top (which I created from scratch on my own by the way, with a few influences from other sites), is a typical representation of a Virtual Private Network (VPN). Companies very commonly have a VPN for their company network to make sure some semblance of confidentiality and privacy are maintained. So what is VPN?

Have any of you guys watched the early 70s show Hogan’s Heroes? Its a show about a group of allied soldiers in a German Prisoner of War (POW) camp who are there by choice. They have a massive underground operation to sneak plans in and out of the camp and bring other allied pilots shot down in and out of the camp while arranging for them to be rescued. The leader of the group, Col. Robert E. Hogan, and his band of misfits regularly exit and renter the camp through a series of tunnels which have been built from the outside into the camp, which are so expertly hidden, secured and fortified that only the ones who built them, know anything about them and accessing them.

So now think of your company as the POW camp and you and your other colleagues are Col. Hogan and his team. You guys need to get in and out of the camp so you create tunnels from the outside to the camp. These tunnels bypass any of the fences and walls that keep folks out of the POW camp and keep camp activities from being seen by people on the outside. The tunnels become an extension of the POW camp grounds.

So when you create a VPN connection to your company, what you’re essentially doing, is creating a secure tunnel that extends the company network to where ever you are. So long as the connection is active, its like you are virtually in the company network, even though you’re no where in the company. You have access to company resources, files, servers, etc which you wouldn’t have access to once you plug your laptop out of the ethernet connection at your office. Most folks think VPNs only protects confidentiality and privacy, but on top of that, there is networking aspect which is often ignored.

Lets touch on that network aspect first. As you may or may not know, the current implementation of IP addresses (aaa.bbb.ccc.ddd), IPv4 is fast running out, so you can’t issue a public IP address to every single network entity you have. You want to save the public IPs for resources that should be accessed by the general public, for example, your website or your public FTP server and use private IP ranges (eg: 192.168.x.x, 172.28.x.x, 10.0.x.x) for all the other devices. In some cases, where one only has a single public IP (there are companies like this, trust me, I know), what is done is to use Network Address Translation (NAT) to map several private IP addresses to that one public IP. This is called One-to-Many NAT.

Having a VPN allows you have private IPs for your company resources that don’t need to be public, but still allow employees outside the company walls (eg: overseas on official visits, on holiday, etc), access to those resources. It also allows for one to bypass firewalls in certain counties – China for example, where access to Google and Google services has been completely cut, companies who have switched their company email to Google Apps email, have no access until they activate their VPN. Doing so, their internet traffic is routed back through their company network and then to Google, rather than through whichever ISP in China they are connected to in which case traffic gets blocked. I recently explained this concept to a friend who was in China and who couldn’t for the life of him get his emails and he very predictably responded “Oh, but I though VPN is for security?” – yes it is for security, but as explained, not only security. Speaking of which, lets get to the security aspect of VPNs.

Looking at most implementations, you’ll find at least two prominent types of VPN connections, PPTP and L2TP/IPSec and folks have been using them for years, blissfully ignorant of just how secure they really are – afterall, if the company swears by it, then it must be good right? Wrong.

Since the Snowden reveal, there’s been a lot said about just how secure security is, especially since government agencies have been chipping away at the integrity of the protocols used for decades allowing them to read in transit what is supposed to be unreadable.

There are several reviews on the types of VPN available these days and just how secure they are (BestVPN has a good article, though there are some inconsistencies, but none the less its a good read). I won’t reiterate whats in the article or dozens of other articles, but the long and short of it is, PPTP and L2TP/IPSec isn’t as secure as its supposed to be.

If you’re going to implement a PPTP solution, then its not for security purposes, but mainly for network access to a private resources. The script on this blog should get one up and running without even needing to understand much, though the explanations are all there if you’re interested:

Jesin’s Blog – Setting up a PPTP VPN Server on Debian/Ubuntu

L2TP/IPSec should only be implemented for non-critical data, data that you want private and folks won’t spend more than 5 minutes trying to decrypt. This is because the IPSec encryption has potentially been compromised by the various governments (curse you governments!).  If you want to set something like this up, download the setup script (for Ubuntu) here:

Setup a simple IPSec/L2TP VPN Server for Ubuntu and Debian

If you want to use L2TP/IPSec, consider using the Internet Key Exchange v2 (IKEv2) IPSec tunneling protocol. Its offers a lot more security than your standard IPSec. Setting this up on Ubuntu is typically a matter of installing StrongSWAN over LibreSWAN (see here).

All things considered (availability of clients, security, etc) your best bet would be to setup an OpenVPN server, which offers extreme security and multiple encryption algorithms. Its basically what most commercial VPN vendors and a lot of companies are switching to these days anyway. The drawback is having to download a 3rd party client and custom built profiles. Setting up the server, isn’t trivial either. Instructions can be found here (pertains to Ubuntu 14.04, but its generic enough for most distros):

How To Set Up an OpenVPN Server on Ubuntu 14.04

Of course you could also spend a couple of thousands and get a commercial, dedicated VPN appliance, but unless you’re running your own business and have lots of corporate secrets worth millions and millions, I don’t figure its a practical idea (if you had millions, you wouldn’t be on my site anyways).

However if you’re a typical home user that just wants simple security of non critical data or basic access to your home network from outside, you now have my take on VPNs. You want to set one up, make sure you know what your needs are. Don’t go tearing your hair out trying to implement OpenVPN or IKEv2 when all you need is access to your home network from outside – PPTP is all you need and you can have that up and running in under 5 minutes. For a security concerns, as long as you don’t intend to go to battle with certain governments, the default L2TP/IPSec implementations are find (also easily setup in under 5 minutes).

As with everything else, know what your goals are before you implement anything.

June 30, 2013

An RPi SMS Gateway

  

e303

After the implementation of my email account sign up system on my Raspberry Pi hotspot system, I decided to go out and get a Huawei 3G USB dongle and together with my 2nd SIM card (on the multisim plan), I built the SMS gateway right onto the Pi itself. I’ll be the first to admit, I can get a little bogged down doing research before I buy anything, but this time I did it on a whim and ended up with the Huawei E303 – purchased for a reasonable price of S$55 at 4am from everybody’s favorite Mustafa Center. There were other 3g modems there, primarily from Prolink and Vodafone, but they cost twice as much as the Huawei one did.

In anycase, this E303 is a multipurpose USB device, meaning that it has 2 functions – firstly its a 3G modem and secondly, its a storage device (it has an internal storage by itself and an expandable storage via a microSD slot). So depending on how your system scans the device, it may or may not allocate the 3G functionality to it. With the newer devices, it detects the 3G rather effortlessly, but if life wants to throw you lemons, it will detect the device as a USB storage device. Thats where things get a little painful.

You essentially have to change the USB mode from storage device to 3G modem using usb_modeswitch. Simple enough one would think. Not in the slightest. The usb_modeswitch requires you to provide the vendor and product id of the device in the storage mode and the vendor and product id you want it to change to (as the 3G modem). The lsusb command can give you the ids at the storage mode quite easily, but you’ve got to go to Google to find out the ids at the 3G modem mode.

And this isn’t the end of it – the power to the device seems to also play a part. When I connected the Huawei directly to the Pi, no matter what I did with the usb_modeswitch, it refused to change. A bit of reading confirmed what I was beginning to realise, that the modem function actually required more power than the Pi’s USB ports could muster. A typical ‘B’ device (512MB Ram 700MHz) Pi puts out 100mA per port, while the 3G modem needs considerably more. That being the case, without sufficient power, the system would never detect the 3G modem and create the device nodes for it.

Solving the power issue was simple enough – I connected a powered USB 2.0 hub to the Pi and powered the Pi via another power adapter dishing out 1A of current. So I basically had 2 power supplies – one for the Pi and one for the hub. With this setup, the 3G modem was detected easily over the storage and I was a happy camper, even though it took me well over 8 hours to figure things out – trial and error takes time. By the way, if you keep getting switched back to storage mode because you plug the dongle into different ports of the USB hub, just unplug and replug the dongle into that same port of  the USB hub. That should have it switch back to modem mode. After which it should always detect the dongle in modem mode. I’m still looking for a software way to do this, since the usbreset codes I found don’t help, at least for the Pi – they seem to work fine on my standard Ubuntu and Slackware though.

With the device detected properly, it was a matter of installing a 3G controlling software. There are 2 to choose from – gnokii and gammu. By far, gammu is the superior of the two and it doesn’t install a lot of junk that I don’t need the way gnokii does. Its a whopping difference of 156MB for gnokii (on my system) compared to 759KB for gammu (there are a lot of gnome dependencies and stuff that gnokii needs).

The gammu software also comes with a handy curses based configuration tool gammu-config which creates and allows you to setup the most pertinent options in the gammu config file. Install gammu via apt-get:

root@raspberrypi:~# apt-get install gammu
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  wammu gammu-doc
The following NEW packages will be installed:
  gammu
0 upgraded, 1 newly installed, 0 to remove and 95 not upgraded.
Need to get 0 B/322 kB of archives.
After this operation, 759 kB of additional disk space will be used.
Selecting previously unselected package gammu.
(Reading database ... 39205 files and directories currently installed.)
Unpacking gammu (from .../gammu_1.31.90-1_armhf.deb) ...
Processing triggers for man-db ...
Setting up gammu (1.31.90-1) ...

Get the port your modem is connected to by checking dmesg:

root@raspberrypi:~# dmesg |grep tty
[    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=1680 
bcm2708_fb.fbheight=1050 bcm2708.boardrev=0xf bcm2708.serial=0xb2a882a3 
smsc95xx.macaddr=B8:27:EB:A8:82:A3 sdhci-bcm2708.emmc_clock_freq=100000000 
vc_mem.mem_base=0x1c000000 vc_mem.mem_size=0x20000000  dwc_otg.lpm_enable=0 
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 
rootfstype=ext4 elevator=deadline rootwait
[    0.000000] console [tty1] enabled
[    0.576921] dev:f1: ttyAMA0 at MMIO 0x20201000 (irq = 83) is a PL011 rev3
[    0.887032] console [ttyAMA0] enabled
[    8.236054] usb 1-1.2.4: GSM modem (1-port) converter now attached to ttyUSB0
[    8.432593] usb 1-1.2.4: GSM modem (1-port) converter now attached to ttyUSB1
[    8.625152] usb 1-1.2.4: GSM modem (1-port) converter now attached to ttyUSB2
[ 4182.867673] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[ 4182.875577] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[ 4182.878408] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2

In this case you can see there are 3 options ttyUSB0, ttyUSB1 and ttyUSB2.

Run gammu-config and setup the configuration file using any of the ttyUSB* values (you can take the defaults for the rest):

gammu-config

Then run gammu –identify to see if you can pick up the device’s IMEI number (values have been masked out for obvious reasons):

root@raspberrypi:~# gammu --identify
Device               : /dev/ttyUSB2
Manufacturer         : Huawei
Model                : unknown (E303)
Firmware             : 11.126.25.00.00
IMEI                 : xxxxxxxxxxxxxxx
SIM IMSI             : xxxxxxxxxxxxxxx

If you get a message along the lines of “phone not connected”, then fire up gammu-config again and try the other ttyUSB* values shown in the dmesg till gammu identifies your device.

After that its a matter of sending off the SMS as follows:

root@raspberrypi:~# echo "Test SMS from RPi SMS Gateway" | gammu --sendsms TEXT +65xxxxxxxx
If you want break, press Ctrl+C...
Sending SMS 1/1....waiting for network answer..OK, message reference=67
root@raspberrypi:~#

Now sit back and wait for the SMS to arrive.

sms

From here it was basically a modification of my hotspot signup scripts to have the user key in their mobile number (local numbers only) and remove the ‘desired password’ section completely.

hotspotsignup

Now when the user signs up, the system will:

  • Send me an email to ask me to authorize adding the user (via a URL link in the mail)
  • If I authorize the user’s request by clicking on the link in the email, the system will automatically add the user’s mobile number (without the country code) as the username to the radcheck table of the radius database and generate a random password which will be encrypted and also added to the radcheck table of the radius database
  • The random password will then be SMS-ed to the users mobile number and the expiry counter gets started
  • Once the expiry counter is over, the system will send the disconnection packet to the wireless router to disconnect the user and then remove the username (mobile number) and password from the radcheck table

If theres any abuse, I’ll have the users mobile number to follow up with. Pretty good way to make use of my many free SMSes, left over every month from my mobile plan because, seriously – who uses SMS anymore?

If you’re trying this out yourself and run into any problems, drop me a line and I’ll see what I can do to help. Setting up a hotspot is a brilliant learning exercise, so despite the frustrations that may occur from time to time, try and have fun – Cheers!

UPDATE:

With regards to using software to ‘unplug and replug’ the modem, I got the usbreset working. My own lack of common sense – I was trying to reset the individual port the modem was on when I should have been resetting the hub.

root@raspberrypi:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 005: ID 12d1:1446 Huawei Technologies Co., Ltd. E1552/E1800/E173 (HSPA modem)
root@raspberrypi:~# gammu --identify
Error opening device, it doesn't exist.
root@raspberrypi:~# ./usbreset /dev/usbdev1.4
Resetting USB device /dev/usbdev1.4
Reset successful
root@raspberrypi:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 007: ID 12d1:1436 Huawei Technologies Co., Ltd.
root@raspberrypi:~# gammu --identify
Device               : /dev/ttyUSB2
Manufacturer         : Huawei
Model                : unknown (E303)
Firmware             : 11.126.25.00.00
IMEI                 : xxxxxxxxxxxxxxx
SIM IMSI             : xxxxxxxxxxxxxxx

Instead of resetting Bus 001 Device 005 (the modem port), I needed to reset Bus 001 Device 004 (the hub). The reason it worked on my Slackware and Ubuntu setups, was because the modem was connected directly to the laptop’s usb ports and not through a hub. Another lesson learnt!

June 26, 2013

Pi Job – Part 3

  

And we’re down to the last part of setting up your Raspberry Pi as a radius authentication server and together with a compatible wireless router, building your own private hotspot.

Hotspot login script

What is the hotspot login script?

hotspotlogin

Well what it is, is a script (in shell or perl or php or any other language that suits you) which handles the entire login and authentication process to your radius server and it gives you the login page similar to whats shown above. There are lots of guides to write one of these, but I prefer not to reinvent the wheel, so I just lifted the default hotspotlogin.cgi from Chillispot. Chillispot was the foremost hotspot solution available but its all but defunct now, with the author having completely vanished and development taken over by CoovaChilli. You can get the hotspotlogin.cgi by downloading the source code from the CoovaChilli website and after uncompressing the tar.gz file, the hotspotlogin.cgi is in coova-chilli-x.x.x/doc/ where x.x.x (mind out of the gutter!) is the version.

Place the hotspotlogin.cgi into /var/www/cgi-bin and make sure its executable. You only need to edit two things in the file:

$uamsecret = "theuamsecret";
$userpassword=1;

The uamsecret is yet another phrase to link your wireless router to your hotspot, so remember it as you’ll need it later when you configure your router.

If everything is setup correctly, and you try to use your browser to get to the hotspotlogin.cgi page (eg: http://192.168.1.20/cgi-bin/hotspotlogin.cgi) you should be greeted by a failure message:

loginthruhotspot

It essentially means you can’t just browse directly to the login page, you need to associate through your wireless router to get to it. Why? Well remember, this isn’t a page that should be accessible from anywhere by anyone on any machine unless its for the specific purpose of validating their credentials so that they can connec to the internet from your network.

Configuring the wireless router

Hotspot configuration

Not all wireless routers come with a hotspot function and infact you’re going to be hard pressed to find a SOHO wireless router or AP  that actually does. The last wireless APs that came with a hotspot, as far as I tinkered with, was the 3 Com Office connect series, which, if memory serves, had its own built in hotspot login  (so there was no need for one to configure their own webserver) . These APs however, cost a bomb which I don’t think you want to spend on a simple SOHO setup. The cheap alternative is to get a simple home router, like the Linksys WRT54G series (I use the WRT54GL) and overwrite the stock Linksys firmware with Tomato, DD-WRT or OpenWRT. I’m not going to go into the installation of DD-WRT , etc because there are so many tutorials on how to do it already, especially on the individual sites themselves. If you’ve managed to get this far with my posts, then installing the firmware into the router would be a breeze. What I will cover is how to fill up the essential parts of the hotspot config.

The configuration for the hotspot can be seperated into core, networking and captive portal sections. In a lot of hotspot implementations these days, the core and networking sections will be merged amd some (like DD-WRT) have only a single section encompassing all three.

Core

The core portion takes care of the client machines that connect to your hotspot and basically takes information on the following:

  • DHCP
  • DNS

For the DHCP portion, the system needs to know what network you want your clients to be on. Your home network might be 192.168.1.0/24, so to ensure complete separation from your clients and home network, you can have them be on 192.168.120.0/24 . The DHCP portion may also you how long you want the IP assigned to a client to last for (if not renewed) before it allows some other client to grab it – this is called the DHCP lease. For a hotspot, 600 seconds is more than enough.

On the DNS portion, you’ll need to decide which DNS servers you want your clients to be referred to for resolving addresses (URLs for example). This all depends on what your purpose for the hotspot is. If you want to restrict all your client to only say Google – you can setup your own DNS server (using DNSMasq for example) and configure every resolution to point to Google’s IP. Of course, the clients could very easily set their machines to point to very specific DNS servers, so I find that specifying public DNS servers (like Google’s DNS) is a much better option.

Networking

You might be wondering why the core section’s DHCP and DNS settings are not in the networking portion. Well thats because the networking here is referring to the radius server’s networking options. Key parts here would be:

  • Radius server (IP)
  • Radius secret

The radius server is the IP address of your radius server – in this case, its the IP address of your Raspberry Pi box. Some configurations will ask for a second radius server, but since you have only one, just leave it blank.

The radius secret is nothing more than the secret pass phrase you set up in your Free Radius clients.conf

root@rpi:/etc/freeradius/# cat clients.conf
client 192.168.1.0/24 {
        secret          = thisismysecretphrase
}

In this case, the radius secret is “thisismysecretphrase”. There might also be some port settings, but unless you changed the ports in the radius server setup, you should be able to leave these as the default values.

Captive Portal

The last section relates to the webserver where your hotspotlogin.cgi is and tells the hotspot that for all unauthenticated network requests, send the client to this webpage. Now this only redirects web traffic, so if the client is trying to do SSH, FTP, etc they will just time out cos the packets won’t be allowed out. They have to open a browser and try to go to some URL so they will get redirected to the login page. What you have to fill in here is:

  • UAM server (URL)
  • UAM secret

Before you ask, UAM stands for Universal Access Method and its a common wifi term used to depict the process of using a web based login to gain access to a network.

The UAM server is the full URL to your hotspotlogin.cgi. From the previous posts, we know that in this write up it would be https://192.168.1.20/cgi-bin/hotspotlogin.cgi. Fill in your own IP and location of the hotspotlogin script as appropriate and don’t forget its https and not http.

The UAM secret is what you defined in your hotspotlogin.cgi. In this write up, all the way at the beginning of this post, you can see the UAM secret was set (boringly) to “theuamsecret”.

Now some captive portal settings may also have options for:

  • UAM allowed
  • UAM any DNS

The UAM allowed lets you set specific IPs or addresses that can be fully accessed without a client needing to be authenticated. Like how some hotspots irritatingly let you do a Google search but won’t let you click on any of the found links without authenticating.

The UAM any DNS is usually a checkbox and when checked allows users to specify their own DNS servers. Remember under the DNS portion of the core section I mentioned that clients may specify their own DNS servers to bypass using your defined DNS servers? Well this basically allows or disallows them to do that. Uncheck this, and all clients will need to use your defined DNS or nothing gets resolved. This is actually a dangerous part of hotspots – a hotspot owner can very easily setup a rogue DNS that redirects bank or mail server URLs over to his replica sites and steal information. This is one reason you never do online banking over hotspot wireless. Since we don’t want to do anything nefarious (I hope you don’t), you should always allow clients to use their own DNS servers and always set your DNS servers to trusted  public DNS servers.

Last but not least, make sure you run Chillispot or CoovaChilli with “–coaport <port number> –coanoipcheck” arguments. Some web management portals (like DD-WRT) have these options there for you to edit, others don’t, and if they don’t, then you’ll have to ssh into the router and put it directly into the startup file in the /etc/init.d directory. Not advisable to put it into the config file, since you don’t know exactly how the file gets re-written everytime you make changes from the web management portal. If it just replaces sections of the file that have been changed, thats fine, but if it rewrites everything (which is most likely the case), then you’ll lose those options everytime you make changes from the portal.

So what is this CoA thing? It stands for Change of Authorization and enables RFC 3567 which allows radius clients (like Chillispot or CoovaChilli) to accept disconnect packets through a predefined UDP port and only from the radius server it is configured with, unless its specifically told (via the –coanoipcheck option) to accept the packets from any server, to knock users off the internet. Handy when the expiration time has run out. The disconnect packed does a clean up of the accounting information for the particular disconnected user too. If this not done, essentially even after you’ve deleted the user from the database, they will still be able to connect to your system. Its all in the way radius sort of caches what it does for previous logins – long winded and really boring. If you’re interested, go Google it. There is no real default port for the CoA, but typically UDP port 3799 is used, so make sure you open that port on the radius client. For a typical OpenWRT router, find the /etc/firewall.users or rules file and add:

iptables -t nat -A prerouting_wan -p udp --dport 3799 -j ACCEPT
iptables -A input_wan -p udp --dport 3799 -j ACCEPT

You can add the above either through direct edtiting (OpenWRT/Tomato) or via the web interface (DD-WRT). Might be important to note that the latest versions of OpenWRT don’t have a web interface module to Chillispot or CoovaChilli. That means you either go with the old version (Kamikaze 7.09 – the last version with the web interface) or you manually edit config files to setup all the above information. A good guide (using CoovaChilli) can be found here

At this point, you’ve got everything set up for your hotspot to work, and you can manually create users into the radcheck table of the radius database in your MySQL server to get your authentication going.  You could write a simple script to do this, for example in perl:

#!/usr/bin/perl

# First argument  is the username, second argument is the password

use DBI;
use Crypt::Passwd;

my @chars = ("A".."Z", "a".."z", "0..9", "-", "_","\!","\@");
my $pwsalt;
$pwsalt .= $chars[rand @chars] for 1..24;

# Generate encrypted password with the username as the salt
$pwd = unix_std_crypt($ARGV[1], $pwsalt);

# Connect to MySQL database and add the user
$dbh = DBI->connect('dbi:mysql:radius','radius','myr4d1u5p455');
$sql = "insert into radcheck VALUES (NULL , '$ARGV[0]', 'Crypt-Password', ':=', '$pwd')";
$sth = $dbh->prepare($sql);
$sth->execute || die "Could not execute SQL statement on Password... maybe invalid?";

$dbh->disconnect;

Save that as some filename, say hsadduser, make it executable and run it giving it a username and password:

root@rpi:~# chmod +x hsadduser
root@rpi:~# ./hsadduser johndoe johndoepw

Log into MySQL and check the table:

mysql> select * from radcheck;
+----+----------+---------------------+----+---------------+
| id | username | attribute           | op | value         |
+----+----------+---------------------+----+---------------+
|  1 | johndoe  | Crypt-Password      | := | tepjTqyjw.F6. |
+----+----------+---------------------+----+---------------+
1 rows in set (0.00 sec)

Similarly for deleting entries:

#!/usr/bin/perl

# First argument  is the username

use DBI;
use Crypt::Passwd;

# Connect to MySQL database and delete the user
$dbh = DBI->connect('dbi:mysql:radius','radius','myr4d1u5p455');
$sql = "delete from radcheck where username='$ARGV[0]'";
$sth = $dbh->prepare($sql);
$sth->execute || die "Could not execute SQL statement on Password... maybe invalid?";

$dbh->disconnect;

Of course I have my users created dynamically from a sign up web page, but the scripts above are a basis from which dynamic user creation (and removal) can be done.

You could easily merge the above 2 scripts into a single script using functions and an argument call to determine if its a add user or delete user request like so:

#!/usr/bin/perl

use DBI;
use Crypt::Passwd;

$rdb = "radius";
$rrt = "radius";
$rpw = "myr4d1u5p455";

sub rad_adduser {
my @chars = ("A".."Z", "a".."z", "0..9", "-", "_","\!","\@");
my $string;
$mysalt .= $chars[rand @chars] for 1..24;

# Generate encrypted password with the username as the salt
$pwd = unix_std_crypt($ARGV[1], $mysalt);

# Connect to MySQL database and add the user
$dbh = DBI->connect("dbi:mysql:$rdb", $rrt, $rpw);
$sql = "insert into radcheck VALUES (NULL , '$ARGV[0]', 'Crypt-Password', ':=', '$pwd')";
$sth = $dbh->prepare($sql);
$sth->execute || die "Could not execute SQL statement on Password... maybe invalid?";

$dbh->disconnect;
}

sub rad_deluser {
# Connect to MySQL database and delete the user
$dbh = DBI->connect("dbi:mysql:$rdb", $rrt, $rpw);
$sql = "delete from radcheck where username='$ARGV[0]'";
$sth = $dbh->prepare($sql);
$sth->execute || die "Could not execute SQL statement on Password... maybe invalid?";

$dbh->disconnect;
}

if (($#ARGV == 2) && ("$ARGV[2]" eq "add")) {
        &rad_adduser;
        exit;
} elsif (($#ARGV == 1) && ("$ARGV[1]" eq "del")) {
        &rad_deluser;
        exit;
} else {
        print "Usage: <progname> <username> <password> [add|del]\n";
        exit;
}

If we save the combined script in /usr/local/bin as radtla (which stands for “radius time limited account”), this is used for adding a new radius user by doing:

root@rpi:~# /usr/local/bin/radtla raduser1 raduser12345 add

And to remove the radius user:

root@rpi:~# /usr/local/bin/radtla raduser1 del

Where raduser1 is the radius username you are trying to add/delete and raduser12345 is the password you are allocating to raduser1.

From here its child’s play to write a simple shell script that on authorization (from clicking a link from an email for example), will run the above combined script to add the user with the supplied credentials to the radius database, sleep for whatever time interval you want and then send the disconnect packet and run the above combined script again but this time to delete the user.

#!/bin/sh

# First argument is the userid and second argument is the password

TIMEINT=3600 # One hour time limit to expire the account
RADTLA="/usr/local/bin/radtla"

# Call radtla to add the account
$RADTLA "$1" "$2" "add"

# Sleep for the time limit
sleep $TIMEINT

# Send disconnect packet to knock user off the internet
echo "User-name=$1" | /usr/bin/radclient -x 192.168.1.20 disconnect thisismysecretphrase

# Call radtla to delete the account
$RADTLA "$1" "del"

If the shell script is called dotla.sh and also located in /usr/local/bin and you want to create a radius user johndoe@jmail.com and password jd12345, then call it with a nohup and push it to the background:

/usr/local/bin/dotla.sh 
root@rpi:~# nohup /usr/local/bin/dotla.sh "johndoe@jmail.com" "jd12345" &

The nohup keeps the process going even if you log out and the & pushes the process to the background so the system can still be used while its waiting for the process to complete.

Let me emphasize that there are a whole load of different ways to implement the addition of user accounts and account expiry. You could write the scripts in php, you could use cron (instead of sleep) to run your expiry script against a log that notes down when the account was created, etc – bottom line is, the scripts and method above are just one way of doing things. It may not be the most efficient or elegant way, but the purpose in this post is to detail, in as much scripting as possible, how it can be done and give the reader a the concept of how to write the functions. From this detailed mess (its a mess of code, I’ll concede that), one can clean things up and find a better way. If you want to be a penny pincher about it, you can even link this to PayPal and make folks pay for using your bandwidth – don’t know how legal that is though.

Also I’m not going to go through how to write a portal page to accept the username and password and integrate the different parts of the script into the portal because if you can’t do that yourself, you shouldn’t be even trying any of this.

So there you have it – your own hotspot with an old router and a Raspberry Pi. Hopefully I’ve not completely confused you and driven you insane, but in the off chance that I have, drop me a line and I’ll be more than happy to help clarify your queries and try to cure your insanity.

Or make it worse.

UPDATE:

Folks have been emailing (why can’t they just leave comments) asking if I have a php solution to all this without as many scripts – yes I do. Its a neat php solution for the portals and the expiry employing cron. Drop me a line if you are really too lazy or inept to write your own solution. Actually with all the spoon feeding above, I’d say just plain lazy.

UPDATE 2:

I forgot to mention, that if you’re going to create a hotspot service, you better make sure you have a set of terms and conditions that users agree to by using your service. You don’t want the authorities knocking on your door claiming you did all sorts of nefarious deeds from your internet connection and dragging you through all kinds of legal formalities when the real culprit was actually someone using your hotspot. Sure, the service is for people you know, but how well do you really know them? Lots of sample T&Cs out there for you to modify for your needs – remember, Google is your friend!

June 26, 2013

Pi Job – Part 2

  

From the last post on turning your Raspberry Pi into a radius authentication server and setting up your own hotspot, I covered installing the webserver, database server and the radius server and then went on to configure the web and database server. Now we’re going to configure the radius server.

Free Radius

The Free Radius configuration gets installed into /etc/freeradius and you should also have a sql/mysql directory in there. If you don’t, then you likely missed installing the freeradius-mysql package.

Inside the sql/mysql directory, you should see a bunch of files including one called schema.sql. You will need to import this file into your MySQL database:

root@rpi~# mysql -u radius -p radius < schema.sql

You will be prompted for MySQL radius user password (which we set earlier as ‘myr4d1u5p455’). Enter it and you should have the necessary tables created. You can then log in to MySQL as the radius user with the password ‘myr4d1u5p455’ and check the imported tables:

mysql> use radius;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;

+------------------+
| Tables_in_radius |
+------------------+
| radacct          |
| radcheck         |
| radgroupcheck    |
| radgroupreply    |
| radpostauth      |
| radreply         |
| radusergroup     |
+------------------+
7 rows in set (0.01 sec)

As you may recall, we want to dynamically add users using a script from a sign up URL later, so there is no need to add users to the Radius server at this point, however we still need to test the setup, so add just one user for this purpose using a clear text password for simplicity (this will change to encrypted passwords for the actual dynamic user addition):

mysql> insert into radcheck (id, username, attribute, op, value) values ('1', 'user1', 'Cleartext-Password', ':=', 'mypassword');
Query OK, 1 row affected (0.01 sec)

mysql> select * from radcheck;
+----+----------+---------------------+----+---------------+
| id | username | attribute           | op | value         |
+----+----------+---------------------+----+---------------+
|  1 | user1     | Cleartext-Password | := | mypassword    |
+----+----------+---------------------+----+---------------+
1 rows in set (0.00 sec)

Now we’re ready configure the radius server. First thing we need to do is edit /etc/freeradius/clients.conf and add in an entry at the bottom for your local network. The provided clients.conf is full of stuff thats mostly commented out with the “#”, so if you’re comfortable working with that mess go ahead, if not I recommend you rename that file to clients.conf.bak and create a new clients.conf and add in the entry for your local network which is actually all you need. Here we assume you are on a 192.168.1.0/24 network which is a fancy way of saying all the machines on your home network have an IP address of 192.168.1.X where X ranges from 1 to 255:

root@rpi:/etc/freeradius/# cat clients.conf
client 192.168.1.0/24 {
        secret          = thisismysecretphrase
}

So now your clients trying to do authentication have supply the secret phrase and they must have an IP on the 192.168.1.0/24 range.

Next check your /etc/freeradius/radiusd.conf and make sure the modules section has an entry for sql:

root@rpi:/etc/freeradius/# cat radiusd.conf | grep -v "#" | grep -A10 "modules {" |sed '/^$/d'
modules {
        $INCLUDE ${confdir}/modules/
        $INCLUDE eap.conf
        $INCLUDE sql.conf
}

Now we need to edit the /etc/freeradius/sql.conf file to add in the necessary information to access your MySQL radius database. Under the sql section, make sure the following are uncommented and correctly assigned:

database = "mysql"
server = "localhost"
login = "radius"
password = "myr4d1u5p455"

Then edit /etc/freeradius/sites-available/default and add sql to the authorize, accounting, session and post-auth sections.

And that should be it – all you have to do now is test the setup. Fire up the radius daemon in debug mode:

/usr/sbin/freeradius -X

The screen should start scrolling pretty fast and you should see it connecting to the MySQL database and start listening on port 1812 for authentication.

FreeRADIUS Version 2.1.12, for host arm-unknown-linux-gnueabihf, built on Dec 19 2012 at 11:55:13
Copyright (C) 1999-2009 The FreeRADIUS server project and contributors.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License v2.
Starting - reading configuration files ...
including configuration file /etc/freeradius/radiusd.conf
.
.
.
rlm_sql (sql): Driver rlm_sql_mysql (module rlm_sql_mysql) loaded and linked
rlm_sql (sql): Attempting to connect to radius@localhost:/radius
rlm_sql (sql): starting 0
rlm_sql (sql): Attempting to connect rlm_sql_mysql #0
rlm_sql_mysql: Starting connect to MySQL server for #0
rlm_sql (sql): Connected new DB handle, #0
.
.
.
 ... adding new socket proxy address * port 40230
Listening on authentication address * port 1812
Listening on accounting address * port 1813
Listening on authentication address 127.0.0.1 port 18120 as server inner-tunnel
Listening on proxy address * port 1814
Ready to process requests.

Fire up another terminal screen and use radtest to test the connection using the test user user1 with password ‘mypassword’ you created earlier and the server secret in the radius.conf of ‘thisismysecretphrase’. If all goes well, you will get an “Access-Accept”.

root@rpi:~# radtest user1 mypassword 192.168.1.20 1812 thisismysecretphrase
Sending Access-Request of id 39 to 192.168.1.20 port 1812
        User-Name = "user1"
        User-Password = "mypassword"
        NAS-IP-Address = 127.0.1.1
        NAS-Port = 1812
        Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 192.168.1.20 port 1812, id=39, length=20

Remember to use the correct IP address (the example is 192.168.1.20) for your server. With this done you can now add freeradius to your service startup so that it auto starts everytime the machine boots (check to make sure freeradius exists in /etc/init.d and it is executable).

The next post will deal with the hotspot login and the configuration for the wireless router.

June 26, 2013

Pi Job – Part 1

  

IMG_00000009

No reference to the ‘American Pie’ movie. Seriously people, get your minds out of the gutter – this is a Tech blog!

A couple of posts back (like 7 or 8 months ago actually) I said I’d let you guys know what I was going to do with my Raspberry Pi which I got for Christmas last year. Lots of ideas were available – turning it into a media server was the foremost suggestion by most folks, but given that I already had my DLNA NAS perfectly setup, that was never an option. Eventually, I decided to use it as a Radius authenticator. And why did I decide that? Well basically because of people streaming in and out of my place and most wanting to use the wifi (a blazing fast fibre connection tends to attract requests like that from my guests). Having gotten tired of keying in the authentication protocols for them, I figured a good use of the Pi would be to have some sort of hotspot authentication going on together with a older Linksys WRT54GL wireless router I had lying around which had been installed with OpenWRT (you can use Tomato or DD-WRT as well with Chillispot or CoovaChilli). I had set this up previously on a Slackware and Ubuntu box so it wasn’t really rocket science but I’ll detail what I did anyway for those looking to do similar.

Now I didn’t want a common name and password that everyone could share around – thats poor security any way you look at it and while I’m not a professional IT security specialist by trade, I still dabble a lot in security (and circumventing it) unofficially (don’t ask, the less you know the less liable you’ll be – call it ‘plausible deniability’ if you want), so it would be embarrassingly idiotic of me to have a common userid/password system in place on anything. While in NTU for work and visits, I noted their SMS system in allowing outsiders to temporarily gain access to their wireless systems and thought it was a good idea. In our little island, every local mobile number must be registered to a real person (as compared to email address which you can create at will), giving me record of exactly who used my system (and essentially someone to blame if there was any abuse). Since I couldn’t find a reliable and viable internet SMS gateway that I could control via CLI, I decided on an email system:

  • the potential user would hook onto my open wireless system
  • the open system would allow them to log in (if they have a userid and password) or go to a  sign up page where they would need to supply a valid email (as their userid) and a choice password.
  • the sign up page would then email me the request and I would click a link embedded in the email to approve/disapprove the sign up
  • after a predefined time period the userid would be removed from the radius server

If you’ve ever administered a mailing list, you’ll see how similar it is to managing users on the list with the exception that the above system has no way to inform the user if their sign up was approved or not (which is why I let them choose their own password). I could send them an email, but there is no guarantee that they have a 3G/LTE connection to receive the email. If I had an internet SMS gateway, I could program things so that the system just takes in the user’s mobile number and on approval for a temporary sign up, will SMS a randomly generated password back to the user’s mobile. Actually I could just build an SMS gateway with the Pi, but I make do with what I have.

Now this is going to be a looooooonnnnnnggggg instructional, as such I’m breaking it up into several posts, so one has to try to keep focused (especially with the long winded way I rant on and on about even the simplest of things).

So here we go – lets get the Pi set up as a Radius server and authenticator. You’re of course going to need the Pi already set up with its base – Raspbian or some server version for the Pi. I suggest the latter since the desktop just slows the whole thing down and you don’t need the desktop at all – you can disable the desktop but theres still a lot of un-needed stuff on Raspbian, so the stripped down server version is the best bet. Make sure your Pi has a fixed IP address and note it down using ifconfig:

root@rpi:~# ifconfig -a
eth0   Link encap:Ethernet  HWaddr c1:02:ca:bd:79:b1
       inet addr:192.168.1.20  Bcast:192.168.1.255  Mask:255.255.255.0
       UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
       RX packets:6398 errors:0 dropped:0 overruns:0 frame:0
       TX packets:1894 errors:0 dropped:0 overruns:0 carrier:0
       collisions:0 txqueuelen:1000
       RX bytes:1162288 (1.1 MiB)  TX bytes:328810 (321.1 KiB)

You can then configure your router to reserve the same IP address for the Pi’s MAC (HWaddr above) – see your router’s manual for more info. If you want to set the static IP from the Pi itself, make sure you know the netmask, gateway and broadcast of your network. Fire up your favorite editor (I use nano) and edit /etc/network/interfaces and change iface eth0 inet dhcp to:

iface eth0 inet static
address 192.168.1.20
netmask 255.255.255.0
gateway 192.168.1.1
network 192.168.1.0
broadcast 192.168.1.255

Those are the network values for my network, so substitute your own. Seriously its a lot easier for the less network inclined to just use the router to reserve a specific IP for the Pi via its MAC address.


The essentials

What are you going to need? Basically a webserver (Apache2), a database server (MySQL), a scripting language to process requests (perl or php – I used perl) and of course the Free Radius authentication server (and its hooks to MySQL)

sudo apt-get install mysql-client mysql-server
sudo apt-get install freeradius freeradius-utils freeradius-mysql
sudo apt-get install apache2 openssl perl

Do note, that apt-get may ask for passwords and stuff while setting up MySQL, so take note of the passwords you supply it with as you’ll need them later.

Configuring the various servers

Apache

Configure the Apache webserver by editing the /etc/apache2/sites-available/default. You can actually safely leave this as what it came as or just add in your proper email address if you want.

Next we need to setup the SSL certs. Reason for this is because the radius auth should happen over an encrypted session.  The hotspotlogin script you’ll be using later will check for an encrypted session and if it doesn’t find one, this (yes, thats my home wireless logo which I designed – don’t go copying it!) is what you’ll get:

useenc

You could make do without an encrypted session and edit the hotspotlogin script to bypass the check, but when you’re dealing with passwords, don’t be an idiot about things, even if its just a home system you’re setting up.

Now when you install openssl, ssl-cert will be installed as well and this gives you a set of self signed certs already (ssl-cert-snakeoil.pem and ssl-cert-snakeoil.key). You can use this if you want or generate your own keys. I’ll go through generating your own just in case:

root@rpi:~# apache2-ssl-certificate

creating selfsigned certificate
replace it with one signed by a certification authority (CA)

enter your ServerName at the Common Name prompt

If you want your certificate to expire after x days call this programm
with -days x
Generating a 1024 bit RSA private key
............++++++
..........................++++++
writing new private key to '/etc/apache2/ssl/apache.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [SG]:
State or Province Name (full name) [Some-State]:Sinagpore
Locality Name (eg, city) []:Singapore
Organization Name (eg, company; recommended) []:MDS
Organizational Unit Name (eg, section) []:
server name (eg. ssl.domain.tld; required!!!) []:rpi
Email Address []: someuser@some.email.address

Then configure the Apache SSL configuration. Most of it will already be in the default-ssl file in /etc/apache2/sites-available and its safe to use whats there, just replace the ssl-cert-snakeoil.pem with the full path of the apache.pem file generated in the step above (if you generate your own cert). Comment out the ssl-cert-snakeoil.key:

SSLCertificateFile    /etc/apache2/ssl/apache.pem

Go to /etc/apache2/sites-enabled and soft link the default-ssl files from /etc/apache2/sites-available to /etc/apache2/sites-enabled with a prefix number (tells the system what order to start up the websites in)

root@rpi:~# cd /etc/apache2/sites-enabled
root@rpi:/etc/apache2/sites-enabled# ln -s ../sites-available/default-ssl 001-default-ssl

Restart apache and you should be able to use any browser to go to https://<your-ip-address> as shown.

https

MySQL Database Server

There isn’t much to do for MySQL. The passwords should have been setup during the apt-get installation already so no worries about that. The initial databases would also have been installed then. Don’t worry about the tables for the users as yet, the schema for that gets set up later with Free Radius.

You will however, need to create an empty database for Free Radius in MySQL called (unsurprisingly), radius:

root@rpi:~# mysql -u root -p -h localhost

You will be prompted for your MySQL root password (which you would have set during the MySQL installation) and after correctly entering it you will be at the mysql prompt where you can then create your database:

mysql> create database radius;
Query OK, 1 row affected (0.00 sec)

Lets now set a user and password to access the radius database – as a matter of security, you don’t want to have the MySQL superadmin root user do this. Create the user and set its permissions – firstly to allow it to connect from localhost with a password and secondly giving it full permissions over the tables in the radius database:

mysql> grant usage on *.* to radius@localhost identified by ‘myr4d1u5p455’;
Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on radius.* to radius@localhost;
Query OK, 0 rows affected (0.00 sec)
mysql> exit;

You may now log in to MySQL as user radius from localhost with the password ‘myr4d1u5p455’.

Setting up the Free Radius server is pretty long, so I’m pushing that to a post all by itself.

UPDATE:

Got a 3G USB dongle and setup an SMS gate way on the Pi itself for a much better temporary user sign up system.

June 25, 2013

PSI Graph

  

psipost1-2

Most people have probably been viewing the NEA PSI website constantly these past few days and for the more statistically inclined, they would probably be wondering why the NEA doesn’t just put up a graph comparison of the various PSI readings instead of their sea of numbers. The answer for most “anti white” camp, is obvious and stems from needing to “confuse the peasants”, but I’ll leave it to you to draw your own conclusions.

In any case, I wrote a quick PHP script (mainly out of boredom) to scrape the readings off the NEA website and employing Google Chart’s API, had the bar chart plotted for their three readings – the 3 hour PSI reading, 24 hour average PSI for PM10 and 24 hour average PSI for PM2.5. The API itself is pretty cool, allowing the user to just input values into an array and call a JS function to plot any type of graph (bar, chart, area, pie, etc).

What do all these readings mean and do we have the right values or standards for determining the air quality? I’m no expert, but this post explains things pretty well.  For  those who want more a modern (better) indication of the air quality and for per hour readings (which NEA is sorely missing and ministers are ignorant about) refer to the AQI and the We/Wear/Masks sites respectively. Its interesting that an NUS PhD student (Jeremy Chen) could come up with a more accurate formula for the PSI readings, but instead of adopting the formula, all NEA can do is argue that their formula is not necessarily worse. Go figure.

All things considered, I would of course advise all not to rely on any readings, but use your eyes and general feel of the environment before venturing out. I stepped outside for less than 3 minutes in what is considered  a “not-so-severe” PSI reading and came back inside with a splitting headache that lasted several hours – not to mention the severe dry throat and tearing eyes.

Stay safe folks!

UPDATE 1:

There have been a few changes since the initial script I wrote, primarily how the different time intervals (hourly, 3 hourly, 24 hourly, etc) have merged to just hourly and the PM 2.5 index has been included into the main reading. As such, now only the average hourly PM2.5 readings from the NEA and AQICN are compared in the graph.

UPDATE 2:

There are several other sites that are quite good for monitoring the PSI situation, in particular, I like this one:

https://www.hazetracker.org/

Its a responsive site (reformats itself on mobile devices),  has a good, easy to understand graphic representation of the situation and some other information on the wind patterns and the Indonesian fires that contribute heavily to the haze. Check it out.