Dynamic access restriction through web authorization

    Often there is a need to provide access to some segment of the guest user network, limited in time.

    I’ll tell you a little about the task.
    We have a wifi network or LAN in an Internet cafe where we need to provide time-based access to the Internet. It is advisable that the system be controlled - set and forget, give the operator a password generation with a printer and hand in a cash register for receiving money.

    Many people come up with authorization schemes, scripts that change the firewall system tables from time to time according to necessary tasks, and no one wrote a fully dynamic system. Therefore, I propose a prototype that any system administrator adapts to his tasks.

    I think Linux system administrators will be able to implement this mechanism based on their favorite firewall, but we will use pf.
    Why pf you ask?
    Because it has a wonderful thing called dynamic tables.
    In the pf configuration file, the tables are described as: The contents of the tables can be dynamically changed using the command line, as well as the pftabled utility . The utility is an udp server that accepts table content management commands. Using the command line, managing tables is very simple:

    table persist



    pfctl -t tablename -T show - показать содержимое таблицы
    pfctl -t tablename -T expire 3600 - удалить все элементы старше 1 часа
    pfctl -t tablename -T add 10.10.10.10 - добавить с таблицу элемент
    pfctl -t tablename -T delete 10.10.10.10 - удалить элемент из таблицы
    pfctl -t tablename -T flush - очистить таблицу

    pftabled allows add, delete, and flush operations through udp packages. The latest release of pftabled 1.07 has a perl client for managing pftabled. Naturally, all operations are performed only from authorized hosts that have the same key as the listening server.

    So what do we need?
    apache with mod_rewrite module and the desire to implement this scheme.

    The basic principle of the circuit is simple. If the address of the host trying to access the Internet host is not in the permissions table, then you must transfer it to the web face with a request to enter a username and password. If the host is in the table, then it must be released to the Internet.
    in pf, this is solved as follows. In the apache config, create a virtual host and write rewrite rules for all incoming requests to our script.
    $int_if = "xl0";
    $ext_if = "xl1";
    rdr on $int_if proto tcp from ! to any port 80 -> $int_if port 8081 # проброс всех запросов на порт apache с вебмордой
    nat on $ext_if proto tcp from to any -> ($ext_if) # nat всех кто разрешен в инет




    Options Indexes ExecCGI FollowSymLinks
    Allow from all
    RewriteEngine on
    RewriteRule ^(.*)$ redirect.cgi?url=$1 [L]
    RewriteRule ^redirect\.cgi$ - [L]


    The script accepts the request and issues an authorization form. As the url parameter, the address requested by the user will be passed. After submit and incorrectly entered login password inside the form, you need to make a redirect to the referrer from which the form was filled. If you skip this operation, then filling out the form will enter an infinite loop.
    If the username and password are correct, that with the help of a piece from the perl client you immediately add online an entry to the wifiallow table and log somewhere that this username and password have already been used (so that there is no abuse)., And then do redirect to the url that the user originally requested. The table of logins and passwords can be maintained in mysql or in any form convenient for you. After the form has earned you add a line to crontab

    * * * * * /sbin/pfctl -t wifiallow -T expire 3600 > /dev/null

    which will remove IP addresses from the table every minute with a creation time of more than 1 hour. The only problem that may arise is pf support for already established connections. The way out is simple. We write a small script on shell + awk + grep that will do pfctl -k hostip once every five minutes (removing keepstate connections) for hosts that are not in the allowed address table.

    This scheme has been tested and works in our company. I don’t think it makes sense to upload the contents of scripts and the current settings of the firewall, because each of the admins has their own situation with the distribution of dhcp addresses, resolving names, etc. The basic idea of ​​implementation is described above.

    Good luck with the implementation and operation of this solution.

    Also popular now: