Complete Bidirectional Bandwidth Control (Web / Mail / FTP / VoIP)
In this article, we’ll build a Linux-based gateway that not only routes traffic between your LAN and the Internet but also provides precise QoS and bandwidth shaping using HTB, iptables, and IFB.
This setup is ideal for small offices, labs, or home networks where you need to control user upload/download speeds and prioritize services (such as VoIP and web traffic).
1. Network Environment
| Interface | Direction | Description |
|---|---|---|
eth0 | WAN | Connected to the Internet |
eth1 | LAN | Connected to internal users (e.g. 192.168.10.0/24) |
gateway | Linux host | Acts as router and NAT device |
| Goal | Control upload (LAN → WAN) and download (WAN → LAN) bandwidth per service |
2. Traffic Flow Logic
| Type | Packet Direction | Controlled Interface |
|---|---|---|
| Upload | LAN → Internet | Outbound (eth0 egress) |
| Download | Internet → LAN | Inbound (eth0 ingress) redirected to ifb0 for shaping |
Even though download traffic eventually goes out via
eth1, the shaping must be applied oneth0 ingress, because that’s where packets first enter the gateway from the Internet.
3. Basic Gateway Configuration
Enable IP forwarding and NAT:
# Internal LAN: 192.168.10.0/24
ip addr add 192.168.10.1/24 dev eth1
ip link set eth0 up
ip link set eth1 up
# NAT (Masquerade)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Enable IP forwarding
sysctl -w net.ipv4.ip_forward=1
4. Full HTB + iptables + IFB Script
This script implements bidirectional shaping and service-based QoS for one client (192.168.10.50).
Save as /usr/local/sbin/qos-gateway.sh and run as root.
#!/usr/bin/env bash
set -e
WAN=eth0 # Internet side
LAN=eth1 # Internal LAN
IFB=ifb0
HOST=192.168.10.50
# === Cleanup ===
tc qdisc del dev $WAN root 2>/dev/null || true
tc qdisc del dev $WAN ingress 2>/dev/null || true
ip link del $IFB 2>/dev/null || true
iptables -t mangle -F
# === Upload (LAN → Internet) ===
echo "[+] Configuring upload shaping on $WAN"
tc qdisc add dev $WAN root handle 1: htb default 130
tc class add dev $WAN parent 1: classid 1:1 htb rate 20Mbit ceil 20Mbit
# Web / Mail / FTP / VoIP / Default
tc class add dev $WAN parent 1:1 classid 1:110 htb rate 2Mbit ceil 20Mbit prio 2
tc class add dev $WAN parent 1:1 classid 1:120 htb rate 1.5Mbit ceil 20Mbit prio 3
tc class add dev $WAN parent 1:1 classid 1:140 htb rate 2Mbit ceil 20Mbit prio 4
tc class add dev $WAN parent 1:1 classid 1:150 htb rate 1Mbit ceil 20Mbit prio 1
tc class add dev $WAN parent 1:1 classid 1:130 htb rate 5Mbit ceil 20Mbit prio 5
# Filters by mark
tc filter add dev $WAN parent 1: protocol ip handle 11 fw flowid 1:110
tc filter add dev $WAN parent 1: protocol ip handle 12 fw flowid 1:120
tc filter add dev $WAN parent 1: protocol ip handle 13 fw flowid 1:140
tc filter add dev $WAN parent 1: protocol ip handle 14 fw flowid 1:150
tc filter add dev $WAN parent 1: protocol ip handle 19 fw flowid 1:130
# Packet marking (upload)
iptables -t mangle -A POSTROUTING -s $HOST -p tcp -m multiport --dports 80,443 -j MARK --set-mark 11
iptables -t mangle -A POSTROUTING -s $HOST -p tcp -m multiport --dports 25,465,587,110,995,143,993 -j MARK --set-mark 12
iptables -t mangle -A POSTROUTING -s $HOST -p tcp -m multiport --dports 20,21 -j MARK --set-mark 13
iptables -t mangle -A POSTROUTING -s $HOST -p udp -m multiport --dports 5060,5061 -j MARK --set-mark 14
iptables -t mangle -A POSTROUTING -s $HOST -p udp --dport 10000:20000 -j MARK --set-mark 14
iptables -t mangle -A POSTROUTING -s $HOST -j MARK --set-mark 19
# === Download (Internet → LAN) ===
echo "[+] Configuring download shaping via $IFB"
modprobe ifb
ip link add $IFB type ifb
ip link set dev $IFB up
# Redirect incoming traffic on eth0 → ifb0
tc qdisc add dev $WAN handle ffff: ingress
tc filter add dev $WAN parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $IFB
# HTB on ifb0
tc qdisc add dev $IFB root handle 2: htb default 230
tc class add dev $IFB parent 2: classid 2:1 htb rate 100Mbit ceil 100Mbit
tc class add dev $IFB parent 2:1 classid 2:210 htb rate 20Mbit ceil 100Mbit prio 2
tc class add dev $IFB parent 2:1 classid 2:220 htb rate 10Mbit ceil 100Mbit prio 3
tc class add dev $IFB parent 2:1 classid 2:240 htb rate 15Mbit ceil 100Mbit prio 4
tc class add dev $IFB parent 2:1 classid 2:250 htb rate 2Mbit ceil 100Mbit prio 1
tc class add dev $IFB parent 2:1 classid 2:230 htb rate 40Mbit ceil 100Mbit prio 5
tc filter add dev $IFB parent 2: protocol ip handle 21 fw flowid 2:210
tc filter add dev $IFB parent 2: protocol ip handle 22 fw flowid 2:220
tc filter add dev $IFB parent 2: protocol ip handle 23 fw flowid 2:240
tc filter add dev $IFB parent 2: protocol ip handle 24 fw flowid 2:250
tc filter add dev $IFB parent 2: protocol ip handle 29 fw flowid 2:230
# Packet marking (download)
iptables -t mangle -A PREROUTING -d $HOST -p tcp -m multiport --sports 80,443 -j MARK --set-mark 21
iptables -t mangle -A PREROUTING -d $HOST -p tcp -m multiport --sports 25,465,587,110,995,143,993 -j MARK --set-mark 22
iptables -t mangle -A PREROUTING -d $HOST -p tcp -m multiport --sports 20,21 -j MARK --set-mark 23
iptables -t mangle -A PREROUTING -d $HOST -p udp -m multiport --sports 5060,5061 -j MARK --set-mark 24
iptables -t mangle -A PREROUTING -d $HOST -p udp --sport 10000:20000 -j MARK --set-mark 24
iptables -t mangle -A PREROUTING -d $HOST -j MARK --set-mark 29
echo "=== HTB QoS active on gateway ==="
5. Testing & Verification
Check traffic statistics and shaping effectiveness:
# Show HTB stats
tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s qdisc show dev ifb0
tc -s class show dev ifb0
# Verify iptables marks
iptables -t mangle -L -v -n
You should see Sent bytes/packets increasing in each corresponding class as different services are used.
6. Practical Notes
🧱 1. Multi-User Environments
- To control an entire LAN subnet:
-s 192.168.10.0/24 - To limit per user individually: create one HTB class and mark per IP.
⚙️ 2. FTP Passive Mode
Passive FTP uses random high ports (e.g., 21000–21050).
Fix this range in your FTP server configuration and add those ports to your QoS rules.
☎️ 3. VoIP Traffic
VoIP is delay-sensitive. Assign it highest priority (prio 1) and fix SIP (5060–5061) and RTP (10000–20000/udp) port ranges.
🧩 4. Debugging and NIC Offload
If you see unstable bandwidth shaping, disable hardware offloading temporarily:
ethtool -K eth0 gro off gso off tso off
7. Conclusion
By deploying HTB + iptables + IFB on a Linux gateway, you can achieve:
- ✅ Upload control: Limit outbound traffic from LAN users
- ✅ Download control: Shape inbound Internet traffic
- ✅ Service-based QoS: Web, Mail, FTP, and VoIP with independent limits
- ✅ Scalability: Extendable to multiple IPs or subnets
This architecture is powerful, flexible, and production-proven — suitable for corporate gateways, VPN routers, or lab environments that require strict traffic management and fair bandwidth allocation.
📘 Further Reading
man tc-htb— HTB structure and parametersman tc-fq_codel— Low-latency queuing disciplineman iptables— Packet marking and filtering basics