NAME
    Captive::Portal - Perl based solution for controlled network access

ABSTRACT
    A so called *Captive Portal* written in perl for Linux Gateways. For a
    longer explanation see:

    <http://en.wikipedia.org/wiki/Captive_Portal>

DESCRIPTION
    Captive::Portal a.k.a. CaPo is a Hotspot solution for Linux Gateways.
    CaPo is developed and in service at Ulm University for thousands of
    concurrent users. The main focus is scalability, performance, simple
    administration and user-friendliness.

    The goals were achieved by using scalable technologies like ipset(8)
    instead of native iptables(8), FastCGI instead of CGI and a fine tuned
    concurrent session handling based on the filesystem locking mechanism
    without any need for an additional RDBMS.

    CaPo is compatible with any FastCGI enabled HTTP(S)-server.

ALGORITHM IN SHORT
    1. Internal NAT redirect
        HTTP-traffic on the gateways inside interface - from unknown clients
        - is redirected by an iptables(8) NAT-rule to a port the HTTP-server
        is listen, e.g.

         iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 5281

    2. HTTP to HTTPS redirect
        The HTTP-server redirects the HTTP-request by a rewrite rule to an
        HTTPS-request for the CaPo script *capo.fcgi* , e.g.

         <VirtualHost *:5281>
             RewriteEngine On
             RewriteRule   .*  https://gateway.acme.org/capo/? [R,L]
         </VirtualHost>

    3. SESSION LOGIN
        The *capo.fcgi* script offers a login/splash page. After successful
        login the firewall is dynamically changed to allow this clients
        IP/MAC tuple for internet access.

    4. SESSION LOGOUT
        The capo.fcgi script offers a status/logut page. After successful
        logout the firewall is dynamically changed to disallow this IP/MAC
        tuple for internet access.

    5. SESSION IDLE
        A cronjob fires periodically the capo-ctl.pl script checking for
        idle sessions. Idle means, the client didn't send any packet for a
        period of time (cfg param: IDLE_TIME = 10min). Before a session is
        put into idle state the client is once pinged.

        It is a design goal not requiring JavaScript on clients!

    6. SESSION REACTIVATION
        For a short period of time (cfg param: KEEP_OLD_STATE_PERIOD = 1h)
        the session is still on disc, but in idle state. If a client request
        matches the sessions IP/MAC/COOKIE data, the session is reactivated
        without a login page.

INSTALLATION
    Please see the INSTALL file in this distribution. As a minimum please be
    aware of the following access restrictions:

    Captive::Portal needs access to iptables(8) and ipset(8) to change the
    firewall-rules on request. You must add the following rule (or similar)
    to the sudoers file, depending on the username of your http daemon:

     WWW_USER ALL=NOPASSWD: /PATH/TO/iptables, /PATH/TO/ipset

    If you use fping(8) (see USE_FPING config parameter) to trigger idle
    sessions before going idle you must add fping to the sudoers file like
    ipset and iptables, regardless of the suid bit on fping, since we need
    special timing flags available only for root:

     WWW_USER ALL=NOPASSWD: /PATH/TO/iptables, /PATH/TO/ipset, /PATH/TO/fping

    The default $SESSIONS_DIR is set to '/var/cache/capo'.

    WWW_USER must be the owner of this dir with write permissions!

CONFIGURATION
    The configuration file is searched in the following default places:

        $ENV{CAPTIVE_PORTAL_CONFIG} ||
        $Bin/../etc/local/config.pl ||
        $Bin/../etc/config.pl

CONFIGURATION PARAMETERS
    The configuration syntax is perl.

  PRESET GLOBAL PACKAGE VARIABLES, CHANGES POSSIBLE
    The following variables can be used for interpolation in config values.

     $APP_NAME = 'capo'

     $APP_DIR = "$Bin/../"

  PRESET DEFAULTS, CHANGES POSSIBLE
    DOCUMENT_ROOT => "$APP_DIR/static"
        Basedir for static content like images, css or error pages.

    TEMPLATE_INCLUDE_PATH =>
    "$APP_DIR/templates/local/:$APP_DIR/templates/orig"
        Directories to search for templates.

    RUN_USER => 'wwwrun'
        Drop privileges to RUN_USER.

    RUN_GROUP => 'www',
        Drop privileges to RUN_GROUP.

    SESSIONS_DIR => "/var/cache/$APP_NAME"
        Where to store the session files. This directory must exist und must
        be readable/writeable by RUN_USER.

    SECURE_COOKIE => ON
        If this attribute is set, the cookie will only be sent to your
        script if the CGI request is occurring on a secure channel, such as
        SSL.

    SESSION_MAX => 48 * 3600 # 2d
        Max session time until a forced disconnect.

    IDLE_TIME => 60 * 10 # 10 min
        How long to wait for activity from ip/mac until a session is marked
        idle.

    KEEP_OLD_STATE_PERIOD => 1 * 60 * 60, # 1h
        How long to keep idle session records on disk for fast reconnect
        with proper ip/mac/cookie match.

    USE_FPING => ON # use fping to trigger idle clients
        Use fping(8) to trigger idle clients.

    FPING_OPTIONS => [qw(-c 1 -i 1 -t 1 -q)] # SuSe default
        fping(8) options for current Linux distribution.

  LOCAL PARAMETERS, CHANGES NEEDED
    ADMIN_SECRET
        Passphrase for detailed sessions view.

    AUTHEN_SIMPLE_MODULES
        Authentication is handled by the Authen::Simple framework. You may
        stack any of the Authen::Simple::... plugins for authentication, see
        the $Bin/../etc/config.pl template.

    IPTABLES->capture_if => 'eth1'
        The inside gateway interface, e.g. 'eth1'. All http traffic, not
        allowed by any predefined rule, is captured and redirected to the
        capo.fcgi script.

    IPTABLES->capture_net => '192.168.0.0/22'
        The inside IP network in CIDR notation, e.g. '192.168.0.0/22'

    IPTABLES->capture_ports => [80, 8080]
        What tcp ports should be captured and redirected, e.g. [ 80, 8080]

    IPTABLES->redirect_port => 5281
        The port where the HTTP-server is listen in order to rewrite this
        http request to an https request.

        The above settings result in a NAT rule equivalent to:

         iptables -t nat -A PREROUTING -i eth1 -s 192.168.0.0/22 ! -d 192.168.0.0/22 \
                  -p tcp -m multiport --dports 80,8080 -j  REDIRECT --to-port 5281

    IPTABLES->throttle => OFF
        You may throttle HTTP/HTTPS requests/sec per client IP. Some
        clients/gadgets fire a lot of HTTP traffic without human
        intervention. Depending on your hardware and your encryption
        resources this will overload your gateway.

    IPTABLES->throttle_ports => [ 80, 5281]
        You should protect/throttle port 80 and the redirect_port (see
        above).

    IPTABLES->throttle_seconds => 30
    IPTABLES->throttle_hitcount => 15
        Both parameters define the average and the burst. Average is
        hitcount/seconds and burst is hitcount in seconds. With the values
        of 30 and 15, the average would be 15hits/30s => 1hit/2s. The burst
        would be 15hits in 30 seconds.

        The above settings result in iptable rules equivalent to:

         # throttle/drop new connections
         iptables -t filter -A INPUT -p tcp --syn -m multiport --dports 80,5281 \
            -m recent --name capo_throttle --rcheck --seconds 30 --hitcount 15 -j DROP

         # at last accept new connections but set/update the recent table
         iptables -t filter -A INPUT -p tcp --syn -m multiport --dports 80,5281 \
            -m recent --name capo_throttle --set -j ACCEPT

    IPTABLES->open_services
        Allow access to open local services like DHCP, DNS, NTP, ...

    IPTABLES->open_clients
        Allow access for some dumb clients without autentication.

    IPTABLES->open_servers
        Allow access to some open servers.

    IPTABLES->open_networks
        Allow access to some open networks.

    I18N_LANGUAGES
        Supported languages for system messages and HTML templates.

    I18N_FALLBACK_LANG
        Fallback language if the client message isn't supported in the
        system message catalog and templates.

    I18N_MSG_CATALOG
        Translations of the system messages.

LOGGING
    Logging is handled by the Log::Log4perl module. The logging
    configuration is searched in the following default places:

        $ENV{CAPTIVE_PORTAL_LOG4PERL}   ||
        $Bin/../etc/local/log4perl.conf ||
        $Bin/../etc/log4perl.conf

SEE ALSO
    capo.fcgi
        (f)cgi script for Captive::Portal

    capo-ctl.pl
        Controller script for Captive::Portal

    test-server.pl
        Simple HTTP server based on HTTP::Server::Simple::CGI to test the
        Captive::Portal installation. Don't use it for production.

    mock-server.pl
        Simple HTTP server based on WWW::Mechanize::CGI for the test suite
        during installation.

BUGS AND LIMITATIONS
    There are no known problems with this module.

    Please report any bugs or feature requests to "bug-captive-portal at
    rt.cpan.org", or through the web interface at
    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Captive-Portal>. I will
    be notified, and then you'll automatically be notified of progress on
    your bug as I make changes.

AUTHOR
    Karl Gaissmaier, "<gaissmai at cpan.org>"

LICENSE AND COPYRIGHT
    Copyright 2010-2011 Karl Gaissmaier, all rights reserved.

    This distribution is free software; you can redistribute it and/or
    modify it under the terms of either:

    a) the GNU General Public License as published by the Free Software
    Foundation; either version 2, or (at your option) any later version, or

    b) the Artistic License version 2.0.

    The full text of the license can be found in the LICENSE file included
    with this distribution.

