Linux FTP Server Traffic Control And Throttle Port 21

I‘ve setup a FTP server at port 21 and 40000:41000 as range of passive ftp. How do I control outgoing traffic for the FTP server/service running on my Debian/CentOS/Ubuntu Linux server?

When traffic is shaped, its rate of transmission is under control. Shaping may be more than lowering the available bandwidth – it is also used to smooth out bursts in traffic for better network behaviour.
Tutorial details
Difficulty level Advanced
Root privileges Yes
Requirements tc & iptables
Pre configured ftpd
Est. reading time N/A
Linux comes with very good traffic control programs. You can set up the guaranteed bandwidth and maximum bandwidth to limit its outgoing traffic using iptables and tc command.

tc command

I recommend that you read this tutorial and tc command man page before typing any one of the following commands.

First, you need to add root qdisc, enter:
### delete old rules if any ###
# /sbin/tc qdisc del dev eth0 root
#### add it ###
# /sbin/tc qdisc add dev eth0 root handle 11: htb default 500 r2q 1

In this following example, I’m going to set guaranteed bandwidth to 64KB/s and max/burstable bandwidth to 128KB/s for testing purpose (feel free to adjust those number as per your setup). Add level 1 class. This class set 128kbps as burstable bandwidth:
# /sbin/tc class add dev eth0 parent 11: classid 11:1 htb rate 128kbps ceil 128kbps quantum 2048

#### this is our level 2 class ####
# /sbin/tc class add dev eth0 parent 11:1 classid 11:101 htb rate 64kbps ceil 128kbps prio 0 quantum 2048

You need to add leaf to our qdisc:
# /sbin/tc qdisc add dev eth0 parent 11:101 handle 1001: sfq
Finally add our filter:
# /sbin/tc filter add dev eth0 parent 11: protocol ip handle 101 fw classid 11:101

iptables POSTROUTING rules

tc is used to configure Traffic Control in the Linux kernel. However, you need to use iptables to apply those rules for ftp tcp port 21 and passive ftp tcp port range 40000:41000 as follows:

### iptables mangle rule ###
/sbin/iptables -A POSTROUTING -t mangle -o eth0 -p tcp -m multiport --sports 21,40000:41000 -j MARK --set-xmark 101
/sbin/iptables -A POSTROUTING -t mangle -o eth0 -p tcp -m multiport --sports 21,40000:41000 -j RETURN

Please note that mangle table is used for specialized packet alteration as follows:

  • PREROUTING – for altering incoming packets before routing.
  • OUTPUT – for altering locally-generated packets before routing.
  • INPUT – for packets coming into the box itself.
  • FORWARD – for altering packets being routed through the box.
  • POSTROUTING – for altering packets as they are about to go out.

Here is a dump of mangle table:
# /sbin/iptables-save -t mangle
Sample outputs:

# Generated by iptables-save v1.4.8 on Sun Sep  9 14:28:18 2012
:INPUT ACCEPT [353:50724]
:OUTPUT ACCEPT [490:67671]
-A POSTROUTING -o eth0 -p tcp -m multiport --sports 21,40000:41000 -j MARK --set-xmark 0x65/0xffffffff 
-A POSTROUTING -o eth0 -p tcp -m multiport --sports 21,40000:41000 -j RETURN 
# Completed on Sun Sep  9 14:28:18 2012

Test it

Use lftp command or any other ftp client to test bandwidth limitations:
$ lftp -u username ftpservername
Try to download a big file:
lftp admin@nas03:/multipedia/iso-images/centos> get CentOS-6.2-x86_64-bin-DVD1.iso
Sample outputs:

(Video.01: Traffic shaping in action)

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 5 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersncdu pydf
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
5 comments… add one
  • Neil Wylie Sep 10, 2012 @ 0:16

    Yay- TC getting used!
    Its an awesome tool that is really neglected in linux. My best use of it is for regulating replication traffic in mysql setups.


  • R Johns Sep 12, 2012 @ 9:44

    Excellent, I modified this how to for samba server :)

  • Ondřej Kopka Sep 23, 2012 @ 8:49

    Nice howto, but for example pure-ftpd has this functionality too.

    • Andrei Neagoe Jan 16, 2013 @ 8:12

      Most ftp server implementations provide per session bw throttling. However, global bandwidth is a different story. Here’s an excerpt from the pure-ftpd documentation:

      * Global bandwidth limitation.

      -> How do I limit the *total* bandwidth for FTP?

      Pure-FTPd can limit bandwidth usage of every session. But limiting the total
      bandwidth is intentionally not implemented, because most operating systems
      already have very efficient algorithms to handle bandwidth throttling.

  • Bayan Dec 12, 2014 @ 7:10

    I tried this method and it worked for downloading a file from my server – the download rate never exceeds 2mbps.
    But when I run iperf at the client, I get an insanely large value of the bandwidth, about 400mbps while the rate I used in tc was 2mbps

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum