3

I am helping to organize a little conference. There is no internet connection, so we are limited to a mobile LTE connection with a limited volume.

We have a Ubuntu-based server that acts as a router, provides a DHCP and DNS server and routes from its subnet 192.168.1.0/24 to the LTE connection (USB Stick).

Even though our configuration of NATing from the internal network to the LTE-based internet works, we want to prevent that a client uses too much of the valuable volume, and limit each client (MAC address?) to a certain amount of data, e.g. 100MB. If a client reaches that limit (sum of up- and downloads), we want to be informed (a log entry suffices), and he should be either throttled (if possible) or cut off from the internet connection (but he should still be able to communicate in the local network).

Is there any mechanism or software we could use for this scenario?

muffel
  • 302
  • 7
  • 20
  • How about using a router that has integrated hotspot feature? – Dan Aug 09 '15 at 18:59
  • 1
    @Dan we would prefer a solution based on the hardware we already have and know. – muffel Aug 09 '15 at 19:25
  • I think you have to connect all clients via wifi (well, wifi usb sticks should be cheap nowadays), but you can have a look at hostapd + hotspotd under linux http://techapple.net/2014/07/procedure-create-wifi-hotspot-linux-creating-wireless-access-point-linux-ubuntulinuxmintfedoraopensuse/ – Dan Aug 10 '15 at 07:25
  • @Dan we do in fact connect nearly all clients via wifi, but need to spread the hotspots around the location. that's why we need several hotspots, and already have few simple APs that can be attached to the (existing) LAN. I read the docs of the tools you mentioned, but didn't find any information about volume limitation. Is there any, and I just overlooked it? – muffel Aug 10 '15 at 07:39
  • Sorry no idea, never tried software hotspot from linux. Seen two types of hotspots, one with a mikrotik router and some APs that are just APs, no routing, and the other using ubiquity (ubnt) gear, their APs and their controller software (that runs on both windows and linux). – Dan Aug 10 '15 at 08:04
  • read this [post](http://serverfault.com/questions/154451/throttle-bandwidth-via-iptables) – gwillie Aug 10 '15 at 09:05
  • @gwillie thank you for the link. unfortunately it seems like it is only about QoS and limiting the transfer speed in general, not limiting based on the traffic a user has generated, right? We want to allow a fast internet connection, and only limit it if the user has already consumed too much data to or from the internet. – muffel Aug 10 '15 at 09:16

1 Answers1

2

The following is just an idea as I'm new to traffic shaping. It's NOT a working or complete script and is missing the tc part or the like, and many other necessities...it is only presented as a curiosity, I don't have time to finish right now...

cron the script to run every minute

cron * * * * * sh /path/to/bitshaper.sh /path/to/whitelist /path/to/blacklist

bitshaper.sh

#!/bin/sh
## limit 1MB
limit=1000000

## ip addresses that are unrestricted
WHITELIST=`cat "$1"`
## ip addresses that are throttled immediately
BLACKLIST=`cat "$2"`

## chain...when routing it'll be FORWARD, otherwise use INPUT for playing
CHAIN='INPUT'

## working directory
WD=/var/tmp/bitshaper
mkdir "$WD" 2> /dev/null && cd "$WD"

## create unique CHAIN name so we can easily identify with iptables -L
## rules for monitoring bytes now should have a target of -j $RULE_ID
RULE_ID='BITSHAPER'
iptables -N $RULE_ID 2> /dev/null

## get byte count stats
STATS=`iptables -L "$CHAIN" -vn | tail -n +3`
## get dhcpd leases
HOSTS=`grep -E '^lease ' /var/lib/dhcp/dhcpd.leases | tr -d '[a-z {]' | sort -u`

for host in $HOSTS; do
  case $WHITELIST in *$host*) continue;; esac
  success=false
  for stat in "$STATS"; do
    ## $RULE_ID has to be specific enough to not match anything else
    case $stat in *${RULE_ID}*${host}*)
      success=true
      tmp=${stat#*[0-9] }
      bytes=${tmp%% *}
      [ $bytes -gt  $limit ] && {
        # use tc to shape traffic
      }
      break
    ;;
    esac
  done
  if [ $success = 'false' ]; then
    ## have host but no firewall rule, add one to track usage
    iptables -t filter -A $CHAIN -s $host -j $RULE_ID
  fi
done

## blacklist host here or somewhere
gwillie
  • 231
  • 1
  • 9