Accessing Hotspots on Linux
Accessing open wireless access points (aka hotspots) on Linux can sometimes be a pain. Depending on the network configuration of the system, captive portal autodetection might not work, custom DNS may mess up automatic redirects or HSTS presents you with obscure security warnings. Yet, if you understand what the computer is attempting to do, the riddle unravels quickly.
A hotspot usually presents itself as an open (i.e. no passphrase required) wireless network, which any WiFi-capable device can connect to. However, the network access through this hotspot is enabled dynamically, after some mean of user input. This user input happens through a captive portal. What is a captive portal, you ask?
A captive portal is a web page accessed with a web browser that is displayed to newly connected users of a WiFi or wired network before they are granted broader access to network resources. Captive portals are commonly used to present a landing or log-in page which may require authentication, payment, acceptance of an end-user license agreement, acceptable use policy, survey completion, or other valid credentials that both the host and user agree to adhere by.
After successfully unlocking the network, the network host usually “remembers” a device by its unique media access code. Anyways, the important point is: Almost all problems concerning hotspot access revolve around problems accessing the captive portal. We can group these problems into three categories:
1. Autodetection problems
Many operating systems (think
Windows) automatically detect when they connect to an open network that requires “solving a captive portal challenge”, through multiple smart network tests. If your Linux distribution is not configured for this, a friendly Popup asking you to go through the captive portal may not pop up upon connecting to the network.
2. DNS problems
In most cases, network devices that connect to a wireless access point obtain their address through means of DHCP. Besides centralized address configuration, DHCP usually assigns DNS-Servers. These are in charge of translating domain names (e.g.
https://duck.com) to IP-Adresses (e.g.
So how does this relate to captive portal access? Simple: The network operator will resolve any domain to the IP-Address of its respective captive portal, until the users authenticates/pays/accepts the license agreement.
However, if the Linux system is configured to use static DNS, e.g. Quad9, it disregards any DNS-Servers it was told about by its DHCP client and therefore attempts to redirect all DNS queries to
184.108.40.206. This request fails, because the captive portal challenge hasn’t been passed.
3. HSTS problems
Consider the case that you are trying to access a website (say
duck.com) and you successfully use the network assigned DNS server to obtain its IP-address. Therefore, the address is (“erroneously”) resolved to e.g.
10.0.0.1, which is where the captive portal resides.
Still, problems may arise from a modern security mechanism called HTTP Strict Transport Security. In a nutshell,
HSTS protects websites against man-in-the-middle attacks, by forcing a browser to only accept
TLS-encrypted traffic for that specific website. This renders DNS-rebinds to a captive portal useless, because your browser will throw a security warning and try to warn you that somebody (the network operator) is trying to impersonate
If you’re trying to pass through a captive portal, keep the above challenges in mind, and proceed as follows:
1. Directly query an IP-address
Preferably, attempt to access your
default gateway via your browser. You can find it out using:
~ ➤ ip route default via 172.18.0.1 dev wlan0 proto dhcp src 172.18.120.148 metric 1024 172.18.0.0/16 dev wlan0 proto kernel scope link src 172.18.120.148 metric 1024 172.18.0.1 dev wlan0 proto dhcp scope link src 172.18.120.148 metric 1024ip route
2. Access an HTTP-only website
http://neverssl.com/. You can exclude
HSTS problems when using this website, since it is always served as pure
3. Find out the captive portal address
Some hotspots advertise their captive portal address. If you use a custom DNS-server, begin by identifying the address of the DNS server advertised through DHCP. Use your
DHCP-client for this, or refer to
~ ➤ nmap --script broadcast-dhcp-discover Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-18 18:24 CEST Pre-scan script results: | broadcast-dhcp-discover: | Response 1 of 1: | Interface: wlan0 | IP Offered: 172.18.198.70 | DHCP Message Type: DHCPOFFER | Server Identifier: 172.18.0.1 | IP Address Lease Time: 2m00s | Renewal Time Value: 1m00s | Rebinding Time Value: 1m45s | Subnet Mask: 255.255.0.0 | Broadcast Address: 172.18.255.255 | Router: 172.18.0.1 | Domain Name Server: 172.18.0.1 | NTP Servers: 172.18.0.1 |_ Interface MTU: 1440 WARNING: No targets were specified, so 0 hosts scanned. Nmap done: 0 IP addresses (0 hosts up) scanned in 10.25 seconds
dig) to query the previously advertised DNS-server for the known captive portal address.
~ ➤ drill @172.18.0.1 wifionice.de ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 17224 ;; flags: qr aa rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;; wifionice.de. IN A ;; ANSWER SECTION: wifionice.de. 0 IN A 10.101.64.10 ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ;; Query time: 5 msec ;; SERVER: 172.18.0.1 ;; WHEN: Sun Jul 18 18:45:09 2021 ;; MSG SIZE rcvd: 46
You should be able to connect to that IP-address and go through the captive portal process.
4. Try to manually resolve a captive portal hop
If the aforementioned methods fail and you use a custom DNS server, try to manually resolve a captive portal hop. For instance, Firefox attempts to resolve
drill @DNS-SERVER-ADDRESS detectportal.firefox.com
While an annoying issue to begin with, I remain convinced that the most sensible way to deal with these kind of network issues is to drill (or dig) a little deeper and understand the underlying problems. It’ll leave you with a better understanding of multiple pieces of technology.