Contents
- Using a BitTorent application with Linux iptables
- BitTorent ports
- Firewall Generic Rules for a BitTorrent application
- iptables Firewall Rules for a Standalone System
- Related Links
- Example
Using a BitTorent application with Linux iptables
To make a Bittorrent application work with Linux firewall iptables, you need to allow the Bittorrent client application to establish network connections to the network. Also, the Bittorent application need to accept connections from peer clients. In this section, we detail the iptables rules needed to achieve the above. These rules have been tested on a Linux Debian OS with the qBittorrent application. the same should apply to other torrent applications and Linux distributions with minor modifications if not any.
BitTorent ports
- BitTorent client listens to one TCP port for incoming connections from peer torrent clients. This port is configurable and is normally set according to the standard to one value in the range 6881 to 6889. This range has then been extended from 6881 to 6999. It is however very common among torrent users to set this port outside the specified range in the standard, These users try to avoid Internet Service Providers (ISPs) bandwidth limitations set on these ports. Indeed, ISPs tend to limit Peer to Peer (P2P) applications due to the amount of internet usage they accounts for.
- BitTorent client should be allowed for TCP connections to peer torrent clients. For the reasons explained above, it very common for these ports to be outside the range 6881 to 6999.
- If enabled, the DHT extension (peer2peer tracker) uses various UDP ports negotiated by the peers. At the client the UDP listening port is configurable.
- The Bittorrent client should be allowed to reach the tracker server at port 6969. Note however, that most of the tracker servers use instead TCP port 80.
The table bellow depicts the list of UDP and TCP used by BitTorrent clients. [source: Wikipedia, List of TCP and UDP port numbers]:
Note that these ports are not registered IANA ports (1024 to 49151).
Ports | TCP | UDP | |
6881-6968 | TCP | UDP | BitTorrent part of full range ports used |
6969 | TCP | BitTorrent Tracker | |
6970-6999 | TCP | UDP | BitTorrent part of full range ports used |
7000 | TCP | Default for Vuze's built in HTTPS Bittorent Tracker | |
10000 and above | TCP | UDP | Used by most BitTorrent applications. |
Firewall Generic Rules for a BitTorrent application
The following table gives the generic rules you need to implement in your firewall to allow the BitTorrent client to work. In this table BitTorrent client IP is the IP of your network device that is connected to the internet.
rule | Protocol | Src. Port | Dest. Port | Src. IP | Dst. IP | Notes |
1 | TCP | 1024:65535 | 80 | BitTorrent client IP | ANY | Allow HTTP connections to web servers and to BitTorrent trackers. |
2 | TCP | 1024:65535 | 6881-65535 | BitTorrent client IP | ANY | Allow BitTorrent client TCP connections to other peer clients. |
3 | UDP | 1024-65535 | 6881-65535 | BitTorrent client IP | ANY | Allow BitTorrent client UDP connection to other peer clients |
4 | TCP | 1024-65535 | Configurable TCP port | ANY | BitTorrent client | Allow peers to establish TCP connections to your BitTorrent application. |
5 | UDP | 1024-65535 | Configurable UDP port | ANY | BitTorrent client | Allow you BitTorrent client to receive UDP packets from peers. |
6 | TCP | 1024-65535 | 53 | BitTorrent Client IP | DNS server IP | Allow TCP connections to the Domain Name Server (DNS) |
iptables Firewall Rules for a Standalone System
We need to translate the generic rules in the table above to iptables rules. Basically, the to set at the firewall should allow input and output TCP and UDP connections at specified ports and IP addresses. The Generic, iptable to allow output TCP connection is as follows:
iptables -A OUTPUT -o $ETH -p tcp \-s $TORRENT_CLIENT_IP --sport $UNPRIVPORTS \--dport $UNPRIVPORTS \-m state --state NEW -j ACCEPTiptables -A OUTPUT -o $ETH -p tcp ! --syn \-s $TORRENT_CLIENT_IP --sport $UNPRIVPORTS \--dport $UNPRIVPORTS -j ACCEPTiptables -A INPUT -i $ETH -p tcp ! --syn \-d $TORRENT_CLIENT_IP --dport $UNPRIVPORTS \--sport $UNPRIVPORTS -j ACCEPT
In the above:
-A OUTPUT | Appends the rule to the 'output' chain. |
-o $ETH |
Specifies the network device name the rule applies applies to. If no device is specified, the rule is applied to all network devices.
Generaly, the output network device is eth0. You may check your network devices on your machine using the command "ip add"
The output shows in our case two devices. the loopback device noted 'lo' and the 'eth0' network device with IP address 192.168.153.51. Thus we have:
|
-p tcp | Specifies the TCP protocol that the rule applies to. |
-s $TORRENT_CLIENT_IP | The IP of the network device. |
--sport $UNPRIVPORTS |
The source port allowed to establish a TCP connection. $UNPRIVPORTS are the unregistered private ports range 1024 to 65535. Therefore:
|
--dport $UNPRIVPORTS | The destination port. |
-m state --state NEW | Rules in iptables are applied on a packet by packet basis. The 'state' filter option here is a performance enhancement that allows to bypass rule checking to packets that belongs to an established TCP or UDP connection. the option '--state NEW' is equivalent to the SYN TCP packet or the first UDP packet. The rule bellow is necessary in case the state gets initialized (lost) in an ongoing TCP or UDP connection.
iptables -A OUTPUT -o $ETH -p tcp ! --syn \
-s $TORRENT_CLIENT_IP --sport $UNPRIVPORTS \
|
-j ACCEPT | If the rule matches the received packet then accept it. |
Related Links
This wiki shows how to save iptables rules to a file and then use it to restore the rules at boot time. This is a handy way for iptables rules to survive a reboot.
You'll learn here how to configure programs to start up automatically at login. You may use that to start your torrent application without further action at boot time. This is useful if your BitTorrent client runs on a dedicated machine that you access remotely via the Torrent's application Web User Interface (Web UI).
A list of Internet service providers (ISPs) that are known to cause trouble for BitTorrent clients and the reason why.
The documentation of qBittorent.
You can use qBittorrent application through a Web User Interface (UI) only. In that case, your desktop do not need X server. This link describes how to achieve this, you need however to recompile the qBittorrent application.
Example
Bellow is an example of a script for iptables rules for the qBittorent application. The qBittorent application runs on HOME_DEBIAN (192.168.153.51) on the same subnet HOME_HP (192.168.153.21) is accessing the WEB UI of the qBittorent on port 5901.
#!/bin/bash
IPT="/sbin/iptables"
if [ "$1" = "status" ]
then
$IPT -L -v -n
exit 0
fi
ENABLE_LOGGING="1"
UDP_TORRENT="0"
ACCEPT_ICMP="1"
CONNECTION_TRACKING="1"
UNPRIVPORTS="1024:65535"
TORRENT_PORTS="6881"
TORRENT_PORTS_RANGE="6881:65535"
SSH_PORTS="1020:65535"
HOMELAN="192.168.153.0/24"
HOMELAN_ADDR="192.168.153.1"
HOME_HP="192.168.153.21"
HOME_DEBIAN="192.168.153.51"
ETH="eth0"
ANY_ADDR="0.0.0.0/0"
LOOPBACK="127.0.0.0/8"
############################################
# Remove any existing rules from all chains#
############################################
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo M1
###########################
# Reset the default policy#
###########################
$IPT --policy INPUT ACCEPT
$IPT --policy OUTPUT ACCEPT
$IPT --policy FORWARD ACCEPT
$IPT -t nat --policy PREROUTING ACCEPT
$IPT -t nat --policy OUTPUT ACCEPT
$IPT -t nat --policy POSTROUTING ACCEPT
$IPT -t mangle --policy PREROUTING ACCEPT
$IPT -t mangle --policy OUTPUT ACCEPT
if [ "$1" = "stop" ]
then
echo "Firewall completely stopped! WARNING: THIS HOST HAS NO FIREWALL RUNNING."
exit 0
fi
##############################################
# Unlimited traffic on the loopback interface#
##############################################
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
#################################
# Set the default policy to drop#
#################################
iptables --policy INPUT DROP
iptables --policy FORWARD DROP
iptables --policy OUTPUT DROP
#$IPT -t nat --policy PREROUTING DROP
#$IPT -t nat --policy OUTPUT DROP
#$IPT -t nat --policy POSTROUTING DROP
#$IPT -t mangle --policy PREROUTING DROP
#$IPT -t mangle --policy OUTPUT DROP
###############
#Stealth Scans#
###############
# Unclean
#$IPT -A INPUT -m unclean -j DROP
# All of the bits are cleared
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# SYN and FIN are both set
$IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# SYN and RST are both set
$IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# FIN and RST are both set
$IPT -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
# FIN is the only bit set, without the expected accompanying ACK
$IPT -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
# PSH is the only bit set, without the expected accompanying ACK
$IPT -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
# URG is the only bit set, without the expected accompanying ACK
$IPT -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
##########################################
#Enable for Debuging purposes #
##########################################
if [ "$ACCEPT_ICMP" = "1" ]; then
iptables -A INPUT -p icmp -j ACCEPT
iptables -A FORWARD -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
fi
##########################################
#Connection State to bypass rule checking#
##########################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
fi
###############################################
# Refuse spoofed packets pretending to be from#
# the external interface's IP address #
###############################################
$IPT -A INPUT -i $ETH -s $HOME_DEBIAN -j DROP
############################################################
# Refuse packets claiming to be from the loopback interface#
############################################################
$IPT -A INPUT -i $ETH -s $LOOPBACK -j DROP
####################################################
#Allow DNS lookup #
####################################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A OUTPUT -o $ETH -p udp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
-d 195.170.0.1 --dport 53 \
-m state --state NEW -j ACCEPT
fi
iptables -A OUTPUT -o $ETH -p udp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
-d 195.170.0.1 --dport 53 -j ACCEPT
iptables -A INPUT -i $ETH -p udp \
-d $HOME_DEBIAN --dport $UNPRIVPORTS \
--sport 53 -s 195.170.0.1 -j ACCEPT
####################################################
#Allow TCP connection from LANA to STB for upgrade #
####################################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A OUTPUT -o $ETH -p tcp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
--dport 80 \
-m state --state NEW -j ACCEPT
fi
iptables -A OUTPUT -o $ETH -p tcp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
--dport 80 -j ACCEPT
iptables -A INPUT -i $ETH -p tcp ! --syn \
-d $HOME_DEBIAN --dport $UNPRIVPORTS \
--sport 80 -j ACCEPT
####################################################
#Allow TCP connection to torrents clients #
####################################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A OUTPUT -o $ETH -p tcp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
--dport $TORRENT_PORTS_RANGE \
-m state --state NEW -j ACCEPT
fi
iptables -A OUTPUT -o $ETH -p tcp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
--dport $TORRENT_PORTS_RANGE -j ACCEPT
iptables -A INPUT -i $ETH -p tcp ! --syn \
-d $HOME_DEBIAN --dport $UNPRIVPORTS \
--sport $TORRENT_PORTS_RANGE -j ACCEPT
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A OUTPUT -o $ETH -p udp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
--dport $TORRENT_PORTS_RANGE \
-m state --state NEW -j ACCEPT
fi
iptables -A OUTPUT -o $ETH -p udp \
-s $HOME_DEBIAN --sport $UNPRIVPORTS \
--dport $TORRENT_PORTS_RANGE -j ACCEPT
iptables -A INPUT -i $ETH -p udp \
-d $HOME_DEBIAN --dport $UNPRIVPORTS \
--sport $TORRENT_PORTS_RANGE -j ACCEPT
#####################################
# Allow SSH incoming access to debian #
# Allow SSH incoming accessto debian #
#####################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A INPUT -i $ETH -p tcp \
-s $HOME_HP --sport $SSH_PORTS \
-d $HOME_DEBIAN --dport 22 \
-m state --state NEW -j ACCEPT
fi
iptables -A INPUT -i $ETH -p tcp \
-s $HOME_HP --sport $SSH_PORTS \
-d $HOME_DEBIAN --dport 22 -j ACCEPT
iptables -A OUTPUT -o $ETH -p tcp ! --syn \
-d $HOME_HP --dport $SSH_PORTS \
-s $HOME_DEBIAN --sport 22 -j ACCEPT
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A INPUT -i $ETH -p tcp \
-s $HOME_HP --sport $SSH_PORTS \
-d $HOME_DEBIAN --dport 5901 \
-m state --state NEW -j ACCEPT
fi
iptables -A INPUT -i $ETH -p tcp \
-s $HOME_HP --sport $SSH_PORTS \
-d $HOME_DEBIAN --dport 5901 -j ACCEPT
iptables -A OUTPUT -o $ETH -p tcp ! --syn \
-d $HOME_HP --dport $SSH_PORTS \
-s $HOME_DEBIAN --sport 5901 -j ACCEPT
##################################
# Allow VNC connection
##################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A INPUT -i $ETH -p tcp \
-s $HOME_HP --sport $UNPRIVPORTS \
-d $HOME_DEBIAN --dport 5900 \
-m state --state NEW -j ACCEPT
fi
iptables -A INPUT -i $ETH -p tcp \
-s $HOME_HP --sport $UNPRIVPORTS \
-d $HOME_DEBIAN --dport 5900 -j ACCEPT
iptables -A OUTPUT -o $ETH -p tcp \
-d $HOME_HP --dport $UNPRIVPORTS \
-s $HOME_DEBIAN --sport 5900 -j ACCEPT
##################################
# Allow peer torrents connections
##################################
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A INPUT -i $ETH -p tcp \
--sport $UNPRIVPORTS \
-d $HOME_DEBIAN --dport $TORRENT_PORTS \
-m state --state NEW -j ACCEPT
fi
iptables -A INPUT -i $ETH -p tcp \
--sport $UNPRIVPORTS \
-d $HOME_DEBIAN --dport $TORRENT_PORTS -j ACCEPT
iptables -A OUTPUT -o $ETH -p tcp ! --syn \
--dport $TORRENT_PORTS \
-s $HOME_DEBIAN --sport $TORRENT_PORTS -j ACCEPT
if [ "$UDP_TORRENT" = "1" ]; then
if [ "$CONNECTION_TRACKING" = "1" ]; then
iptables -A INPUT -i $ETH -p udp \
--sport $UNPRIVPORTS \
-d $HOME_DEBIAN --dport $TORRENT_PORTS \
-m state --state NEW -j ACCEPT
fi
iptables -A INPUT -i $ETH -p udp \
--sport $UNPRIVPORTS \
-d $HOME_DEBIAN --dport $TORRENT_PORTS -j ACCEPT
iptables -A OUTPUT -o $ETH -p udp \
--dport $TORRENT_PORTS \
-s $HOME_DEBIAN --sport $TORRENT_PORTS -j ACCEPT
fi
#drop everything and Log it
iptables -A INPUT -j LOG --log-prefix IN
iptables -A INPUT -j DROP
iptables -A OUTPUT -j LOG --log-prefix OUT
iptables -A OUTPUT -j DROP
#if [ "$ENABLE_LOGGING" = "1" ]; then
#for i in $STBLANS;do
# iptables -A CDNCHAIN -s $i -j LOG --log-prefix STB_INVALID:
#done
# iptables -A CDNCHAIN -s $STBLAN2 -j LOG --log-prefix STB_INVALID:
# iptables -A CDNCHAIN -s $ANY_ADDR -j LOG --log-prefix UNKNOW_INVALID:
#fi
#for i in $STBLANS;do
#iptables -A CDNCHAIN -s $i -j DROP
#iptables -A CDNCHAIN -s $STBLAN2 -j DROP
#done
#iptables -A CDNCHAIN -s $ANY_ADDR -j DROP