The holiday season is upon us, and you know what that means: relatives coming over wanting to use your WiFi. If you’d like to find a solution somewhere between “run an open, unsecured AP” and “hand out your WPA2 password to people who write things like that down on sticky notes” then setting up a captive portal is a convenient option.
There are several open source captive portals to choose from for your Linux box, including NoCat, HotSpotPA, PacketFence, and ChilliSpot. Unless you have time to explore the features and options, however, a simple, actively-developed solution like WiFiDog is probably the best bet. WiFiDog will run on any Linux distribution, and is an optional package on most of the embedded Linux router firmware projects (like OpenWRT and DD-WRT).
Obviously the task that a captive portal package performs depends on the presence of two (or more) network interfaces on the machine; the portal intercepts connections originating on the restricted interface, performs some sort of authentication, and subsequently begins routing traffic to the unrestricted interface, whether it is also on the LAN or is a WAN port. The canonical layout of this setup is like that on a typical router; the Wi-Fi interface is the restricted side, and the WAN interface is the unrestricted route to the Internet upstream. Other, wired interfaces on the router typically do not involve transient devices, so the portal software does not listen or restrict access on them.
But a dedicated router is not necessary; the same setup will work just as well if you install a Wi-Fi card on a standard Linux server. Nor do you necessarily need to lock yourself out of the Wi-Fi network along with your visitors: if your router is capable of running multiple WLAN SSIDs simultaneously through “virtual interfaces,” you simply choose which interface is to be used for the captive portal, and which interfaces are not.
A basic WiFiDog setup consists of two components: the gateway, which listens for client connection requests, and the authentication server, which approves clients and maintains the active connections. You can run both programs on a full-fledged Linux box, but an embedded router will typically only have enough resources to run the gateway locally; you will want to run the authentication server on another machine.
In terms of actual usage, WiFiDog requires users to create an “account” that is unique to their email address. When the user visits the Wi-Fi gateway, the login page allows them to either log in, or to create a new account, and temporarily opens up network access so that they can check their email for the registration email. When they attempt to log in with the gateway, the gateway forwards the request to the authentication server — if the credentials check out, the gateway and the server exchange tokens, and traffic is permitted from the new client. That may seem like an odd authentication handshake, since the client and the gateway never exchange cryptographic tokens, but it allows WiFiDog to work for a wide variety of devices — unlike systems that require the client to download an SSL certificate or keep a JavaScript script running during the entire browsing session.
Installation and Setup: The Gateway
The gateway package is available as a source code bundle from the WiFiDog project, although if you are installing the gateway on a server or desktop you may find it available through your distro’s package management system. If you are interested in running the gateway on your Linux router, your best bet for installation instructions is to check with the firmware project’s documentation, but you will probably discover a pre-compiled binary available or included in the default builds.
For everyone else, though, the source is easy to compile, as it uses only Linux’s standard netfilter and iptables functionality. Just unpack the source, cd
into the directory, and do the traditional ./autogen.sh; make; sudo make install
three-step.
This creates the wifidog binary and a skeleton configuration file in /etc/wifidog.conf. Open the configuration file in the editor of your choice; the file created documents every option in comment blocks, so it is comparatively easy to read through and supply the right settings. The most important settings are the GatewayID, ExternalInterface, GatewayInterface, and AuthServer.
GatewayID is a name that you assign to this specific node, such as MyHomeWifi. WiFiDog supports administering multiple gateways from a central location, thus the need for naming, but if you only have one node, just pick a name you’ll remember. The ExternalInterface and GatewayInterface settings are the upstream and downstream network interfaces on the system, respectively. In a common configuration, you would set eth0 (a wired Ethernet interface) to be the ExternalInterface, and wlan0 (a wireless network card) to be the GatewayInterface.
The AuthServer setting consists of a block describing the authentication server that this node needs to contact to authorize new clients. Multiple AuthServer blocks are permissible; again this is to allow distributed setups — the node will try them in order until it gets a response. A sample block looks like this:
AuthServer { Hostname mylocalserver.lan SSLAvailable yes Path /wifidog/ }
This tells the node to contact the authorization server at https://mylocalserver.lan/wifidog/. You can customize the URIs used to reach the authentication server in several ways, including tweaking the path to the user login script and success page; the default settings are generally fine unless you already run a complicated Apache configuration on the server.
You can also set timeouts and “keepalive” ping intervals in the config file, along with basic firewall rules, a list of clients to automatically pass-through (the TrustedMACList option), and a custom “portal landing page.” When the file is set up, save it, then start the gateway service from a shell prompt with sudo wifidog -f -d7
. The -f switch keeps the process running in the foreground, and the -d 7 switch sets it to maximum verbosity — this way you can work out all of the kinks. For production usage, you would omit both switches and let wifidog start as a daemon.
Installation and Setup: The Authentication Server
Setup and prerequisites are noticeably higher on the authentication server side; you’ll need Apache, PHP, PostgreSQL, and about a dozen PHP extensions. Most are common, like xmlrpc and mhash, but some are not, such as Auth_RADIUS. Consult the official documentation for a current list. The official docs also suggest increasing the memory size in your php.ini file to at least 32MB.
With the prerequisites in place, though, setup is straightforward. Download and unpack the source code, placing it wherever you choose in your DocumentRoot. It should be available to other machines in the URL you set in /etc/wifidog.conf on the gateway — in this example, http://mylocalserver.lan/wifidog/. When you visit http://mylocalserver.lan/wifidog/install.php, you will be greeted by the authentication server install wizard.
The current installer can check package dependencies, making sure that you have a supported version of PHP and PostgreSQL, but it does not create the PostgreSQL database for you automatically. It does explain how to do so, though, including step-by-step example commands to create the “wifidog” database user, followed by the database and tables. Step through the package validation pages one at a time; verifying the proper version of the PHP libraries and file permissions. Finally, you will be asked to upload the database schema, and create an administrator account. Once this is done, remove the install.php file.
Configuring the authentication server is done by editing the file config.php in the wifidog directory. As with the gateway, examples and comments document each of the options. At the top are typical database settings (hostname, database user) that you may need to adjust. Below that in the “WiFiDog Basic Configuration” section are some options relating to Google Maps and other bling; for the most part you can leave these as-is.
Managing a Gateway
When the server is up and running, connect to the base URL (but not your Wi-Fi gateway…) — you should see the WiFiDog login page. Here you should log in with the administrator account you created earlier; this provides access to the web-based management tool. The first time you connect, nothing will be configured, so you begin by creating a “network” from the Network administration menu.
In the simple case (one authentication server and one gateway), you can assign it any memorable name of your choosing, such as MyBasicNetwork. By default, WiFiDog uses email account verification to authenticate users; if you want to use another authentication method, you can choose it under “Network authentication.” The “Validation grace period” setting allows a newly logged-in user a configurable time slot during which they can check their email for the validation message (by default it is 20 minutes).
After your new network is defined, you add your gateway node to the network by choosing “Add Node” from the “Node administration” menu. The Node ID that you enter must be the name of the node that you created in wifidog.conf on the gateway machine: it was called GatewayID in that file (the inconsistency is WiFiDog’s problem, not yours); our example used MyHomeWifi. Save your settings, and clients will be able to connect through the gateway node, based on the general rules that you set up in under MyBasicNetwork. Here again, WiFiDog’s ability to remotely manage multiple nodes on multiple networks allows for great flexibility in a distributed system, even if it seems like overkill for a single hotspot.
Now, from the web administration interface, you can see which accounts are logged in, check their bandwidth consumption, graph network usage, and check the registration logs. You can also manage user accounts, if you detect strangers that don’t belong, or suspicious account creation activity.
Extra Credit: Extra Vigilance
The procedure outlined above won’t protect you from ne’er-do-wells all on its own; we simply set up a basic gateway without any service restrictions. To keep your hotspot visitors from bringing down your LAN, you have to take extra precautions — starting with setting up firewall rules on the gateway in wifidog.conf. You can use all of the same packet filtering schemes iptables supports on Linux, so you can set up rules to block Bittorrent traffic, restrict access to particular IP address, and more. There are examples detailed in the comments in wifidog.conf, or you can consult any iptables HOWTO.
On top of that, though, it is still your responsibility to notice who is connecting to your network. Recognizing and blocking nefarious visitors is by no means a simple task; one of the problems of Wi-Fi in general is that attackers can sniff the signal, note authenticated IP and MAC addresses, and spoof packets from them to imitate a logged-in client. So as is usually recommended, when it comes to securing your WiFiDog captive portal, you can’t get safer than deny by default. Just be sure not to wander too far off, for when the relatives need you to open up a few more ports.