Linux firewalls - ufw

 

 

The netfilter facility has been part of the Linux kernel since kernel version 2.4.

The basic ability of netfilter is packet filtering, network address translation, and port translation- it can be used to build firewall capability into the kernel - and this can be anything from a simple packet filtering firewall for desktop computers through firewalls for server protection and up to Enterprise level network firewalls.

There are several kernel modules which can be utilised to build up the packet filtering, NAT and PAT mechanisms - different distributions of Linux install their chosen modules - it may be possible to add more to get more specialised forms of packet filtering.

A significant group of modules are the conntrack modules which track outflowing packets and block or allow inflowing packets based on the tracking record - thus creating a stateful firewall.

In order to "programme" netfilter there are a number of userspace tools available - the original one was and still is iptables - this is a command line tool which can be used on the go, or can be used in shell scripts.

Iptables provides the ability to save a firewall configuration into a file, and then restore this configuration either manually through the command line or during the boot up of Linux.

There are three files recognised by the command line environment - they are frequently found in /sbin -

iptables

iptables-save

iptables-restore

They are used as follows

iptables is used in the command line instructions to create chains and rules

iptables-save is used to export the current firewall configuration to a text file

iptables-restore is used to import the previously saved firewall configuration from a text file

A firewall configuration set up using iptables is volatile - the configuration will be lost after a restart - hence the existence of iptables-save and iptables-restore.

 

----------------------

 

A newer command line tool is nftables which includes a wider range of commands available - it has been available since kernel version 3.13.

It provides a single unified interface to replace the four separate interfaces of iptables, ip6tables, arptables, and ebtables

It is now recommended that nftables is used in preference to iptables.

I haven`t ever used it so can`t add much more information.

 

----------------------

 

Another userspace tool for configuring netfilter firewalls is firewalld - this is a command line tool but it has a GUI tool associated with it.

Early versions of firewalld were based on iptables - newer versions are based on nftables.

My only experience of firewalld was trying to install it on the Linux installation on a Chromebook - the installation didn`t really go to plan, and it didn`t work once it was installed.

However it is the default firewall configuration tool on Linux distributions such as Red Hat, Centos, Fedora, and SUSE - and others.

 

----------------------

 

Another userspace tool for configuring netfilter firewalls is ufw - this is another command line tool, but there is an associated graphical userspace tool called gufw which talks to ufw and allows for the creation of simple rules.

Although it a command line tool, ufw is actually built on iptables - the commands used are ufw versions of the iptables commands.

However ufw is very different from iptables in that by default it creates an extensive framework of chains and rules, and any user created rules are slotted into this framework.

Developed by the developers of Ubuntu linux, ufw is the default userspace tool for configuring the firewall on the Ubuntu and Mint distributions of Linux, and is optional on Arch and Debian.

After installing ufw on the Linux installation on a Chromebook, I became increasingly concerned about ufw - and the thought that kept cropping up is obfuscation - and what is ufw actually doing.

 

The installation of ufw

Installing ufw on the Linux installation on the Chromebook was quite straighforward using apt - the command

sudo apt install ufw

was all that was required.

However the result is a bit surprising - as ufw had spread its tentacles through the Linux file structure - with files installed in the following locations -

/etc/ufw/ - 10 files in total - 2 init files, 2 config files, 6 ruleset files

/etc/default/ufw - 1 file - a high level configuration file

/lib/ufw/ - another 2 init files

In addition it set up the required boot up initialisation files in

/etc/init.d

and

/etc/rcS.d

So apt did a good job of installing ufw.

But does ufw really need

three configuration files

four initialisation files

six ruleset files

Again - it all rather points towards obfuscation.

 

The ufw framework

After the installation of ufw on the Linux installation on the Chromebook I found that ufw had created something like 80 chains - over 40 for ipv4 and just under 40 for ipv6.

On a Linux Mint computer that uses ufw and is a few years old there are a similar number of chains for ipv4, so all these chains has been the norm for quite a while.

The default position is that many of these chains have no rules assigned to them - by definition a chain is a group of rules - so having chains with no rules is a bit of a puzzle as to why they exist.

But their existence does make it harder to try and work out the packet flow through the firewall.

Ufw is a command line interface, and as far as I can see there are no ufw commands which allow for the setting up of, or the removal of chains - so this chain framework can`t be altered through the command line or through gufw.

While I don`t claim to fully understand all the coding in this file, it seems that the chain structure is created by the initilisation file /lib/ufw/ufw-init-functions.

The default rules for IPv4 that ufw sets up are created by four different files -

/lib/ufw/ufw-init-functions

/etc/ufw/before.rules

/etc/ufw/after.rules

/etc/ufw/user.rules

The default rules for IPv6 that ufw sets up are created by four different files -

/lib/ufw/ufw-init-functions

/etc/ufw/before6.rules

/etc/ufw/after6.rules

/etc/ufw/user6.rules

Based on my previous experience of using ufw and gufw, any user created rules that were set up using gufw are added into the /etc/ufw/user.rules and /etc/ufw/user6.rules files.

However I can`t say with certainty that all rules created through gufw are entered into the /etc/ufw/user.rules and /etc/ufw/user6.rules files - it may depend on what the rules are doing.

 

----------------------

 

By default, ufw doesn`t use the built-in chains in the filter table of INPUT, OUTPUT, FORWARD to do any kind of packet filtering - each of these built-in chains is used as a router to access six ufw created chains in the ufw framework - these six ufw created chains are tried in sequence to see if there is a route through the firewall for each packet.

It isn`t a technique I have ever seen before - it does make it a lot more difficult to see the flow through the firewall for both wanted and unwanted packets - is this more obfuscation ?

There is a configuration setting that allows for the changing of some aspects of this default behaviour, so that the built-in chains are or can be used for packet filtering - however I haven`t done it and don`t know the full implications of doing it.

 

My concerns about ufw

The more I looked into ufw the more I was concerned about what I was seeing.

My first concern is that ufw has no idea what the firewall is being used for - it could be a firewall for a desktop computer or laptop - it could be a firewall for a server - it could be a firewall that is part of a network infrastructure.

The requirements of a firewall for these different uses are quite different - so trying to create a firewall structure that can work in all these different situations doesn`t seem to be possible - either it will not work, or there will be unwanted routes through the firewall.

 

----------------------

 

The second ufw created chain that the built-in INPUT chain routes traffic to is the ufw-before-input chain.

The first rule in this chain concerns local produced traffic.

The second rule in this chain uses conntrack to identify related and established packets, and immediately passes all this traffic through and out of the firewall into the host machine with no other type of filtering.

Now stateful firewalls are a great invention, but they are not infallible - any malicious packets that can matched to a conntrack entry will be allowed in.

One of the powers of netfilter and iptables is the ability to have a chain that does some kind of packet filtering - then pass the traffic to another chain that does some other kind of filtering - then pass the traffic to another chain that does another kind of filtering - and so on.

So it is possible to create a firewall that does multiple levels of packet filtering as well as the stateful filtering - and ufw is not doing this.

One of the problems of stateful only filtering is that if some malware like ransomware gets installed on the machine, the firewall will let out the packets trying to set up a connection to a remote server and conntrack will record it, then the traffic from the server will be allowed back in through the firewall and the malware can then function as it was designed to do.

 

----------------------

 

Subsequent rules in the ufw-before-input chain allow several other types of packet through the firewall, such as multiple types of ICMP, DHCP, mDNS, and UPNP.

The last rule in the ufw-before-input chain is to route the remaining traffic to the ufw-user-input chain - this is the chain which receives the user created rules created either by gufw or through the command line.

So users who create new rules have no control over any of the above packet filtering as it has already happened before the user created rules have any effect.

I am still strugling to work out if any packet ever arrives in the ufw-user-input chain - and do rules added using gufw actually do anything.

 

----------------------

 

In the ufw-before-output chain there is a rule which allows all ESTABLISHED or RELATED packets out of the firewall - this happens before the link down to the ufw-user-output chain - this therefore comes before any user added rules in ufw-user-output.

So once again the question arises as to how much the rules added either by gufw or through the command line are going to be affected.

There is also the question as to why there is provision for stateful packet filtering on the output path of a firewall - it isn`t required or wanted on a firewall for a desktop machine.

 

----------------------

 

The ufw framework sets up a situation that some kinds of traffic are not logged - namely NetBIOS on ports 137, 138, 139, and TCP/IP MS Networking on port 445.

NetBIOS is an old and famously insecure network protocol that Microsoft just can`t seem to move away from - it is a much used way as a means of attacking computers.

TCP/IP MS Networking on port 445 is also insecure - the WannaCry and Nimbda malware use it.

Both can be used to attack computers from outside, as well as by malware already on the computer.

Even if you are diligent at looking at firewall logs you will not see anything about these type of packets because they are not getting logged.

 

----------------------

 

An advisory posted in January 2017 by US-CERT recommends blocking all versions of Server Message Block (SMB) at the network boundary by blocking TCP port 445 as well as the related protocols on UDP ports 137-138 and TCP port 139.

It is a fairly typical sort of advisory in the cyber security world.

Absolute packet blocking based on ports or addresses is a fairly standard requirement for network firewalls as well as server firewalls and firewalls for destop machines, but I don`t see how you can do this on ufw in its default configuration - the default configuration has too much emphasis on stateful packet filtering and speeding ESTABLISHED or RELATED packets through the firewall without any consideration for the port numbers or addresses of the packets.

Now if you use either gufw or the ufw command line instructions, any rules you add go into the user.rules file, and when ufw is loaded, the rules are put into either the ufw-user-input chain or the ufw-user-output chain as appropriate for the rule.

So as an example of the command line instructions, to block port 445 you could use the command

ufw deny 445

ufw assumes that this is to block incoming packets, and it ends up in the ufw-user-input chain.

You could be more specific and specify the direction -

ufw deny in 445

and the rule will go into the ufw-user-input chain.

The command

ufw deny out 445

will put the rule into the ufw-user-output chain.

Now I have already discussed my concerns about the ufw-user-input chain and the ufw-user-output chain, and pointed out that the links that pushes packets into these two chains are the last rules in the ufw-before-input chain and the ufw-before-output chain - by the time the packets arrive in the ufw-user-input chain or the ufw-user-output chain there has already been a succession of filtering done, including stateful packet filtering - so it is very clear that this would not be absolute blocking of the specified port - it is very conditional on whether or not the packet has already found a route through the firewall.

You could possibly add rules to the relevant default chain, INPUT or FORWARD - but that would entail some significant changes to the configuration of ufw.

 

Kernel modules

The netfilter firewall relies extensively on loadable kernel modules - many of these are loaded automatically at startup - presumably the developers of any particular distribution decide what modules are going to be built into the kernel and what modules are going to be external loadable modules - and then decide on which of the loadable kernel modules are going to be loaded at startup.

The developers of ufw have extended this - as the configuration script "/etc/default/ufw" suggests that some more loadable kernel modules should be loaded -

nf_conntrack_ftp

nf_nat_ftp

nf_conntrack_netbios_ns

Now two of these loadable kernel modules are what are known as kernel helper modules -

nf_conntrack_ftp

nf_conntrack_netbios_ns

A kernel helper module is used to augment the ability of the conntrack mechanism by analysing one particular type of traffic - so

nf_conntrack_ftp analyses ftp traffic

nf_conntrack_netbios_ns analyses NetBIOS traffic

and if they see that the connection is going to start using a different port number, the helper advises the conntrack mechanism that it should allow traffic on the new port number as well as on the original port number.

So they would appear to be useful.

However there are some downsides - the first is the usual general one in that the more code there is in the kernel the more the possible attack surface is increased.

The second one is specific to helper modules - there seems to be a vulnerability that they introduce - specifically they are open to attack via spoofed addresses.

There is very little information about this on the internet - after extensive searching I have found a few independent web pages providing some information - but there is obvious plagiarism going on between some of them.

There is more information about helper modules and ufw in a page on the Ubuntu website - it calls it a manpage, but it has different content from the more commomly available man page.

It looks like you can reduce the risk of the vulnerability by adding some specific rules to the Prerouting chain in the Raw table.

It can be done using iptables - it can possibly be done using ufw, but you would need to look into the ufw command line syntax to do it.

It looks like you can partially disable the helper modules through the content of a file

/proc/sys/net/netfilter/nf_conntrack_helper

But why load the helper modules and then partially disable them - doesn`t seem like a sensible approach.

The default configuration of ufw seems to be somewhat negligent in this - it loads the helper modules by default, but I don`t see any rules which can lessen the vulnerability caused by loading the helper modules.

It again raises the question about what ufw is doing with NetBIOS - why is ufw appearing to want to create a firewall that is geared up to enable NetBIOS through it by default, and trying to hide it.

Maybe worth noting that from kernel 2.6.34 onwards there have been several substantial changes to the recommended way to use module helpers - one of these changes is that it is now advised that helper modules should not be loaded by default - I am not sure that ufw is keeping up with the changes.

On a machine running kernel 4.15 ufw loaded these extra modules.

If you don`t need these helper modules I recommend changing the "/etc/default/ufw" script so that they are not loaded.

PS - I have removed ufw from most of my Linux machines, but an interesting side effect of loading the "nf_conntrack_netbios_ns" helper module on the only Linux installation I am using that still has ufw on it is that this results in another kernel module also getting loaded - "nf_conntrack_broadcast".

Whether ufw is doing it, or whether it is an oddity of the Linux distribution, I don`t know - but that is four extra modules that shouldn`t be there.

 

Changing the framework

Having spent a lot of time looking into the framework and the problems it causes, I wondered about how practical it would be to change the framework to turn ufw into a firewall that I believe is more effective in blocking unwanted packets.

NB - all that follows is for IPv4 only, I don`t need IPv6, and disabled it in ufw.

NB - this was a firewall specifically for a desktop or laptop - it would not be suitable for a firewall for a server, or for a network firewall.

NB - this configuration does not do any logging - logging is disabled in the ufw configuration file.

It required extensive modifications to three files in particular -

/etc/ufw/before.rules

/etc/ufw/after.rules

/lib/ufw/ufw-init-functions

The coding in the first two files is quite straightforward - they are really just lists of rules with numerous comments - so not hard to understand and modify.

The coding in the third file is a lot more complicated and there is a lot of it - I still don`t understand it all, but it wasn`t too difficult to pick out the various rules that I needed to change.

This file creates all the chains - I could have altered the number of chains being setup, but that would have made the modifications to the before.rules and the after.rules files more difficult.

So what I did was alter the way the chains are interconnected - and therefore created a new chain framework.

I ended up only using three of the many chains that the file ufw-init-functions creates - all the rest are just unused.

I continued the ufw practice of not using the three default chains - INPUT, OUTPUT, FORWARD - for any packet filtering.

The default policy for the INPUT, OUTPUT, and FORWARD chains is DROP.

The essence of the firewall is as follows :

All incoming traffic coming into the INPUT chain is passed to the ufw-before-input chain.

The ufw-before-input chain has a sequence of several rules which drop various kinds of unwanted packets.

The ufw-before-input chain then has a number of rules which pass packets with specific port numbers through to the ufw-after-chain.

All remaining packets are then dropped.

The ufw-after-input chain does stateful packet filtering and the wanted packets are accepted.

All blocked packets are then dropped.

All outgoing traffic arriving at the OUTPUT chain is passed to the ufw-before-output chain.

The ufw-before-output chain has multiple rules which do packet filtering based on port numbers - each rule has a target of ACCEPT.

All remaining packets are dropped.

The FORWARD chain is not used.

It took a while to get it all to work, but it does.

The configuration and initialisation of ufw is maintained - ufw can be disabled, enabled, and reloaded just as before.

However I am not sure if it is a good solution to the problems of the default installation of ufw - perhaps a better solution would be to remove ufw entirely and write an iptables shell script instead.

 

Final thoughts

ufw is developed by, and copyright of, Canonical Ltd.

To their credit, Canonical Ltd have declared ufw to be free software that can be redistributed or modified under the terms of the GNU Genaral Public License version 3 as published by the Free Software Foundation.

Canonical Ltd are the developers of Ubuntu Linux - and this is widely used in workstations and in servers.

So does this mean that there are Ubuntu based workstations and servers out there that have a default configuration of ufw - and the weaknesses that I have described above.

Mint Linux is based on Ubuntu, and uses ufw - so this applies to Mint Linux as well.

Debian allows for the installation of ufw through its package management system called apt - so there may well be Debian based workstations and servers out there using a default installation of ufw.

To a somewhat limited extent the configuration of ufw can be modified through various settings, but there are risks attached by doing so unless you have a good understanding of the default framework and the implications of changing the configuration.

And changing these settings doesn`t really alter the fundamental framework.

The documentation associated with ufw provides plenty of examples of ways to add rules to the default ufw configuration, but the documentation also suggests that this should not be done without a good understanding of what they do - which really means that you have to have a good understanding of the ufw framework and of iptables.

If you have a good understanding of iptables why use ufw ?

 

 

 

 

 

website design by ron-t

 

website hosting by freevirtualservers.com

 

© 2024   Ron Turner

 

+                                   +  

 

Link to the W3C website.   Link to the W3C website.