November 2, 2014

Layer X Devices

  

We’re talking networking layers folks! The layers are the subdivisions of the Open Systems Interconnection (OSI) model which characterizes the functions of the communications flow between devices, as shown in the image below.osiSo why this particular topic? As I mentioned, I’ve been busy, mainly with an office and datacenter relocation and few consults for other departments, two of which were very network heavy. If theres one thing I noticed during the many meetings and discussions for these consults, was that a lot of folks (even those who are supposed to be network savvy) have a very unclear concept of the various “layers” that networking devices have. The other thing I noticed, is that those who are clear about them, can’t explain things simply enough for those who don’t understand them, so I want to try and clear things up. Now I don’t profess to be able to simplify things sufficiently either, but lets give it a shot.

Basically the layers in the image represent how, for example, this blog appears on your computer screen.

step 7 (webserver) –[data]– step 1 <—- cable —-> step 1 –[data]– step 7 (browser)

So you request for a html page by typing in a URL on your browser, the browser takes that URL, does its conversion of the host and domain name to an IP and packs the request into a TCP packet and sends it out through your LAN cable and the packet goes through your switch and then to the ISP’s router which tells it which path to take to reach the webserver of the URL you wanted and it reaches another router where the said webserver’s network is connected, gets told to go to a particular switch where the webserver is hooked up to and since it is HTML data you are requesting, it sends it by default to port 80 of the webserver. The webserver then takes the HTML page you wanted and coverts and compresses it into some format, then packs that into a TCP packet and passes that packet back down to the HTTPd port of the webserver, up the switch its hooked onto, back to the router who tells its which path to take to get back to your browser and it will travel to the router  of your home network and down to the switch where your pc (browser) is connected to and your browser will decompress and unconvert it and display it for you to see.

Man that was tiring and confusing. Go read the above paragraph five times, if you haven’t torn your hair off by then,  you probably understand what I’m talking about. Its just a flow, so unless you intend to take an exam on this, don’t worry too much about getting confused. In any case, I only want to discuss 2 particular layers. By the way, if you are intending to take an exam on this, then for goodness sakes, get off my blog and go read a real textbook!

We hardly talk about layer 1 devices in terms of the OSI layer and layer 4-7 devices are typically for select operations (L4 – typically load balancing, L5-6 TCP issues, L7 – application). What interest us IT architects and networking folks is layers 2 and 3 because these are key in how data gets moved about in a network and how to connect various networks together. For example, you can have switches (layer 2) connect your various devices together so they can talk to each other and transfer data to each other, that is considered a “single network” or a LAN. You could set up a few of these “single networks” each with their own switch (creating a few LANs), but how would you make them talk to each other? And thats what your router (layer 3) is for. Each of those “single networks” connected to a router would enable intercommunication between the “single networks”. Based on certain routing tables or other IP logic, data is passed from one network to another.

In a simplistic nutshell:

Layer 2 devices:
– connect machines together to form a LAN
– uses ARP to convert an IP address to a MAC address
– transports data to network port where a machine with the destination MAC address is

In a building-lift analogy, switches are liftshafts, floors of the building are the network ports (which have devices connected to them), passengers are the data. Passengers (data) can go from floor to floor (network ports where devices are connected) to access different units (devices) by traveling though the liftshaft (switch), as shown below.

 lift-switch-analogy-comparison

Layer 2 – Lift Analogy

Layer 3 devices:
– connect different networks (eg: LANs) together
– transports data from network to network, based on destination IP address

Sticking with the lift analogy, the building the lift shaft is in, is your LAN, skybridge(s) are your routers. Passengers (data) can go from floor to floor (network ports) to access units (devics) by travelling through the liftshaft (switch) and if they need to go to a unit (device) in another building (LAN), they will take the liftshaft (switch), head for the skybridge (router), go to the other building (LAN) and then take the liftshaft (switch) of that building (LAN) to get to the floor (network port) of that building (LAN) where the unit (device) is. Yeah I’d be confused too if I wasn’t the one explaining things – just look at the diagram for clarity. Its all pretty simple.

router-lift-skybridge-analogy-2

Layer 3 Skybridge Analogy

We then come to the “Layer 3 Switching Device”. This is all the rage now, as almost every SOHO (Small Office Home Office) “router” is a Layer 3 Switching Device. Why did I put the term ‘router’ in quotes? Because the terminology isn’t quite right. The similarities are there, as explained in the “About Tech” article:

“…a layer 3 switch is a high-performance device for network routing. Layer 3 switches actually differ very little from routers. A Layer 3 switch can support the same routing protocols as network routers do. Both inspect incoming packets and make dynamic routing decisions based on the source and destination addresses inside…”

however there is a clear difference. From the CiscoPress Book, “Cisco LAN Switching“, pages 451-453, authored by Kennedy Clark and Kevil Hamilton:

“…a Layer-3 switch (routing switch) is primarily a switch (a Layer-2 device) that has been enhanced or taught some routing (Layer 3) capabilities. A router is a Layer-3 device that simply does routing only…”

So “Layer 3 Switch” is essentially a marketing term, blurring the lines between the actual definition of layer 2 and layer 3 devices. Actual layer 3 devices make use of hardware, specifically “application-specific-integrated-circuits” or ASIC hardware to achieve its functionality, while the so called layer 3 switches use software to get things done.The useful thing about having software doing things, is that you can bundle other stuff with it, such as QoS, Firewalls and NAT.

So what was the problem with the vendors for our consults? They didn’t know difference between an L2, L3 and L3 switch. Our design called for an L3 switch with NAT, the vendors said they would give us the “Rolls Royce” of L3 switches, which would cover all the bells and whistles like NAT, VPN, vLANs and the like. End of the day, this “Rolls Royce” was nothing more than a “Camry” – an L2 switch with advanced monitoring and ACLs. Guess who had to start screaming at people?

Anyway, I hope the above has given some clarity (if not more confusion) to the difference between the L2, L3 and L3 switch situation – don’t get caught unaware if you’re doing a network design and most importantly, don’t get caught by me!

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 30, 2014

One-To-One NAT and vLANs

  

This is one super long post, but then knowing me and my minutely-detailed-posts, this shouldn’t come as a surprise.

I recently was asked to re-look at the Internet infrastructure of my condo estate and see how we could update it for fibre without too much costs. It was about 11 years old, making use of old 100BaseT equipment and still using an ADSL uplink, a real pain considering  everyone was now on fibre. We had 5 wireless units around the estate, 2 user PCs and a network printer in the management office, a web server and 2 video cam servers to be fed from a single uplink. Now all these devices were already on their own internal vLANs on the old setup which I had put in place some time ago and there was absolutely nothing wrong with the internal setup. All we wanted at this point was to swap the ADSL uplink for a fibre uplink. The issue was that everything was configured through an extremely outdated 3Com core switch and with the new fibre setup, there was no replacement for this, neither was there any technical assistance rendered – all part of keeping things on the cheap (including asking me to design and set things up for free). Basically I wanted this:

dpnet2

Now the ONT and router were provided of course by the ISP, but we had no core switch, neither did we want to spend a couple of thousand on one. So the dilemma was how to get the functionality of a high end switch without spending that kind of money? Answer – don’t. Get a SOHO Layer 3 switch (your typical home cable router) which can be run with some of the more awesome 3rd party firmware like DD-WRT or OpenWRT and get all the functionality you need at a fraction of the price. The functionality I needed was pretty basic, One-To-One Network Address Translation (NAT), Virtual LAN (vLAN) support (didn’t need tagging) and a DHCP server. Now I had a bevy of choices, Tomato, DD-WRT or OpenWRT to name a few and I went with OpenWRT. I’m not a fan of Tomato’s UI and neither was I fond of the haughty attitudes of the DD-WRT developers and also since I had been a user of OpenWRT from it early implementations, I decided to stick with it.

So just a little education first – what exactly was the functionality I mentioned? I’m sure you’re all familiar enough with a DHCP server, thats what dishes out IP addresses automatically to the clients that connect to the network. What about One-To-One NAT and vLAN support and what is tagging (even though it wasn’t needed)?

Firstly, One-To-One NAT is mapping multiple public IPs to multiple private IPs. The common NAT that most of you folks do at home, is to map your public IP address and a port number to a private IP address and a port number. The reason you use port numbers is because you only have 1 public IP address and using different ports are a good way to share that 1 public IP with a host of services you want to run (which obviously run on different ports). When you have a couple of public IPs, you can afford to map the entire public IP to an entire private IP including all its ports. So for example, If I had public IP addresses, eg: 136.130.20.11 – 136.130.20.15 (5 public IPs) I could map each one of those addresses to machines on my private IP range:

136.130.20.11 -> 172.28.1.11
136.130.20.12 -> 172.28.2.12
136.130.20.13 -> 172.28.3.13
136.130.20.14 -> 172.28.9.14
136.130.20.15 -> 172.28.9.15

And when I access the public IP, say 136.130.20.12, it would route all traffic to my machine on my private network with the private IP, in this case, 172.28.2.12.

Now onto vLANs. The vLAN is a virtual LAN. It is a means of segregating a network into distinct network groups, separate of each other without using a physical switch/router. So with 1 switch, you could create a few vLANs and depending on how you configure things, they may or may not be able to see each other and pass data between each other.

If its tagged, it means all data passing through will be tagged with the vLAN’s id. Tagging is primarily used to pass vLAN data across different network devices in more complexed network setups, where, the (for example) the Human Resource vLAN may span different floors and offices and data would have to pass through several edge switches through which data from other vLANs also pass through. The tagging is a means of identifying the data so that it knows how to pass from switch to switch such that (for example) all the machines in the Human Resource vLAN can see and talk to each other.

Again as with my hotspot posts, I’m not going to detail installing OpenWRT, there are tonnes of guides out there and its really not rocket science.

Setting Up vLANs

Now there is already a vLAN setup going with the router, the hardware basically creates 2 vLANs, vLAN 1 for your internal LAN data and vLAN 2 for your WAN data (as far as OpenWRT is concerned anyway). These vLANs are tagged so the processor knows which packets belong to which network (LAN or WAN) and hence how to pass the data. Typically for a 4 port router its this:

openwrt-switch-logical

What we are going to be doing is essentially adding to these vLANs. Also instead of having all (usually) 4 of your LAN ports on vLAN 1, we isolate the ports for different vLANs. So for example, I could have one vLAN for staff machines on port 1 (via a switch), another vLAN for video cameras on ports 2 and 3 and a third vLAN for wireless APs on port 4.

Open up your OpenWRT web UI, click on the ‘Network’ tab, then select the ‘Switch’ tab. You’ll see a graphic representation of the ports on your router. Don’t worry if you see more ports than your router actually has, some versions of OpenWRT don’t pick up the right number of ports. ‘Port 0’ is your WAN Port and ‘Port 1’ is the first of your LAN ports – work your way up from 1 with the number of ports your router has. The last port (CPU Port) is an internal port (not visible on the router) that links back to the processor. As shown in the figure above, its labelled as Port 5. If you had 8 LAN ports it would be Port 9 and so on. For any of the vLANs, this CPU port must be set as ‘tagged’ so the data is embedded with the vLAN id and hence the processor knows which vLAN the data passing through these ports belongs to.

For this post, the router in question is a 4 port router, so the LAN ports we will be looking at are ‘Port 1’ to ‘Port 4’.

You will notice at the start, under vLAN 1, ‘Port 1’ to ‘Port 4’ are all set as ‘untagged’, meaning they belong to the same vLAN and that data is not being tagged as it passes through them. We are going to:

– create 3 new vLANs (vLAN 102, vLAN 103 and vLAN 109)
– assign ‘Port 1’ to vLAN 102
– assign ‘Port 2’ and ‘Port 3’ to vLAN 103
– assign ‘Port 4’ to vLAN 109
– deassign all the LAN ports from vLAN 1

Operationally, this means:

– Click the ‘Add’ button and create 3 new vLANs vLAN 102, vLAN 103 and vLAN 109
– Under vLAN102 set ‘Port 1’ to ‘untagged’
– Under vLAN103 set ‘Port 2’ and ‘Port 3’ to ‘untagged’
– Under vLAN109 set ‘Port 4’ to ‘untagged’
– Change all the ‘untagged’ to ‘off’ for vLAN 1

‘Port 0’ will remain as ‘untagged’ on vLAN 2.

openwrt-switch1

So looking at the above, you can see that I am actually keeping vLAN 1, but not assigning any ports to it. Fact is, the router’s LAN IP (typically 192.168.0.1 or 192.168.1.1, but in my estate’s setup 172.28.1.1) is on vLAN1 and, if you’re using a wireless router (which you most likely are), the wireless DHCP range will be on vLAN 1, so you should NOT reassign or delete vLAN1. In other words, even though there are no ports assigned to it, the router itself is still making use of vLAN 1.

Once you click ‘Save & Apply’ and if you are on a wire connected to any of the LAN ports, you’ll find yourself kicked off the network and without an IP address (we took all the ports of vLAN 1 remember?) The router’s DHCP service is only configured by default for vLAN 1. No ports assigned, means no IPs dished out. If you’re connected to the router via the wireless, then you’re ok (wireless is on vLAN 1 so you’ll still get an IP if you’re on wireless). For this reason, I suggest you configure the vLANs one by one, setting each one up individually then repeating the process for the remaining vLANs that you want setup, or at least leaving ONE port still on vLAN 1 for you to remain connected.

Assuming you’re still connected after the ‘Save & Apply’, if you go to the OpenWRT web UI, click on the ‘Network’ tab, then select the ‘Interface’ tab, you’ll see the virtual interfaces for each of the vLANs you created, on top of the default virtual interfaces for vLAN 1 (labled ‘LAN’) and vLAN 2 (labled ‘WAN’).

Now to configure the network, subnet, DHCP for the individual vLANs created.  Firstly click on the ‘Edit’ button under the ‘Actions’ column of the vLAN to be configured. Now since each interface is going to act as the gateway for the vLAN, choose ‘Static address’ as the ‘Protocol’. Fill up the IPv4 information (IP, netmask) – this can be any network class and subnet segregation (I’m using a whole class B network with 256 IPs). Then select the gateway address, which will be the LAN address of the router, (in this case  172.28.1.1). To understand why this is so, you have to understand that your router is ultimately the one thats processing all the data and telling it how to go out to the internet/intranet and come back with whatever you want. So each vLAN interface will have to pass its data through the actual router (hence why you use its IP as your gateway).

After everything is configured for that particular vLAN, you’ll have something like this:

openwrt-iface2

Next go to the ‘Firewall Settings’ tab and make sure the firewall zone is set for the vLANs as below.

openwrt-iface1-fw

This implies that all the vLANs will be able to see each other and communicate with each other. If you want complete vLAN isolation (where the vLANs have absolutely no communication between them), it can be set up under the custom firewall rules later.

Next we set up the DHCP service for the vLAN. Under the ‘DHCP Server’, ‘General Setup’ tab, make sure ‘Ignore interface’ is not checked. Set the starting IP and the number of IPs and the leastime for the IP (accept the defaults unless you have some special requirements). Under the ‘Advanced Settings’ tab, ensure ‘Dynamic DHCP’ is checked, then click on ‘Save & Apply’.

owrt-dhcpadv

Now repeat the above for remaining vLANs created, using different IP ranges (for the case of my estate setup, 172.28.3.1/24 for vLAN 103 and 172.28.9.1/24 for vLAN 109).

This last step is optional. I did mention about adding vLAN isolation via the custom firewall rules. You can do this by going to the ‘Firewall’ tab and selecting ‘Custom Rules’, then add the following into the text area and click ‘Submit’:

iptables -I FORWARD -i vlan+ -o vlan+ -j DROP
iptables -I FORWARD -i vlan+ -o vlan1 -j ACCEPT
iptables -I FORWARD -i vlan1 -o vlan+ -j ACCEPT

This basically tells the firewall to drop any packets from any of the created vLANs that are trying to reach each other (first line) effectively killing all communications between the vLANs and achieving vLAN isolation. It then tells the firewall to allow any packets from the other vLANs to vLAN 1 (second line) or from vLAN1 (third line) to any of the other vLANs. This is to ensure data can go out from the router and come back in – remember, the router is the gateway for all the vLANs.

And thats that for the vLAN setup. If everything was done properly, you can plug in your laptop with the wire to each of the ports and see that it gets IP addresses on the IP ranges you specified. Plug in two machines to check the vLAN isolation – you shouldn’t be able to ping either machine from the other. Lastly check to see that your machines have internet access.

Configuring One-To-One NAT

This is relative simple, considering its all cutting and pasting of network config commands and firewall rules.

To assign an IP address to the WAN interface, you simple issue an ‘ifconfig’ command for that interface.

ifconfig <interface> <IP> <subnet mask> broadcast <broadcast address>

If you look at your ‘Interfaces’ tab under ‘Network’, you can see that your WAN interface is designated ‘eth0.2’. You can actually get this information by issuing the following command at a command line for the router (if you’ve enabled SSH – Google it if you don’t know how to):

/sbin/uci -p/var/state get network.wan.ifname

That will also return you ‘eth0.2’. So to assign an IP address of say 136.130.20.11 (for example with netmask 255.255.255.0, broadcast 136.130.20.0) to the WAN interface do:

ifconfig eth0.2 136.130.20.11 255.255.255.0 broadcast 136.1130.20.0

If you have multiple IPs to assign to the WAN interface you do:

ifconfig eth0.2:1 136.130.20.11 255.255.255.0 broadcast 136.130.20.0
ifconfig eth0.2:2 136.130.20.12 255.255.255.0 broadcast 136.130.20.0
ifconfig eth0.2:3 136.130.20.13 255.255.255.0 broadcast 136.130.20.0
ifconfig eth0.2:4 136.130.20.14 255.255.255.0 broadcast 136.130.20.0
ifconfig eth0.2:5 136.130.20.15 255.255.255.0 broadcast 136.130.20.0

This is called ‘plumbing the interface’ (like branching pipes from a main pipe, hence the ‘plumb’ reference). You can put this into a shell script format and add it to the router’s local start up section so that it runs at every boot. Click on ‘System’ and select the ‘Startup’ tab and scroll to the ‘Local Startup’ section at the bottom and add the following into the text area and click ‘Submit’:

IFNUM=0
STARTOCT=11
ENDOCT=15
WANSFX="136.130.20"
NETMSK="255.255.255.0"
BRDCST="136.130.20.0"
WANIF=`/sbin/uci -p/var/state get network.wan.ifname`

for i in `seq $STARTOCT $ENDOCT`
do
  IFNUM=`expr $IFNUM + 1`
  ifconfig $WANIF:$IFNUM $WANSFX.$i $NETMSK broadcast $BRDCST
done

This auto detects the WAN interface name (might not always be ‘eth0.2’) and loops through the last octect of the IPs, plumbing the interface with the IPs.

So now your WAN interface will accept all traffic for any of the above addresses. The next part will be to configure the firewall rules to forward the data for the IPs to the right private IPs. Nothing more than adding stuff to the ‘Custom Rules’ under the ‘Firewall’ section again. Copy the following code and alter the WAN IPs and LAN IPs (which the WAN IPs are supposed to point to) for every public to private NAT you have:

iptables -t nat -I PREROUTING -d <PUBLIC-IP> -j DNAT --to <PRIVATE-IP>
iptables -t nat -I POSTROUTING -s <PRIVATE IP> -j SNAT --to <PUBLIC-IP>
iptables -I FORWARD -d <PRIVATE-IP> -j ACCEPT

This basically routes all packets from the public IP to the private IP (first line) and all packets from the private IP to the public IP (second line) and forwards all TCP/UDP packates for all port numbers of the public IP to the same port number on the private IP (third line). This is kind of a “allow all through” situation. If you want only forward certain ports, then specify the ports to allow. For example, to allow SSH and HTTP traffic, forward only packes for ports 22 and 80:

iptables -I FORWARD -d <PRIVATE-IP> -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -d <PRIVATE-IP> -p tcp --dport 80 -j ACCEPT

A complete working example (the one I gave up top about 136.130.20.12 pointing to 172.28.2.12 via NAT) allowing only SSH and HTTP traffic would be:

# WAN 136.130.20.12 -> LAN 172.28.2.12
iptables -t nat -I PREROUTING -d 136.130.20.12 -j DNAT --to 172.28.2.12
iptables -t nat -I POSTROUTING -s 172.28.2.12 -j SNAT --to 136.130.20.12
iptables -I FORWARD -d 172.28.2.12 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -d 172.28.2.12 -p tcp --dport 80 -j ACCEPT

Do this for every WAN IP pointing to an private IP and then click ‘Submit’ and after that you should have the translation working fine.

And that folks, is how you do vLANs and One-To-One NAT without spending thousands.

References:
One-To-One NAT
vLAN Detached Networks

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.

December 12, 2013

Speed Boost!

  

Time files when your internet connection is as fast as what I have. Back at the end of 2011, I jumped onto the fiber broadband-wagon and have been burning rubber every since. M1 started off back then with the 100Mbps package plans as their basic offering, just like all the other ISPs. Difference being, that M1 actually delivered on the speeds. For the last two years that I’ve been on their 100Mbps plan (100Mbps down, 50Mbps up), I’ve been getting consistent average speeds of 105Mbps down and about 85Mbps up – way more than what was promised. Notice I said consistent – not just during “off peak” hours. Where other friends were bitching about Singnet and Starhub, I was blissfully happy with M1.

Well, my two year contract with M1 was coming to and end, so I recontracted my plan with them – they don’t offer 100Mbps plans anymore, instead their basic package plan starts off with 200Mbps. At no change in my already very-low-cost monthly subscription, I got a speed boost too with 3 months free subscription (I missed the SITEX promo of 6 months free – bummer!). M1 even threw in a free ASUS RT-N56U wireless N router on top of that.

M1-Asus-RT-N56U

Now the N56U is arguably one of the top five gigabit SOHO routers in the market and its hardly low cost. I already had my TP-Link TL-WR2543ND gigabit router which had been serving me perfectly for the last two years, so my initial plan was to just keep the N56U as a spare or sell it. That was until I found out that my TP-Link was more of a gigabit switch rather than a gigabit router.  All routers have what we call  WAN-to-LAN (WTL) throughput. The value of this figure is basically how much data the router can process passing from the WAN interface to the LAN interface in either direction (up or down). Sadly the WR2543ND’s WTL maxes out at 120Mbps on the default firmware. I tried switching to OpenWRT and DD-WRT where it was said these alternative firmwares could actually push the WTL to about 235Mbps, but it still capped out at 120Mbps. The switch ports (LAN) were all hitting a full 1Gbps though.

The ASUS however, has a WTL of nearly 900Mbps, making it more than capable of handling my 200Mbps bandwidth and with those numbers, this router should last me into my next contract as well (unless they start handing out 1Gbps package plans at low prices by then). With little choice, I unwrapped the ASUS and set it up – the default firmware is an August 2013 build and its absolutely horrid with loads of stuff that makes a good router completely missing, but thankfully the latest October 2013 build fixes that. Interface is sophisticated looking, but its not complicated and has all the bells and whistles that made my WR2543ND great, including the dual band 2.4 and 5.0 GHz wireless bands, media server, FTP server for the 2 USB ports that even support a large list of AIO printers. The only gripe I have with it is that I can’t change the username from ‘admin’ to something else. From a security stand point, it bugs me that I can’t do this, but in an overall sense, its a trivial matter. In any case with ASUS in place, my connection started rocking with the new speeds, and again M1 was giving me way more than what their plan promises – no complaints there!

M1-200Mbps

With that done, I re-used the WR2543ND as a wirless switch (not router) – bypassing the WAN port and only using the LAN ports to extend my wireless signal. All in all, its working out fabulous, so if you’re getting your own router, make sure you know what its WTL is to which SmallNetBuilder has pretty good comparison charts.

Oh and for all of you out there who will be upgrading your fiber connections soon and who are already Red or Green, think Orange this time round.

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.

August 25, 2012

Wire Power!

  

I’d been noticing that streaming HD videos from my NAS to my DLNA certified BD player was having intermittent buffering issues. The video would play for a while, then hang for a long while, then play a little, then hang again and so on. After a little bit of experimenting I figured that the HD streams were too large for the wireless to pump to the BD player. We’re talking about 8 to 12GB files here. So here I was, after changing all my networking equiptment to ensure the house was on a full Gigabit setup, but I couldn’t get my videos streamed from my NAS to my BD player properly. The solution was of course to get a wire to my BD player. How to do that was the issue since I didn’t have any network ports near the BD player.

I had a couple of 200Mbps Prolink homeplugs however and I figured they would be the solution, but unfortunately the stuttering didn’t stop even when I used the home plugs. I actually thought there was something wrong with my BD player, but on a hunch I decided to do some speed test over the Prolink homeplugs and I was appalled to see that they weren’t pushing data over more than 40 to 60Mbps. I went into research mode, hit Google and found out that most of the homeplugs didn’t really give great speeds, definitely never hitting what was stated on their packaging. I figured maybe it was old tech and there should be something new out there now, since most everyone was on a Gigabit network now. I was partially right, they didn’t make Gigabit homeplugs but Aztech had put out their 500Mbps homeplugs. Reading the reviews gave me a pretty good impression of the device and I headed out to purchase a pair from Challenger at S$75 each (found out later that Sim Lim was selling it at S$65, bummer!)

I plugged the devices in and it was super easy to pair, unlike the Prolink ones. Just press one of the plug’s config button for 2 seconds, watch the ‘home network’ led start to blink, go to the next plug and press it’s config button for 2 seconds. After the blinking stops, they’re paired, simple as that. I did the speed tests again and very happily saw speeds of between 200 and 220Mbps. It wasn’t 500Mbps, but as I said, the speeds are never what they advertise, but this was good enough!

Plugged the BD into the home plug and no more stuttering!