How to Get Free Wi-Fi Anywhere
by Curufuin
The purpose of this article is to provide an easy method for acquiring free Wi-Fi access from a van or RV in most major cities. (I am happy to report that many small towns in Vermont also have free Wi-Fi and this method works there as well.)
We will need to set up a Raspberry Pi to more or less act as a router that you will connect to from your Wi-Fi enabled devices and it will forward your devices transparently to a nearby open Wi-Fi or a password protected Wi-Fi for which you put credentials in the passwords.txt file. As you come into range of a network or multiple networks, the Pi will connect to the one with the strongest connection. You can also blacklist things like Comcast open networks, since they may have a good connection, but require credentials through a captive portal interface. If you are a frequent 2600 reader, you will be familiar with spoofing your MAC address to connect to a network that uses a captive portal, but I will not cover that here, though I may add that functionality to my program in the future.
So I had a kind of unique problem getting started with my Raspberry Pi. I live in a van and, until recently, connected to the Internet via mobile hotspots (which I was paying $70 a month for through Cricket (not a terrible deal if you can afford it, but totally unnecessary now). I don't have, nor do I want, a spare monitor hanging around as I don't want it to take up room in the van. So I had to do a little digging.
The first steps to installing your Pi are as normal. Download a Raspian image and use the dd command to load it to an SD card that has been formatted with FAT.
First, determine where Linux has mounted your SD card before plugging it into your card reader. Go ahead and type the following into your terminal application of choice:
$ fdisk -lNow plug it in and type the previous command again and the new device is your SD card. Most likely it will be at /dev/sdb.
Next, format the SD card for FAT, or VFAT if your card is 32 GB, (make sure you have the right drive unless you want to get acquainted with hard drive recovery software, as this will overwrite the partition on the current drive):
$ mkfs.fat /dev/sdbNext, download and unzip a Raspian image and copy the image onto your SD card:
$ dd bs=4M if=path_to_raspbian_image of=/dev/sdX (probably sdb) conv=fsyncThis step often fails because crappy card readers can't seem to handle it. If that is the case, you may have to buy a card reader that can. I have one from Steelton Tech that works well, but the one built into my laptop does not. It can be a real pain, but if you can find one that works well, it will save you many headaches.
Now that you have the image on the SD card, remount the card and add a blank file named ssh to the /boot partition as well as a file called wpa_supplicant.conf, which we will edit as follows:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev network={ ssid="YOUR_NETWORK_NAME" psk="YOUR_PASSWORD" key_mgmt=WPA-PSK }Save the file in the /boot partition.
Finally, we need to edit the /etc/dhcpd.conf file. Add this to the bottom of the file and save it:
interface wlan0 static ip_address=(IP ADDRESS YOU ARE ASSIGNING HERE)/24 static routers=(IP OF ROUTER) static domain_name_servers=8.8.8.8 8.8.4.4Finally, you can unmount the SD card and plug it into your Pi.
Plug in the Pi and the red power indicator should stay on, and the green ACT indicator should blink a bunch, stay on for about 30 seconds, and then turn off.
At this point, from the computer you would like to SSH in from, ping the IP of the Raspberry Pi until it comes online:
$ ping (Pi's IP here)When it comes online, you will see it change from "Host Unreachable" like so:
From 192.168.43.6 icmp_seq=19 Destination Host Unreachable From 192.168.43.6 icmp_seq=20 Destination Host Unreachable From 192.168.43.6 icmp_seq=21 Destination Host Unreachable From 192.168.43.6 icmp_seq=23 Destination Host Unreachable From 192.168.43.6 icmp_seq=24 Destination Host Unreachable 64 bytes from 192.168.43.10: icmp_seq=26 ttl=64 time=1706 ms 64 bytes from 192.168.43.10: icmp_seq=27 ttl=64 time=683 ms 64 bytes from 192.168.43.10: icmp_seq=28 ttl=64 time=10.2 msNow you can login using SSH:
$ ssh pi@ (Pi's IP here)The default password will be raspberry and we will go over how to change that shortly...
Now that we are connected, we need to connect another wireless adapter to the Pi. I chose the ALFA AWUS036NH, which is boosted by an amplifier connected to a 16 dBi antenna.
Next, we will need to bring in some tools to turn the Raspberry Pi into a hotspot like so:
$ sudo apt-get install python-pip hostapd dnsmasq gitNow we need to stop hostapd and dnsmasq from running while we configure them using:
$ sudo systemctl stop hostapd $ sudo systemctl stop dnsmasqNext, we need to configure a static IP for wlan0 in /etc/dhcpcd.conf like so:
interface wlan0 static ip_address=192.168.4.1/24 nohook wpa_supplicantWhere 192.168.4.1 is the static IP for wlan0. This could be any IP of your choosing.
Next, let's configure the DHCP server.
First, make a backup of the default:
$ sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.origThen we will edit /etc/dnsmasq.conf by adding the following:
interface=wlan0 dhcp-range=192.168.4.2, 192.168.4.20, 255.255.255.0, 24hNow we need to configure hostapd by creating and editing /etc/hostapd/hostapd.conf:
$ touch /etc/hostapd/hostapd.confand edit it to contain the following:
interface=wlan0 driver=n180211 ssid=NETWORK hw_mode=g channel=7 wmm_enabled=0 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=2 wpa_passphrase=PASSWORD wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMPThen we have to tell the Raspberry Pi where the configuration file lives by editing /etc/default/hostapd:
DAEMON_CONF="/etc/hostapd/hostapd.conf"Now we need to forward the traffic between the interfaces. In the /etc/sysctl.conf, uncomment the line that says:
#net.ipv4.ip_forward=1It should now just read:
net.ipv4.ip_forward=1Now we will enable IP masquerading on wlan1 with the following iptables rules:
$ sudo iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE $ sudo iptables -A FORWARD -i wlan1 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT $ sudo iptables -A FORWARD -i wlan0 -o wlan1 -j ACCEPTand save it:
$ sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"Next, tell the Pi to reload the iptables on boot by editing /etc/rc.local. Just add the line:
$ iptables-restore < /etc/iptables.ipv4.natAnd reboot:
$ sudo rebootOnce the Pi is booted, give or take about a minute and a half, you should see a Wi-Fi network with the name you assigned in the previous steps and you should be able to log into it using the password you assigned. Then you can SSH in again and change the password for the user Pi:
$ passwdYou will be prompted for the current password, which is just raspberry and then to enter a new one. Keep it secret, keep it safe (insert rant on password security here). If you keep it the same, somebody on a network you connect to can easily just SSH into your router and muck about, which is certainly not ideal.
Next, we need some dependencies for the Python script that will look for open Wi-Fi for us. The following should pull all of those in. (By the way, the script is using Python 2.7, not Python 3. Sorry, not sorry, feel free to fork it and fix it.)
$ sudo pip install wifi wireless netifacesEverything else should be in the standard libraries.
Now make a folder where you want the project to live and clone the git repository as follows:
$ git clone https://github.com/curufuin/WiFi-ConnectorThis should give you a few Python files as well as some text files. (WiFi-Connector.tgz)
blacklist.txt is an ESSID blacklist you can fill with the names of Wi-Fi networks you don't want to connect to in the future. It has a few defaults, but you can add new ones, one name per line.
passwords.txt contains passwords for secure Wi-Fi for which you have the password. The format is ESSID:password - one entry per line.
Finally, connector.py is the program that does the heavy lifting. I have it run once a minute from the crontab. You can edit the crontab as follows:
$ sudo crontab -eSelect your favorite editor and add the following to the bottom of the file:
* * * * * /usr/bin/sudo /usr/bin/python (path to connector.py) >> (path to log file 2>&1For good measure, I automatically restart the Pi every five hours because hostapd has some bugs that are sorted by restarting, so add this line below the previous:
1 5,10,15,20,23 * * * sudo /sbin/rebootNow test this against some networks and everything should be working at this point.
The great thing about a setup like this is that you can also use the Pi as a Samba server for media, which you can connect to with your phone using VLC. You can also use Google Voice for phone calls and texts and get rid of your normal phone. I won't cover that here as this article could get quite bloated if I discuss everything I did for my van, but I will discuss one more thing. I like my privacy... a lot. So I wrote a little shell script that will give your computer a randomized hostname and MAC address. It is included in that git repository, and I suggest using it if you have a network card that supports it. First install macchanger:
$ sudo apt-get install macchangerAll you have to do to use that is add another line to your crontab:
$ sudo crontab -eAnd add the following at the end of the file:
1 * * * * (path to changemac.sh) >> /home/mac.log 2>&1In addition to this, I suggest using a reputable VPN such as protonVPN while connected to any open Wi-Fi you plan on using to log into anything requiring a password. There are working "man-in-the-middle" attacks that could jeopardize your credentials.
Finally, you will probably run into some problems with paths in both changemac.sh and connector.py and, if you are running them from Cron as should be the case, we will need to change some of the paths to be absolute. Open up connector.py and where it says self.blacklistFile, change the path to the absolute path on your system to the blacklist file. For me it is something like /home/pi/connector/blacklist.txt. Your mileage may vary. Then do the same for the self.passwordsFile variable. Now do the same for changemac.sh. Change ./hostnames.txt to its absolute path. This should fix any problems you might be experiencing. Now reboot and reconnect.
$ sudo rebootGood luck!