iptables and iprules

Testing Your iptables Rules

It may not be obvious, but you need to test your rules - both routing rules (per ip rules) and iptables rules - before you cement them in place. One of the great things about the Routing Policy DataBase (RPDB) and iptables is they are very forgiving of catastrophic screw-ups. Simply force a server reboot, your rules are emptied, and you may start over. So, before you make them permanent (automatically load on boot-up), it's critical to thoroughly test them, lest you lock yourself out of your server. I can't stress this enough, especially with a headless or remote server.

I've found the best way to do this is to create custom scripting files that populate the rules in your RPDB and iptables. You can certainly also populate your route tables with this method as well, and I'll show you how to do that as well.

Listing Rules by Number

Here's how to list all the rules in all the chains with line numbers so you can identify each rule's number. This can be very useful when troubleshooting or to identify a rule number for deletion.

iptables -L -v -n --line-numbers
You may specify a particular table if you know which you want to focus on. Simply include the table name after the -L command.

Shell Scripts

Create two scripts. One for iptables and one for your RPDB rules and/or routes. The reason why is because the implementation process that will automatically load your rules needs to be segmented.

iptables Shell Script

Open your favorite text editor and begin a new file. Populate the file with your iptables entries. This is a very basic example. Your needs will vary, and this guide's purpose is simply to provide an overview of Linux networking in Ubuntu and various processes. You must figure out what iptables rules you need and modify the sample script below to meet your needs.

nano /etc/iptables-script.sh

Here's a very basic sample script. Notice at the end of the file it calls the next file, which will update your RPDB rules and routes.

#! /bin/bash

# iptables sample test script

# flush iptables rules
iptables -F -t nat
iptables -F -t mangle

# OUTPUT chain
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

# launch RPDB script

exit 0

Save the file.

Make the script file executable.

chmod +x /etc/iptables-script.sh

chmod 755 /etc/iptables-script.sh

Routing and RPDB Rules Shell Script

You'll now create an independent script to manage changes to the RPDB routes and rules. If you plan on using custom routing tables, make sure you've already created them in the master routing table. Instructions on how to do this are found in The Master Routing Table.

Begin a new script file. Remember, this will be called by the first file. Ensure the filename reference at the end of your first script matches this filename.

nano /etc/routing-script.sh

Here's a very basic sample script that will update your RPDB rules and routes. Remember, this is just a sample file. Do not use this verbatim!

#! /bin/bash
# RPDB sample test script

# presume there is an existing table called custom-table-name
# you would have created this table previously in the table names file

# sample ip rule
ip rule add from lookup custom-table-name

# sample ip route
ip route add default via dev eth0 table custom-table-name

# reload cache to load new rules and routes
ip route flush cache

exit 0

Save the file.

Make the script file executable.

chmod +x /etc/routing-script.sh

chmod 755 /etc/routing-script.sh

To test your changes, simply execute the first script.


This article presumes you're using a Linux-based operating system utilizing the SystemD system manager. The code examples here were written on Ubuntu 16.04. If you are using Ubuntu 16.04 or later, or a modern Debian distro of Linux, they should work fine.

SystemD and the Start-up Process

Now that you've setup and tested your scripts, it's time to configure your server to automatically execute them when it boots. This will cause your rules and routes to be established every time the server restarts, which is necessary because otherwise they won't be present. This is called making your iptables rules persistent.

To make this happen, you need to create a hook that calls your script file during the server's startup process. If you don't already know how to do this, you can read about different methods of accomplishing this task in Persistence: Making iptables Changes Stick.