Transform Raspberry Pi in hot spot Wifi with captive portal (2/2)

For an automatic install of the hotspot, read this post.

In a previous article, We had installed our own Wifi access point. Now it comes to add a captive portal to control who will use it. Hotspot_WiFiTo a captive portal you have several options :

  1. The simple method is passing through a PHP page. You can display a message in an HTML page, wait for an and then allow access to Internet.
  2. The more complex method where you go through a specialized tool as for example YFi Hotspot Manager.

Each method has much on its advantages and disadvantages but initially I chose simplicity and only control basic way Internet access. It will be through a PHP page.

A captive portal in PHP

  1. Install Nginx with PHP support. The simplest is to follow the instructions of this article. Here is my server configuration :
    server {
    	root /var/www;
    	index index.php;
    	server_name localhost;
    	location / {
    		try_files $uri $uri / index.php;
    	}
    	location ~ .php$ {
    		fastcgi_split_path_info ^(.+\.php)(/.+)$;
    		fastcgi_pass unix:/var/run/PHP5-fpm.sock;
    		fastcgi_index index.php;
    		include fastcgi_params;
    	}
    }
  2. Install additional packages :
    apt-get install conntrack
  3. Allow the user www - data to perform the commands required to manage access :
    Launch visudo then add the following lines at the end of the file :
  4. www-data ALL=NOPASSWD: /usr/sbin/arp
    www-data ALL=NOPASSWD: /sbin/iptables
    www-data ALL=NOPASSWD: /usr/bin/rmtrack [0-9]*.[0-9]*.[0-9]*.[0-9]*
    
  5. Create the home page index.php
    <!--?php 
    $ip = $_SERVER['REMOTE_ADDR'];
    $mac = shell_exec("sudo /usr/sbin/arp -an " . $ip);
    preg_match('/..:..:..:..:..:../',$mac , $matches);
    $mac = @$matches[0];
    if( $mac === NULL) { echo "Access Denied."; exit; }
    ?-->
    <form action="process.php" method="post">
    <input name="mac" type="input" value="<?php echo $mac; ?>" /> 
    <input name="ip" type="input" value="<?php echo $ip; ?>" />
    <input style="padding: 10px 20px;" type="submit" value="OK" />
    </form>
    
  6. Create the page that will generate the rules to allow access to the Internet process.php. When the user has validated the form on the previous page, It is she who will be called to give full access.
    
    
  7. Create the set of routing rules
    iptables-t mangle-N internet iptables-t mangle-A PREROUTING-i wlan0-p tcp-m tcp--dport 80 -j internet iptables-t mangle-A internet-j MARK--set-mark 99
    iptables -t nat -A PREROUTING -i wlan0 -p tcp -m mark --mark 99 -m tcp --dport 80 -j DNAT --to-destination 192.168.10.1
  8. Save the rules for the next few reboots
    service iptables-persistent

 

Here you are ! An access point with a captive portal. You can edit PHP pages to change the look and features. A database could, for example, memorize the MAC addresses to not ask the connection, manage a connection time, a volume, etc.

Sources :

You may also like...

  • EDWARDS ABDO

    Very good tuto ,
    A note remove the php code comments in the two files index.php and process.php.

  • luckidu33

    ATTENTION !!! This tutorial allows an attacker to take control of the server by injecting (with rights very high!!!!!!) system in the variable $ip and $mac commands!!! A control should be done at the time $ip = $_POST['ip'];
    $mac = $_POST['mac'];

  • Hi, code on point 5 is empty 🙁

    • Hi
      Updated. You have to copy/paste in a page called process.php

      • perfet, thank you

      • Prasan Dutt

        Code is still missingwhat should be the process?

        • Look at http://www.andybev.com/index.php/Using_iptables_and_PHP_to_create_a_captive_portal
          I lost code and have no time to rebuild it. Else you the automatic script with coovachilli

          • Prasan Dutt

            You won’t believe but I was using the same link to modify my index.php and was trying to understand. 🙂 However, thanks for recommending coovachilli, it seems simpler, will give it a try

          • Prasan Dutt

            Today I guessed one strange thing, the DHCP server is internal wifi on RPi3, not external USB wifi dongle. WiFi is generated even without the dongle.
            I guessed it yesterday only as the range of wifi was just 10-15 feet. How to route the internet to external USB wifi dongle? WLAN1 is the configuration which I think will be helpful in setting up.

          • Identify your dongle and confirm that it’s wlan1 and replace wlan0 by wlan1 in all steps. Never tested but should work

  • lesjno

    Hello,
    It has to be a good tutorial; Unfortunately I have a concern.
    Just before making the step 6 (routing rules), the system behaves as a simple access point : It connects well with wifi and access to internet, either http or https.
    But after the stage 6 It gets a “404 Not Found” When you type an http address while I expected to display the page index.php of the access point (the /var/ www/index.php page that appears well when that I type directly address 192.168.10.1 in the browser).
    What's missing in my setup to automatically go on the captive portal ?

    Thanks in advance !

    • lesjno

      Little additional info : Here is what I have in the log if I want to access for example to the page http://lesjno.free.fr/Solar/index.html

      in /var/log/nginx/access.log ==>
      192.168.10.4 - - [29/Dec/2014:17:10:44 -0100] “GET /Solar/index.html HTTP/1.1” 404 142 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64; RV:34.0) Gecko/20100101 Firefox/34.0”

      in the file error.log ==>
      2014/12/29 17:10:44 [error] 6830#0: *14 open() “/var/www/Solar/index.html” failed (2: No. such file or directory), client: 192.168.10.4, server: , request: “GET /Solar/index.html HTTP/1.1”, host: “lesjno.free.fr”

      • The index.html file there is therefore not. Is required ? If not in creating ca will remove the error

        • lesjno

          Hello,

          I expressed myself badly. The example given was that a “example” ! I set myself as “client” connected to wifi access point and who wished to visit a web page any. The website it even is not the problem, I could have taken thousands of other examples.
          To be generic, Imagine you want to access the site http://aaaaa/bbbbb : I guess only in operation “normal” of the access point with captive portal I should first go not on the requested page, but on the login page prepared for the identification of the user, Therefore, the page that is located locally on the Raspberry : /var/www/index.php. But this is not the case : log indicate that the system is trying to make an open() from “/var/www/banks” (that does not exist of course !), request “GET /bbbbb HTTP/1.1”, host: “AAAAA”.
          There is something going wrong in the configuration. Is this in the iptables config ? What is elsewhere ?

          • OK actually passing through the page should by default be. If this is correct side login password then the ip tables are put in place to open up access to the outside. But I don't know if the page is set by default to the beginning or to get it the first time ….

          • Nicolas Leleu

            Et si on faisait la page de logon via la page d’erreur 404, page non trouvée? ou alors, la page 404 redirigerait vers index.php

  • Ricardo

    Hello,

    The point 5 is empty, could put it back you please, Thank you.

  • Henry Bernard

    Thank you bcp for this tutorial, it allowed m to set up wifi. On the other hand, even with a ipforward 0, I do not have the popup / splash-page captive portals… nor on mac, ni ios, ni android. Do you know how to do ? It would be very best to be able to ca, we connect and - pop - a browser window is displayed as in restaus, hotels, etc.

    • Je ne sais pas mais moi aussi ca m’interresse de savoir comment faire 🙂

      • Henry Bernard

        The thing, c is that it should be done alone. As with free wifi… When an OS (iOS, Android, Mac) connects to wifi it checks if it is captive or not… If Yes, it sends a popup. What's weird is that it is c not already done …

        • Iptv

          I'm interested in what you can do with the device , See homepage hotels or restaurants . Thank you

          • FYI I'll do an article with CoovaChilli that displays a popup with the arrival on the WiFi network, in the popup window there is a customizable HTML page and users are managed by an authentication via FreeRadius

  • Iptv

    Hello, I see that the comments are not in Spanish, You could answer questions in Spanish?

  • Chris

    The code on point 5 seems to be missing.

  • Mohit Madan

    The code is missing(Point 5)

  • cpS

    The codes in section 4 and 5 are missing.

  • The code in section 4 and 5 are again missing…….

  • Tania Daniela Paiva Falcón

    Hello, code on point 5 is misisng.

  • Chris

    Hello what has happened to section 4 and 5 after-all?

    • Code has been deleted and I do not find any backup sorry. I should take time to recreate it. Else use my post with coovachilli

  • Rodrigue ANDRIANOMENJANAHARY

    Hello

    How did we going to do if you installed apache2 and phpmyadmin on raspberry??

    I get to share the connection of my raspberry with a phone and a computer but I do not want that every time I have to type my ip address tracking file that I want I want voir.Alors in connecting to my network with a phone,when I open the browser,there immediately the homepage that appears.

    Does someone can help me??,Thank you very much

    • Instead, use the freeradius and coovachilli solution that is presented on this site and that works as you expect

  • Paddy

    I found the old side with the code: http://www.pihomeserver.fr/de/2014/05/23/raspberry-pi-home-server-creer-hot-spot-wifi-portail-captif-22/

    Auf der Seite fndet man den Quellcode für 5.

Handpicked links

disk Page Caching using disk: enhanced Database Caching 116/536 queries in 0.273 seconds using disk Served from: pihomeserver.fr @ 2017-07-18 22:23:07 by W3 Total Cache -->