Port Triggering Using A NAT Firestarter Firewall And Specter In Debian/Ubuntu
Port Triggering Using A NAT Firestarter Firewall And Specter In Debian/Ubuntu
Many that play PC games, such as battle.net, need to be able to set up port triggering. Typical "hardware" routers have the ability to set this up from online menus. However, using a Linux PC to perform your router functions can provide much more control and versatility than can be realized with a "hardware" router. All of your NAT (network address translation), firewall, and port forwarding functions can be implemented by iptables, the de facto firewall in Linux versions 2.4.x and 2.6.x.
I looked online quite a lot to try to
linux- or iptables-based port triggering
setup. There was plenty on port forwarding using iptables, but not
on port triggering. This article provides the details to implement
triggering using iptables, firestarter, ULOG, Specter, and a small
amount of bash scripting.
ULOG is the user space logging facility that can be added onto
allowing for multicasting of packets. Specter is a program that runs a
that allows you to initiate actions as a result of subscribing to ULOG
streams. Firestarter is a firewall GUI front-end to iptables, which
makes interfacing to your firewall easy. Although it appears that there
has not been recent development activity of firestarter, it is still a
viable, user-friendly, easily-installed package that really does not
require upgrades once properly configured. The only software that you
need to install to be able to implement port triggering with this
method is firestarter, Specter, and a few bash scripts. My
configuration uses a PC running Debian Linux (although the
following instructions will work for Ubuntu as well) as the
router/firewall for my home LAN, and most of the PCs in my LAN are
running Windows (the gaming PCs).
I use as an example port triggering for battle.net. The main reason for this is that my son likes to host games for this, so I have a decent tester, and he has proven the setup for many months. Battle.net primarily uses tcp port 6112; the concept here is that when a PC on the internal LAN (for example, 192.168.0.102) initiates a tcp connection to the battle.net server site to start hosting a game, the PC initiates this on tcp destination port 6112. This action then "triggers" a sequence of commands that reconfigure the firewall temporarily: it enables port 6112 to be opened on the firewall, and forwards connections aimed at this port to machine 192.168.0.102, the "triggering" (hosting) machine. After a reasonable period of time, the port is closed and stealthed, dropping any packets that are routed to it to thwart any outside meddling or attacks (as usual).
Port triggering was implemented by specifying which port would be involved. Two iptables rules were added to the OUTBOUND chain, which in my setup (firestarter) is the set of rules that are jumped to from the OUTPUT chain after some screening is done on the OUTPUT traffic on the LAN. The rules perform ULOG logging output to the nlgroup 20 (an arbitrary number), matching only on TCP packets in the NEW state. When those packets are output, then Specter executes a bash file. The bash file sets up additional iptables rules and also creates lock files, so that we ensure that we do not create redundant iptables rules. Aside from setting up the port forwarding rules to the initiating PC on the LAN for incoming connections, the new iptables rules also add another ULOG output, ulog-nlgroup 21. This subscribes to packets at a very limited rate, specifically only 1/minute. This checks to make sure that the outbound traffic that initiated the connection is still active; if it is inactive for a specified amount of time (15 minutes), then the forwarding rules are eliminated, and the triggering setup is abandoned. This distinguishes port triggering from port forwarding; in port forwarding, the forwarding is implemented indefinitely, which is less secure.Before we begin, some assumptions:
- you are using two NICs in the linux box being used as the router/firewall,
- one connected to the internet via a cable / DSL modem (I am assuming it is eth1),
- one connected to your LAN (I am assuming it is eth0).
You can check which card
is which on your system by using the command:
You can check which card is which on your system by using the command:
On a typical setup
possessing two cards, the
output of this command should identify one card with a broadcast ID of
something like "192.168.0.255" or "10.0.0.255", etc. In that case, that
interface is your LAN interface and you should change what has been
assumed here (eth0) to the value given by the command output. The other
interface should access the internet and have a broadcast address like
"255.255.255.255". If it is different from "eth1", then change eth1 to
the proper value throughout this howto.
On a typical setup possessing two cards, the output of this command should identify one card with a broadcast ID of something like "192.168.0.255" or "10.0.0.255", etc. In that case, that interface is your LAN interface and you should change what has been assumed here (eth0) to the value given by the command output. The other interface should access the internet and have a broadcast address like "255.255.255.255". If it is different from "eth1", then change eth1 to the proper value throughout this howto.
Set up Firestarter per the
instructions at the following link:
Set up Firestarter per the instructions at the following link:
its wizard, Firestarter can be easily configured to function as a
router for internet connection sharing. It is essentially a
interface to Linux's iptables.
Using its wizard, Firestarter can be easily configured to function as a router for internet connection sharing. It is essentially a GUI interface to Linux's iptables.
feature of Firestarter is that you can insert your own custom rules
into iptables. We will use this to insert two rules after the
configuration script for Firestarter has been run. This is done by
creating the file:
A feature of Firestarter is that you can insert your own custom rules into iptables. We will use this to insert two rules after the configuration script for Firestarter has been run. This is done by creating the file:
with the following two
lines in it (use your favorite editor, such as nano; or if you are
using gnome, you can copy and paste these lines into a graphical
with the following two lines in it (use your favorite editor, such as nano; or if you are using gnome, you can copy and paste these lines into a graphical editor):
$IPT -I OUTBOUND 4 -s 192.168.0.0/24 -i eth0 -p tcp -m tcp --dport 6112 -j ULOG --ulog-prefix "trigger write" --ulog-nlgroup 20 -m hashlimit --hashlimit 1/minute --hashlimit-burst 2 --hashlimit-mode srcip,dstport --hashlimit-name w6112
(replace 192.168.0.0/24 with your LAN address range, and eth0 with the appropriate interface name). In order to create the file, you will need to create it as root or with root privileges.
These two iptables rules watch your LAN for outgoing packets with a destination port of 6112 (the battle.net networking port). When it sees these packets, a limited number of them are logged to user space via netlink sockets. A package which we will install next, called "Specter", subscribes to these sockets and acts upon them. Initial packets are logged to nlgroup 21, and a script is used to initiate a battle.net session by setting up port forwarding to the initiating PC. Continuing packets (regardless of whether they are in a NEW state or not) are logged to nlgroup 20, and a script is used to keep track of whether there is still activity by the initiating PC or not. Since port forwarding to an internal LAN client opens ports to the internet, it is not something that you should leave in place when you are not playing a game. As long as packets have been sent from this PC within 15 minutes, the ports are left open and forwarded. After 15 minutes of inactivity, port forwarding is stopped, the session is closed, and it is assumed the game is over. A new session can then be immediately initiated.
To install Specter in Debian or Ubuntu, issue the following command:
sudo apt-get install specter specter-mysql specter-pgsql
We will need to edit the config file for Specter, /etc/specter.conf, to be able to act upon the user space logging. Add the following lines to the end of this file:
# nlgroup 20, write to file /tmp/forward.6112 if dest port 6112 is outbound from LAN
Again, you will need root privileges to save this file.
The home page for Specter is at: http://joker.linuxstuff.pl/specter/
Next, create the bash script file (it also needs root ownership) and save it as:
That file contains the following lines:
After creating it, you will need to make it
executable with the command:
sudo chmod 755 /etc/firestarter/initial_trigger_action
Next, create the following bash script file (it also needs root ownership) and save it as:
Here is the file:
After creating it, you will need to make it executable with the command:
sudo chmod 755 /etc/firestarter/trigger_test_6112
These scripts create a few files in the /tmp directory for debugging purposes; they can be disregarded aside from the lock file (or you can modify the scripts if you like to prevent them from being created). By default, mail is sent to root when a session is initiated, and during a session, announcing the status of the session. One useful feature of Firestarter is that you can monitor who is actually connected to your LAN PCs from the outside world; when a battle.net session is functioning properly, you will see several IP addresses connected on port 6112 to your LAN PC (for example, 192.168.0.102).
A couple of notes regarding this setup: with it, you can have multiple game participants behind the firewall on your LAN, at the same time that you have external connections to the hosting PC. The key issue is that the hosting PC needs to be the first one that contacts the battle.net website (the first one that actually makes an outgoing request to port 6112). This PC is identified as the host for 15 minutes after its last attempt to contact the website, and if that PC does not follow through and become the host, but instead a different LAN PC attempts to become the host, it will not be able to until the timers in the scripts expire and the firewall closes again. This can be a source of frustration if you have eager gamers on the LAN that are not heeding this requirement. This setup does not enable (or disable) pings from the internet. That can be done separately in Firestarter. Allowing pings (ICMP) is not necessary for battle.net to work; however, it is used sometimes for troubleshooting. I prefer to make my firewall entirely stealthed when a game is not active, and I haven't gone to the trouble to change the behavior of ICMP during a game.
Also, bash/sed gurus out there will note that I am no advanced scripter -- my goal was to get something working and document it sufficiently for someone else to know what I did. I welcome suggestions for improvement of the setup; as I mentioned, I found no setups (outside of OpenWrt, and it requires specialized hardware) that would allow you to do the type of automated port triggering needed for gaming and still close the ports at the end of the game for better security. Although this setup was written for Debian/Ubuntu, it should work equally well (with properly amended installation instructions) for other flavors of Linux. The hardware requirements of the router/firewall PC, aside from needing 2 NICs, is very modest. Mine has no terminal, it's in the closet collocated with the cable modem; I control it entirely by using remote VNC software and SSH (Putty and ultraVNC from a Windows PC).