Squid Proxy — Splash Page

Hi All! So after my last article regarding securing a guest network web access with Squid and SquidGuard, I wanted to share how I came about creating a Splash Page for Guest users of my Free WiFi hotspot. My goal was to present new Guests with a splash page identifying certain Terms of Usage, etc. Basically we will need a HTML or PHP Splash Page, an ACL identifying the Guests by IP, an external ACL program (squid_session), and a Deny with Information (deny_info).

Some prelimary info:

  • Squid 3.1.19
  • Ubuntu 12.04.2 64-bit Server Edition
  • Apache2 w/PHP5 Installed
  • Guest’s Subnet 192.168.1.0/24
  1. Confirm you have the External ACL Helper Installed

    Search for a program called squid_session, mine was located in /usr/lib/squid3/squid_session. If you do not have this installed, you will need to uninstall squid, and reinstall it from source with squid_session. (outside the scope of this post.)

    find / -name squid_session -print
  2. Create Session Database file

    touch /home/user/sessions.db 
    chown squid. sessions.db

    NOTICE: You have to give whatever user runs the squid process access to this file.

  3. Configure Squid

    vi /etc/squid3/squid.conf
    #Add the following to the conf file:
    #ACL
    acl gNetwork src 192.168.1.0/24
    
    ...omitted...
    
    #splash page
    external_acl_type sessions ttl=60 negative_ttl=0 children=1 concurrency=100 %SRC /usr/lib/squid3/squid_session -t 30 -b /home/user/sessions.db
    acl guest_sessions external sessions
    deny_info http://192.168.0.2/splash.php?url=%s guest_sessions
    http_access deny gNetwork !guest_sessions
    
    • external_acl_type — denotes that an external ACL helper will be used to determine validity
    • acl guest_sessions external sessions — creates a new ACL called guest_sessions that will use the external ACL from above
    • deny_info — location of page to be presented when user is denied. %s is a dynamic variable that contains the original URL the user tried to go to.
    • http_access deny — in this statement we deny every client in the gNetwork range of 192.168.1.0/24 unless, they are part of the guest_sessions ACL.
  4. Create Splash Page

    A splash page should contain any content that you want to present to your users. In my case I create one with basic Terms of Usage, such as no illegal activity, or downloading of large files, etc. Now remember our last deny_info statment? the splash.php?url=%s This is important as this is how we will remember what URL our user tried to go to before forcing them to the splash page.

    <html> 
    ...omitted HTML head and title... 
    <body> bla bla bla bla 
    <h4> By clicking accept you accept the terms of usage explained above for WiFi Usage</h4> 
    <?php echo '<form action="' . htmlspecialcars($_GET["url"]) . '" target="_blank"> 
    <input type="submit" value="Accept" /></form>' ?> 
    </body> 
    </html>

     

    NOTICE: I use PHP here to capture the url=value and place it in the HTML form. When a user clicks the form the action is the URL they originally tried to visit, so they will be navigated there.

  5. Restart squid3

    Restart squid3 to ensure that the child process squid_session starts..

    service squid3 restart

    Verify squid_session process:

    ps gaux |grep squid_session

Other Thoughts

The above example is not entirely secure in presenting the page properly to each user at a set interval. See the squid3 documentation below in the source section. For example, if a user on the gNetwork tries to navigate to a web site, they are presented with the Splash page, once the Splash page has been sent to them they are now stored in the squid_session helper, before they click accept. The concern here is liability, if you are setting this up for a massive Free WiFi network and have legitimate legal concerns, etc. You should look into the active squid_session method. From my understanding, this method allows you to set more than just a client’s IP as a valid check, you could have them enter their email address or something else identifiable. I was unable to figure out how to incorporate Squid Sessions with Active Method, but if someone has please comment! I would like to see what you did to make it work.

Sources: