How to Implement Application-Aware Firewall Rules for Outgoing Connections in Linux/Ubuntu


10 views

Many Linux users coming from Windows miss the interactive firewall experience where applications request network access. While Linux has powerful firewall tools like iptables and nftables, they operate at a lower network level without application context.

Here are three approaches to achieve application-aware firewall control:

1. OpenSnitch (Python/Go solution)


# Installation on Ubuntu/Debian:
sudo apt install golang git libnetfilter-queue-dev
git clone https://github.com/evilsocket/opensnitch
cd opensnitch
make
sudo make install

OpenSnitch provides real-time monitoring with a Qt GUI that pops up when new outbound connections are detected.

2. Douane (D-Bus based)


sudo add-apt-repository ppa:douane/stable
sudo apt update
sudo apt install douane-dkms douane

Douane works at the kernel level using Netfilter hooks and provides both CLI and GUI interfaces.

For programmers who prefer more control, here's a basic implementation using nftables and auditd:


# Create nftables table
sudo nft add table inet filter

# Create chain for outgoing connections
sudo nft add chain inet filter output { type filter hook output priority 0 \; }

# Default drop policy
sudo nft add rule inet filter output drop

# Install auditd
sudo apt install auditd

# Configure audit rules
echo "-a exit,always -F arch=b64 -S connect -F a1!=0x10000 -k network_connect" | sudo tee -a /etc/audit/rules.d/network.rules
sudo service auditd restart

# Monitor connections
sudo ausearch -k network_connect | grep "pid="

For system services, you can create dynamic rules based on unit files:


#!/bin/bash
# Create firewall rules for active services
for service in $(systemctl list-units --type=service --state=running --no-legend | awk '{print $1}'); do
    PID=$(systemctl show -p MainPID $service | cut -d= -f2)
    if [ $PID -ne 0 ]; then
        EXE=$(readlink -f /proc/$PID/exe)
        echo "Allowing $service ($EXE)"
        sudo nft add rule inet filter output meta skuid == $(stat -c %u $EXE) accept
    fi
done

For GUI applications, you can create a Python script using DBus to monitor applications:


import dbus
from gi.repository import Gtk, GLib

bus = dbus.SessionBus()
proxy = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
proxy.connect_to_signal('NameOwnerChanged', handle_name_change)

def handle_name_change(name, old_owner, new_owner):
    if new_owner != '':
        # Show GTK dialog for new application
        dialog = Gtk.MessageDialog(
            parent=None,
            flags=0,
            message_type=Gtk.MessageType.QUESTION,
            buttons=Gtk.ButtonsType.YES_NO,
            text=f"Allow network access for {name}?"
        )
        response = dialog.run()
        # Add nftables rule based on response
        dialog.destroy()

When implementing application-level firewalling, consider:

  • Use kernel modules instead of userspace when possible
  • Cache frequent decisions to reduce popups
  • Whitelist system processes that make many connections
  • Consider performance impact of deep packet inspection

As a Linux user, you might be looking for a personal firewall solution similar to those available on Windows, which can monitor outgoing connections and prompt for permission before allowing them. While Linux has robust built-in firewall tools like iptables and ufw, they lack the user-friendly interactive features found in Windows firewalls. This article explores the best alternatives for achieving this functionality on Linux/Ubuntu.

Here are some of the most effective tools for monitoring and controlling outgoing connections on Linux:

1. Gufw (Graphical Interface for UFW)

While not interactive like Windows firewalls, Gufw provides a user-friendly interface for managing ufw (Uncomplicated Firewall). You can create rules to block specific outgoing connections.

sudo apt install gufw
gufw

2. OpenSnitch

This is the closest equivalent to Windows personal firewalls. OpenSnitch monitors outgoing connections in real-time and allows you to create allow/deny rules.

sudo add-apt-repository ppa:opensnitch/opensnitch
sudo apt update
sudo apt install opensnitch

3. Douane

Another application-level firewall that can intercept and filter outgoing connections based on user-defined rules.

sudo add-apt-repository ppa:douane/douane-unstable
sudo apt update
sudo apt install douane

For more advanced users, you can create your own monitoring system using these components:

Using iptables for Logging

sudo iptables -A OUTPUT -j LOG --log-prefix "OUTGOING: " --log-level 4
sudo tail -f /var/log/kern.log

Python Monitoring Script

Here's a basic Python script to monitor network connections:

import psutil

def monitor_connections():
    for conn in psutil.net_connections(kind='inet'):
        if conn.status == 'ESTABLISHED' and conn.raddr:
            print(f"Process {conn.pid} connecting to {conn.raddr}")

while True:
    monitor_connections()
Tool Interactive GUI Complexity
Gufw No Yes Low
OpenSnitch Yes Yes Medium
Douane Yes Yes Medium
Custom iptables No No High

For most users wanting Windows-like firewall behavior, OpenSnitch is the best choice. It provides real-time monitoring and interactive permission prompts. Advanced users might prefer creating custom solutions with iptables or Python scripts for more granular control.