{"id":23637023,"url":"https://github.com/O-X-L/ansible-role-nftables","last_synced_at":"2025-08-31T11:34:17.724Z","repository":{"id":150854214,"uuid":"585215053","full_name":"ansibleguy/infra_nftables","owner":"ansibleguy","description":"Ansible Role to provision NFTables firewall","archived":false,"fork":false,"pushed_at":"2024-09-06T16:32:46.000Z","size":182,"stargazers_count":7,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"latest","last_synced_at":"2024-09-06T19:46:07.142Z","etag":null,"topics":["ansible","ansible-role","automation","firewall","firewall-rules","iac","infrastructure-as-code","network-as-code","nftable","nftables","nftables-rules"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ansibleguy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"ansible0guy","github":"ansibleguy"}},"created_at":"2023-01-04T15:55:44.000Z","updated_at":"2024-09-06T16:32:50.000Z","dependencies_parsed_at":"2024-06-02T11:42:02.922Z","dependency_job_id":"c063c670-db22-417c-be1e-7c64ca58a017","html_url":"https://github.com/ansibleguy/infra_nftables","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nftables","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nftables/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nftables/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansibleguy%2Finfra_nftables/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ansibleguy","download_url":"https://codeload.github.com/ansibleguy/infra_nftables/tar.gz/refs/heads/latest","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231590686,"owners_count":18396934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-role","automation","firewall","firewall-rules","iac","infrastructure-as-code","network-as-code","nftable","nftables","nftables-rules"],"created_at":"2024-12-28T06:17:26.154Z","updated_at":"2025-08-31T11:34:17.717Z","avatar_url":"https://github.com/ansibleguy.png","language":"Python","funding_links":["https://ko-fi.com/ansible0guy","https://github.com/sponsors/ansibleguy"],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://netfilter.org/projects/nftables/index.html\"\u003e\n\u003cimg src=\"https://netfilter.org/images/netfilter-logo3.png\" alt=\"NFTables logo\" width=\"400\"/\u003e\n\u003c/a\u003e\n\n# Ansible Role - NFTables\n\nRole to provision NFTables firewall on linux servers.\n\n\n[![Lint](https://github.com/ansibleguy/infra_nftables/actions/workflows/lint.yml/badge.svg)](https://github.com/ansibleguy/infra_nftables/actions/workflows/lint.yml)\n[![Ansible Galaxy](https://badges.ansibleguy.net/galaxy.badge.svg)](https://galaxy.ansible.com/ui/standalone/roles/ansibleguy/infra_nftables)\n\n**Molecule Integration-Tests**:\n\n* Status: [![Molecule Test Status](https://badges.ansibleguy.net/infra_nftables.molecule.svg)](https://github.com/ansibleguy/_meta_cicd/blob/latest/templates/usr/local/bin/cicd/molecule.sh.j2) |\n[![Functional-Tests](https://github.com/ansibleguy/infra_nftables/actions/workflows/integration_test_result.yml/badge.svg)](https://github.com/ansibleguy/infra_nftables/actions/workflows/integration_test_result.yml)\n* Logs: [API](https://ci.ansibleguy.net/api/job/ansible-test-molecule-infra_nftables/logs?token=2b7bba30-9a37-4b57-be8a-99e23016ce70\u0026lines=1000) | [Short](https://badges.ansibleguy.net/log/molecule_infra_nftables_test_short.log) | [Full](https://badges.ansibleguy.net/log/molecule_infra_nftables_test.log)\n\nInternal CI: [Tester Role](https://github.com/ansibleguy/_meta_cicd) | [Jobs API](https://github.com/O-X-L/github-self-hosted-jobs-systemd)\n\n\n**Tested:**\n* Debian 11\n* Debian 12\n\n----\n\n## Install\n\n```bash\n# latest\nansible-galaxy role install git+https://github.com/ansibleguy/infra_nftables\n\n# from galaxy\nansible-galaxy install ansibleguy.infra_nftables\n\n# or to custom role-path\nansible-galaxy install ansibleguy.infra_nftables --roles-path ./roles\n```\n\n----\n\n## Documentation\n\n* NFTables: [Wiki](https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes)\n* Check out the [Example](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/Example.md)!\n* [Practical Use-Cases](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/UseCaseExamples.md) (_Docker, Proxmox, Network firewall_)\n  * Integration of [Fail2Ban with NFTables](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/Fail2Ban.md)\n* [Troubleshooting Guide](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/Troubleshoot.md)\n\n## Troubleshoot\n\n* [Troubleshooting Guide](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/Troubleshoot.md)\n\n----\n\n## Usage\n\n### Config\n\nDefine the config as needed:\n\n```yaml\nnftables:\n  # enable:  # features must be supported by kernel\n  #   sets: true\n  #   nat: true\n  #   deb11_backport: false  # use debian11 backports repository to install newer version on debian 10\n  #   bash_completion: false\n\n  _defaults:  # defaults inherited by all tables and chains\n    table:\n      type: 'inet'\n    \n    chain:\n      policy: 'drop'\n      type: 'filter'\n      priority: 0\n      log:\n        drop: true\n\n    rules:\n      _all: []  # rules added to all chains of all tables\n      incoming: []  # rules added to 'incoming' chain of all tables\n\n  tables:\n    example:\n      # type: 'inet'  # ipv4 + ipv6\n      _defaults:\n        rules:\n          _all: []  # rules added to all chains of this table\n\n      vars:\n        dns_servers: ['1.1.1.1', '1.1.0.0', '8.8.8.8', '8.8.4.4']\n        private_ranges: ['192.168.0.0/16', '172.16.0.0/12', '10.0.0.0/8']\n\n      sets:\n        blacklist:\n          flags: ['dynamic', 'timeout']\n          settings:\n            timeout: '3m'\n\n      counters:\n        invalid_packages:\n          comment: 'Invalid'\n\n      chains:\n        incoming:\n          hook: 'input'\n          rules:\n            - sequence: 1\n              raw: 'ct state invalid counter name invalid_packages log prefix \"DROP invalid states\" drop'\n            - seq: 2\n              raw: 'ct state {established, related} counter accept comment \"Allow open sessions\"'\n            - s: 3\n              raw: 'iifname \"lo\" accept comment \"Allow loopback traffic\"'\n            - {proto: 'icmp', type: 'echo-request', limit: 'rate 10/second', comment: 'Allow icmp-ping'}\n            - {proto: 'icmpv6', type: 'echo-request', limit: 'rate 10/second', comment: 'Allow icmp-ping'}\n            - {proto: 'icmp', code: 30, limit: 'rate 10/second', comment: 'Allow icmp-traceroute'}\n            - {proto: 'icmpv6', limit: 'rate 10/second', comment: 'Allow necessary icmpv6-types for ipv6 to work',\n               type: ['nd-neighbor-solicit', 'nd-router-advert', 'nd-neighbor-advert']}\n            - {proto: 'udp', port: 46251, counter: 'invalid_packages'}\n\n        outgoing:\n          hook: 'output'\n          # policy: 'accept'\n          rules:\n            - {dest: '$dns_servers', proto: 'udp', port: 53}\n            - {dest: '$dns_servers', proto: 'tcp', port: [53, 853]}\n            - {proto: ['tcp', 'udp'], port: [80, 443]}\n            - {proto: ['icmp', 'icmpv6'], comment: 'Allow outbound icmp'}\n\n        route:\n          hook: 'forward'\n\n        translate:\n          hook: 'postrouting'\n          type: 'nat'\n          policy: 'accept'\n          rules:\n            - {'src': '$private_ranges', oif: 'eno2', masquerade: true}  # dynamic outbound nat\n            - {'src': '$private_ranges', oif: 'eno3', snat: '192.168.0.1'}  # static outbound nat\n```\n\nIf you want to **merge group- \u0026 host-rules** you could do it like that:\n\n```yaml\n# define the basic ruleset used by all hosts as: 'fw_rules_all'\n# define service-specific rules as: 'fw_rules_group'\n# define host-specific rules as: 'fw_rules_host'\n\n- name: NFTables\n  become: true\n  hosts: all\n  vars:\n    nftables:\n      tables:\n        example:\n          chains: \"{{ fw_rules_all |\n          combine(fw_rules_group|default({}), recursive=true, list_merge='append') |\n          combine(fw_rules_host|default({}), recursive=true, list_merge='append') }}\"\n\n  pre_tasks:\n    - debug:\n        var: nftables\n\n  roles:\n    - ansibleguy.infra_nftables\n```\n\n### Execution\n\nRun the playbook:\n```bash\nansible-playbook -K -D -i inventory/hosts.yml playbook.yml\n```\n\nThere are also some useful **tags** available:\n* config_table =\u003e only provision actual rulesets\n* config\n* purge\n\nTo debug errors - you can set the 'debug' variable at runtime:\n```bash\nansible-playbook -K -D -i inventory/hosts.yml playbook.yml -e debug=yes\n```\n\n----\n\n## Functionality\n\n* **Package installation**\n  * Ansible dependencies (_minimal_)\n  * NFTables\n\n\n* **Configuration**\n  * Possibility to define\n    * **variables** on global level\n    * **variables, sets, counters and limits** on table level\n    * **variables** on chain level\n  * **Config will be validated** before being written\n\n\n  * **Default config**:\n    * Enabled features (_must be supported by kernel_)\n      * Sets\n      * NAT\n    * No rules are added by default\n    * tables\n      * table-type = inet\n    * chains\n      * chain-type = filter\n      * chain-policy = drop\n      * priority = 0\n      * add counter = yes\n      * log implicit dropy = yes\n    * sets\n      * set-type = ipv4_addr\n      * add counter = yes\n    * rules\n      * policy = accept (_set it to 'none' if you want to explicitly remove it_)\n      * logging drops = yes\n\n\n  * **Default opt-ins**:\n    * Purging of unmanaged config-files stored in '/etc/nftables.d/'\n\n  * **Default opt-outs**:\n    * Installing NFTables from Debian 11 backports when running on Debian 10 (_newer version_)\n    * Adding [bash-completion script](https://patchwork.ozlabs.org/project/netfilter-devel/patch/1454691182-6573-1-git-send-email-giuseppelng@gmail.com/) for the 'nft' command\n\n----\n\n## Info\n\n* **Note:** Most of the role's functionality can be opted in or out.\n\n  For all available options - see the default-config located in [the main defaults-file](https://github.com/ansibleguy/infra_nftables/blob/latest/defaults/main/1_main.yml)!\n\n\n* **Warning:** Not every setting/variable you provide will be checked for validity. Bad config might break the role!\n\n\n* **Info:** You can add **DNS-Resolution and IP-Blocklist** functionalities to NFTables using the [ansibleguy.addons_nftables](https://github.com/ansibleguy/addons_nftables) role!\n\n\n* **Warning:** Some **core functionalities** (_NAT/Sets_) might **not be supported by mainstream Distribution kernels**.\n\n  See: [Troubleshooting Guide - 'Unsupported Operation'](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/Troubleshoot.md#unsupported-operation)\n\n\n* **Info:** Read the [Hook documentation](https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks) to know when and how to configure **hooks and priorities**!\n\n\n* **Info:** Rules can be provided in dictionary format as seen in the examples.\n\n  These are the available fields and aliases:\n\n  | Function             | Keys                                                                      | Note                                                                                                                                                                                                               |\n  |----------------------|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n  | Rule sequence        | s, id, seq, sequence                                                      | The sequence-id (_integer_) to sort the rules inside a chain. If none is provided one will be auto-generated beginning at 1000. If a duplicate sequence id is provided the role will fail its config-check!        |\n  | Input interface      | if, iif, iifname                                                          | -                                                                                                                                                                                                                  |\n  | Output interface     | of, oif, oifname                                                          | -                                                                                                                                                                                                                  |\n  | Protocol             | proto, pr, protocol                                                       | -                                                                                                                                                                                                                  |\n  | Protocol sub-type    | t, type                                                                   | -                                                                                                                                                                                                                  |\n  | Protocol sub-code    | co, code                                                                  | -                                                                                                                                                                                                                  |\n  | Destination Address/Network | d, dest, target, destination, 'ip daddr', d6, dest6, target6, 'ip6 daddr' | -                                                                                                                                                                                                                  |\n  | Destination Port     | dp, port, dport, dest_port                                                | -                                                                                                                                                                                                                  |\n  | Source Address/Network | s, src, source, 'ip saddr', s6, src6, source6, 'ip6 saddr'                | -                                                                                                                                                                                                                  |\n  | Source Port          | sp, sport, sport, src_port                                                | -                                                                                                                                                                                                                  |\n  | Logging / Log message | l, log, 'log prefix'                                                      | If set to 'True' and a 'comment' is provided, it will be used as message. Else no message will be used                                                                                                             |\n  | Traffic counter      | count, counter                                                            | If set to 'True' a rule-specific counter will be used. Else it will use the provided pre-defined counter                                                                                                           |\n  | Traffic Limit        | lim, limit                                                                | A limit to set for the rule, see: [Anonymous Limits](https://wiki.nftables.org/wiki-nftables/index.php/Rate_limiting_matchings) and [Pre-defined Limits](https://wiki.nftables.org/wiki-nftables/index.php/Limits) |\n  | Rule action          | a, action                                                                 | If no action is provided, it will default to 'accept'                                                                                                                                                              | \n  | Source NAT masquerading | m, masque, masquerade                                                     | If NAT masquerading should be used                                                                                                                                                                                 |\n  | Source NAT           | snat, src_nat, source_nat, outbound_nat, 'snat to'                        | -                                                                                                                                                                                                                  |\n  | Destination NAT      | dnat, dest_nat, destination_nat, 'dnat to'                                | -                                                                                                                                                                                                                  |\n  | Redirect             | redir, redirect, 'redirect to'                                            | By using redirect, packets will be forwarded to local machine                                                                                                                                                      |                                                                                                                                                                                                                  |\n  | Rule comment         | c, cmt, comment                                                           | -                                                                                                                                                                                                                  |\n  | User                 | user, uid                                                                 | Match only traffic originating from specific user                                                                                                                                                                  |\n  | Group                | group, gid                                                                | Match only traffic originating from specific group                                                                                                                                                                 |\n  | Firewall-Mark        | mark                                                                      | -                                                                                                                                                                                                                  |\n  | Priority             | prio, priority                                                            | -                                                                                                                                                                                                                  |\n  | Packet length        | len, length                                                               | -                                                                                                                                                                                                                  |\n  | Timestamp            | time, timestamp                                                                    | Match timestamp of packet reception                                                                                                                                                                                |\n  | Weekday              | day                                                                       | Match day of week (0 = Sunday to 6 = Saturday or \"Monday\", \"tuesday\" also \"fri\", \"Sat\")                                                                                                                            |\n  | Time                 | hour                                                                      | Match 24-hour \"HH:MM:SS\", with seconds optional                                                                                                                                                                    |\n\n  Only one of Action, Source-NAT, Masquerading or Destination-NAT can be set for one rule!\n\n\n* **Info:** Special/complex rules cannot be configured using the rule-dictionary.\n\n  You can use the 'raw' key to provide any custom rule that will be added to the ruleset directly.\n\n\n* **Info:** You can define **variables, sets, counters and limits** on table-level.\n\n  * **Variables** are key-value pairs.\n    ```yaml\n    var-name: var-value\n    var2-name: ['value1', 'value2']\n    ```\n  * **Sets** have this structure:\n    ```yaml\n    set-name:\n      flags: [list-of-flags]  # optional\n      settings:\n        setting: value  # optional\n    ```\n  * **Counters** have this structure:\n    ```yaml\n    counter-name:\n      comment: text  # optional\n    ```\n  * **Limits** have this structure:\n    ```yaml\n    limit-name:\n      rate: 'over 1024 bytes/second burst 512 bytes'\n      comment: text  # optional\n    ```\n\n* **Warning:** If you want to add a 'count-only' rule you need to set 'action' explicitly to 'none' - else the default value 'accept' will be added!\n\n\n* **Info:** If any unsupported field is supplied to the rule-translation it will throw an error as this might lead to unexpected results!\n\n\n* **Info:** Docker might need IPTables as Package-Dependency. \n\n  See: [Use-Case Docker Host](https://github.com/ansibleguy/infra_nftables/blob/latest/docs/UseCaseExamples.md#docker-host)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FO-X-L%2Fansible-role-nftables","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FO-X-L%2Fansible-role-nftables","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FO-X-L%2Fansible-role-nftables/lists"}