Project Adverpising: A Wi-Fi Beacon with Raspberry Pi

Privacy is a major issue, especially as we continue to gear-up and carry various wireless devices which emit signals which can be used to track our movements, be it just a smartphone with Wi-Fi turned on, probing for access points or a fitness tracker that’s announcing its presence on Bluetooth Low-Energy. We are also living in a world filled with advertising, that is increasingly becoming ad-blind to traditional advertising channels.

Combine that thought, with the fact that I’m a bit of an introvert, and as much as I would like to promote the presence of my site, I don’t really think it’s worthy of “regular” advertising. It wouldn’t be cost-effective, or even effective.

That’s where I had a bit of an eureka momentwhy don’t I use the technology I love to help advertise the site for me? Enter Project Adverpi(sing).

What is Adverpi?

The whole adverpi concept makes use of the concept of Wi-Fi access points and SSIDs. Most people are aware that if they scan for networks, they can receive beacons from nearby access points, along with their name (the SSID).

You can thus “use” this to advertise your existence just by running an access point and naming it creatively. Of course, if you just run a regular access point (say tethering on your phone), you get just one network which can be “buried” amongst the noise of other networks. Ideally, you’d like to have several entries, so you can send more sophisticated messages. You could potentially get this part done with a DD-WRT/OpenWRT capable router, but who wants to carry a router around with them?!

Of course, just seeing a network name is advertising, but I wanted to take it one step further. I wanted to entice them on, and demonstrate the danger of connecting to other networks. So I wanted my networks open, which makes them attractive to desperate passers by, and accessible to all. Once on the network, I wanted to deliver them a longer message.

Ideally, I would also like to know how effective the scheme is, so some logging was a natural part of the system.

The adverpi is a system which:

  • Broadcasts multiple virtual access points with names designed to “rank” highly.
  • Accepts connections from clients, offers them a DHCP address so they’re on the network.
  • Intercepts all DNS requests and returns the address of the adverpi itself.
  • Runs a HTTP server that intercepts all requests for all hosts and rewrites them all to point to one particular domain.
  • Serves an advertising message.

What do you need?

20150720-2339-2429

To cook up your own adverpi, you will need the following hardware:

  • A Raspberry Pi (pretty much every model is applicable, but with different set-up in case of Model A’s). I recommend using A+ or B+ models due to lower power consumption with the switching converters on 3.3v.
  • A 4Gb or larger microSD/SD card to run Raspbian from
  • A good USB battery pack (to make it portable)
  • A microUSB B cable
  • One or more USB Wi-Fi adapters which are hostapd compatible (i.e. have mac80211 drivers), but watch out for power consumption issues. Although it is possible to fit four Wi-Pi’s into the Model B+, it causes the polyfuse to just be on the edge of tripping when in use causing instability.
  • Compatible Monitor, Keyboard and Mouse, if you want to set it up interactively, or you can do it via SSH over Ethernet cable.

20150719-1222-2421

Don’t try this … it doesn’t work. The Pi just can’t power itself and that many active Wi-Pis … at least, not with the polyfuse installed.

Initial Setup

You need to get the Raspbian image from Raspberry Pi foundation, unzip and write this to your microSD/SD card. Decide how you are going to set-up the Raspberry Pi – you can use a USB keyboard/mouse and monitor and do it interactively, in which case connectivity is more flexible (i.e. you can use Wi-Fi to grab the packages later). If you want to set it up without keyboard and monitor, then you will need to use Ethernet cable, and log into the unit via SSH.

Set-up the Pi to your preferred settings in raspi-config. I recommend leaving overclocking off to save some energy, setting a strong password, having SSH on, resizing the root partition to fill the device and giving it a unique hostname. If you’re using wireless to do your connectivity to the network to set-up your Pi, also boot into X and set-up your wireless using the network manager applet, which only needs to be done once.

It may seem strange to some that I’ve mentioned one or more USB Wi-Fi adapters. As it turns out, I’ve got a bit of a lack of Ethernet ports around the house, so I like to dedicate one adapter on my Raspberry Pis to connecting to the network for remote administration, package updates, etc. The other adapter(s) will be used for your virtualized APs.

It pays to have your administration adapter be allocated a static IP through configuring /etc/network/interfaces, so that you know where it is and you can get into your Pi in case of trouble, without resorting to old-fashioned keyboard, mouse and monitor.

It then pays to reboot, get all your software up to date with sudo apt-get update and sudo apt-get upgrade. Once that is done, your pi is ready for actually being set-up.

Grabbing the Packages

To do the above, you really should have the following packages installed:

  • iw – to configure and check wireless interfaces
  • dnsmasq – to provide DNS and DHCP server functionality
  • bridge_utils – to bridge interfaces
  • hostapd – to produce our software APs
  • lighttpd – to serve our documents

As a result, you should issue sudo apt-get install iw dnsmasq bridge_utils hostapd lighttpd to grab and install them all. Once you have them all, if you’re on a Model A/A+, you can then clear the network configuration for your Wi-Fi adapter and substitute wlan0 for wlan1 in the following scripts. The Model A+ consumes the least power, and could be highly preferable for this kind of work where future updates or repurposing of the project is not required.

Configuring the Packages

First thing first, we want to be able to do things without breaking DNS resolution on the Raspberry Pi itself, so edit /etc/resolvconf.conf and uncomment the name_servers= line. Modify that line to your local nameserver – say your router at 192.168.0.1, to make sure that name resolution works even when static IP addresses are allocated (useful if you’ve set-up an administration Wi-Fi adapter). You might need to reboot to ensure that /etc/resolv.conf is correctly generated.

Now, we should check the Wi-Fi adapter properties to see if it is capable of creating virtual APs, and as to how many can be created in what combination. To do this, issue the iw list command. You will have a long output, but the important lines are as follows:

        valid interface combinations:
                 * #{ AP, mesh point } <= 8,
                   total <= 8, #channels <= 1

This shows that the Wi-Pi (Ralink based) is capable of up to 8 virtual APs on the same channel. Atheros ath9k based cards can only have two, from my experience.

Now that we are armed with this, we can write up a basic hostapd configuration file. I’ve decided to call mine ~/hapd1.conf and it contains the following:

interface=wlan1
bridge=br0
hw_mode=g
channel=1
ieee80211d=1
country_code=AU
ieee80211n=1
wmm_enabled=1
beacon_int=100
max_num_sta=128

ssid=00-goughlui.com

bss=wlan11
bridge=br0
ssid=01-goughlui.com

bss=wlan12
bridge=br0
ssid=02-goughlui.com

bss=wlan13
bridge=br0
ssid=03-goughlui.com

bss=wlan14
bridge=br0
ssid=04-goughlui.com

bss=wlan15
bridge=br0
ssid=05-goughlui.com

This was the result of some trials, which initially had longer messages and different configurations. This final one causes six virtual APs to be produced on channel 1, supporting 802.11n with no encryption. It allows up to 128 users, with a beacon interval of 100ms.

The beacon interval controls how often the beacons are sent, and theoretically can be dialled as low as 16ms. Lower beacon intervals improve the chance of the APs showing up in scans, but consume more energy and reduce the amount of airtime available for transmissions.

I tried it at 32ms, and we can see just how long the batched beacons are, resulting in flaky throughput, which is why I reverted to 100ms. I also found that running with eight virtual APs had issues as the last two APs beacons were not sent “on time” causing their appearance to be erratic.

transmit-power-time

The six virtual APs will have the device names of wlan1, wlan11 … wlan15. But instead of dealing with interfaces individually, we can “group” them all together into one large network, so anyone on any one of the virtual APs can talk to the Pi and anyone else. This is called bridging. If you try to configure bridges by brctl as you would on Ethernet interfaces, you will find hostapd panics. So don’t do that! Instead, you can name an interface with the bridge= directive, which will create a bridge if it doesn’t exist, and add to a bridge if it does. If you try to run hostapd with that configuration file, you might come into an error … so just ignore that for now and keep reading on to find out why.

The plan is to have the Raspberry Pi assume the address of 10.0.0.1, using a subnet mask of 255.255.255.0 on our virtualized network. As a result, we will need to configure dnsmasq to hand out IPs from the 10.0.0.2 – 10.0.0.254 range, set with DNS resolver at 10.0.0.1 which is run by dnsmasq, and to have all requests resolved to 10.0.0.1. But we don’t need any of these services to go out on our home network, in my case eth0 (when by cable) and wlan0 (by Wi-Fi). We also want to get some logging happening. This can be done by modifying the /etc/dnsmasq.conf to read as follows:

no-resolv
except-interface=eth0
except-interface=wlan0
log-dhcp
dhcp-range=10.0.0.2,10.0.0.254,6h
address=/#/10.0.0.1

Now, you need to put all the files you want served to your visitors in your /var/www folder, ready for hosting by lighttpd. I decided to go with some simple hand-coded HTML and included a set of favico and touch-icons. You will then need to modify your /etc/lighttpd.conf so that requests for any page not on a certain domain is redirected to that one domain. This is the “nice” way to do it, otherwise you might get 404’s when visitors try to visit some site with a path.

$HTTP["host"] !~ "^goughlui\.com.*$" {
  url.redirect  = (
    "^/(.*)" => "http://goughlui.com/",
  )
}

I added this to the end of my lighttpd.conf file, which basically says that “if the request is not to goughlui.com, then redirect to http://goughlui.com

Having gotten this far, we now need to tie it all together so as to get it to start on boot-up, and configure the interfaces correctly. I’ve also added an optimization, as I have my administration adapter at wlan0, and it eats power, so I set its transmit power to 0dBm and then turn it off after 10 minutes after booting (as I would have done any fixes by then). Administration is still possible as a client by connecting to the virtualized APs and SSHing into 10.0.0.1, which can also allow you to turn wlan0 back on.

In order to do this, I’ve decided to write a script called ap1.sh in the root (/) folder, and chmod +x‘d the file to ensure it is executable. The script contains the following:

#!/bin/sh
iwconfig wlan0 txpower 0
iptables --flush
ifconfig wlan1 down hw ether 00:c1:41:06:05:10
ifconfig wlan1 up
hostapd -B /home/pi/hapd1.conf
sleep 10
ifconfig br0 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255
service dnsmasq reload
sleep 600
ifdown --force wlan0

It starts by reducing power on wlan0 (my local administration Wi-Fi adapter), then flushes all iptables rules (disabling the firewall which can interfere with bridging). It then configures wlan1 (our virtual AP adapter) with a MAC address ending in zero (this is important – I’ll explain later) and brings it back up. Then it executes hostapd with our configuration set earlier, waits 10 seconds, then sets the bridge interface (br0) with the appropriate addresses. It then reloads dnsmasq to ensure it’s active over the interface, waits 10 minutes, then turns off the administrative Wi-Fi adapter.

While playing with hostapd, I was receiving the following errors especially with multiple APs configured:

Invalid BSSID mask ff:ff:ff:ff:ff:f8 for start address

As it turns out, because of the way virtual APs work, all of them have to have consecutive MAC addresses which only involve changing the least significant three bits of the address. As a result, if your adapter’s default MAC was 00:c1:41:06:05:16, then the next AP will be granted 00:c1:41:06:05:17. If we were to add another AP after that, it would be 00:c1:41:06:05:18 and would trigger the error, because it’s now exceeded the allowed bit-mask. The easy solution is just to “clear” the last three bits by setting the MAC as above, by setting the last nibble to 0 or 8.

Now that we have the script configured, we need to set it to run on start-up. Instead of using the other methods which most people tend to use on the Raspberry Pi, I instead decided to reach right into the root crontab at /etc/crontab and modify it to add a line near the top, under the PATH= line:

@reboot root /ap1.sh

This executes the script above with root user permissions when cron is started, which is on every boot. Sweet! Of course, this write-up simplifies many “piecemeal” test and debug sessions, where there were bugs in configuration and sequencing/timing issues causing inconsistent results.

The Result

scan-result-winAfter all of this effort, what might we be rewarded with? Well one of my initial tests was to try and batch together a story from several SSID lines, but unfortunately Windows sorts by signal strength, rather than by SSID, resulting in a small jumble. Still not bad, and doesn’t take much to make.

You might be wondering why the SSIDs all start with 0’s … well this is because mobile OSes typically sort SSIDs alphabetically, rather than by signal strength. On a scan in a crowded area, you will “float” to the top.

Think of this as “Wi-Fi Scan Result Optimization” [chuckles as a jab at SEO].

Screenshot_2015-07-20-14-55-21I then realized that there is a good likelihood that fast scanners won’t see all the SSIDs, so it pays to tell your story in one, hence I decided to change all the SSIDs to one message (with different prefixes, so as to be distinct lines), but then I discovered that the Wi-Pi doesn’t like having more than 6 (the 7th and 8th APs don’t beacon as frequently, and erratically). So I decided to have six, and then I decided to make them open, so as to be appetizing to passers by.

The result is a very interesting one. On Windows 8 and newer, it recognizes that the network is a “captive portal” type and automatically loads a page to try and sign-in, resulting in the delivery of my “advertisement”.

Apple devices did something very similar, upon connecting, autoloading the advertisement. As there was no sign-in offered, the cancel button disconnected them from the network.

IMG_1202

Screenshot_2015-07-21-15-23-53That’s a slightly older version of the advertisement, but I also tested with Android. It took a little longer on Android to see it prompt for “Sign into Wi-Fi Network”, which if followed, delivered the ad. It didn’t auto-load it, which is different.

Windows 7 machines aren’t “smart” enough to worry about it, and neither are Linux machines, so people will only get delivered the ad when they open their web browser, and get redirected to http://goughlui.com, which is actually just the ad on the Raspberry Pi.

Once you’re done for the day, you need to connect as yourself, ssh in and shutdown via SSH to be safe. But as it’s relatively low on writes, the chance of corruption is relatively low.

The virtualized access points do allow communication from AP to AP due to the use of bridging, so someone connected to 03-goughlui.com can see anybody connected to 01-goughlui.com, which makes it an interesting “hub”, but data transfer speed is ultimately constrained due to the power of the original Raspberry Pi, the forwarding delay, packet loss and the fact that everything is on one channel. When broadcast traffic is sent, it is copied and sent out from every virtual AP if a station is connected, further compounding bandwidth issues.

When running from the Xiaomi 10,400mAh gold power bank, the system lasts a surprisingly long 18 hours continuous running. You can beacon all day while you’re out, and you won’t have to charge. You couldn’t easily do this several years back … think laptop running Linux or customized OpenWRT router and power supply hack.

Of course, I should warn potential users that they will be subjecting themselves to 2.4Ghz radiation at about 10mW, which is unlikely to have any adverse health effects but is still of concern to some, and they are deliberately exposing their location, so probably best not to run this around sensitive locations and if you fear that you might be a target. Leaving this in a place to do your advertising for you is unadvisable, unless you know it’s safe to do so and you have the permission to do so.

Does it Work?

While simple in concept, one question you might ask is “does it work?” This was a question I definitely asked myself, because 3G/4G mobile data has never been more affordable, and more and more users are not constrained by free-Wi-Fi needs anymore. So, do people still scan for and connect to unknown networks?

To find out, we have our handy logs in /var/log/daemon.log to trawl for. Grepping for “DHCPACK”, shows five people had definitely connected to my AP in the two days I had carried it around with me. I have painted over all of my own devices in the logs and cleared the last three octets of their devices’ MAC address.

adverpi-gotcha

Further Options

If you’re familiar with Wi-Fi, you will realize there are lots of nasty things that can be done. Before I continue, let me say that I’ve considered them to be dangerous and I don’t condone them.

  • You could make a Wi-Fi scanning or sniffing device for wardriving purposes.
  • As management frames are not encrypted, it is possible to send deauth packets to devices to force them off networks, or broadcast deauth to cause denial of service to users. This is used by certain access points as rogue AP protection.
  • It is possible to spoof other APs (e.g. common free access points) which will cause other people’s devices to auto-connect to you as they may have a profile for them stored in their device from before. This is potentially quite a security issue, and could potentially be a legal issue especially if the SSID includes the company trademark (as that might be taken as inappropriate use of trademark).
  • If your equipment is powerful enough, you could also end up man-in-the-middle attacking users on open Wi-Fi networks, stealing identities and unencrypted traffic, modifying traffic, etc.

All are possibilities, but I don’t think they’re possibilities I will bother exploring myself.

Conclusion

I had a little thought last weekend, which then culminated in me producing the adverpi. This little device illustrates the possibility of using SSIDs and open networks to deliver an advertising message to those around you, if they are scanning for open networks and are desperate enough to connect to you. It definitely works, although its hit rate is much lower now that mobile data plans are more affordable and common. It’s still a worthy exercise in showing the power of Linux, the original Raspberry Pi and open source software.

An Aside: Site Status

Apologies for the slow load speeds over the past day or so. At times, some pages can take a whole 20 seconds before they start to load! Not good. I’ve been investigating what is going on, but it just seems like the GoDaddy server I’m being hosted on is a bit bogged down and their database response time is a bit slow.

hmm-memoryuse

Also, for some reason, the memory usage and process count has been higher than usual (7 day graph), although the site files check out as clean and no major changes (bar security related updates) have been done, and there hasn’t been any big sudden increase in site traffic that I can tell. Rest assured, I’ll continue to keep an eye on the situation and try to maintain service as much as I can.

You know what? Just as I was finishing this article, everything sort of returned to normal on its own. But then the cache broke … and while checking that out, I realized the mySQL database had disappeared from my GoDaddy account but was still accessible by WP but not any of the admin tools. Ultimately, I had to cut-over to another database to restore adminability and fix the cache up. NOT what I needed today.

About lui_gough

I'm a bit of a nut for electronics, computing, photography, radio, satellite and other technical hobbies. Click for more about me!
This entry was posted in Computing, Radio, Raspberry Pi and tagged , , , , , , , . Bookmark the permalink.

4 Responses to Project Adverpising: A Wi-Fi Beacon with Raspberry Pi

  1. Justin L. says:

    Use a Wifi Pineapple 🙂

  2. Jack says:

    Thank you for your excellent Adverpi project.

    Many years ago I have got Open WRT enabled WiFi router by Linksys exactly with the intention to set up open access point (hot spot) with default web page and a nice SSID message
    I was not aware a single router can feature multi SSIDs .
    As I recall my WiFi router by Linksys came with default web page in plain html, opening on no connection established to outer world.

    I have planned to edit default (no connection error) web page to include a nice messsage.
    I don’t remember what was the limit on a size of default.html file.

    Please tell me if Adverpi project can be run on old Open Wrt enabled router by Linksys, since I need to cut my spending.

    • lui_gough says:

      I didn’t have much of a play with OpenWRT, so I’m not entirely sure. But in theory, any device that’s Linux based with a configurable DNS server (e.g. dnsmasq), a configurable Wi-Fi softAP interface (via hostapd), with any web server should be able to do it. Whether you can do it without fighting OpenWRT’s default configuration, without running out of storage or breaking its web configuration interface is something I don’t know. As for the number of SSIDs offered, this normally ranges from 2 to 8, and are normally forced to be consecutive MAC addresses owing to hardware MAC address mask limitations. Very few only support one virtual AP. All of these SSIDs are basically created by sending out beacon frames for them over the same radio just with the different MAC/SSID/encryption parameters, so as a result, they are all on the one channel. There are some obfuscation tools which send randomized beacon frame information to spam network scanners with false results, so as to appear to be hundreds or thousands of APs as well, requiring just one “promiscuous mode” Wi-Fi interface, but this does not allow for connection.

      – Gough

  3. Jack says:

    Thank you.
    The idea of using an old WRT54GL or GS router by Linksys came from your comments above

    (from website of DD-WRT)
    DD-WRT is free Linux-based firmware for several wireless routers, most notably the Linksys WRT54G (including the WRT54GL and WRT54GS) ..

    you said:

    You could potentially get this part done with a DD-WRT/OpenWRT capable router, but who wants to carry a router around with them?!

    I can get an old WRT54GL router for $10 to run tests since Raspberry Pi is higher priced at $50-100.
    Another choice is my Android tablet, supporting WiFi tether
    I need to get it rooted first and test what number of virtual APs is supported
    as you said above

    To do this, issue the iw list command. You will have a long output, but the important lines are as follows:

    valid interface combinations:
    * #{ AP, mesh point } <= 8,
    total <= 8, #channels <= 1
    "

    What is called virtual access point in MS Windows environment is WiFi tether on Android
    (see myPublicWiFi )
    – Sharing Your Internet Connection –

    http://www.mypublicwifi.com/publicwifi/en/index.html

    not sure of any redirecting all traffic to locally hosted home page
    making local Hotspot or AccessPoint to work

    The above failed to install on Windows XP ;(
    to let me test it

    It looks like you are the first and the only man who has successfully implemented multi SSID virtual AP technology into life (my Google searches from the past)

    Life is so complicated with iptables configuration, setting up web server to work properly configured so I do hoped to get virtual AP apk from Google Play.
    Unfortunately, what is offered is WiFi tethering AP = Hotspot, no home page to open option offered.

    Hope to preconfigured virtual multi APs app to be offered one day since public WiFi gets down with advent of pocket money priced 3G/LTE plans in EU

Error: Comment is Missing!