# Native Linux firewall — DebTik The firewall forms describe the implemented iptables/ip6tables backend. Unsupported RouterOS template options have been removed from the forms. The API rejects unsupported actions and populated legacy fields with a clear error; it never substitutes ACCEPT or MASQUERADE for an unknown action. `GET /api/firewall/capabilities` lists the implemented fields/actions. Supported matches include IPv4/IPv6 addresses, protocols, source/destination/any ports, explicit interfaces, nonempty LAN/WAN role lists, Linux packet/connection marks, assigned conntrack helpers, connection/NAT states, address lists, IPv4 GeoIP, content string, MAC, bridge physical ports, IPsec policy, DSCP/TOS, TCP MSS/flags, packet length, random percentage, TTL/hop-limit, UTC schedules and packet rate limits. Mangle also supports nth, connection limits, address types and IPv4 non-initial fragment matching. Kernel validation checks every change before application. Matches needing a kernel extension fail explicitly if the host does not provide it. Ports accept `443`, `80,443`, `1000-2000` or `1000:2000`; inversion is supported for the standard address, interface, protocol, mark, list and port matches. Negated interface *lists* are not implemented; their inversion controls were removed. Use an explicit negated interface where appropriate. An empty or unknown interface role returns an error instead of dropping the entire rule silently. A rule may select an explicit interface or an interface list for each direction. Packet and routing mark criteria refer to the same Linux fwmark. Separate conflicting packet/routing mark criteria are rejected. Marks set by mangle retain the existing named-mark mapping used by policy routing. Connection helpers match already assigned helpers; selecting a helper does not configure conntrack helper assignment. Content is a packet string match, not TLS inspection or full stream reassembly. Bridge-port matching depends on the host's bridge/netfilter setup. Schedules use UTC and accept `HH:MM[:SS]-HH:MM[:SS]`, with weekday selection in Filter/NAT. Rate limits accept `100/second,5`, `100/5s,5`, or the compatible `100,5:packet` notation (rate, burst). UI custom chains are editable and limited to 16 characters, allowing the internal owned prefix to fit Linux chain limits. Custom chains need a jump from another chain to receive traffic. Filter supports accept/drop/reject, jump/return, logging, passthrough counters and adding source/destination IPs to a dynamic list. NAT supports masquerade, SNAT, DNAT, redirect and IPv4 NETMAP, plus the shared non-translating actions. NETMAP requires a CIDR and translates addresses only; port translation uses the other NAT actions. Masquerade supports to-ports for TCP/UDP. Mangle supports native connection/packet/routing marks, MSS, DSCP (including 0), TTL/hop-limit and Linux packet priority, plus the shared actions. MSS rewriting handles a selected TCP protocol without duplicate protocol options. IPv6 ICMP is matched as ICMPv6. The Log checkbox produces a logging rule before the selected action. For mangle, `passthrough=false` uses a helper and goto so it stops that managed chain even if the action changes a mark used by the original criterion. Foreign chains, policies and counters remain outside DebTik ownership. Address lists use separate static and dynamic sets and a matching union. Edits replace only the static set; dynamic IPs survive Save/Reapply. Dynamic timeouts accept `0` (no expiry), `30s`, `5m`, `1h` or `1d`. Dynamic entries appear in the UI and may be deleted; they are not edited as static records. At most 2,000 dynamic entries are included in a list response. Set names are hashed to avoid UI-name collisions. Unused owned sets/chains are collected only when no external kernel reference prevents deletion. Country sets use validated bulk restore and atomic swap, with unchanged-data caching rather than a process per subnet. An enabled country referenced directly or through a preset by an active rule cannot be disabled. No referenced GeoIP set is flushed to pretend success. Batch/update failures are reported; failed background updates retain the last successful update timestamp and expose `last_error`. GeoIP currently provides IPv4 data, and an IPv6 GeoIP match is rejected. Counters survive unrelated edits and reapplication. The per-rule Reset button resets kernel counters through a dedicated endpoint. Empty saved rule lists stay empty across restart; defaults are created only for a first installation. Config load/application failures are logged and appear in the firewall status banner. Saved configuration files are staged before replacement, with restoration on replacement failure. A failed change restores the prior managed configuration. Connection tracking reads both families, parses actual timeouts and traffic counters, and surfaces command failures. Deletion requires a complete tuple, including ports for TCP/UDP and ID/type/code for ICMP. Incomplete selectors are rejected before launching conntrack. Unsupported per-flow delete protocols are not offered as Kill actions. Comments and other stored firewall strings are escaped before rendering. Legacy unsupported settings remain readable so an operator can review them. Saving a rule with removed settings asks the UI operator to review their removal; unsupported active settings are rejected rather than silently ignored at startup. Disabled rules are not compiled. Configuration health is distinct from a successful HTTP read of the configuration. Verification covers real private kernel namespaces, rollback, both IP families, packet/counter behavior, dynamic expiration/preservation, GeoIP in-use guards, request validation, browser form submissions, legacy/custom-chain handling and XSS regression. Production firewall edits are not used for destructive tests. Version 1.3.1 also restores existing country sets whose creation limits differ from the current defaults, using atomic swap without recreating the existing set. Startup exposes `is_restoring`; migration verification waits for all country restores and checks `last_error` before declaring success. In 1.3.2 NAT action and destination fields are together on the General tab. NAT port matches require explicit TCP or UDP; configure both for DNS. Existing legacy `all` port matches are displayed as TCP, preserving their prior kernel behavior. NAT exposes the Linux chains `prerouting`, `input`, `output` and `postrouting`. The MikroTik aliases `dstnat` and `srcnat` map to `prerouting` and `postrouting`, respectively, including existing rules. DNAT can be used in `dstnat`/`prerouting` for incoming traffic or `output` for traffic created on this machine. Custom chains need a jump from a reachable chain; they are not evaluated automatically. New rules are checked for incompatible chain, action and interface combinations. Existing saved rules are not migrated or reinterpreted. From 1.3.6 the UI uses iptables table, chain and target names. Filter offers INPUT/FORWARD/OUTPUT, NAT offers PREROUTING/INPUT/OUTPUT/POSTROUTING, and mangle offers all five. Existing `srcnat`/`dstnat` records are displayed and filtered as POSTROUTING/PREROUTING without rewriting the saved configuration; editing a rule saves its native chain name. The API accepts native DNAT/SNAT, MARK/CONNMARK, TCPMSS, DSCP, TTL/HL and CLASSIFY target names as well as the older internal names. Address-list SET operations retain explicit source or destination selection. Named routing marks still use DebTik's fwmark mapping. Rule moves skip rules belonging to other kernel chains; each chain's processing order is independent. New and edited port matches must use an explicit, non-inverted TCP or UDP protocol: configure separate rules for both. Existing saved rules keep their prior interpretation until edited. Invalid jumps to built-in chains are rejected. A custom chain receives packets only when reached through an explicit jump. Address lists, GeoIP and conntrack remain available.