📜 ⬆️ ⬇️

Dynamic access restriction through web authorization

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

I will tell 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 desirable that the management of the system be - set and forget, give the operator a generic password with the printer and hand the cash register to receive money.

Many people come up with authorization schemes, scripts that change the firewall system tables from time to time according to the necessary tasks, and no one has written a fully dynamic system. Therefore, I propose a prototype that any sysadmin 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:
')
table <wifiallow> persist

Table contents can be dynamically changed using the command line, as well as the pftabled utility. The utility is a udp server that accepts commands for managing table contents.
Using the command line, managing tables is very simple:
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 you to add, delete, and flush operations using udp packages. In the latest release of pftabled 1.07, there is a perl client for managing pftabled. Naturally, all operations are performed only from authorized hosts with 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 scheme is simple. If the host address is trying to access the Internet host is not in the table of permissions, then you need to transfer it to the web with a request to enter a username and password. If the host is present in the table, it must be released to the Internet.
in pf this is solved as follows
$int_if = "xl0";
$ext_if = "xl1";
rdr on $int_if proto tcp from !<wifiallow> to any port 80 -> $int_if port 8081 # apache
nat on $ext_if proto tcp from <wifiallow> to any -> ($ext_if) # nat

In the apache config, we create a virtual host and set rewrite rules for all incoming requests to our script.

<Directory "/usr/local/www/wifi-redir">
Options Indexes ExecCGI FollowSymLinks
Allow from all
RewriteEngine on
RewriteRule ^(.*)$ redirect.cgi?url=$1 [L]
RewriteRule ^redirect\.cgi$ - [L]
</Directory>

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, it is necessary to redirect to the referrer from which the form was filled. If you skip this operation, the form will enter an infinite loop.
If the login and password are correct, that using a piece from the perl client you immediately online simply add an entry to the wifiallow table and somewhere in your journal that the login and password is already used (to avoid abuse). 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 the line to crontab

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

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

This scheme has been tested and works in our company. I think it makes no sense to lay out the contents of the scripts and the current firewall settings, because each admin has his own situation with the distribution of dhcp addresses, a name resolution, etc. The basic idea of ​​implementation is described above.

Good luck to you in the implementation and operation of this solution.

Source: https://habr.com/ru/post/53955/


All Articles