I'm a fan of saving the firewall settings in nvram, much like (i think) dd-wrt does. Accordingly, I have rewritten firewall.user to read from the nvram setting forward_spec -- I am also working on a web page to make setting these easier, but I haven't used haserl before, so there is a bit of a learning curve.
This firewall.user script only handles port forwarding, so far:
#!/bin/sh
# set WAN to the wan_ifname from nvram
WAN=$(nvram get wan_ifname)
# clear out the firewall rules
iptables -F forwarding_rule
iptables -t nat -F prerouting_rule
# function to set forwarding rules
forward_rule () {
PROTO=$1
DPORT=$2
IP=$3
# if destination port isn't provided, pass nothing to iptables
if [ -n "$4" ]
then
DEST="$IP:$4"
else
DEST=$IP
fi
# if the destination port is a range, replace the - with a : AND don't pass the destination port to --to
if ( echo $DPORT | grep -q '-' )
then
DPORT=`echo $DPORT | sed 's/-/:/'`
DEST=$IP
fi
# set the rules
echo "FORWARDING $PROTO:$2 TO $DEST"
iptables -t nat -A prerouting_rule -i $WAN -p $PROTO --dport $DPORT -j DNAT --to $DEST
iptables -A forwarding_rule -i $WAN -p $PROTO --dport $DPORT -d $IP -j ACCEPT
}
# go through the nvram setting "forward_spec", setting rules accordingly
# forward_spec should be a space separated list, set as:
# service_name:on|off:proto:forward_port(s):dest_ip[:dest_port]
# EXAMPLE: ssh:on:both:22:192.168.1.2:22
# EXAMPLE: bittorrent:on:tcp:6881-6999:192.168.1.3
for i in `nvram get forward_spec`
do
# set variables for the rule
eval "set $(echo $i | sed 's/:/ /g')"
# only do this if the rule is currently enabled
if [ "$2" = "on" ]; then
# one protocol or both tcp/udp
if [ "$3" = "both" ]
then
forward_rule tcp $4 $5 $6
forward_rule udp $4 $5 $6
else
forward_rule $3 $4 $5 $6
fi
fi
done