How to Secure Your Linux Desktop with Iptables

Secure Linux Iptables

Linux may have a reputation for security, but it isn’t perfect. Many distributions also don’t have the best security defaults, so it’s best to implement some best practices for security or use open source security tools. One such example is using a firewall.

There are a few options for firewalls in Linux, but most are actually just wrappers around iptables. For this guide we will show you how to work with iptables directly.

Also read: What Is Log4Shell and How to Protect Your Linux System Against It

What Is Iptables?

Iptables is the Linux kernel firewall. It comes with every Linux distribution, and it’s the most direct way to control traffic coming into and out of your computer.

Iptables has a reputation for being complex, and it can be. You don’t need to know everything about iptables to use it effectively on your desktop, though. You just need some basic knowledge of how it works and how its rules are structured.

Command Structure

All iptables rules follow the same basic structure. Each rule is a single-line command to iptables that tells it how to handle traffic on a specific port. Take a look at the example below:

-A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED --sport 80 -j ACCEPT

That might look like a lot, but it’s really simple when you break it down. First, this rule begins with -A because it will append onto your iptables rules.

Next, the -i flag specifies the interface that the rule is for. In this case, it’s eth0. When you write your own rules, make sure that you know which interface you’re connected to your network through.

The following flag, -p, names the protocol. This rule is for tcp, which is Web traffic.

The -m flag is a little different. It is used to assert that there is a condition that must be met in order for traffic not to be rejected. The condition in this rule is the state.

State is actually the next flag. You need to give --state a list of acceptable states written in all caps and separated with commas. This rule accepts both new and established connections.

The second to last flag here is --sport. It stands for “source port,” and it tells iptables where the traffic is coming from. There is also a --dport flag that stands for “destination port.” It’s used for OUTPUT rules for handling which port traffic is arriving from.

Finally, there’s the -j flag. It tells iptable which action to “jump” to. In this case it should ACCEPT the traffic that meets the previous conditions.

Also read: How to Use the Nessus Vulnerability Scanner on Linux

Using a File

You can enter your rules into iptables manually one by one. That’s incredibly tedious, and it’s very easy to lose track of where you are and what you’re doing. It’s much better to create a rules file that you can import into iptables all at once.

It doesn’t matter where you create the file. People even make them in the /tmp directory because iptables stores the result after it is imported.

Create your file. This guide is going to use /tmp/iptables-ip4. In the file add the following two lines. All of your rules will go between them.

*filter
 
# Your Rules Here
 
COMMIT

Create Your Rules

You can start setting up your rules. These are just suggestions. Obviously, if you’re running other services or need other ports open, you can certainly tweak some things or add your own rules.

Loopback

The loopback interface is an internal interface that Linux uses.

-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

Ping

This one is a matter of preference. Many people don’t like allowing ping at all on their desktops. It can be useful to have it, though, to test connections. If you want to allow ping, add the rules below. If you don’t, exclude them.

-A INPUT -i eth0 -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT
-A INPUT -i eth0 -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -o eth0 -p icmp -j ACCEPT

The Web

You obviously want to be able to connect to the Web. On the flip side of that, you don’t want to allow connections originating from the Internet.

-A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED --sport 80 -j ACCEPT
-A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED --sport 443 -j ACCEPT
 
-A OUTPUT -o eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 443 -j ACCEPT

You’re also going to need to allow DNS connections so that your computer can use URLs instead of only IP addresses because that wouldn’t be very convenient. Substitute your router’s IP address for the one used here.

-A INPUT -i ens3 -s 192.168.1.1 -p udp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -o ens3 -d 192.168.1.1 -p udp --dport 53 -m udp -j ACCEPT

Time

Most Linux desktops use NTP to set and maintain the system time from the Internet. You need to allow your computer to connect to an NTP server to get the time.

-A INPUT -i eth0 -p udp -m state --state ESTABLISHED,RELATED --dport 123 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --sport 123 -j ACCEPT

Printing

Unless you’re using a USB printer or an external print server, you need to enable connections to CUPS.

-A INPUT -p udp -m udp --dport 631 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A OUTPUT -p udp -m udp --sport 631 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 631 -j ACCEPT

Email

You probably want to be able to send and receive email, too. Email can be tricky. The ports allowed here are the SSL email ports. If you need to use unsecured email, substitute those ports.

# IMAP
-A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED --sport 993 -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 993 -j ACCEPT
 
# POP3
-A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED --sport 995 -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 995 -j ACCEPT
 
# SMTP
-A INPUT -i eth0 -p tcp -m state --state ESTABLISHED,RELATED --sport 465 -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 465 -j ACCEPT

SSH

In order to fully utilize SSH connections, you need to be allow both input and output over SSH.

# Input
-A INPUT -i ens3 -p tcp -m state --state NEW,ESTABLISHED --dport 22 -j ACCEPT
-A OUTPUT -o ens3 -p tcp -m state --state ESTABLISHED --sport 22 -j ACCEPT
# Output
-A OUTPUT -o ens3 -p tcp -m state --state NEW,ESTABLISHED --dport 22 -j ACCEPT
-A INPUT -i ens3 -p tcp -m state --state ESTABLISHED --sport 22 -j ACCEPT

DHCP

Most Linux desktops use DHCP to automatically receive an IP address from a router. DHCP uses its own ports, so they need to be accessible too. If you’re using a static IP, you don’t need these rules.

-A INPUT -i eth0 -p udp -m state --state ESTABLISHED,RELATED --sport 67:68 -j ACCEPT
-A OUTPUT -o eth0 -p udp -m udp --dport 67:68 -j ACCEPT

Reject Everything Else

Finally, you’re going to tell iptables to reject absolutely everything that you didn’t explicitly allow in the rules above.

-A INPUT -j REJECT
-A FORWARD -j REJECT
-A OUTPUT -j REJECT

After everything, your rules should looks something like these.

iptables rules

Also read: How to Use Password Store to Manage Your Passwords in Linux

Importing Your Rules

You now have a fully-functional iptables rules list. You just need to hand it off to iptables to use.

In case some rules have been added over time, clear them out. After these commands, you’ll see the defaults that allow everything.

sudo iptables -F && sudo iptables -X

Iptables clear rules

With those gone, you can restore the new ones from the file that you created.

sudo iptables-restore < /tmp/itpables-ip4

Your computer is now using the new iptables rules. You can check them out.

sudo iptables -S

Iptables Rules List

However, they aren’t permanent yet. If you restart your computer now, you’re going to have a really bad time.

Also read: How to Secure Your Linux Servers With SELinux

Making Them Permanent

There are several ways to make the rules permanent. They’re different for each distribution. This guide is going to focus on Debian- and Ubuntu-based systems, since they’re the most popular.

There is a package available, called iptables-persistant, that handles saving and restoring iptables. All you have to do is install it.

sudo apt install iptables-persistent

Save Iptables Rules

During the installation, the package will ask you if you want to save your configuration. Select “Yes.”

In the future, if you want to add rules, you can save again by running the following command.

sudo service netfilter-persistent save

You are now in control of the traffic flowing through your computer. There is certainly more that you can do with iptables, but you should feel confident with the basics first.

Subscribe to our newsletter!

Our latest tutorials delivered straight to your inbox

Nick Congleton

Nick is a freelance tech. journalist, Linux enthusiast, and a long time PC gamer.