Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions packages/netifyd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,27 @@ uci del_list netifyd.config.bypassv4='192.168.1.0/24 | My network'
uci commit netifyd
reload_config
```

## Firewall-local traffic analysis

The `firewall_traffic` option controls how traffic to/from the firewall itself is handled. It accepts three values:

| Value | Description |
|---|---|
| `full` | Analyze all firewall traffic: inbound, outbound (firewall-initiated), and forwarded |
| `inbound` | Analyze only traffic initiated from outside toward the firewall, plus forwarded traffic (default) |
| `forward` | Analyze only forwarded traffic; ignore all firewall-local traffic entirely |
Comment thread
Tbaile marked this conversation as resolved.

```bash
# Default: only inbound connections to the firewall + forwarded traffic
uci set netifyd.config.firewall_traffic='inbound'

# Full analysis including firewall-originated connections (e.g. DNS, monitoring)
uci set netifyd.config.firewall_traffic='full'

# Forwarded traffic only, skip all local firewall traffic
uci set netifyd.config.firewall_traffic='forward'

uci commit netifyd
reload_config
```
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ all = include

[netlink]
# Set the Netlink buffer size
buffer_size = 32768
buffer_size = 327680
bridge_pvid_discovery = no

# vim: set ft=dosini :
27 changes: 26 additions & 1 deletion packages/netifyd/files/usr/sbin/ns-netifyd-configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,18 @@
}

# push input packets to userspace queues for DPI analysis
{%- if firewall_traffic in ('full', 'inbound') %}
chain nfq_input {
type filter hook input priority filter + 10; policy accept;
iifname lo accept

# Skip untracked traffic
ct state untracked accept
{%- if firewall_traffic == 'inbound' %}
# Skip reply traffic for connections initiated by the firewall itself
# (e.g. DNS responses, monitoring ping replies)
ct direction reply accept
{%- endif %}
# Accept traffic matching bypass set
ip saddr @nfq_bypass_v4 accept
ip daddr @nfq_bypass_v4 accept
Expand All @@ -50,11 +58,14 @@
# Traffic to queues 54-57
queue flags bypass to 54-57
}
{%- endif %}

# push forward packets to userspace queues for DPI analysis
chain nfq_forward {
type filter hook forward priority filter + 10; policy accept;

# Skip untracked traffic
ct state untracked accept
# Accept traffic matching bypass set
ip saddr @nfq_bypass_v4 accept
ip daddr @nfq_bypass_v4 accept
Expand All @@ -68,11 +79,14 @@
queue flags bypass to 50-53
}

{%- if firewall_traffic == 'full' %}
# push output packets to userspace queues for DPI analysis
chain nfq_output {
type filter hook output priority filter + 10; policy accept;
oifname lo accept

# Skip untracked traffic
ct state untracked accept
# Accept traffic matching bypass set
ip saddr @nfq_bypass_v4 accept
ip daddr @nfq_bypass_v4 accept
Expand All @@ -85,6 +99,8 @@
# Traffic to queues 54-57
queue flags bypass to 54-57
}
{%- endif %}

}
"""

Expand Down Expand Up @@ -125,11 +141,20 @@ def generate_nfq_table():
# Format elements with optional comments for nftables
v4_elements = _format_nft_elements(v4_raw)
v6_elements = _format_nft_elements(v6_raw)


# Read which firewall-local traffic to include in DPI analysis:
# 'full' - analyze all firewall traffic (input + output + forward)
# 'inbound' - analyze only traffic initiated from outside toward the firewall (input + forward)
# 'forward' - analyze only forwarded traffic, ignore firewall-local traffic entirely
firewall_traffic = e_uci.get('netifyd', 'config', 'firewall_traffic', dtype=str, default='inbound')
if firewall_traffic not in ('full', 'inbound', 'forward'):
firewall_traffic = 'inbound'

template = Environment(loader=BaseLoader()).from_string(NFQ_TABLE)
render = template.render(
v4_elements=v4_elements,
v6_elements=v6_elements,
firewall_traffic=firewall_traffic,
)

# Apply nftables
Expand Down
Loading