Ubuntu Wi-fi Hotspot with Web Authentication

I'm searching for a solution to use in my company for guests or visitors, an wi-fi hotspot system like hotels have. i'll share wi-fi connection with username and password. When users connect to wi-fi system will re-direct to them web based login page to connect web sites.

I searched on Google and here but honestly after so many articles as a rookie about linux i'm having an brain explode :) Most of peoples recommended an live cd name is ZoneCD but i couldn't find on internet (The page they provided is about roof fixing -- http://www.publicip.net/features.php -- the article is here http://www.linuxplanet.com/linuxplanet/reports/7087/2).

Also i've found some other articles which says you can do with open radius, open hotspot add-ons but honestly i couldn't installed on my ubuntu.

I get really confused and decided to ask here, i think it's possible to do this on ubuntu bot how we can do it ? Is anybody did this before and can you share about information or an article about how we can do it ?


Part-One

I have come across an Ubuntu hotspot app that allows you to provide wifi through Ubuntu so I hope this will help with that aspect of what you are looking for.

The article source is here http://www.webupd8.org/2013/06/how-to-set-up-wireless-hotspot-access.html

To install the ppa, execute the following commands

sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install ap-hotspot

Now, in version 14.04, hostapd doesn't work properly so the following commands will downgrade hostapd and will use apt to hold the package, preventing automatic upgrades.

For 64bit

cd /tmp
wget http://archive.ubuntu.com/ubuntu/pool/universe/w/wpa/hostapd_1.0-3ubuntu2.1_amd64.deb
sudo dpkg -i hostapd*.deb
sudo apt-mark hold hostapd

Or, for 32bit

cd /tmp
wget http://archive.ubuntu.com/ubuntu/pool/universe/w/wpa/hostapd_1.0-3ubuntu2.1_i386.deb
sudo dpkg -i hostapd*.deb
sudo apt-mark hold hostapd

To start up and configure . . .

sudo ap-hotspot start

To reconfigure after installation . . .

sudo ap-hotspot configure

To stop the hotspot . . .

sudo ap-hotspot stop

and to restart . . .

sudo ap-hotspot restart

For a list of commands . . .

ap-hotspot

Part Two: Web based authentication

adapted from http://pepperspot.sourceforge.net/index.php?n=Doc.UserDocumentation

I have updated some of the commands to comply with the more current practice of using sudo.

First install the build modules

sudo apt-get install build-essential linux-headers-generic automake subversion libtool

To download and build the pepperspot source package; execute the following commands:

svn co svn://svn.code.sf.net/p/pepperspot/code/trunk pepperspot
cd pepperspot
autoreconf -f -i
./configure
make
sudo make install
sudo modprobe ipv6
sudo apt-get install radvd iptables libc6-dev quagga apache2 libapache2-mod-php5 libssl-dev freeradius

1.) Activate IPv6

First of all, be sure that IPv6 is activated on your kernel. If IPv6 is compiled as a module, type:

sudo modprobe ipv6

1.1) Stateless autoconfiguration

This is an example of the /etc/radvd.conf configuration file:

interface ath0  
{
  AdvSendAdvert on;
  AdvIntervalOpt on;
  MinRtrAdvInterval 2;
  MaxRtrAdvInterval 6;
  prefix 2001:db8:1::/64
  {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;
    };

    RDNSS 2001:db8:2::1 
    {
        AdvRDNSSPreference 8;
    AdvRDNSSOpen off;
    AdvRDNSSLifetime 30;
    };
};

Replace interface, prefix and RDNSS (DNS server information) lines with your own values, and launch radvd with:

sudo radvd -C /etc/radvd.conf

1.2) Addressing and Routing

A captive portal have to route packets of an authenticated user towards Internet. So the system must have IPv6 forwarding enabled. You can turn it on with:

echo "1" | sudo tee /proc/sys/net/ipv6/conf/all/forwarding

To keep this configuration persistent, you can use the following command:

echo 'net.ipv6.conf.all.forwarding=1' | sudo tee -a /etc/sysctl.conf

IPv6 forwarding will disable the IPv6 autoconfiguration, so network configuration (assign addresses and routes) can be set statically or dynamically with routing daemons. For the last ones procedure look at section 2.

If you want to use the static addressing and routing procedure, assuming that eth0 is the interface connected to the IPv6 network to Internet, type the following command and replace with your own value.

Assign address on wired interface:

sudo ip -6 addr add 2001:db8:1::1234/64 dev eth0

Add the default route configuration (replace with you route address value):

sudo route -A inet6 add default gw fe80::1:2:3:4 dev eth0

You can turn this configuration persistent insert the network configuration in your /etc/network/intefaces as you can see in this example:

auto eth0
iface eth0 inet6 static
        address 2001:db8:1::1234
        netmask 64
                gateway fe80::1:2:3:4
        pre-up modprobe ipv6      # to be sure that ipv6 is enabled before we turn up the interface 

Note that you do not have to configure address on interface connected to the Access Point box (or the wireless interface if you use ones).

1.3) IPv4

The IPv4 configuration is more or less the same than IPv6, except that you don't need the advertise the client for network configuration. PepperSpot integrates a DHCP module to attribute an IPv4 address to remote clients. You can disable this module in the PepperSpot configuration if the wireless link already have a DHCP server, or if clients configuration is set statically. You need nevertheless to configure the interface linked to the IPv4 network.

In the same way, enable the IPv4 forwarding using the following commands:

echo "1" | sudo tee /proc/sys/net/ipv4/conf/all/forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf

and configure the interface address and route (Replace with your parameters):

sudo ip addr add 192.168.0.1/24 dev eth1
sudo route add default gw 192.168.0.254 dev eth1

You can use the following block command to update your /etc/network/interfaces file:

echo 'auto eth1
iface eth1 inet static
    address 192.168.0.1
    netmask 24
    gateway 192.168.0.254' | sudo tee /etc/network/interfaces

1.4) Netfilter Support

PepperSpot will use some Netfilter's rules to proceed the communication between the client and Internet. So the system must support Netfilter. If it's not the case, modify the configuration of your kernel:

For IPv4, you need to enable the Nat, Mangle and tracking support;

For IPv6, you only need the basic support.

1.5) Notes

All services (Radius, web server, PepperSpot, ...) can be installed on systems which provide Wi-Fi access (Master mode). It can be an embedded device, or a system from scratch configured as an Access Point.

For this case, your Wi-Fi card must support the Master mode.

For example if you use wireless interface with madwifi driver, here is an example initialisation script:

#!/bin/bash

# Setting ath0 in Master mode
# Replace PepperSpot by your SSID

wlanconfig ath0 destroy
wlanconfig ath0 create wlandev wifi0 wlanmode ap
iwconfig ath0 essid "PepperSpot"    
ifconfig ath0 up

2) Configure the Quagga routing suite

The Quagga routing suite implements some IPv4 and IPv6 routing protocols. This section describes the installation of the RIPng protocol to allow IPv6 routing. We assume that you have a delegated IPv6 prefix, and that you need to route the communication for this prefix. If it's not the case, you can skip this section.

The configuration of quagga is done by setting up some configuration files in the /etc/quagga directory, but the quagga suite integrates some cisco-like interfaces for each protocol to allow configuration on the fly and to view some routing information like routing table.

You can put IPv6 and IPv4 network configurations described before, in the routing protocol configuration. For each protocol you want, enable it in /etc/quagga/daemon .

We need to enable zebra, because it's the main routing module needed to use other protocol and configure interfaces. In our case, we only need to add RIPng too:

# This file tells the quagga package which daemons to start.
#
# Entries are in the format: <daemon>=(yes|no|priority)
#   0, "no"  = disabled
#   1, "yes" = highest priority
#   2 .. 10  = lower priorities
# Read /usr/share/doc/quagga/README.Debian for details.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/quagga/examples/.
#
# ATTENTION:
#
# When activation a daemon at the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "quagga", else
# the daemon will not be started by /etc/init.d/quagga. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "quaggavty" and set to ug=rw,o= though. Check /etc/pam.d/quagga, too.
#
zebra=yes
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=yes
isisd=no

Now we have to create one configuration file for each daemon launched.

/etc/quagga/zebra.conf file:

!
! Zebra configuration saved from vty
!   2008/04/10 12:18:58
!
hostname MobSpot
password ***********
enable password *************
!
interface ath0
 ipv6 nd suppress-ra
!
interface eth0
 ipv6 address 2001:db8:1::1234/64
 ipv6 nd suppress-ra
!
interface eth1
 ip address 192.168.0.1/24
 ipv6 nd suppress-ra
!
interface eth2
 ipv6 nd suppress-ra
!
interface eth3
 ipv6 nd suppress-ra
!
interface lo
!
interface tun0
 ipv6 nd suppress-ra
!
interface wifi0
 ipv6 nd suppress-ra
!
ipv6 forwarding
!
!
line vty
!

In this file, we set up the static configuration of each interface linked to the service network (eth0 and eth1).

/etc/quagga/ripngd.conf file:

! -*- rip -*-
!
! RIPngd sample configuration file
!
! $Id: ripngd.conf.sample,v 1.1.1.1 2002/12/13 20:15:30 paul Exp $
!
hostname MobSpot
password ***********
enable password ************
!
! debug ripng events
! debug ripng packet
!
!
router ripng
network eth0
redistribute connected
redistribute static
route 2001:db8:1::/64
!
line vty
!

In this file, we configure the RIPng protocol, indicating that we are able to route packet for 2001:db8:1::/64 prefix on the eth0 interface.

For the both files, the first section will define the password for the configuration interfaces (vty). The enable password line indicate that a password is required to get the right to reconfigure the daemon. Don't forget the line vty line to enable this configuration interface.

For zebra configuration type:

sudo telnet 127.0.0.1 zebra

For RIPng configuration:

sudo telnet 127.0.0.1 ripngd

Note: After authentication (with the password line renseigned into configuration file), you will obtain a command line to configure the daemon. Type "?" to see available commands.

To finish, restart quagga daemons:

sudo /etc/init.d/quagga restart 

Note: If you need to configure IPv4 routing, adapt this configuration to RIP daemon.

3) Apache configuration

PepperSpot needs to communicate with a Web Server installed on the same machine to allow clients to proceed authentication. The web server have to be configured for SSL, PHP and CGI.

Here is the configuration for Apache2 web server:

Generate a SSL certificate to guarantee the identity of the web server:

sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/key.pem

The second step is to load the Apache2-SSL module:

sudo a2enmod ssl

The web server need a virtual host to be reachable. Create the file /etc/apache2/sites-available/pepperspot with the following contents (Adapt to your needed configuration):

NameVirtualHost *:443

<VirtualHost *:443>
        ServerAdmin webmaster@pepperspot
        SSLEngine on
        SSLCertificateFile /etc/apache2/key.pem

        DocumentRoot /var/www/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
                    # This directive allows us to have apache2s default start page
                    # in /apache2-default/, but still have / go to the right place
                RedirectMatch ^/$ /apache2-default/
        </Directory>

            # CGI - We need cgi support to communicate with PepperSpot
        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
</VirtualHost>'

If you want to modify the name of the virtual host, don't forget that Apache needs to listen on both IPv6 and IPv4 address for dual stack mode, and on IPv4 or IPv6 interface regarding to the single mode you will choice.

Add in /etc/apache2/ports.conf to allow HTTPS listening (if not already present) with the following block code:

echo '<IfModule mod_ssl.c>
    Listen 443
</IfModule>' | sudo tee -a /etc/apache2/ports.conf

Finally, load the site:

sudo a2ensite pepperspot
sudo /etc/init.d/apache2 reload

4) FreeRadius Configuration

PepperSpot is able to communicate with a Radius Server over IPv4 or IPv6 protocol, regarding to the radius server address configuration in /etc/pepper.conf. Here is the configuration of FreeRadius Server. To have IPv6 support, you need a version of FreeRadius >= 2.0.

The FreeRadius configuration is complex, and the following describes only an elementary configuration to enable IPv6 support on FreeRadius, and an easy way to add some user accounts. If you want a better configuration, see the FreeRadius documentation.

4.1) IPv6 configuration

Modify the /etc/freeradius/radiusd.conf file to add the followings section:

# For authentication 
listen {
        type = auth
#       ipaddr = *
        ipv6addr = ::1
        port = 0
#       interface = eth0
#       clients = per_socket_clients
}

# For accounting                         
listen {
        type = acct
#       ipaddr = *
        ipv6addr = ::1
        port = 0
#       interface = eth0
#       clients = per_socket_clients
}

With this configuration, replace ::1 for the field ipv6addr by the address in which FreeRadius must listen. port = 0 means that default Radius ports are used. If you specify * for ipv6addr, FreeRadius will listen on each IPv6 address configured on the system.

Now, you need to configure a FreeRadius client (called as NAS), typically the NAS is the captive portal.

Open the /etc/freeradius/clients.conf file and add the following lines:

client ::1 {      # here ::1 is the name of the client. Replace with your own value
    ipv6addr    = ::1
    secret  = testing123
    shortname   = localhost
    nastype     = other
}

If PepperSpot and FreeRadius are on different box, ipv6addr must be replace by the address with which PepperSpot and FreeRadius communicate. Modify the shortname too.

To restart FreeRadius:

sudo /etc/init.d/freeradius restart

4.2) IPv4 configuration

For IPv4 configuration of FreeRadius, replace the ipv6addr field with ipaddr, and fill it with the IPv4 address wanted.

4.3) Accounts

Finally, we need to create accounts in /etc/freeradius/users:

toto Cleartext-Password := "totoilsaitpas"

ping6 Cleartext-Password := "pong6"

Restart FreeRadius:

sudo /etc/init.d/freeradius restart

5) PepperSpot configuration

Copy some configuration files:

sudo cp doc/pepper.conf /etc/
sudo cp doc/hotspotlogin.cgi /usr/lib/cgi-bin/
sudo chmod +x /usr/lib/cgi-bin/hotspotlogin.cgi

For IPv4:

sudo cp doc/pepper.iptables /etc/
sudo chmod +x /etc/pepper.iptables

For IPv6:

sudo cp doc/pepper.ip6tables /etc/
sudo chmod +x /etc/pepper.ip6tables

5.2) iptables

Modify the /etc/pepper.iptables and/or /etc/pepper.ip6tables scripts and adapt $INTIF (interface connected to the access point or the wireless interface), $EXTIF4 (interface connected to the IPv4 LAN) and $EXTIF6 (interface connected to the IPv6 LAN) values regarding to your configuration. Note that for dual stack configuration $EXTIF4 and $EXTIF6 could have the same value.

You can follow the rest of the setup from the pepperspot user documentation. http://pepperspot.sourceforge.net/index.php?n=Doc.UserDocumentation There is only one configuration section left.