[ale] Buy your wifi routers now...

James Sumners james.sumners at gmail.com
Thu Sep 3 11:49:09 EDT 2015


Before I started using a WRT54-GL, and now a E3000, I used a Pentium 2 box
to fill the same role. It's quite simple to setup, really. Included in this
email are the two scripts that really comprised my whole setup (which will
need some updating for sure). The main reason I prefer Tomato over DD-WRT
is that Tomato's QoS rules use the CBQ discipline, as I do below, and
DD-WRT uses something else (at least by default). Whatever discipline
DD-WRT uses did not work as well for me.

(firewall.sh)
```
#!/bin/bash -v

echo "Bringing up firewall..."
echo ""

EXTERNAL_IFACE='eth0'
INTERNAL_IFACE='eth1'
WIRELESS_IFACE='eth2'
IPTABLES=`which iptables`
EXTERNAL_IP=`ifconfig ${EXTERNAL_IFACE} | grep "inet addr" | cut -d \: -f 2
| cut -d ' ' -f 1`
INTERNAL_IP='192.168.1.0/24' # /24 covers both subnets
# These numbers must match the numbers in the classes.sh file
VOIP='10'
WWW='11'
GAMES='12'
P2P='13'
OTHER='14'

# Clear old rules
${IPTABLES} -F
${IPTABLES} -F -t nat
${IPTABLES} -F -t mangle

# Our default policy is to DROP packets
${IPTABLES} -P INPUT DROP

### Configure classes ###
${IPTABLES} -t mangle -A PREROUTING -j CONNMARK --restore-mark
${IPTABLES} -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT # If we
have already marked it then accept it

# We need to classify packets on all ethernet devices except lo, both
incoming and outgoing.
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p udp \
--dport 10000:20000 -j MARK --set-mark ${VOIP}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p udp \
--dport 10000:20000 -j MARK --set-mark ${VOIP} # VoIP

${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p udp \
--dport 53 -j MARK --set-mark ${WWW}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p udp \
--dport 53 -j MARK --set-mark ${WWW} # DNS
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
-m multiport --dport 80,443 -j MARK --set-mark ${WWW}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p tcp \
-m multiport --dport 80,443 -j MARK --set-mark ${WWW} # HTTP/HTTPS
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 5900:5901 -j MARK --set-mark ${WWW}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 5900:5901 -j MARK --set-mark ${WWW} # VNC
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 22 -j MARK --set-mark ${WWW}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 22 -j MARK --set-mark ${WWW} # SSH
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 21 -j MARK --set-mark ${WWW}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 21 -j MARK --set-mark ${WWW} # FTP

${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 3724 -j MARK --set-mark ${GAMES}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 3724 -j MARK --set-mark ${GAMES} # World of Warcraft
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 6112 -j MARK --set-mark ${GAMES}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 6112 -j MARK --set-mark ${GAMES} # Guild Wars

${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 7000:7100 -j MARK --set-mark ${P2P} # BitTorrent
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 6112 -j MARK --set-mark ${P2P}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 -p tcp \
--dport 6881:6999 -j MARK --set-mark ${P2P} # WoW downloader

# All other packets, on the tcp and udp protocols, need to be classified as
"other".
${IPTABLES} -t mangle -A PREROUTING -i ! lo --dst ${EXTERNAL_IP} -m mark
--mark 0 \
-j MARK --set-mark ${OTHER}
${IPTABLES} -t mangle -A PREROUTING -i ! lo --src ${INTERNAL_IP} -m mark
--mark 0 \
-j MARK --set-mark ${OTHER} # Everything else

${IPTABLES} -t mangle -A PREROUTING -j CONNMARK --save-mark # Save the mark
to the connection tracking.
## Classes configured ##

## Forward ports ##
${IPTABLES} -t nat -A PREROUTING --dst ${EXTERNAL_IP} -p udp --dport
10000:20000 -j DNAT --to 192.168.1.3
${IPTABLES} -t nat -A PREROUTING --dst ${EXTERNAL_IP} -p tcp --dport 22 -j
DNAT --to 192.168.1.5
${IPTABLES} -t nat -A PREROUTING --dst ${EXTERNAL_IP} -p tcp --dport 5900
-j DNAT --to 192.168.1.5
${IPTABLES} -t nat -A PREROUTING --dst ${EXTERNAL_IP} -p tcp --dport 7000
-j DNAT --to 192.168.1.5
${IPTABLES} -t nat -A PREROUTING --dst ${EXTERNAL_IP} -p tcp --dport 5901
-j DNAT --to 192.168.1.6
## ##

## Setup filters ##
${IPTABLES} -A INPUT --dst ${EXTERNAL_IP} -p icmp --icmp-type echo-request
-m limit \
--limit 10 -j ACCEPT # Sure, let's reply to pings.
${IPTABLES} -A INPUT --dst ${EXTERNAL_IP} -m state \
--state INVALID -j DROP # We don't want any invalid packets.
${IPTABLES} -A INPUT --dst ${EXTERNAL_IP} -m state \
--state ESTABLISHED,RELATED -j ACCEPT # Only connections that were
initiated from the inside.
${IPTABLES} -A INPUT --src ${INTERNAL_IP} -j ACCEPT # Accept connections
from the LAN.
## Filters configured ##

# Make all outbound packets look like they are coming from one IP
${IPTABLES} -t nat -A POSTROUTING -o ${EXTERNAL_IFACE} -j MASQUERADE
# Enable packet forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward

```

(classes.sh)
```
#!/bin/bash

tc=`which tc`
INTERNAL_IFACE='eth1'
EXTERNAL_IFACE='eth0'
WIRELESS_IFACE='eth2'
INTERNAL_ROOT='1'
EXTERNAL_ROOT='2'
WIRELESS_ROOT='3'

# Define your incoming and outgoing bandwidth here. Take a little off
# for overhead bandwidth.
IN_BANDWIDTH='3008' # 3Mbit : 3072Kbit - 64Kbit overhead = 3008Kbit
OUT_BANDWIDTH='240' # 256Kbit : 256Kbit - 16Kbit overhead = 240Kbit

LIMIT='2' # Classes for limited packets
MANAGEMENT='8' # Class for management

# Here we define the classes we want to classify out bandwith usage with.
VOIP='10'
WWW='11'
GAMES='12'
P2P='13'
OTHER='14'
# Now the maximum shared bandwidth to assign each class (in kilobits).
VOIP_RATE_OUT='96'
VOIP_RATE_IN='96'
WWW_RATE_OUT='80'
WWW_RATE_IN='1200'
GAMES_RATE_OUT='48'
GAMES_RATE_IN='392'
P2P_RATE_OUT='8'
P2P_RATE_IN='1200'
OTHER_RATE_OUT='8'
OTHER_RATE_IN='120'

# Remove any previously applied disciplines
${tc} qdisc del dev ${INTERNAL_IFACE} root 2>/dev/null
${tc} qdisc del dev ${EXTERNAL_IFACE} root 2>/dev/null
${tc} qdisc del dev ${WIRELESS_IFACE} root 2>/dev/null

# Create the new queueing disciplines
${tc} qdisc add dev ${INTERNAL_IFACE} root handle ${INTERNAL_ROOT}:0 cbq \
avpkt 1000 rate 100mbit bandwidth 100mbit
${tc} qdisc add dev ${EXTERNAL_IFACE} root handle ${EXTERNAL_ROOT}:0 cbq \
avpkt 1000 rate 100mbit bandwidth 100mbit
${tc} qdisc add dev ${WIRELESS_IFACE} root handle ${WIRELESS_ROOT}:0 cbq \
avpkt 1000 rate 54mbit bandwidth 54mbit

# Create an inband management class. I don't think this is really necessary
on a home
# network, but the http://www.sigsegv.cx/qos.html article suggests it.
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:0 \
classid ${INTERNAL_ROOT}:${MANAGEMENT} cbq allot 1500 rate 10mbit prio 1
avpkt 1500 bounded

# Now to setup the LIMIT classes for incoming and outgoing bandwidth.
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:0 \
classid ${INTERNAL_ROOT}:${LIMIT} \
cbq allot 1500 rate ${IN_BANDWIDTH}kbit prio 1 avpkt 1500 bounded
${tc} class add dev ${WIRELESS_IFACE} parent ${WIRELESS_ROOT}:0 \
classid ${WIRELESS_ROOT}:${LIMIT} \
cbq allot 1500 rate ${IN_BANDWIDTH}kbit prio 1 avpkt 1500 bounded
# We only need to throttle the outgoing bandwidth on the external interface.
${tc} class add dev ${EXTERNAL_IFACE} parent ${EXTERNAL_ROOT}:0 \
classid ${EXTERNAL_ROOT}:${LIMIT} \
cbq allot 1500 rate ${OUT_BANDWIDTH}kbit prio 1 avpkt 1500 bounded

### Classes ###

# VoIP
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:${LIMIT} \
classid ${INTERNAL_ROOT}:${VOIP} cbq allot 1500 rate ${VOIP_RATE_IN}kbit
prio 1 \
weight 9.6 avpkt 1500 isolated
${tc} class add dev ${WIRELESS_IFACE} parent ${WIRELESS_ROOT}:${LIMIT} \
classid ${WIRELESS_ROOT}:${VOIP} cbq allot 1500 rate ${VOIP_RATE_IN}kbit
prio 1 \
weight 9.6 avpkt 1500 isolated
${tc} class add dev ${EXTERNAL_IFACE} parent ${EXTERNAL_ROOT}:${LIMIT} \
classid ${EXTERNAL_ROOT}:${VOIP} cbq allot 1500 rate ${VOIP_RATE_OUT}kbit
prio 1 \
weight 9.6 avpkt 1500 isolated

# WWW
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:${LIMIT} \
classid ${INTERNAL_ROOT}:${WWW} cbq allot 1500 rate ${WWW_RATE_IN}kbit prio
2 \
weight 120 avpkt 1500
${tc} class add dev ${WIRELESS_IFACE} parent ${WIRELESS_ROOT}:${LIMIT} \
classid ${WIRELESS_ROOT}:${WWW} cbq allot 1500 rate ${WWW_RATE_IN}kbit prio
2 \
weight 120 avpkt 1500
${tc} class add dev ${EXTERNAL_IFACE} parent ${EXTERNAL_ROOT}:${LIMIT} \
classid ${EXTERNAL_ROOT}:${WWW} cbq allot 1500 rate ${WWW_RATE_OUT}kbit
prio 2 \
weight 8 avpkt 1500

# Games
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:${LIMIT} \
classid ${INTERNAL_ROOT}:${GAMES} cbq allot 1500 rate ${GAMES_RATE_IN}kbit
prio 3 \
weight 39.2 avpkt 1500
${tc} class add dev ${WIRELESS_IFACE} parent ${WIRELESS_ROOT}:${LIMIT} \
classid ${WIRELESS_ROOT}:${GAMES} cbq allot 1500 rate ${GAMES_RATE_IN}kbit
prio 3 \
weight 39.2 avpkt 1500
${tc} class add dev ${EXTERNAL_IFACE} parent ${EXTERNAL_ROOT}:${LIMIT} \
classid ${EXTERNAL_ROOT}:${GAMES} cbq allot 1500 rate ${GAMES_RATE_OUT}kbit
prio 3 \
weight 4.8 avpkt 1500

# P2P
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:${LIMIT} \
classid ${INTERNAL_ROOT}:${P2P} cbq allot 1500 rate ${P2P_RATE_IN}kbit prio
4 \
weight 120 avpkt 1500
${tc} class add dev ${WIRELESS_IFACE} parent ${WIRELESS_ROOT}:${LIMIT} \
classid ${WIRELESS_ROOT}:${P2P} cbq allot 1500 rate ${P2P_RATE_IN}kbit prio
4 \
weight 120 avpkt 1500
${tc} class add dev ${EXTERNAL_IFACE} parent ${EXTERNAL_ROOT}:${LIMIT} \
classid ${EXTERNAL_ROOT}:${P2P} cbq allot 1500 rate ${P2P_RATE_OUT}kbit
prio 4 \
weight 0.8 avpkt 1500

# Other
${tc} class add dev ${INTERNAL_IFACE} parent ${INTERNAL_ROOT}:${LIMIT} \
classid ${INTERNAL_ROOT}:${OTHER} cbq allot 1500 rate ${OTHER_RATE_IN}kbit
prio 5 \
weight 12 avpkt 1500
${tc} class add dev ${WIRELESS_IFACE} parent ${WIRELESS_ROOT}:${LIMIT} \
classid ${WIRELESS_ROOT}:${OTHER} cbq allot 1500 rate ${OTHER_RATE_IN}kbit
prio 5 \
weight 12 avpkt 1500
${tc} class add dev ${EXTERNAL_IFACE} parent ${EXTERNAL_ROOT}:${LIMIT} \
classid ${EXTERNAL_ROOT}:${OTHER} cbq allot 1500 rate ${OTHER_RATE_OUT}kbit
prio 5 \
weight 0.8 avpkt 1500

## Apply classes to packets marked with iptables ##

# VoIP
${tc} filter add dev ${INTERNAL_IFACE} protocol ip \
parent ${INTERNAL_ROOT}:0 prio 1 handle ${VOIP} \
fw flowid ${INTERNAL_ROOT}:${VOIP}
${tc} filter add dev ${WIRELESS_IFACE} protocol ip \
parent ${WIRELESS_ROOT}:0 prio 1 handle ${VOIP} \
fw flowid ${WIRELESS_ROOT}:${VOIP}
${tc} filter add dev ${EXTERNAL_IFACE} protocol ip \
parent ${EXTERNAL_ROOT}:0 prio 1 handle ${VOIP} \
fw flowid ${EXTERNAL_ROOT}:${VOIP}

# WWW
${tc} filter add dev ${INTERNAL_IFACE} protocol ip \
parent ${INTERNAL_ROOT}:0 prio 2 handle ${WWW} \
fw flowid ${INTERNAL_ROOT}:${WWW}
${tc} filter add dev ${WIRELESS_IFACE} protocol ip \
parent ${WIRELESS_ROOT}:0 prio 2 handle ${WWW} \
fw flowid ${WIRELESS_ROOT}:${WWW}
${tc} filter add dev ${EXTERNAL_IFACE} protocol ip \
parent ${EXTERNAL_ROOT}:0 prio 2 handle ${WWW} \
fw flowid ${EXTERNAL_ROOT}:${WWW}

# GAMES
${tc} filter add dev ${INTERNAL_IFACE} protocol ip \
parent ${INTERNAL_ROOT}:0 prio 3 handle ${GAMES} \
fw flowid ${INTERNAL_ROOT}:${GAMES}
${tc} filter add dev ${WIRELESS_IFACE} protocol ip \
parent ${WIRELESS_ROOT}:0 prio 3 handle ${GAMES} \
fw flowid ${WIRELESS_ROOT}:${GAMES}
${tc} filter add dev ${EXTERNAL_IFACE} protocol ip \
parent ${EXTERNAL_ROOT}:0 prio 3 handle ${GAMES} \
fw flowid ${EXTERNAL_ROOT}:${GAMES}

# P2P
${tc} filter add dev ${INTERNAL_IFACE} protocol ip \
parent ${INTERNAL_ROOT}:0 prio 4 handle ${P2P} \
fw flowid ${INTERNAL_ROOT}:${P2P}
${tc} filter add dev ${WIRELESS_IFACE} protocol ip \
parent ${WIRELESS_ROOT}:0 prio 4 handle ${P2P} \
fw flowid ${WIRELESS_ROOT}:${P2P}
${tc} filter add dev ${EXTERNAL_IFACE} protocol ip \
parent ${EXTERNAL_ROOT}:0 prio 4 handle ${P2P} \
fw flowid ${EXTERNAL_ROOT}:${P2P}

# OTHER
${tc} filter add dev ${INTERNAL_IFACE} protocol ip \
parent ${INTERNAL_ROOT}:0 prio 5 handle ${OTHER} \
fw flowid ${INTERNAL_ROOT}:${OTHER}
${tc} filter add dev ${WIRELESS_IFACE} protocol ip \
parent ${WIRELESS_ROOT}:0 prio 5 handle ${OTHER} \
fw flowid ${WIRELESS_ROOT}:${OTHER}
${tc} filter add dev ${EXTERNAL_IFACE} protocol ip \
parent ${EXTERNAL_ROOT}:0 prio 5 handle ${OTHER} \
fw flowid ${EXTERNAL_ROOT}:${OTHER}
```

On Thu, Sep 3, 2015 at 11:33 AM, Damon L. Chesser <damon at damtek.com> wrote:

> Ahhh.  Makes sense.
>
> On 09/03/2015 12:14 AM, James Sumners wrote:
>
> Set the wireless interface into AP mode and plug the wired interface into
> an uplink port on my switch. Plus, you know, some iptables rules.
>
>

-- 
James Sumners
http://james.sumners.info/ (technical profile)
http://jrfom.com/ (personal site)
http://haplo.bandcamp.com/ (band page)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.ale.org/pipermail/ale/attachments/20150903/87e3851d/attachment.html>


More information about the Ale mailing list