Linux IPtables

Firewalls are tools that can protect an OS. Linux has iptables and firewalld, which contain firewall rules and can manage firewall rules in Linux. Essentially, iptables and firewalld are configured by the systems administrator to reject or accept traffic. While you are not expected to be able to configure a system, read this article to see how iptables can control incoming or outgoing traffic. Why does the order of the rules matter?

The script

Here's how that will all fit into a Bash script:

#!/bin/bash
iptables -A OUTPUT -p tcp -d bigmart.com -j ACCEPT
iptables -A OUTPUT -p tcp -d bigmart-data.com -j ACCEPT
iptables -A OUTPUT -p tcp -d ubuntu.com -j ACCEPT
iptables -A OUTPUT -p tcp -d ca.archive.ubuntu.com -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j DROP
iptables -A OUTPUT -p tcp --dport 443 -j DROP
iptables -A INPUT -p tcp -10.0.3.1 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -0.0.0.0/0 --dport 22 -j DROP

The basic anatomy of our rules starts with -A, telling iptables that we want to add the following rule. OUTPUT means that this rule should become part of the OUTPUT chain. -p  indicates that this rule will apply only to packets using the TCP protocol, where, as -d tells us, the destination is bigmart.com. The -j  flag points to ACCEPT  as the action to take when a packet matches the rule. In this first rule, that action is to permit, or accept, the request. But further down, you can see requests that will be dropped, or denied.

Remember that order matters. And that's because iptables will run a request past each of its rules, but only until it gets a match. So an outgoing browser request for, say, youtube.com will pass the first four rules, but when it gets to either the –dport 80 or –dport 443 rule – depending on whether it's an HTTP or HTTPS request – it'll be dropped. iptables won't bother checking any further because that was a match.

On the other hand, a system request to ubuntu.com for a software upgrade will get through when it hits its appropriate rule. What we're doing here, obviously, is permitting outgoing HTTP or HTTPS requests to only our BigMart or Ubuntu destinations and no others.

The final two rules will deal with incoming SSH requests. They won't already have been denied by the two previous drop rules since they don't use ports 80 or 443, but 22. In this case, login requests from my workstation will be accepted but requests for anywhere else will be dropped. This is important: Make sure the IP address you use for your port 22 rule matches the address of the machine you're using to log in – if you don't do that, you'll be instantly locked out. It's no big deal, of course, because the way it's currently configured, you could simply reboot the server and the iptables rules will all be dropped. If you're using an LXC container as your server and logging on from your LXC host, then use the IP address your host uses to connect to the container, not its public address.

You'll need to remember to update this rule if my machine's IP ever changes; otherwise, you'll be locked out.

Playing along at home (hopefully on a throwaway VM of some sort)? Great. Create your own script. Now I can save the script, use chmod to make it executable, and run it as sudo. Don't worry about that bigmart-data.com not found error – of course it's not found; it doesn't exist.

chmod +X scriptname.sh
sudo ./scriptname.sh

You can test your firewall from the command line using cURL. Requesting ubuntu.com works, but manning.com fails.

curl ubuntu.com
curl manning.com