IPTables and conntrack

When you are using LANforge as a virtual router doing NAT, you might need to see how many NAT table entries you’re handling.  This can be important because NAT entries take memory, and if you want to handle 65,000 simultaneous connections, you might be heading for trouble.

If your LANforge is only generating traffic, you won’t see NAT entries…rather you want to use netstat -ntp to see how many open connections there are.

LANforge uses iptables PREROUTING heavily, forcing each port to have it’s own set of tables. When you type iptables -nvL and see nothing…that’s because nothing is in the tables for your default route, which is probably eth0. You get close with the raw table. Try iptables -S -t raw. You will see PREROUTING entries for every interface:

# iptables -S -t raw
-A PREROUTING -i br2000 -j CT --zone 10001
-A PREROUTING -i eth1 -j CT --zone 10001
-A PREROUTING -i vap13 -j CT --zone 10001
-A PREROUTING -i vap14 -j CT --zone 10001
-A PREROUTING -i eth2 -j CT --zone 10001

This shows we have a CT chain and a zone note for that chain.

When you create a virtual router, add NAT to a port in it, you can view the NAT table entries with conntrack.

* conntrack -L will list them all, but that’s probably not super useful
If you’re running TCP-multicon connections, expect thousands of connections.
* conntrack -C will show how many NAT entries are present, so you can avoid doing a conntrack -L | wc -l

Happy networking!

Enabling Remote X Connections (updated)

Getting remote X applications displaying on your CentOS desktop used not to be difficult. X11 remote connections are typically governed by the -listen tcp or -nolisten tcp arguments to X or Xorg server running your desktop. It’s not sufficient to just run xhost + from a terminal on your desktop, you have to edit a display manager configuration file and start a new X session (log out, log in again).

First, disable the firewall:

sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo systemctl mask firewalld
sudo systemctl daemon-reload

The right command to test with

If you ssh from desktop1 to server2, you probably have X11 forwarding happening already. This uses implied port forwarding through ssh for port 5900 to localhost:5010 usually. This is why when you type $ echo $DISPLAY you will likely see localhost:10 as your new display. By default, many X11 based programs take a -d host:display.number argument. Use this to avoid testing out the ssh local X forwarding. You want to use xhost + from your desktop first, of course:

desktop1$ xhost +
access control disabled, clients can connect from any host
desktop1$ ssh server2
server2$ echo $DISPLAY
server2$ xterm -d desktop1:0.0

When running lightdm as your display manager:


Updated: The files you want to edit if you’re running lightdm include:
1) /usr/share/lightdm/lightdm.conf.d/50-xserver-command.conf

xserver-command=X -core -listen tcp

2) /etc/lightdm/lightdm.conf
This file probably won’t exist, you may create it if it is missing.

xserver-command=X -listen tcp

Then run $ sudo systemctl restart lightdm

When you log in again, check that no -nolisten tcp arguments are present in the X command line. Multiple -listen tcp arguments are fine.

$ pgrep X | xargs ps -lfwwwp

When running gdm as your display manager:

Then edit /etc/gdm/custom.conf

You want to add this line to [security] stanza:


And allow a listen tcp argument to the [xdmcp] stanza:

ServerArguments=-listen tcp

A full configuration looks like:

# GDM configuration


ServerArguments=-listen tcp



Log out of your CentOS desktop session, and log in again. Open a terminal and run:

$ xhost +

You can check the efficacy of that by looking at the arguments X was started with:

$ pgrep X | xargs ps -lfwwwp


Other options include TigerVNC:

$ sudo yum install tigervnc
$ vncviewer

Or use Rdestop:

$ sudo yum install freerdp
$ xfreerdp

Remote X connections have been out of fashion for many years, and the default is to not allow connections for security reasons. If you are running equipment in an isolated environment, you should feel safe doing this.

Temporarily Changing the Default Gateway to a Virtual Station

When testing a virtual station and you need to verify with a browser that you can reach a captive portal page, or browse the Internet–you want to change the default gateway of the system to the gateway that the virtual station was assigned. This is a manual change, because when the virtual station associates, the default route of the system doesn’t change. If it did, you’d probably lose connection between the LANforge resource and your management station would probably be lost.

After checking your associated station, you can write a script to help set the new default gateway. Here’s an example with some fixed values:

echo "Please do this command in screen"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Use this script to modify your routes to allow a station      #
# to become the default route. Should maintain route for your   #
# existing connection to management laptop through eth0.        #
# This script is an example to be modified.                     #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
set -x
ip a show eth0
ip a show sta100
ip route show

# this adds address to station, referred to below
# ip a add dev sta100

# make static route to old gateway
ip route add dev eth0

# make static route to mgt laptop
ip route add dev eth0

# now update default route to go out sta100
ip route change default via dev sta100

sleep 1s
ping -nc2
ping -nc2

# adjust this to your work time window
read -t $((2 * 60)) -p "Press Enter to end and reset"

# and set the route back
ip route change default via dev eth0
ip route show
ping -nc2
ping -nc2

Notice that the script suggests using screen.  Why use screen? Because if your terminal session disconnects, the script will continue and reset the previous default gateway. If the script is interrupted (by session disconnection or control-c) your default route will remain running across your AP. (We add default link-local routes to our laptop to help mitigate this.)
There is a default .screenrc file in /home/lanforge. You want to run the script as root. This will work: sudo ./change_gw.sh

This is an example script with some logic to help detect the default gateway, your ssh connection, and you tell it what station to use:

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#  Use this script to modify your routes to allow a station     #
#  to become the default route. Should maintain route for your  #
#  existing connection to management laptop through eth0.       #
#  This script is an example to be modified.                    #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

if [ -z "$3" ]; then
   echo "Use this script to assign a station on this system to be the new default gateway."
   echo "Usage: $0   "
   echo ""
   echo "Your manager-ip is the LANforge resource in mode 'manager' or 'both' and might"
   echo "not be the machine hosting the virtual station."
   echo "Example, sta3000 on resource 3, manager is"
   echo ""
   echo "./$0 3 sta3000"
   echo ""
   echo "Please do this command in screen"
   exit 1

def_gw_dev=`route -n | awk '/^ / {print \$NF}'`
def_gw_ip=`ip a show $def_gw_dev | awk '/inet /{print \$2}'`
echo "default gw device: $def_gw_dev $def_gw_ip "
sleep 3
manager_ip=`who | perl -ne '/\(([0-9.]+)\)$/ && print "$1\n";'`
#ip a show $def_gw_dev
echo "This is the station you requested:"
ip a show $3
sleep 3

#  make static route to old gateway
echo "ip route add $def_gw_ip dev $def_gw_dev"
ip route add $def_gw_ip dev $def_gw_dev

#  make static route to mgt laptop
echo "ip route add $manager_ip dev $def_gw_dev"
ip route add $manager_ip dev $def_gw_dev
sleep 3

# now update default route to go out sta100
cd /home/lanforge/scripts
sta_gw=`./lf_portmod.pl --manager $1 --card $2 --port_name $3 \
  --show_port --quiet yes \
  | awk '/ IP:/{print \$6}'`

echo "* Changing default gateway in 3 seconds *"
sleep 3s
echo "ip route change default via $sta_gw dev $3"
sleep 1s
ip route change default via $sta_gw dev $3
sleep 1s
ping -nc2 $def_gw_ip
ping -nc2 $manager_ip

# adjust this to your work time window (in seconds)
#  $(( 2 * 60)) == 120, 2 minutes
read -t $((2 * 60)) -p "Press Enter to end and reset"

# and set the route back
echo "changing route back to previous default gw..."
ip route change default via $def_gw_ip dev $def_gw_dev
ping -nc2 $def_gw_ip
ping -nc2 $manager_ip
echo "...done."

To use the script, you would say:

sudo ./change_gw.sh 3 sta3000

You are probably going to need to alter the script. If you hit Ctlc in the script you will need to reset the routes by hand.

For actually using Firefox, you need to operate this from the desktop of LANforge resource hosting the virtual station. So if, in this example, sta3000 is on resource 3, you need to get on the virtual desktop of resource 3. Open a terminal from the virtual desktop or ssh to resource 3 and start screen as user LANforge.

Controlling ARP Solicitations

When your network endpoints are not changing during testing scenario, transmitting ARP packets at the default rate is arguably wasted bandwidth. You can tune the Linux networking stack to extend the time between ARP broadcasts.

These tunables are in /proc/sys/net/ipv4/neigh and are divided by default and per-device settings. The knobs I find that are useful are:

  • base_reachable_time: a guideline on how often to broadcast for ARP updates
  • gc_stale_time: threshold in seconds on when to consider evicting an arp entry
  • locktime: minimum time to keep an ARP entry

You can set twist these knobs for two ports in a shell script like so:

for f in /proc/sys/net/ipv4/{enp2,enp3}/{base_reachable_time,gc_stale_time,locktime} ; do
    echo 300 > $f

This changes the values to 5 minutes.