Hello misc,

Using OpenBSD 5.0 I've managed to put together a simple captive portal
based on a ticketed system. When a customer wants to use the internet
they must get an access key from the front desk. When they associate
with the network they must authorize the key in order to pass through
the firewall.


This system was built very short notice and has been running relatively
smooth for several months. My intent is to turn it over to the public
for scrutiny and hopefully some feedback.


There are two web interfaces, one for the admins which allows key
creation and key summaries, and one for the user; which until they
authorize a valid key, only takes them to a page which asks for a key
input (Apache mod_rewrite). Once authenticated they can also check their
usage summary.


The web interfaces interact with the system through CGI scripts, httpd
is run chroot disabled (httpd_flags="-u").


The system offers up dhcpd leases to whomever associates successfully
with the access points, dhcpd is run to interact with pf's table entries
(dhcpd_flags="-L leased_users -C authorized_users vr0 vr1).


The other network services in effect are of course pf and named.


pf's config is setup to allow leased_users dns resolution and web access
to the gateway, once authenticated the user becomes part of the
authorized_users table and is unrestricted. The authorized_users table
has counters turned on. The counters are monitored by a cron script
which deletes the table entry for anyone who has exceeded a pre-defined
limit.


The scripts consist of: authorize-key.cgi, check-usage-admin.cgi
check-usage-user.cgi, generate-key.cgi, generate-keys.cgi,
generate-key-1GB.cgi, monitor-usage.cgi, monitor-usage-1GB.cgi,
search-records.cgi, show-keys.cgi, show-keys-1GB.cgi, show-limits.cgi,
show-start.cgi, show-users.cgi. Email me off-list and I'll be happy to
share the scripts.


The only way I can see someone getting passed this portal is through arp
spoofing or something similar. I haven't witnessed it yet although it is
a real possibility. What does this mean, well someone can force an IP
onto their computer and "piggy-back" on someone else's access key or
change their mac address and cause other confusion.


The question I have is relating to the way which I monitor usage
summaries. I've included the script below (monitor-usage.cgi) for
reference. I'm currently grep'ing and cut'ing the data output by pfctl.
So far it's been working great, BUT, is there an easier, more efficient
way to get data out from pfctl?


All comments welcome!


#!/bin/ksh
#
#       Monitor Usage (cron)
#

LOCKFILE_KEY_LIST="/tmp/key_list.lockfile"
LOCKFILE_AUTH_LOG="/tmp/auth_log.lockfile"
KEY_LIST="/var/www/cgi-bin/.key_list"
AUTH_LOG="/var/www/cgi-bin/.auth_log"
LIMIT_LOG="/var/www/cgi-bin/.limit_log"

USAGE_LIMIT="157286400"


# For each key in the active key list, search for the key and associated
IP's in the authorized user list
for KEY in `cat "$KEY_LIST"`; do
if [ `grep -w -e "$KEY" "$AUTH_LOG" >/dev/null 2>&1; echo $?` -eq "0" ];
then
TOTAL=0
for AUTH in `cat "$AUTH_LOG" | grep -w -e "$KEY"`; do
i=0
for ADDRESS in `echo "$AUTH" | cut -d ',' -f '3'`; do
i=$((++i))
        
if [ `sudo pfctl -t authorized_users -T show -v | grep -A 2 -e
${ADDRESS} | grep Bytes >/dev/null 2>&1; echo $?` -eq "0" ]; then
PFSTAT[$i]=$(sudo pfctl -t authorized_users -T show -v | grep -w -A 5 -e
${ADDRESS})
IP_ADDRESS[$i]=$(echo ${PFSTAT[$i]} | cut -d ' ' -f '1')
TIMESTAMP[$i]=$(echo ${PFSTAT[$i]} | cut -d ' ' -f '3-7')
IN_PASS_BYTES[$i]=$(echo ${PFSTAT[$i]} | cut -d ' ' -f '20')
OUT_PASS_BYTES[$i]=$(echo ${PFSTAT[$i]} | cut -d ' ' -f '34')
else
PFSTAT[$i]=$(sudo pfctl -t authorized_users -T show -v | grep -w -A 1 -e
${ADDRESS})
IP_ADDRESS[$i]=$(echo ${PFSTAT[$i]} | cut -d ' ' -f '1')
TIMESTAMP[$i]=$(echo ${PFSTAT[$i]} | cut -d ' ' -f '3-7')
IN_PASS_BYTES[$i]=0
OUT_PASS_BYTES[$i]=0
fi

A=${IN_PASS_BYTES[$i]}
B=${OUT_PASS_BYTES[$i]}
TOTAL_USAGE[$i]=$((A + B))
C=${TOTAL_USAGE[$i]}

TOTAL=$((C + TOTAL))

echo "$KEY,$TOTAL"
done
done

if [ "$TOTAL" -ge "$USAGE_LIMIT" ]; then
# Insert timestamp and key into usage log
echo -n "`date "+%Y/%m/%d@%H:%M:%S"`,$KEY," >> "$LIMIT_LOG"

for AUTH in `cat $AUTH_LOG | grep $KEY`; do
for ADDRESS in `echo $AUTH | cut -d ',' -f '3'`; do
# Append all the IP addresses paired to the access key
echo -n "$ADDRESS," >> "$LIMIT_LOG"

# Remove address from authorized users table
echo -n "$KEY,$ADDRESS, "; sudo pfctl -t authorized_users -T delete
"$ADDRESS"

# Create lockfile or wait
while true; do
if mkdir "$LOCKFILE_KEY_LIST" >/dev/null 2>&1; then
break
fi
sleep 3
done

# Remove key from key list
NEW_KEY_LIST=$(sed -e "/$KEY/d" "$KEY_LIST"); echo "$NEW_KEY_LIST" | tr
' ' '\n' > "$KEY_LIST"

# Remove lockfile
rmdir "$LOCKFILE_KEY_LIST"

# Create lockfile or wait
while true; do
if mkdir "$LOCKFILE_AUTH_LOG" >/dev/null 2>&1; then
break
fi
sleep 3
done

# Remove key from auth list
NEW_AUTH_LOG=$(sed -e "/$KEY/d" "$AUTH_LOG"); echo "$NEW_AUTH_LOG" | tr
' ' '\n' > "$AUTH_LOG"

# Remove lockfile
rmdir "$LOCKFILE_AUTH_LOG"
done
done

# Complete the usage log entry with the total bytes used up for the
access key
echo "$TOTAL" >> "$LIMIT_LOG"
fi
fi
done


  
  Byron Klippert
  [email protected]
  http://byronklippert.ca
  Tel 867-332-4184

Reply via email to