summaryrefslogtreecommitdiff
path: root/src/conf_mode/firewall.py
AgeCommit message (Collapse)Author
13 daysfirewall: T8761: re-introduce VRF interface names in generated firewall configDavid Vølker
This change re-implements the intended behaviour from T4180 aswell as from T4506, it ensures that both the vrf-member interface aswell as the vrf itself is added as an oifname -> meaning that traffic traversing and originating from withing VyOS is matches outbound. Changes done by c-po: * re-sort dependency list to keep diff low * vyos.configdict.is_vrf_changed() should return early and not carry over the to-be return value * keep common coding style (dict by . separation) in nftables-zone.j2 Co-authored-by: Christian Breunig <christian@breunig.cc>
2026-06-04geoip: T5746: Add GeoIP ASN supportsarthurdev
2026-05-19geoip: T8590: fix initialization failure and set clobbering on boot and commitxTITUSMAXIMUSX
Three related bugs prevented GeoIP nftables sets from being populated correctly at boot and when incrementally modifying firewall or policy route rules. 1. geoip_updated() always returned False The previous implementation called node_changed() and then searched the result with dict_search_recursive(changes, 'geoip'). This could never match: node_changed() is annotated `-> list` and returns a flat list of the immediate top-level child names whose subtree changed (e.g. ['ipv4'] for the firewall path, or route names for policy route). The 'geoip' key sits several levels deeper than those names, so dict_search_recursive — which only walks dicts and lists for a matching dict key — never yielded a hit, and geoip_updated() always returned False. As a consequence, geoip_update() was never triggered by an incremental add or change of a GeoIP rule; the only path that ever populated /run/nftables-geoip.conf was the explicit \"update geoip\" command or the fallback when geoip_refresh() failed. Fix: bypass node_changed() and call get_config_diff() / get_child_nodes_diff() directly with expand_nodes=Diff.ADD|Diff.DELETE and recursive=True. In that mode, the 'add' and 'delete' values in the returned dict are full nested subtrees of the config diff, so dict_search_recursive correctly finds 'geoip' wherever it appears in the change set. 2. GeoIP block executed unconditionally, breaking the boot sequence geoip_sets() always returns {'name': [], 'ipv6_name': []}. A non-empty dict is truthy in Python regardless of whether its values are empty lists, so the guards \"if geoip_sets:\" and \"if 'name' in geoip_sets:\" were always True. On boot, when policy_route.py is invoked as a dependent of firewall.py (triggered by group_resync), it entered the GeoIP block even with no policy route GeoIP rules configured. Because /run/nftables-geoip.conf did not yet exist, geoip_refresh() returned False and geoip_update(policy=policy) was called with an empty policy. This created /run/nftables-geoip.conf containing only empty table stubs. When firewall.py subsequently called geoip_refresh(), the file existed and nft loaded it successfully — so the geoip_update(firewall) call was never reached and the firewall GeoIP sets stayed empty for the entire uptime of the router. Fix: check the actual list contents instead of the container dict: if geoip_sets['name'] or geoip_sets['ipv6_name']. 3. geoip_update() clobbered the other caller's sets geoip_update() renders /run/nftables-geoip.conf from both firewall_sets and policy_sets in a single pass. When called with only one argument (as firewall.py and policy_route.py each do), the other argument defaulted to None and that half of the file was rendered empty, erasing whatever the other script had written. The geoip-update helper used by \"update geoip\" and the weekly cron was unaffected because it always passes both arguments, which masked this bug in normal manual operation. Fix: when either argument is absent, read the missing config from the live Config session before building the set tables, so every invocation writes the complete combined firewall + policy file.
2026-03-31firewall: T8446: Prevent chain with offload rule on local zonesarthurdev
* Add warning when defining `offload-target` without setting action to `offload`
2026-01-21geoip: T8049: Add MaxMind database supportsarthurdev
2026-01-21geoip: T7926: Refactor geoip handlingsarthurdev
* Move core logic to separate vyos.geoip module * Use a sqlite database for storing and querying address ranges by country * Remove downloaded geoip ranges once loaded into sqlite db * No longer rebuild geoip sets on each commit unless necessary * Allows for extensibility using other geoip data vendors
2025-11-24Merge pull request #4672 from apschultz/zone_default_firewall_rulesetSimon
firewall: T7739: Default ruleset for firewall zones
2025-11-05firewall: T7112: Default action drop failsOleksandr Kuchmystyi
Prevent `KeyError` by safely handling missing 'member' dict in zone config. Add smoketest to verify commit fails gracefully when zone has no interfaces.
2025-10-21firewall: T7739: Default ruleset for firewall zonesAdam Schultz
In large networks with many zones where simple allow/deny rules are not sufficient, zones become tedious to manage. Many use cases can be simplified by providing an ability to define a default ruleset for traffic from other zones. This change proposes adding the follwing syntax: set firewall zone <name> default_firewall name <name> set firewall zone <name> default_firewall ipv6_name <name> The proposed behavior is the following: local in: The default firewall ruleset for the local zone will be appended after all from configurations. local out: If a non-local zone does not have a from local ruleset but does have a default_firewall ruleset, the default_firewall ruleset will be appended using oifname forward: The default firewall ruleset for the zone will be appended after all from configurations To keep the behavior consistent with from ruleset configurations, a return is appended after the default_firewall ruleset. The proposed behavior differs slightly from the default_policy configuration for the local out chains. The default_policy applied in the out templates comes from the local zone, not the actual outbound zone. The proposed change does not amend this, but does make default_firewall logically consistent with the intent of the out rules.
2025-09-05Firewall: T7475: Disable conntrack per firewall chainl0crian1
- Added command to disable conntrack per firewall chain - Added test_disable_conntrack_per_chain function to smoketest
2025-09-04T7366: Firewall rules allow empty nodesl0crian1
Added checks in the verify_rule() function of firewall.py for empty nodes. Added migration script 19-to-20 to remove empty nodes from the config.
2025-06-28T7591: remove copyright years from source filesChristian Breunig
The legal team says years are not necessary so we can go ahead with it, since it will simplify backporting. Automatically removed using: git ls-files | grep -v libvyosconfig | xargs sed -i -E \ 's/^# Copyright (19|20)[0-9]{2}(-[0-9]{4})? VyOS maintainers.*/# Copyright VyOS maintainers and contributors <maintainers@vyos.io>/g' In addition we will error-out during "make" if someone re-adds a legacy copyright notice
2025-05-20Merge pull request #4468 from sarthurdev/T5707Daniil Baturin
wireguard: T7387: Optimise wireguard peer handling
2025-04-25resolver: T4930: Fix always True on glob checksarthurdev
2025-04-25Merge pull request #4457 from l0crian1/t7358-add-offload-to-global-stateViacheslav Hletenko
firewall: T7358: add offload option to global state policy
2025-04-16firewall: T7358: add offload option to global state policyl0crian1
Since the jump to the global state chain is inserted before all rules, it wasn't possible to use offload with the global state policies This commit adds a new chain for offloaded traffic in the forward chain and jumps to that chain. Please enter the commit message for your changes. Lines starting
2025-03-28geoip: T5636: Add geoip for policy route/route6sskaje
2025-03-21firewall: T5493: Implement remote-groupAlex W
2025-01-06T6841: firewall: Fixed issues in ZBF when using VRFsaapostoliuk
Improve config parsing for ZBF when using VRFs and interfaces attached to VRFs
2025-01-06T6841: firewall: improve config parsing for ZBF when using VRFs and ↵Nicolas Fort
interfaces attached to VRFs
2024-12-30T6983: treat vyos-domain-resolver as a real service (#4261)Christian Breunig
* op-mode: T6983: add "show log" and "monitor log" commands for vyos-domain-resolver * firewall: T6983: drop unused variable domain_resolver_usage_nat * T6983: introduce Python logging module in vyos-domain-resolver * T6983: treat vyos-domain-resolver as a real service
2024-09-16T6687: add fqdn support to nat rules.Nicolas Fort
2024-08-12configverify: T6642: verify_interface_exists requires config_dict argJohn Estabrook
The function verify_interface_exists requires a reference to the ambient config_dict rather than creating an instance. As access is required to the 'interfaces' path, provide as attribute of class ConfigDict, so as not to confuse path searches of script-specific config_dict instances.
2024-08-04firewall: T4694: Adding GRE flags & fields matches to firewall rulesAndrew Topp
* Only matching flags and fields used by modern RFC2890 "extended GRE" - this is backwards-compatible, but does not match all possible flags. * There are no nftables helpers for the GRE key field, which is critical to match individual tunnel sessions (more detail in the forum post) * nft expression syntax is not flexible enough for multiple field matches in a single rule and the key offset changes depending on flags. * Thus, clumsy compromise in requiring an explicit match on the "checksum" flag if a key is present, so we know where key will be. In most cases, nobody uses the checksum, but assuming it to be off or automatically adding a "not checksum" match unless told otherwise would be confusing * The automatic "flags key" check when specifying a key doesn't have similar validation, I added it first and it makes sense. I would still like to find a workaround to the "checksum" offset problem. * If we could add 2 rules from 1 config definition, we could match both cases with appropriate offsets, but this would break existing FW generation logic, logging, etc. * Added a "test_gre_match" smoketest
2024-08-02T4072: change same helpers in xml definitions; add notrack action for ↵Nicolas Fort
prerouting chain; re introduce <set vrf> in policy; change global options for passing traffic to IPvX firewall; update smoketest
2024-08-01T4072: firewall: improve error handling when firewall configuration is ↵Nicolas Fort
wrong. Use nft -c option to check temporary file, and use output provided by nftables to parse the error if possible, or print it as it is if it's an unknown error
2024-07-28firewall: T4694: Adding rt ipsec exists/missing match to firewall configs ↵talmakion
(#3616) * Change ipsec match-ipsec/none to match-ipsec-in and match-none-in for fw rules * Add ipsec match-ipsec-out and match-none-out * Change all the points where the match-ipsec.xml.i include was used before, making sure the new includes (match-ipsec-in/out.xml.i) are used appropriately. There were a handful of spots where match-ipsec.xml.i had snuck back in for output hooked chains already (the common-rule-* includes) * Add the -out generators to rendered templates * Heavy modification to firewall config validators: * I needed to check for ipsec-in matches no matter how deeply nested under an output-hook chain(via jump-target) - this always generates an error. * Ended up retrofitting the jump-targets validator from root chains and for named custom chains. It checks for recursive loops and improper IPsec matches. * Added "test_ipsec_metadata_match" and "test_cyclic_jump_validation" smoketests
2024-06-09firewall: T3900: T6394: remove unused importChristian Breunig
With commit 770edf016838 ("T3900: T6394: extend functionalities in firewall; move netfilter sysctl timeout parameters defined in conntrack to firewall global-opton section.") the import of the glob module is no longer required. Found my running: make unused-imports
2024-06-04T3900: T6394: extend functionalities in firewall; move netfilter sysctl ↵Nicolas Fort
timeout parameters defined in conntrack to firewall global-opton section.
2024-05-15T3900: add support for raw table in firewall.Nicolas Fort
2024-04-15T5535: firewall: migrate command <set system ip disable-directed-broadcast> ↵Nicolas Fort
to firewall global-optinos
2024-04-01firewall: T2199: always use full nft command name (e.g. --file over -f)Christian Breunig
2024-03-18T6136: add error checks when using dynamic firewall groupsNicolas Fort
2024-03-05T6075: firewall and NAT: check if interface-group exists when using them in ↵Nicolas Fort
firewall|nat rules.
2023-12-31T5474: establish common file name pattern for XML conf mode commandsChristian Breunig
We will use _ as CLI level divider. The XML definition filename and also the Python helper should match the CLI node. Example: set interfaces ethernet -> interfaces_ethernet.xml.in set interfaces bond -> interfaces_bond.xml.in set service dhcp-server -> service_dhcp-server-xml.in
2023-12-24T5837: cleanup use of calls to vyos.configdict.node_changed()Christian Breunig
node_changed() will return a list of changed keys under "path". We are not always interested what changed, sometimes we are only interested if something changed at all, that what vyos.configdict.is_node_changed() is for.
2023-11-10T5729: firewall: switch to valueless in order to remove unnecessary ↵Nicolas Fort
<enable|disable> commands; log and state moved to new syntax.
2023-10-25T5681: Firewall,Nat and Nat66: simplified and standarize interface matcher ↵Nicolas Fort
(valid for interfaces and groups) in firewal, nat and nat66.
2023-10-13T5541: firewall zone: re add firewall zone-base firewallNicolas Fort
2023-09-28firewall: T5217: Synproxy bugfix and ct state conflict checkingsarthurdev
2023-09-21T5217: Add firewall synproxyViacheslav Hletenko
Add ability to SYNPROXY connections It is useful to protect against TCP SYN flood attacks and port-scanners set firewall global-options syn-cookies 'enable' set firewall ipv4 input filter rule 10 action 'synproxy' set firewall ipv4 input filter rule 10 destination port '22' set firewall ipv4 input filter rule 10 inbound-interface interface-name 'eth1' set firewall ipv4 input filter rule 10 protocol 'tcp' set firewall ipv4 input filter rule 10 synproxy tcp mss '1460' set firewall ipv4 input filter rule 10 synproxy tcp window-scale '7'
2023-09-19firewall: ethernet: T4502: Add interface offload node and verify interface ↵sarthurdev
supports HW flowtable offload - Add required offload setting for interfaces + flowtable offload (hw-tc-offload) - Verification of interface support for hardware offloaded flowtables
2023-09-19firewall: T4502: Update to flowtable CLIsarthurdev
`set firewall flowtable <name> interface <ifname>` `set firewall flowtable <name> offload [software|hardware]` `set firewall [ipv4|ipv6] forward filter rule N action offload` `set firewall [ipv4|ipv6] forward filter rule N offload-target <name>`
2023-09-16conntrack: T5571: Refactor conntrack to be independent conf script from ↵sarthurdev
firewall, nat, nat66
2023-09-09T4502: firewall: Add software flow offload using flowtableYuxiang Zhu
The following commands will enable nftables flowtable offload on interfaces eth0 eth1: ``` set firewall global-options flow-offload software interface <name> set firewall global-options flow-offload hardware interface <name> ``` Generated nftables rules: ``` table inet vyos_offload { flowtable VYOS_FLOWTABLE_software { hook ingress priority filter - 1; devices = { eth0, eth1, eth2, eth3 }; counter } chain VYOS_OFFLOAD_software { type filter hook forward priority filter - 1; policy accept; ct state { established, related } meta l4proto { tcp, udp } flow add @VYOS_FLOWTABLE_software } } ``` Use this option to count packets and bytes for each offloaded flow: ``` set system conntrack flow-accounting ``` To verify a connection is offloaded, run ``` cat /proc/net/nf_conntrack|grep OFFLOAD ``` This PR follows firewalld's implementation: https://github.com/firewalld/firewalld/blob/e748b97787d685d0ca93f58e8d4292e87d3f0da6/src/firewall/core/nftables.py#L590 A good introduction to nftables flowtable: https://thermalcircle.de/doku.php?id=blog:linux:flowtables_1_a_netfilter_nftables_fastpath
2023-08-26firewall: T5080: Disable conntrack unless required by rulessarthurdev
2023-08-26Merge pull request #2163 from sarthurdev/firewall_rpfilterChristian Breunig
firewall: T3509: Add support for IPv6 reverse path filtering
2023-08-25T5502: firewall: add validator for interface matcher, and allow only ↵Nicolas Fort
interface-name or interface-group
2023-08-25firewall: T3509: Add support for IPv6 return path filteringsarthurdev
2023-08-15T5478: remove config-trap configuration parser in firewallNicolas Fort