Skip to content
Snigdha OSDecentralized

NetGuard Subsystem

NetGuard state machine, D-Bus daemon, and fail-closed firewall enforcement.

5 min readUpdated: 2026-11-12

Snigdha NetGuard — Firewall Policy Specification

1. Overview

The Snigdha NetGuard firewall is the primary enforcement mechanism preventing clearnet packet leakage in Snigdha OS Decentralized. It is written exclusively for the modern Linux nftables netfilter framework, replacing legacy iptables rulesets with atomic, unified IPv4/IPv6 packet processing.


2. Table Ownership and Scoping

  • Table Family: inet (processes dual-stack IPv4 and IPv6 traffic simultaneously).
  • Table Name: snigdha (table inet snigdha).
  • Isolation Guarantee: The ruleset owns only table inet snigdha. It explicitly avoids flush ruleset. To modify or reload the ruleset atomically:
    add table inet snigdha
    delete table inet snigdha
    table inet snigdha { ... }
    
    Unrelated packet filters, virtualization bridges (KVM/libvirt), or user network namespaces remain untouched.

3. Chains and Hook Priorities

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object] [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

4. Address Sets

The firewall maintains four static and dynamic interval sets:

  1. set tor_bootstrap_dns_v4: Dynamically populated by NetworkManager dispatcher during interface activation. Contains DHCP-provided IPv4 DNS servers.
  2. set tor_bootstrap_dns_v6: Dynamically populated by NetworkManager dispatcher. Contains DHCP-provided IPv6 DNS servers.
  3. set private_networks_v4: Static interval set covering RFC 1918, link-local, carrier-grade NAT, and broadcast ranges:
    • 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 240.0.0.0/4
  4. set private_networks_v6: Static interval set covering IPv6 loopback, ULA, link-local, and multicast:
    • ::1/128, fc00::/7, fe80::/10, ff00::/8

5. Chain Rules & Evaluation Logic

5.1 chain nat_output (Destination NAT Hook)

Executed before the routing decision for locally generated outbound packets:

  1. Loopback Exemption: oif "lo" return Prevents redirecting traffic already destined for loopback interfaces.
  2. Tor Daemon Exemption: meta skuid 43 return Prevents Tor's own outbound connection traffic to guard relays or bridges from looping back into its transparent listener.
  3. DNS Redirection: udp dport 53 redirect to :5353 Intercepts all outbound UDP DNS requests and alters destination port to Tor's DNSPort (5353).
  4. Private Network Return: ip daddr @private_networks_v4 return ip6 daddr @private_networks_v6 return Packets destined for RFC 1918 or local subnets exit the NAT chain unredirected and are subsequent dropped by the filter chain.
  5. TCP Transparent Redirection: meta l4proto tcp redirect to :9040 Intercepts all outbound TCP connections and alters destination port to Tor's TransPort (9040).

5.2 chain output (Filter Hook)

Executed after routing and destination NAT:

  1. Loopback Traffic: oif "lo" accept Accepts local inter-process communication.
  2. Redirected Tor Listeners:
    ip daddr 127.0.0.1 tcp dport 9040 accept
    ip6 daddr ::1 tcp dport 9040 accept
    ip daddr 127.0.0.1 udp dport 5353 accept
    ip6 daddr ::1 udp dport 5353 accept
    
    Accepts packets whose destinations were rewritten by nat_output to Tor's local ports.
  3. Connection State Tracking: ct state established,related accept ct state invalid drop
  4. Tor Service Identity Exemption: meta skuid 43 accept Allows the Tor daemon (UID 43) to initiate outbound connections to guard nodes, relays, and bridges.
  5. Tor Bootstrap DNS Resolution:
    meta skuid 43 udp dport 53 ip daddr @tor_bootstrap_dns_v4 accept
    meta skuid 43 tcp dport 53 ip daddr @tor_bootstrap_dns_v4 accept
    meta skuid 43 udp dport 53 ip6 daddr @tor_bootstrap_dns_v6 accept
    meta skuid 43 tcp dport 53 ip6 daddr @tor_bootstrap_dns_v6 accept
    
    Permits Tor (and Tor alone) to query DHCP-provided DNS servers to resolve bridge hostnames.
  6. DHCP Client Protocol: udp sport 68 udp dport 67 accept Allows local network DHCP requests necessary for network link association.
  7. IPv6 Discovery: Allows ICMPv6 router discovery, neighbor discovery, and packet-too-big MTU messages.
  8. DHCPv6 Client Protocol: ip6 nexthdr udp udp sport 546 udp dport 547 accept
  9. DNS Leak Prevention: udp dport 53 drop tcp dport 53 drop udp dport 853 drop tcp dport 853 drop
  10. UDP Leak Prevention: meta l4proto udp drop Drops all other outbound UDP packets, eliminating QUIC, NTP, and STUN leaks.
  11. Default Policy: drop (fail-closed).

5.3 chain input (Filter Hook)

Filters inbound packets arriving at the host:

  1. iif "lo" accept (Accept loopback).
  2. ct state established,related accept (Accept responses to valid outbound flows).
  3. ct state invalid drop.
  4. udp sport 67 udp dport 68 accept (Accept DHCP server leases).
  5. ip6 nexthdr icmpv6 ... accept (Accept ICMPv6 router/neighbor discovery).
  6. ip6 nexthdr udp udp sport 547 udp dport 546 accept (Accept DHCPv6 leases).
  7. Default policy: drop.

6. Pre-Activation Validation

Firewall reload operations are governed by /etc/systemd/system/snigdha-firewall.service:

  • ExecStartPre=/usr/bin/nft -c -f /etc/nftables.d/snigdha.nft
  • ExecStart=/usr/bin/nft -f /etc/nftables.d/snigdha.nft
  • If syntax or netlink parsing fails, systemd rejects the unit, NetworkManager is prevented from starting, and the live system remains isolated from clearnet.