free WiFi

Bash script for automatic connect to free WiFis

For automatic connect to free WiFis i've made the bash script freewifi_autoconnect.sh in 2010 and do update it every every few months. The script scanns for free WiFis, sorts them due to their signal strength and connects one after the other till it finds one which is really online. If the connection gets lost it reconnects and if that does not work it searches for other free WiFis and so on.
The script status is mature, the changelog is in the header and the script has a good online-help, availible via the parameter --help.
The script is optimized for privacy and leaves no traces: The own MAC-Address gets randomized (changed to a random other) before each scan, so that your hardware MAC-Address(es) can not be seen. The script creates only temporary files, only in RAMFS, and deletes them with a bash trap function to leave no traces.

A free WiFi is a WiFi with an obvious invitation for free usage because it is a) open (unencrypted), b) is public, has a range to a public place like a public street or public way, c) has no obstacles like a MAC filter, d) has a working DHCP server which gives an IP, DNS server, Gateway etc. and e) gives Internet access, with the given IP or the IP of the Gateway (via NAT).
An open WiFi has generally only a), so the free WiFis are a subset of open WiFis. Free WiFis are made obviously for free usage, jurists do name this conduct implying an intent.

An Article about the script is "Automatic Usage of Free Wi-Fi" in 2600 Volume Twenty-Eight, Number one, Spring 2011.

With this script you don't have to look or scan for free WiFis and you don't have to (re-)connect and test them. You only have to start the script, e. g. via a boot script.
It works e. g. under Knoppix 6.2, OpenSuSE 12.3 and Ubuntu 13.04.
Example output:

No old lock file found (ok).
List of 2 availible WIFI device(s): wlan0 wlan15
Device wlan0:   Old MAC = 4f:19:9b:0d:ad:50
          permanent MAC = c8:f7:33:bf:68:7d
                new MAC = 4e:de:41:9f:ba:85
Scan number 0, scanning ...................................................................
Found 1 open WIFI(s) and 4 closed WIFI(s).
List of WIFI(s) with Channel, Encryption, Quality, Signal Level, MAC, ESSID, Vendor:
 7      on      48/70   -59     00:0F:DE:00:42:40  "NewYork"           "Sony Ericsson Mobile Communications AB"
 1      off     66/70   -40     00:17:4D:D5:B5:DA  "freitag_2.4_GHz"   "DYNAMIC NETWORK FACTORY, INC."
 1      on      21/70   -88     10:C5:1F:2C:21:CE  "WLAN-21CE46"       ""
 1      on      26/70   -97     02:25:4D:F4:4B:F3  ""                  ""
 11     on      23/70   -76     10:BE:48:3E:2A:BB  "Skynet"            ""
Sorted list of 1 free WIFI(s):
Channel:1       off     Quality=66/70   level=-40       00:17:4D:D5:B5:DA "freitag_2.4_GHz"
Checking the open WIFI with MAC 00:17:4D:D5:B5:DA, Channel 1, ESSID freitag_2.4_GHz
          inet addr:  Bcast:  Mask:
Station 00:17:4d:d5:b5:da (on wlan0)
        inactive time:  56 ms
        rx bytes:       5350
        rx packets:     70
        tx bytes:       886
        tx packets:     5
        tx retries:     0
        tx failed:      0
        signal:         -38 dBm
        signal avg:     -38 dBm
        tx bitrate:     1.0 MBit/s
        authorized:     yes
        authenticated:  yes
        preamble:       long
        WMM/WME:        yes
        MFP:            no
        TDLS peer:              no
wlan0     IEEE 802.11abgn  ESSID:"freitag_2.4_GHz"  
          Mode:Managed  Frequency:2.412 GHz  Access Point: 00:17:4D:D5:B5:DA   
          Bit Rate=1 Mb/s   Tx-Power=15 dBm   
          Retry limit:30   RTS thr=1 B   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=70/70  Signal level=-38 dBm  
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:2   Missed beacon:0

Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE
 face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22
 wlan0: 0000   70.  -38.  -256        0      0      0      0      2        0
DNS lookup check: 2 DNS lookup(s) successfull!
It is useful e. g. to test you own Access Point (AP) or to go online to check the emails or read some news even when you have no own internet connection but you can use a free WIFI.
The script tests the internet connection by two times name resolving and two small downloads every few seconds. In mode 4 it does test only the connection to the access point by pings, for local radio links.
The script does not work under Microsoft Windows (with Cygwin), because under Cygwin commands like iwconfig and iwlist are missing.

Under Microsoft Windows (XP) there is an alternative: By default, MS-Windows XP only auto-connects to Preferred networks. The Advanced button (german: Erweitert) on the Wireless Networks (german: Drahtlosnetzwerke) tab of Wireless Network Connection properties controls the default behavior of MS-Windows XP automatic connections. One option on the Advanced window, "Automatically connect to non-preferred networks," (german: Automatisch mit nicht bevorzugten Netzwerken verbinden) allows MS-Windows XP to auto-connect to any network on the available list, not just Preferred ones. This option is disabled by default but can be enabled. But the MS-Windows XP does not check if the connection gives internet access and it does not change the MAC, so it's a poor alternative, like the wifinetics - wificonnect and Tenacious WLAN Association Script which only connect to the first available open wireless network.

The automatic connect from MS-Windows and my script are legal in most (all?) countries of the world, not only inside a building like a cafe or airport but also at public paths and areas, e. g. in the USA and Germany, see e. g. http://www.hrr-strafrecht.de/hrr/archiv/04-08/index.php3?seite=7 and the article "W-LAN: Legal schwarzsurfen", CHIP, März 2005, S. 212-213.

Update october 2010

The german Linuxmagazin published an article with Perl scripts which open WiFis which have a splash page, advertising and to accept terms of use by simple following all links and checking all check boxes: http://www.linux-magazin.de/Heft-Abo/Ausgaben/2010/11/Schluesseldienst. Article and code are freeware and complete online available! The english translation can be found e. g. at http://translate.google.com/translate?u=http%3A%2F%2Fwww.linux-magazin.de%2FHeft-Abo%2FAusgaben%2F2010%2F11%2FSchluesseldienst&sl=de&tl=en&hl=&ie=UTF-8. A combination of my Bash script and these Perl scripts would automatically connect to free WiFis and establish the internet access without a splash page, advertising and to accept terms of use.

Update september 2012

The freewifi_autoconnect.sh now prints the wifi data also in files in the directory /tmp/wifiscan for the program wifiscan.c. This program makes a list of the wifis with exponential smoothing of the quality and the level, so that most of the noise is eleminated. This is much better than signaling the signal level with only five bars, like from MS-WindowsXP.
Programs like Linssid are much better, do show the level (0... -100), but have the problem that the level is noise, so it can't be used for detailed measurements, e. g. for comparing antennas or boosters with an accuracy of 1 dB.
Example: For the WiFi dlink MS-WindowsXP displays one bar, the program displays a quality of 0.494 and a level of -75.39, where the level is roughly the power in dBm.
The Level is also called RSSI (Received Signal Strength Indikator) and indicates the received power in that channel, including all sources, even thermal noise but no zero-point noise. Without calibration the RSSI is only propotional to the power in dBm and not the same.
Example: With a 18 dBi yagi antenna a WL0162 shows the (channel with the) router with a level of -51, another WL0162 shows -58 and an AWUS051NH shows -65.
Example output, with sorting due to the Level:

Ch. Enc. Qual.  Level  MAX  MIN   MAC                t  f   count  ESSID
 1   1  0.371  -84.00  -84  -84  02:24:01:55:49:50  31  O       5  "dlink"
 6   1  0.389  -82.79  -80  -86  14:D6:4D:CF:D8:9C  21  O      34  "DIR-615"
11   1  0.406  -81.61  -78  -82  74:31:70:76:08:D0   1          f  "WLAN-760829"
 1   1  0.408  -81.46  -76  -86  74:31:70:27:9A:CE   2        2bf  "ALICE-WLAN89"
11   1  0.427  -80.13  -68  -86  00:1F:3F:BA:C5:51   2        568  "wi-fi"
 6   1  0.449  -78.54  -76  -84  00:12:2A:06:89:23  12  O       d  "Sinus
 7   1  0.494  -75.39  -66  -82  FC:75:16:7A:2B:3B   2        955  "dlink"
 2   1  0.527  -73.10  -68  -84  00:1A:2A:18:4C:3F   2       1073  "WLAN-184C85"
 9   1  0.575  -69.76  -58  -84  00:1F:3F:75:A8:0B   2        6a9  "Skynet"
 1   1  0.687  -61.88  -58  -70  00:26:4D:C8:44:83   1        39d  ""
 4   1  0.992  -35.78  -24  -70  1C:7E:E5:00:42:40   2       1d02  "NewYork"
Via the keys for 0, 1, ... 9 the data can be sorted due to the channel, encryption (0=off, 1=on), Quality, Level, Level Minium, Level Maximum, MAC, time since last successfull scan, Count or ESSID.
The Flag (f) is + at the first ten scans, for new found WiFis, and O for more than 10 seconds not seen WiFis. And WiFis which have not been seen for more than a minute are deleted.
The program can also be used for optimisations like a better antenna position or orientation.
Another application is locating the access point. With a directional antenna, e. g. a small and cheap yagi antenna, it is easy.
There are many other parameters of the WiFis which can not be displayed, like polarisation, bandwidth and modulation.

Update june 2014

If you know the parameters of the Wifi (device, ESSID, channel, IP) you want to use, e. g. your own router, you can simply use a simple short script:

ifconfig $DEVICE down
iwconfig $DEVICE essid $ESSID
iwconfig $DEVICE channel $CHANNEL
iwconfig $DEVICE mode Managed
iwconfig $DEVICE ap any
ifconfig $DEVICE inet $IP
rfkill unblock wifi
ifconfig $DEVICE up
sleep 1
ping -c 1 $AP

This method connects immediately; there is no waiting for an answer from the router! And the router does not need a DHCP server.
The kernel uses another association method, which silently disables the device after a timeout of a few seconds, when the AP does not answer; ifconfig, iwconfig and other tools can't show the silently disabled status.
A simple workaround is to disable and enable manually, simply "ifconfig $DEVICE down; ifconfig $DEVICE up". And this can be automated with a script wich checks the connection with pings.
For MAC randomisation, default gateway, encryption and other features you have to add some lines more.

Update january 2015

I updated the script with few changes, because the DNS root nameserver D has a changed IPV4 IP (now, it was
The script uses this IP for testing the translation (resolution) of the current name server, often in the WiFi router.

BTW: At tests with the script under Ubuntu 14.10 i often had the problem of hangsups so that even Magic SysRq does not work and the reason seems to be bootchart: http://forums.linuxmint.com/viewtopic.php?f=46&t=121457 .

Update february 2015

I updated the script with several changes, because in the Hotel NH Cordillera in Mendoza, Argentina, checking the connection only to the AP with (ICMP) pings works good because even downloading of small files takes longer than 6 seconds. For this mode 4 (and higher) the script now gets the default gw from the route output.
I also added Mode 5 which is like 4 but with ARP instead of ICMP pinging the AP, because more and more APs do a) not connect to the internet directly and b) do not answer ICMP pings. I found this in a hotel in Santiago (Chile), in an Iberia airplane (IBE6830) and on the international airport Madrid. In the plane and at the airport the new mode 5 worked without problems. So i could use the "first free 30 minutes" in Madrid eight times :-)
It should also work at all other places with "First 30 Minutes FREE", e. g. airport Auckland, JFC etc., after clearing the browser history (including Cache and Cookies), because the script always starts with a random MAC which is not the hardware MAC.

BTW: Unter Windows 8.1, after 1.5 years and about 50 boots, suddenly the "Intel WiFi Hotspot-Assistent" poped up on my Ultrabook for the first time and could connect to the hotel WiFi at booting. But after the third reboot something from Windows 8.1 degenerated and this did not work anymore, but my script still works.

Update march 2015

I added some lines for terminating/stopping of other processes which would disturb the script, e. g. NetworkManager.

Update june 2015

I Changed the scanning of the channel number, which did not work for channel numbers greater 100.

Update august 2016

Under Kernel 4.4 there are some name changes, like the name of the Wifi adapter changed from wlanX to wloX, e. g. from wlan0 to wlo0. I modified the script so that it also works with Kernel 4.4. The old version is availible at freewifi_autoconnect_old.sh

WiFi on ICE

Update 2016-12-13

The script works in the ICE trains of the Deutsche Bahn (Germany). I tested it today with:

freewifi_autoconnect.sh 4 WIFIonICE

At Starbucks at Munich main railway station it works with:

freewifi_autoconnect.sh 4 BTOpenzone

In both cases you have to push an OK button to get really online.
In the ICEs it worked only in one of two tested ICEs. At the second ICE the default page www.wifionice.de did show only an empty directory from an Apache/2.4.10 (Debian) Server at Port 80.

Update 2017-01-06

Under Ubuntu i had to change the extraction of the MAC, because the format of the ifconfig output has changed.

Update 2017-01-06

In the german ICE 577 the script works, is connected with an IP and pinging the AP works. But DNS does not work, because in /etc/resolve.conf under Ubuntu (Zesty Zapus) there is only a systemd-resolved stub resolver which does not resolve. Manuelly setting the AP, in this case and also other ICEs, was the sollution. In the days before that was not necessary, even for a WPA2 encrypted connection to a Fritzbox DSL router.


Gallery with some pictures with the script

Gallerie mit Bildern mit dem Skript

A Map Of Wireless Passwords From Airports And Lounges Around The World

Since 2015 Captive portals are specified in the standard RFC 7710.