Crear reglas de IPTABLES para restringir la navegación

The kiosk project

To illustrate all this, let’s imagine we work for a store that’s part of a larger chain called BigMart. They’ve been around for decades; in fact, our imaginary grandparents probably grew up shopping there. But these days, the guys at BigMart corporate headquarters are probably just counting the hours before Amazon drives them under for good.

Nevertheless, BigMart’s IT department is doing its best, and they’ve just sent you some WiFi-ready kiosk devices that you’re expected to install at strategic locations throughout your store. The idea is that they’ll display a web browser logged into the products pages, allowing them to look up merchandise features, aisle location, and stock levels. The kiosks will also need access to, where many of the images and video media are stored.

Besides those, you’ll want to permit updates and, whenever necessary, package downloads. Finally, you’ll want to permit inbound SSH access only from your local workstation, and block everyone else. The figure below illustrates how it will all work:


kiosk traffic flow ip tables

The kiosk traffic flow being controlled by iptables.

The script

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

iptables -A OUTPUT -p tcp -d -j ACCEPT
iptables -A OUTPUT -p tcp -d -j ACCEPT
iptables -A OUTPUT -p tcp -d -j ACCEPT
iptables -A OUTPUT -p tcp -d -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 -s –dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s –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. -pindicates that this rule will apply only to packets using the TCP protocol, where, as -dtells us, the destination is 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, will pass the first four rules, but when it gets to either the –dport 80or –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 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 not found error—of course it’s not found; it doesn’t exist.

chmod +X
sudo ./

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


Configuring iptables to load on system boot

Now, how do I get these rules to automatically load each time the kiosk boots? The first step is to save the current rules to a .rules file using the iptables-save tool. That’ll create a file in the root directory containing a list of the rules. The pipe, followed by the tee command, is necessary to apply my sudo authority to the second part of the string: the actual saving of a file to the otherwise restricted root directory.

I can then tell the system to run a related tool called iptables-restore every time it boots. A regular cron job of the kind we saw in the previous module won’t help because they’re run at set times, but we have no idea when our computer might decide to crash and reboot.

There are lots of ways to handle this problem. Here’s one:

On my Linux machine, I’ll install a program called anacron that will give us a file in the /etc/ directory called anacrontab. I’ll edit the file and add this iptables-restorecommand, telling it to load the current values of that .rules file into iptables each day (when necessary) one minute after a boot. I’ll give the job an identifier (iptables-restore) and then add the command itself. Since you’re playing along with me at home, you should test all this out by rebooting your system.

sudo iptables-save | sudo tee /root/
sudo apt install anacron
sudo nano /etc/anacrontab
1 1 iptables-restore iptables-restore < /root/

I hope these practical examples have illustrated how to use iptables and firewalld for managing connectivity issues on Linux-based firewalls.

Deja una respuesta