≡ Menu

FreeBSD ipfw Traffic Shaping Firewall Script

# Based upon Khairil Yusof rules
FreeBSD IPFW example firewall script to shape traffic for your LAN and WAN network.
#firewall command
fwcmd="/sbin/ipfw"
#interfaces
wifi=ath0
wire=fxp0
oif=tun0
vpn=tun1
internal="10.1.1.0/24,192.168.1.0/24,192.168.3.0/24"
fw="skipto 1000"
nat_in="skipto 2000"
nat_out="skipto 5000"
cs="skipto 3000"
# Force a flushing of the current rules before we reload.
$fwcmd -f flush
#Setup incoming and outgoing pipes
$fwcmd pipe 10 config bw 1024Kbit/s
$fwcmd pipe 20 config bw 384Kbit/s
################################################################################
# Setup bandwidth shaping queues
# Higher weight, high priorities
################################################################################
# High priority queue for tcp ACK
$fwcmd queue 1 config pipe 20 weight 90
# High priority queue for DNS
$fwcmd queue 2 config pipe 10 weight 70
$fwcmd queue 3 config pipe 20 weight 70
# High priority queue for SSH
$fwcmd queue 4 config pipe 10 weight 69
$fwcmd queue 5 config pipe 20 weight 69
# High priority queue for IMAP
$fwcmd queue 6 config pipe 10 weight 68
$fwcmd queue 7 config pipe 20 weight 68
# High priority queue for HTTP/FTP
$fwcmd queue 8 config pipe 10 weight 67
$fwcmd queue 9 config pipe 20 weight 67
# General low priority queue for home users
$fwcmd queue 10 config pipe 10 weight 50
$fwcmd queue 11 config pipe 20 weight 50
# Low priority queue for other users
$fwcmd queue 20 config pipe 10 weight 25
$fwcmd queue 21 config pipe 20 weight 25
################################################################################
#No shaping between internal networks
################################################################################
$fwcmd add 100 $fw ip from $internal to $internal out via ${wire}
$fwcmd add 110 $fw ip from $internal to $internal in via ${wire}
$fwcmd add 120 $fw ip from $internal to $internal out via ${wifi}
$fwcmd add 130 $fw ip from $internal to $internal in via ${wifi}
################################################################################
#Traffic shaping
################################################################################
#TCP ACK
$fwcmd add 140 queue 1 ip from any to any out via ${oif} tcpflags ack iplen 52
$fwcmd add 150 $fw ip from any to any out via ${oif} tcpflags ack iplen 52
#DNS
$fwcmd add 180 queue 3 ip from any to any 53 out via ${oif}
$fwcmd add 185 queue 2 ip from any 53 to any in via ${oif}
$fwcmd add 190 $fw ip from any to any 53 out via ${oif}
$fwcmd add 195 $fw ip from any to any 53 in via ${oif}
#SSH
$fwcmd add 210 queue 5 ip from $internal to any ssh out via ${oif}
$fwcmd add 215 queue 4 ip from any ssh to $internal in via ${oif}
$fwcmd add 220 $fw ip from $internal to any ssh out via ${oif}
$fwcmd add 225 $fw ip from $internal to any ssh in via ${oif}
#IMAP
$fwcmd add 250 queue 7 ip from $internal to any imap,imaps out via ${oif}
$fwcmd add 255 queue 6 ip from any imap,imaps to $internal in via ${oif}
$fwcmd add 260 $fw ip from $internal to any imap,imaps out via ${oif}
$fwcmd add 265 $fw ip from $internal to any imap,imaps in via ${oif}
#Web and ftp
$fwcmd add 290 queue 9 ip from me to any http,https,ftp out via ${oif}
$fwcmd add 295 queue 8 ip from any http,https,ftp to me in via ${oif}
$fwcmd add 300 $fw ip from me to any http,https,ftp out via ${oif}
$fwcmd add 305 $fw ip from any http,https,ftp to me in via ${oif}
#General traffic, assign higher priority for home users
$fwcmd add 310 queue 11 ip from $internal to any out via ${oif}
$fwcmd add 315 queue 10 ip from any to $internal in via ${oif}
$fwcmd add 320 $fw ip from $internal to any out via ${oif}
$fwcmd add 325 $fw ip from any to $internal in via ${oif}
#General traffic low priority
$fwcmd add 330 queue 21 ip from $internal to any out via ${oif}
$fwcmd add 335 queue 20 ip from any to $internal in via ${oif}
$fwcmd add 340 $fw ip from $internal to any out via ${oif}
$fwcmd add 345 $fw 20 ip from any to $internal in via ${oif}
#######################################################################################
#firewall rules
#######################################################################################
#Allow all localhost connections
$fwcmd add 1000 allow ip from any to any via lo0
#Allow openvpn tunnel
$fwcmd add 1130 allow ip from 192.168.2.0/24 to 192.168.2.1 1194 via ${wifi} keep-state
#transparent proxy
$fwcmd add 1200 fwd 192.168.1.1,3128 tcp from any to any http keep-state via ${wire}
$fwcmd add 1210 fwd 192.168.3.1,3128 tcp from any to any http keep-state via ${vpn}
$fwcmd add 1220 fwd 192.168.2.1,3128 tcp from 192.168.2.0/24 to any http keep-state via ${wifi}
$fwcmd add 1300 allow ip from any to any via ${wire}
$fwcmd add 1400 allow ip from any to any via ${vpn}
########################################################################################
# Divert all packets coming in through the tunnel interface.
########################################################################################
$fwcmd add 2000 divert natd all from any to any in via ${oif}
# Allow all connections that have dynamic rules built for them,
# but deny established connections that do not have a dynamic rule.
# See ipfw(8) for details.
$fwcmd add 3000 check-state
$fwcmd add 3100 deny ip from any to any in via $oif not verrevpath
#Allow any traffic from gateway interfaces out
$fwcmd add 3200 $nat_out ip from any to any out via ${oif} keep-state
#Wired network
#Wireless network
# Everyone on the Internet is allowed to connect to the following
# services on the machine. This example specifically allows connections
# to sshd and a webserver.
#$fwcmd add allow tcp from 202.187.94.4 to any dst-port 22 in recv any setup keep-state
#Allow DNS queries
$fwcmd add 3300 $nat_out udp from any to any 53 keep-state
$fwcmd add 3310 $nat_out udp from any 53 to any keep-state
$fwcmd add 3400 $nat_out udp from any to any 3130 keep-state
$fwcmd add 3410 $nat_out udp from any 3130 to any keep-state
# Allow IRC DCC transfers
$fwcmd add 3500 $nat_out tcp from any to any dst-port 54000-54019 recv any setup keep-state
# Allow ICMP (for ping and traceroute to work).
$fwcmd add 4000 $nat_out icmp from any to any
#Allow IP fragments through
$fwcmd add 4100 pass all from any to any frag
# This sends a RESET to all ident packets.
$fwcmd add 4200 reset log tcp from any to me 113 in recv any
$fwcmd add 4300 deny log ip from any to any
#Outgoing packet traffic
$fwcmd add 5000 divert natd ip from any to any out via ${oif}
$fwcmd add 5100 allow ip from any to any

Comments on this entry are closed.

  • Francisco

    I could not see what will make packets enter on rule 310 or 330 ?
    Both seems to be equal ??

    #General traffic, assign higher priority for home users
    $fwcmd add 310 queue 11 ip from $internal to any out via ${oif}

    #General traffic low priority
    $fwcmd add 330 queue 21 ip from $internal to any out via ${oif}

    And… could you provide the “rc.conf” file for this example too ?

    Thanks
    Francisco

  • Thanks !

  • Nick Hibma

    Could someone change “don’t” to “do not” so the syntax highlighting isn’t confused?

    Thanks for the nice example for the queueing, and high to separate statements into functional blocks.

  • nixcraft

    Heh.. done. Hope this helps. Appreciate your post!