Several months ago, I decided to explore a somewhat obscure topic of outbound per-application firewall control in Linux. A concept that Windows users are well familiar with, it’s been around for ages, providing Windows folks with a heightened sense of – if not practical factual – protection against rogues residing in their system and trying to phone home.
In Linux, things are a little different, but with the growing flux of Windows converts arriving at the sandy shores of open-source, the notion of need for outbound control of applications has also risen, giving birth to software designed to allay fears if not resolve problems. My first attempt to play with Leopard Flower and Douane was somewhat frustrating. Now, I’m going to revisit the test, focusing only on the former.
The last time, I struggled somewhat with Leopard Flower (lpfw). The program just didn’t work well for me, and the testing ended up being a fiasco. This time around, things were a little better, but still somewhat wonky. To begin with, compiling from sources is so 80s. Then, you actually need to run the firewall service yourself, by hand. And, if you want it to run all the time, you will need to daemonize it and whatnot. Hint, startup service, but I understand this introduces development and packaging overhead, because the Linux landscape is very simple and uniform to manage.
There’s no installation command either, so your firewall will run wherever you place it. The actual service and the GUI component are two separate parts, the first being a binary, the second a python script. You need root permissions to launch the service, of course, but the frontend should run as a regular user. If you do launch it as root, you will also suffer from a visual inconsistency, at least on Gnome as tested using Werewolf Gnome edition.
Your problems do not end there. The firewall will not work correctly if you do not launch both components, service then frontend. In fact, it took me two attempts to get lpfw to function correctly. Meanwhile, my network traffic was blocked, and I couldn’t do anything. It seems you need the GUI component to allow or deny network requests, so if it’s not active, the firewall just blocks everything.
nfq_handle - raddr: 192.168.2.1 laddr:192.168.2.104 socket not found in cache socket found with state:07 in socket handle found after searching procfd <UDP remote 192.168.2.1:53 local 52114 /usr/sbin/dnsmasq 1031 (frontend not active) drop
Eventually, I started getting the right prompts and allowing things. The network resumed breathing, and the overall performance and throughput were reasonable enough. You do need to be aware that lpfw can only control a small subset of your traffic. To be honest, yes, UDP and TCP are good enough for most cases, but the limitations aren’t encouraging.
The workflow is intrusive, as you can imagine, because you need to allow pretty much all and every outgoing connection, including your browser plugins, DNS traffic, updates, and other services. It is important to remember that your answers will dictate the health and sanity of your system. You can always reset the firewall and/or delete rules, but you need to be aware of the implications and possible quirks as a direct result of your tweaking.
The popups are fairly descriptive. However, they are not necessarily practical enough to help you decide if you ought to allow traffic. If you have just started a browser, yes, it makes sense. But what if you get a sudden prompt, out of the blue, while doing nothing Internet facing? Worse, what if you do get a popup while browsing? Is this somewhat related to your activity?
Take the Firefox plugin container as an example. I had lpfw alert me on this. As it happens I was trying to perform a speed test, but then, for that matter, the plugin may have been compromised by a web page, and it was now asking to connect to a remote server, to grab some nefarious data. How would you know the difference? Only when you expect it? Nah, that does not count.
Leopard Flower was behaving well-ish, but then a few more weird things happened. I realized I wasn’t able to actually close the GUI window. It would vanish, but the command line prompt would remain stuck and never return.
While the GUI was missing, the firewall continued working. But in an erratic way. It did prompt me for Opera, but not for Steam, and the latter was able to connect to remote servers without any problems. I’m wondering what the desired behavior is. If the GUI has been closed, is the firewall still active and protecting the system? What about new connections? I don’t have a record of consistent behavior to actually tell you, and this bothers me. At the very least, firewall rules are preserved between runs. It wasn’t smooth sailing, but at least, we were afloat.
('Sending:', 'LIST') In askUser allow clicked ('Sending:', 'ADD L3Vzci9zYmluL2Ruc21hc3E= 1031 ALLOW_ALWAYS') In askUser allow clicked ('Sending:', 'ADD L3Vzci9saWIvZmlyZWZveC9maXJlZm94 1942 ALLOW_ALWAYS') In askUser allow clicked ('Sending:', 'ADD L3Vzci9saWIvZmlyZWZveC9wbHVnaW4tY29udGFpbmVy 5638 ALLOW_ALWAYS')
The First Paradox of Computing
And now, we come back full circle to the First Paradox. Which says:
“Those who need software security can’t use it; those who don’t can.” — Nikola Tesla
The sad reality is, if you need, or think you need, security software for Linux, then you have a much bigger problem than the choice of particular programs you will be using. Furthermore, the usage of software mandates knowledge, which on its own, precludes or supersedes the actual need for it. This is the Dunning-Kruger of software.
Outbound firewall control, especially the per-application concept, has many philosophical and practical issues. There’s the simple matter of containing damage. Which is best contained by avoiding it in the first place. If you don’t land baddies onto your system, there’s no need to fight them. The second issue is that of managing damage. If you have something rogue on your system, it is best removed rather than neutered, as damage can and may come to bear in many different ways. The presence of undesirable code on your system should be removed, not mitigated. Some may argue that this is better than no protection, and that it actually helps minimize damage. But in fact, it makes people to reduce their outer layers of security, because they assume they will be able to fight it later on.
The only way to stop damage in the first place is to know that all and any system intrusion is 100% fatal. While you may be able to recover, you should treat it as an immediate and total loss of control. In that case, it does not matter what security software you use, what matters is making sure the infection never happens, because after that, all bets are off.
The third issue is of containing semi-untrusted software. This happens a lot in Windows. People implement firewall rules to prevent legitimate if somewhat undesirable or pesky software, Windows components included, from sending information back to the mothership. But this violates the basic premise of trust. If you do not like or trust a specific product, do not use it. And if you must, then there’s no point half-handling it with outbound rules.
You would not tolerate malicious programs, even if they gave you some decent and needed functionality. Therefore, if you do tolerate a program, then by same logic, it is NOT malicious, and therefore, there is no need to block it in any way, shape, or form.
Things change. Are you certain /usr/bin/python now is the same /usr/bin/python you allowed a month ago? How are we going to verify that the software you’re running is valid or legit? Digital signatures? Hashes? Full path and size values? Something else? And even if the numbers match, what then?
Lastly, knowledge. How are honest, simple people to respond correctly to firewall prompts, asking them to approve unknown binaries, ports, and whatnot? If you do know all the right bits and pieces, then you really don’t need any help. But if you struggle with concepts like network protocols, application names and paths, then how are you going to make a right judgement call when you try to do something. Besides, you may assume you need or want something, and you will do whatever it takes to get it. In other words, you will let your own guard down, and this quite often happens when you are in your comfort zone, and you have a sense of trust toward your environment, computing assets included.
In a nutshell, this is the First Paradox. It transpires operating systems, technologies and cultures. It is relevant for aspects of knowledge and decision making. And this is why LPFW is a very tricky product, as it aims to solve a problem for those who cannot use it. Thus, it becomes a hobby for nerds and geeks who want more control over their boxes. Nothing more.
Leopard Flower firewall is an interesting concept. Misplaced, though, for most parts. It caters to a Windows need that does not exist on Linux, and to be frank, has no place in the Microsoft world either. Then, it also tries to resolve a problem of control and knowledge by requiring the user to exercise the necessary control and knowledge. But if they had those to begin with, they wouldn’t need to dabble in per-application firewalls. Furthermore, the software is still fairly immature. There are at least half a dozen little things and changes that can be implemented to make lpfw more elegant, starting with installation and followed by service and GUI model, prompts, robustness, and a few others.
Overall, I am pleased with the testing, and lpfw has the same merits as Douane, so it comes down to how you feel about using per-application firewalls, and choosing the one with the best match for your needs. At the end of the day, though, this is more of an intellectual exercise than anything else. But then if you’re bored, there are worse ways to spend an afternoon than playing with some new and exciting software. Leopard Flower could become a nice product, but it has a long way to go, including both the presentation layer and functionality. The bigger philosophical paradox still full applies.