quota sometimes doesn't work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm trying to track down a problem in my ipchains rules. I use a quota for some MACs.

When someone connects on the guest network, dnsmasq adds the following rules:

# first allow outbound connections for this MAC
iptables -A FORWARD -i $guest_if -o $outside_if -m mac --mac-source $mac -m quota --quota $quota -j ACCEPT
# now limit inbound quota
iptables -A FORWARD -i $outside_if -o $guest_if -d $ip -m state --state ESTABLISHED,RELATED -m quota --quota $quota -j ACCEPT

This works - sometimes.  At other times, users can download past the quota.

I've tried to test this but the quota always works for me, even if I disconnect and reconnect. I'm not sure why or how these users are bypassing the quota.

Chain FORWARD (policy DROP 1130 packets, 267K bytes)
 pkts bytes target     prot opt in     out     source destination
....

156K 13M ACCEPT all -- eth1.5 eth0 anywhere anywhere MAC A4:67:06:53:1B:47 quota: 52428800 bytes 134K 212M ACCEPT all -- eth0 eth1.5 anywhere 192.168.5.177 state RELATED,ESTABLISHED quota: 52428800 bytes

38440 3688K ACCEPT all -- eth1.5 eth0 anywhere anywhere MAC 30:F7:C5:C5:51:85 quota: 52428800 bytes 40151 67M ACCEPT all -- eth0 eth1.5 anywhere Captain-161.guest.lan state RELATED,ESTABLISHED quota: 52428800 bytes

54671 4106K ACCEPT all -- eth1.5 eth0 anywhere anywhere MAC F4:09:D8:80:11:5E quota: 52428800 bytes 65041 105M ACCEPT all -- eth0 eth1.5 anywhere 192.168.5.152 state RELATED,ESTABLISHED quota: 52428800 bytes

50758 60M ACCEPT all -- eth1.5 eth0 anywhere anywhere MAC 78:31:C1:14:3D:41 quota: 52428800 bytes 30650 4291K ACCEPT all -- eth0 eth1.5 anywhere iPhone.guest.lan state RELATED,ESTABLISHED quota: 52428800 bytes

My entire firewall followed by the dnsmasq script that adds the quota rules per user

# set up our interfaces
# eth0 is for outgoing throttling
# eth1 is for inbound throttling
# this works even though we have vlans on eth1
# we don't want to use the vlan interfaces as we lose the ability to share bandwidth
# each nterface should have 3 classes, one for each network/vlan

bandwidth_down=10000
bandwidth_up=10000
auth_down=$(( $bandwidth_down / 2 ))
auth_up=$(( $bandwidth_up / 2 ))
tenant_down=$(( $bandwidth_down / 4 ))
tenant_up=$(( $bandwidth_up / 4 ))
guest_down=$(( $bandwidth_down / 8 ))
guest_up=$(( $bandwidth_up / 8 ))

# Subnets and interfaces
# dmz provides servers from outside
# only auth network is allowed access to the dmz from the inside

dmz='192.168.3.0/24'
dmz_ip='192.168.3.1'
dmz_if='eth2'

# auth network
# has access to dmz, outside, and firewall

auth='192.168.4.0/24'
auth_ip='192.168.4.1'
auth_if='eth1.4'

# guest network
# has no access to dmz, other networks, or anyone else in the guest network
# has limited download bandwidth

guest='192.168.5.0/24'
guest_ip='192.168.5.1'
guest_if='eth1.5'

# tenant network
# has access to outside and others on same network but not dmz or firewall

tenant='192.168.6.0/24'
tenant_ip='192.168.6.1'
tenant_if='eth1.6'

outside='!192.168.0.0/16'
outside_if='eth0'

inside_if='eth1'

server_mail="192.168.3.2"
server_http="192.168.3.2"
server_vpn="192.168.3.2"
server_rsync="192.168.3.2"
server_ssh="192.168.3.2"
server_japan="192.168.3.2"

# delete and flush all existing rules

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# delete all qdisc

tc qdisc del root dev ${outside_if}
tc qdisc del root dev ${inside_if}

# always accept loopback traffic

iptables -A INPUT -i lo -j ACCEPT

# set up for qdisc

# mark our packets
# we use the FORWARD chain so we have access to both inbound and outbound info for the packet
# we must restore the connection mark before NAT
# and set it when the packet is all the way through

iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A FORWARD -s $auth -o ${outside_if} -j MARK --set-mark 0x04 iptables -t mangle -A FORWARD -s $guest -o ${outside_if} -j MARK --set-mark 0x05 iptables -t mangle -A FORWARD -s $tenant -o ${outside_if} -j MARK --set-mark 0x06
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

# HTB classes on interfaces with rate limiting
# we limit uploads on the common outside interface

tc qdisc add dev ${outside_if} root handle 1: htb default 30
tc class add dev ${outside_if} parent 1: classid 1:1 htb rate ${bandwidth_up}kbit tc class add dev ${outside_if} parent 1:1 classid 1:14 htb rate ${auth_up}kbit ceil ${bandwidth_up}kbit tc class add dev ${outside_if} parent 1:1 classid 1:15 htb rate ${guest_up}kbit ceil ${bandwidth_up}kbit tc class add dev ${outside_if} parent 1:1 classid 1:16 htb rate ${tenant_up}kbit ceil ${bandwidth_up}kbit

tc filter add dev ${outside_if} parent 1:0 protocol ip handle 0x04 fw flowid 1:14 tc filter add dev ${outside_if} parent 1:0 protocol ip handle 0x05 fw flowid 1:15 tc filter add dev ${outside_if} parent 1:0 protocol ip handle 0x06 fw flowid 1:16

# for downloads we limit on common inside interface, the one with the vlans

tc qdisc add dev ${inside_if} root handle 1: htb default 30
tc class add dev ${inside_if} parent 1: classid 1:1 htb rate ${bandwidth_down}kbit tc class add dev ${inside_if} parent 1:1 classid 1:14 htb rate ${auth_down}kbit ceil ${bandwidth_down}kbit tc class add dev ${inside_if} parent 1:1 classid 1:15 htb rate ${guest_down}kbit ceil ${bandwidth_down}kbit tc class add dev ${inside_if} parent 1:1 classid 1:16 htb rate ${tenant_down}kbit ceil ${bandwidth_down}kbit

tc filter add dev ${inside_if} parent 1:0 protocol ip handle 0x04 fw flowid 1:14 tc filter add dev ${inside_if} parent 1:0 protocol ip handle 0x05 fw flowid 1:15 tc filter add dev ${inside_if} parent 1:0 protocol ip handle 0x06 fw flowid 1:16

# general rules


iptables -t nat -A POSTROUTING -o $outside_if -j MASQUERADE

# allow unlmited return connections to the firewall
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Since we're limiting what guests can do, we only allow forwarding for auth and tenant
# guest is handled by a dnsmasq script with quotas
iptables -A FORWARD -i $outside_if -o $auth_if -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i $outside_if -o $tenant_if -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $auth_if -o $outside_if -j ACCEPT
iptables -A FORWARD -i $tenant_if -o $outside_if -j ACCEPT

# allow access to DMZ only from our authorized network

iptables -A FORWARD -i $auth_if -o $dmz_if -j ACCEPT

# allow access to the router/firewall only from authorized network

iptables -A INPUT -s $auth -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s $auth -p tcp --dport 443 -j ACCEPT

# everyone has access to the proxy

iptables -A INPUT -s $auth -p tcp --dport 3128 -j ACCEPT
iptables -A INPUT -s $guest -p tcp --dport 3128 -j ACCEPT
iptables -A INPUT -s $tenant -p tcp --dport 3128 -j ACCEPT

# allow dhcp traffic

iptables -A INPUT -i $auth_if -p udp --dport 67:68 -j ACCEPT
iptables -A INPUT -i $guest_if -p udp --dport 67:68 -j ACCEPT
iptables -A INPUT -i $tenant_if -p udp --dport 67:68 -j ACCEPT

# allow dns traffic

iptables -A INPUT -i $auth_if -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i $auth_if -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i $guest_if -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i $guest_if -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i $tenant_if -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i $tenant_if -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i $dmz_if -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i $dmz_if -p tcp --dport 53 -j ACCEPT

# allow access to the firewall from the outside with ssh
# TAKE THIS DOWN
# BEFORE WE GO LIVE

iptables -A INPUT -i $outside_if -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i $outside_if -p tcp --dport 80 -j ACCEPT

# drop any traffic from unauthorized interfaces
# unless it's headed outside
# unnecessary as long as the default policy is DROP or REJECT
# iptables -A FORWARD -i $tenant_if -o !$outside_if -j DROP
# iptables -A FORWARD -i $guest_if -o !$outside_if -j DROP

# now dmz forwarding rules from the outside

# www
for p in 80 443 ; do
iptables -t nat -A PREROUTING -i $outside_if -p tcp --dport $p -j DNAT --to $server_http:$p iptables -A FORWARD -i $outside_if -o $dmz_if -d $server_http -p tcp --dport $p -j ACCEPT
        done

# openvpn
iptables -t nat -A PREROUTING -i $outside_if -p udp -m multiport --dports 1194,80,81,8080,33434 -j DNAT --to $server_vpn:1194
iptables -A FORWARD -i $outside_if -o $dmz_if -p udp --dport 1194 -j ACCEPT

# mail
# for p in 993 465 587 25 ; do
# iptables -t nat -A PREROUTING -i $outside_if -p tcp --dport $p -j DNAT --to $server_mail:$p # iptables -A FORWARD -i $outside_if -o $dmz_if -d $server_mail -p tcp --dport $p -j ACCEPT
#       done
# japan
for p in 8001 8002 8003 8004 ; do
iptables -t nat -A PREROUTING -i $outside_if -p tcp --dport $p -j DNAT --to $server_japan:$p iptables -A FORWARD -i $outside_if -o $dmz_if -d $server_japan -p tcp --dport $p -j ACCEPT
        done

# rsync
iptables -t nat -A PREROUTING -i $outside_if -p tcp --dport 873 -j DNAT --to $server_rsync:873 iptables -A FORWARD -i $outside_if -o $dmz_if -d $server_rsync -p tcp --dport 873 -j ACCEPT

# ssh
# ENABLE THIS BEFORE WE GO LIVE
# iptables -t nat -A PREROUTING -i $outside_if -p tcp --dport 22 -j DNAT --to $server_ssh:22 # iptables -A FORWARD -i $outside_if -o $dmz_if -d $server_ssh -p tcp --dport 22 -j ACCEPT

*******************************************
dnsmasq script run every time a guest connects

#!/bin/sh

guest_if=eth1.5
outside_if=eth0

interval=1
quota=52428800

# DO NOT hande 'del' events. We don't want to delete these rules as that resets the counter.
# Fflush the rules at midnight.

case "$1" in
        'add' )
                echo $DNSMASQ_TAGS | grep 'guest' || exit
                mac=$2
                iptables -L FORWARD -v | grep -i $mac && exit
                ip=$3
#               starttime=`date -u +%H:%M`
# stoptime=$(( ( `date -u +%H ` + $interval ) % 24 )):`date +%M` # iptables -A FORWARD -i $guest_if -o $outside_if -m mac --mac-source $mac -m time --timestart $starttime --timestop $stoptime -j ACCEPT
#
# we want to limit incoming data; we don't care how much they send out as it's typically much less
# this should limit guests to 50MB down every 12 hours

# first allow outbound connections for this MAC
iptables -A FORWARD -i $guest_if -o $outside_if -m mac --mac-source $mac -m quota --quota $quota -j ACCEPT
# now limit inbound quota
iptables -A FORWARD -i $outside_if -o $guest_if -d $ip -m state --state ESTABLISHED,RELATED -m quota --quota $quota -j ACCEPT

        ;;
        esac

--
To unsubscribe from this list: send the line "unsubscribe netfilter" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux