Workshop: Lock down your Linux system with Firewalld and OpenSnitch
Double Protection
For maximum security, you'd better watch traffic in both directions. This hands-on workshop takes you through the steps of setting up firewalls for outgoing as well as incoming traffic.
Linux has a great selection of firewalls for securing stand-alone computers or whole networks. Small LANs usually depend on small routers for security. But what if your Linux machine is exposed on the network and you don't have control over the upstream router or gateway? What if you're working behind one of the millions of smaller routers with out-of-date firmware or missing security patches?
If you're really serious about building a perfectly secure, network-attached Linux workstation, you'll need to fortify the system from two directions: with a host-based firewall for managing incoming connections and with a per-application firewall for controlling outbound traffic. This hands-on workshop will show you how to fortify your system using Firewalld and the OpenSnitch application firewall.
Limiting the Incoming Flow
Network security starts with limiting access to your host from the outer world. One of the most advanced and popular tools for limiting incoming traffic is Firewalld [1], a modern and flexible firewall that replaced the legacy Iptables software a few years ago. Firewalld was introduced as a default network security solution in Fedora 18 and RHEL 7, and consequently, in CentOS 7 as well. The Firewalld firewall is now included in many other mainstream Linux distributions, such as openSUSE and Arch.
Firewalld has many benefits over Iptables and other old-fashioned tools for accessing the netfilter feature of the Linux kernel. Previous firewall tools required manual and precise rules for blocking or allowing certain ports and network addresses, which were not trivial and caused a lot of headache once the host's network configuration changed. Firewalld is more flexible, allowing you to add system services to zones and assign a zone to a network interface. A user does not need to know which port is associated with a service because Firewalld comes with over 140 presets for many, if not all, Linux services.
By assigning services to zones, users can create a custom set of rules for various use cases and conditions. By default, Firewalld has 9 zones that differ by the level of trust to a network. Several interfaces can be assigned to a zone, but only one zone can be assigned to an interface. Firewalld applies all changes on the fly, so you won't need to restart when changing zones, services, or ports. Although Firewalld has no mechanism of auto-changing zones, you can use the zone system to adapt to changing network conditions. For instance, a laptop connected to a wired Ethernet network would probably use the eno1
interface, and a public Wi-Fi interface might use wlan0
. You could assign each of these interfaces to different zones: eno1
could be in the work
zone, which includes SSH access, and wlan0
will belong to the public
zone, which does not.
Firewalld (Figure 1) has a couple of graphical front-ends, specifically a GTK3-based GUI, which you will find in Gnome Software, and a Qt5-based interface bundled with Yast in openSUSE and SuSE Linux Enterprise. For this article, I will use the command-line utility known as firewall-cmd
, which works everywhere (Figure 2).
Check to see if the firewall is running:
$ sudo firewall-cmd --state
If it is not, enable and launch it with:
$ sudo systemctl enable firewalld && sudo systemctl start firewalld
Say you want to open TCP port 80 to allow access to your network's web server from remote hosts:
$ sudo firewall-cmd --add-port=80/tcp
If no zone is specified, the preceding command applies to the current zone, which should be public
according to the Firewalld defaults. If you are unsure, you can check the default zone with:
$ sudo firewall-cmd --get-default-zone
By default, all network interfaces are assigned to the default zone. You can find out what zones your current network interface has been assigned with the following command:
$ sudo firewall-cmd --get-active-zones
Assume the current zone is public
. The following command would allow you to view the zone configuration:
$ sudo firewall-cmd --zone=public --list-all
The output will probably list dhcpv6-client
as the only allowed service. Most of the other parameters for public
are empty by default, which means that nothing else is allowed. Not a good zone for further experiments in our sandbox. To transition the current network interface to another zone, enter:
$ sudo firewall-cmd --zone=trusted --change-interface=eno1
Note that changing zones changes the set of services that will be allowed. To tailor the zone for the needs of your network, you might wish to add services to the zone. For a list of available services, enter:
$ sudo firewall-cmd --get-service
You can also examine the contents of usr/lib/firewalld/services
for a list of available services. Suppose I want to add the IPP service to the home
zone for enabling remote printing to the CUPS server via the Internet Printing Protocol:
$ sudo firewall-cmd --zone=home --add-service=ipp
Other use cases require accessing your home PC from the outer world for the sake of remote administration, granting access to BitTorrent downloads, and other common scenarios.
Masquerading
On small home LANs, a home router usually performs network address translation, but it is also possible to set up a Linux computer as a router and then configure Firewalld to perform port forwarding and masquerading for incoming connections.
A router would need two network interfaces: one for the Internet (eno0
) and another for the internal LAN (eno1
).
To assign different zones to the two interfaces, enter:
$ sudo nmcli c mod eno0 connection.zone internet $ sudo nmcli c mod eno1 connection.zone lan $ sudo firewall-cmd --get-active-zones
Now that the two connections belong to different Firewalld zones, you can start masquerading. The following commands enable the masquerade
feature for the internet
zone and then forward all remote SSH connections from port 22 to port 2222 of another machine (192.168.88.11) inside the internal LAN:
$ sudo firewall-cmd --zone=internet --add-masquerade $ sudo firewall-cmd --zone=internet --add-forward-port=port=22:proto=tcp:toport=2222:toaddr=192.168.88.11
So far all the changes to the Firewalld configuration are temporary and will be lost after the Firewalld service is restarted. To make the changes permanent, add the --permanent
parameter to every firewall-cmd
command that changes something. It is also possible to save the current setup by converting it to the permanent
configuration:
$ sudo firewall-cmd --runtime-to-permanent
A reverse action is sometimes also required: changes made with the --permanent
parameter are saved but not applied immediately (which is not obvious). To make permanent changes work for the current session, use the command:
$ sudo firewall-cmd --reload
Firewalld also has some dedicated features for handling outgoing connections (use --direct
and --add-rule
options), but another tool called OpenSnitch offers a more user-friendly solution for managing outgoing traffic.
Controlling Outgoing Traffic
For security and privacy reasons, many users wish to know what outgoing connections the applications you use and websites you visit want to establish from your machine. Various apps and APIs might try to launch outgoing connections from your computer, including cloud storage clients, weather widgets, and big data collectors.
OpenSnitch [2] is designed to track all outgoing network connections. It is an open source project inspired by Little Snitch, an application firewall for Macs. The value of OpenSnitch is that it reveals all such background network activity and lets you explicitly allow or block each connection (Figure 3).
OpenSnitch is a work in progress, which is why it is not yet packaged for easy installation in most Linux distributions. Despite that, the software is stable enough and fits well into typical home or office usage scenarios. The steps for installing OpenSnitch are the same for any Linux flavor. If you're working in a recent Ubuntu version, the commands would look like Listing 1.
Listing 1
Setting Up OpenSnitch
$ mkdir -p ~/go/bin && export GOPATH=~/go $ export PATH=$PATH:$GOPATH/bin $ sudo apt-get install git libnetfilter-queue-dev libpcap-dev protobuf-compiler python3-pip golang-go $ go get github.com/golang/protobuf/protoc-gen-go $ go get -u github.com/golang/dep/cmd/dep $ $GOPATH/src/github.com/golang/dep/install.sh $ python3 -m pip install --user grpcio-tools $ go get github.com/evilsocket/opensnitch $ cd $GOPATH/src/github.com/evilsocket/opensnitch
You will probably need to comment out the first line in the ui/requirements.txt
file as long as the plain grpcio
component (not the one with -tools
) is only needed for Python2 and not for the newer Python3. Then complete the installation with:
$ make && sudo make install
OpenSnitch provides a Systemd service that you will need to activate upon startup:
$ sudo systemctl enable opensnitchd && sudo systemctl start opensnitchd
Fire up the OpenSnitch graphical front-end with:
$ opensnitch-ui
A new icon should appear in the system tray area. After any process initiates a connection to a TCP or UDP port, OpenSnitch will throw up a warning window. You will have 15 seconds to review the source and target IP addresses, the process name, port ID, and user ID and make a decision whether you allow or deny the connection. By default, if time runs out and you do nothing, OpenSnitch will allow the connection. Of course, in many situations, you simply need more time to decide what to do with an OpenSnitch warning. Extend the time to any other length by editing the ~/.opensnitch/ui-config.json
file.
Although OpenSnitch may look a bit paranoid at first, remember that it was designed to distrust everything. Frequent warnings indicate that OpenSnitch is in the training mode
and it's up to you to decide if you will allow or block each connection once
, for the current session
, or forever
.
Using the Firefox web browser for daily surfing reveals that the systemd-resolved
service consumes UDP port 53 for DNS name resolution, Mozilla browser integration uses Python3.x to communicate with extensions.gnome.org
on TCP 443, Ubuntu's version of NetworkManager runs a custom connectivity checker using TCP 80 and that's almost it – nothing really bad or suspicious. If you allow these typical connections from the very beginning, you will for the most part be able to surf the web without further annoyances.
OpenSnitch will turn up a lot more when you are dealing with desktop integration APIs, weather services, online accounts, remote cloud connectors, and other services. If you run Skype, Dropbox, Google Drive, Windows apps via Wine, or any proprietary software, it always makes sense to keep OpenSnitch up and running. Even if the extended time period is not enough and you prefer to apply OpenSnitch actions once or for this session only, it is easy to trigger the alarm again:
$ sudo systemctl restart opensnitchd
The restart only applies to the per-application firewall and does not interfere with other network processes.
Saving your response as forever creates an appropriate JSON file under /etc/opensnitchd/rules
. Just as with Iptables rules, you can modify OpenSnitch rules and even add your own.
OpenSnitch will help you understand how various applications and system services use the network. Many of these services are perfectly normal; the key is to look for rare or unusual or unfamiliar services that might be behaving strangely. Nevertheless, the offending service does not have to be that exotic – you'll find examples of misbehaving Gnome Shell extensions and KDE Plasmoids that somehow want to connect to remote hosts, and you definitely have the right to know what is happening.
OpenSnitch is not just safeguarding software; it diligently collects statistics and keeps track of past incidents. Right-click on the application's icon in the tray and select Statistics. A new window will appear with several tabs for viewing network connection statistics (Figure 4). By default, statistics display on the General tab as a table with timestamps, processes, destinations, protocols, and actions. This tab, along with others (Hosts, Processes, Addresses, Ports
and Users
), has a small button near the top-right corner of the window that exports the current view to CSV format for further usage. With the help of Statistics, it is possible to analyze past events that you may not have noticed at the time they occurred.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Gnome Fans Everywhere Rejoice for the Latest Release
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.