How To: Protect Your Mac & Linux Computers from Hacks by Creating an iptables Firewall

Protect Your Mac & Linux Computers from Hacks by Creating an iptables Firewall

Formerly ipchains, iptables is a script-based firewall that's included with both Mac and Linux operating systems. In my opinion, it's the best firewall in existence. The only downfall is that it's complicated for some people to use due to its script-based nature. But this should be disregarded, as firewalls are nearly the entire security of your computer.

Still worried about creating a firewall with iptables? Don't worry, Null Byte's got your back. I'm going to show you how to set up some rules as examples, which will allow you to set up your own!

Why Have a Firewall?

A firewalls main purpose is to filter ports. But what are ports?

Certain applications run on specific ports (for the most part). Think of a port like a connection to the Internet in a way that doesn't use your web browser. Normal HTTP Internet traffic runs on port 80. Some services like SMB (Microsoft's file sharing) are the most dangerous services to have running on a port. The program requires authentication to use media shares, and that isn't even a requirement. Even if a user has a passworded media share, the SMB share can still be brute-forced for the password, or even have exploits run agaisnt it to get inside your computer and do whatever the attacker wants.

This is where the firewall comes in. Firewalls filter the ports and try to anticipate traffic from certain protocols via the packet headers. They also can use packet headers to filter out packets via a MAC address, which will avoid being attacked by someone using malformed packets and will allow you to filter out even local users from accessing your media share. Firewalls allow you to have a level of control over your connections that you would not normally have.

Let's get started. This tutorial's commands will all be run from the terminal.

Step 1 Download and Install iptables

It comes with Ubuntu and Mac by default, so this doesn't need to be extensive. If you don't have it, Arch users use:

    sudo pacman -S iptables

and Ubuntu users use:

    sudo apt-get install iptables

Now we're ready to set some rules!

Step 2 Load and Save the Default Ruleset

iptables comes with a default set of rules, one of which does allow all connections to be unfiltered. You can see why this needs to be changed, right?

Let's look at our default configuration located in /etc/iptables/empty.rules:

    cat /etc/iptables/empty.rules

You will see that INPUT, OUTPUT and FORWARD have [0:0] next to them, which means they are unfiltered. INPUT is incoming traffic, OUTPUT is the opposite, and FORWARD is whatever traffic you are forwarding from your computer to be used as a service by another (ex. SSH).

Let's make a copy of the ruleset so we have something to fall back on if we make a mistake:

    sudo cp /etc/iptables/empty.rules /etc/iptables/custom.rules

To load a ruleset that we have previously made, we use the iptables-restore command:

    sudo iptables-restore < /etc/iptables/custom.rules

To save a ruleset when we have modified rules from the terminal instead of modifying a ruleset directly, we use the iptables-save command. This is useful for testing a command first, without having to save a backup of your rules:

    sudo iptables-save > /etc/iptables/custom.rules

We have to add rules above the line that says COMMIT and afterr the [0:0] on the OUTPUT line.

Step 3 Alter the Default Ruleset

Let's set a good first rule to allow the local loopback interface uninterrupted access with the following commands.

Open the ruleset:

    sudo nano /etc/iptables/custom.rules

Add this to your custom ruleset. -i specifies and interface, and -j is the ACCEPT or DROP line:

    -A INPUT -i lo -j ACCEPT

Now that we know how to grant an interface access, let's try giving a port some access. Start by dropping the INPUT access. Change :INPUT ACCEPT [0:0] to :INPUT DROP [0:0] in your custom.rules file. Let's give HTTP, port 80, some access:

    -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

This rule will tell iptables that TCP port 80 has incoming access to your computer. That is the basic format for accepting TCP ports. Let's tell our computer we want to be able to have outgoing traffic in all forms by adding the following lines:

    -A OUTPUT -p icmp -j ACCEPT

    -A OUTPUT -p udp -j ACCEPT

    -A OUTPUT -p tcp -j ACCEPT

These are the basic outlines for creating rules. To learn more about ports and what services you need to enable/disable, check out this Wiki article on TCP and UDP port numbers. If you understand ports already, just use:

    netstat -lnp

You should see which services you have running to enable your firewall accordingly.

If you have questions, jump in the IRC! Follow me on Twitter to get the latest updates.

Just updated your iPhone? You'll find new features for Podcasts, News, Books, and TV, as well as important security improvements and fresh wallpapers. Find out what's new and changed on your iPhone with the iOS 17.5 update.

Photo by mandolux


I am in Xubuntu and have the latest version of iptables, but my .rules file is not located where you said. How would I go abut finding it?

That means it is probably a loose file in /etc. Try looking for /etc/iptables.rules

Is this the equivalent of little snitch on the Mac ? In other words, can this replace Little snitch on the Mac?

Yes, but iptables is more configurable, and has no GUI by default. It's all around better IMO.

Keep up the good work. Will refer "wallet conscious" mac users to your article.

Haha, cool, thanks! Let me know if they have any issues with file paths being different, so I can document it and help them.

I have multiple rule set files -> /usr/share/ufw/iptables/after.rules
how do I know which to configure (which ones will actually be used)? :/

bob marley UFW stands for uncomplicated firewall... UFW is just a GUI (graphical user interface) for configuring IPTABLES. (UFW can also be configured from a terminal) by default ubuntu comes with UFW.

How do i do this on kali

So this is not actually for a mac then, none of it works on a mac with the commands used in this tutorial.


Welcome to Null Byte!

Although MacOS and Linux are very similar, they are not identical. The MacOS is based on BSD Unix while Linux is re-engineered Unix.

Specifically, what part did not work for you and what version of MacOS are you running?


Share Your Thoughts

  • Hot
  • Latest