nleiva / capirca_acl

This collection includes a module (translate) to use Capirca from your Ansible playbooks.
GNU General Public License v3.0
9 stars 2 forks source link

Nftables #2

Open mdomore opened 1 year ago

mdomore commented 1 year ago

Hi, I am in the process of moving from iptables to nftables. I try to re-use as mutch as possible of my actual configuration.

After testing my policy files with capirca I am confiant that they are generating the need policies.

I have created a new task like this

  - name: Nftables - Generate ACL for INPUT
    nleiva.capirca_acl.translate:
      platform: 'nftables'
      filter_options:
          - inet
      def_folder: "{{ def_folder }}"
      pol_file: "{{ input }}"
      comment: "INPUT policy for nftables."
    register: input_res

First I have some doubt about filter_options values in nftables and the documentation is not clear for me. How can I specify :

Second I have try with a polici file like that :

header {
  target:: nftables
}

# Default policies

# This NFTables ACL generator generates stateful policies via conntrack

term base-allow-icmp-in {
  protocol:: icmp
  icmp-type:: echo-request
  action:: accept
}

I have an error :

raise NoTermsError('no terms found')\ncapirca.lib.policy.NoTermsError: no terms found\n"

And with a policy file like that :

# Default policies

# This NFTables ACL generator generates stateful policies via conntrack

term base-allow-icmp-in {
  protocol:: icmp
  icmp-type:: echo-request
  action:: accept
}

I have an error :

capirca.lib.nftables.HeaderError: Invalid header for Nftables. Required fields missing.

I have tried several different options but can find the right one. Do you have an example for nftables ? Thanks.

I have check in capirca documentation and i see :

target:: nftables [chain name] [filter name] [priority] [inet|inet6]

So for me the good filter_options is

filter_options: ['nftables','INPUT','0','inet']

But error here is :

The error was: capirca.lib.nftables.HeaderError: Invalid address family in header: nftables. Supported: frozenset({'mixed', 'inet6', 'inet'})
mdomore commented 1 year ago

At the end I managed to use find the good headers and good order for those filters :

in capirace code :

  _HEADER_AF = frozenset(('inet', 'inet6', 'mixed'))
  _SUPPORTED_HOOKS = frozenset(('input', 'output'))

So you need to put something like that : filter_options: ['inet', 'input'] The important part is netfilter family first with one of those 3 values 'inet', 'inet6', 'mixed'

But a problem remains. I try to add this first term :

term base-allow-icmp-in {
  protocol:: icmp
  icmp-type:: echo-request
  action:: accept
}

But I have some errors.

File "/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/aclgenerator.py", line 322, in __init__
    self._TranslatePolicy(pol, exp_info)
  File "/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py", line 700, in _TranslatePolicy
    {term.name: term_object.RulesetGenerator(term)})
  File "/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py", line 481, in RulesetGenerator
    proto_and_ports = self.PortsAndProtocols(self.address_family,
  File "/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py", line 267, in PortsAndProtocols
    statement_lines.append('icmp type' + Add(icmp_type))
  File "/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py", line 50, in Add
    return TabSpacer(1, statement)
  File "/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py", line 44, in TabSpacer
    return (blank_space * number_spaces) + string
TypeError: can only concatenate str (not "list") to str
fatal: [hulelbfr1-011 -> 127.0.0.1]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1680514675.9389675-17599-178970046398278/AnsiballZ_translate.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1680514675.9389675-17599-178970046398278/AnsiballZ_translate.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1680514675.9389675-17599-178970046398278/AnsiballZ_translate.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.nleiva.capirca_acl.plugins.modules.translate', init_globals=dict(_module_fqn='ansible_collections.nleiva.capirca_acl.plugins.modules.translate', _modlib_path=modlib_path),\n  File \"/usr/local/lib/python3.9/runpy.py\", line 210, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/local/lib/python3.9/runpy.py\", line 97, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/local/lib/python3.9/runpy.py\", line 87, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_nleiva.capirca_acl.translate_payload_mojzk74w/ansible_nleiva.capirca_acl.translate_payload.zip/ansible_collections/nleiva/capirca_acl/plugins/modules/translate.py\", line 278, in <module>\n  File \"/tmp/ansible_nleiva.capirca_acl.translate_payload_mojzk74w/ansible_nleiva.capirca_acl.translate_payload.zip/ansible_collections/nleiva/capirca_acl/plugins/modules/translate.py\", line 274, in main\n  File \"/tmp/ansible_nleiva.capirca_acl.translate_payload_mojzk74w/ansible_nleiva.capirca_acl.translate_payload.zip/ansible_collections/nleiva/capirca_acl/plugins/modules/translate.py\", line 252, in run_module\n  File \"/tmp/ansible_nleiva.capirca_acl.translate_payload_mojzk74w/ansible_nleiva.capirca_acl.translate_payload.zip/ansible_collections/nleiva/capirca_acl/plugins/modules/translate.py\", line 198, in get_acl\n  File \"/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/aclgenerator.py\", line 322, in __init__\n    self._TranslatePolicy(pol, exp_info)\n  File \"/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py\", line 700, in _TranslatePolicy\n    {term.name: term_object.RulesetGenerator(term)})\n  File \"/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py\", line 481, in RulesetGenerator\n    proto_and_ports = self.PortsAndProtocols(self.address_family,\n  File \"/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py\", line 267, in PortsAndProtocols\n    statement_lines.append('icmp type' + Add(icmp_type))\n  File \"/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py\", line 50, in Add\n    return TabSpacer(1, statement)\n  File \"/root/.local/lib/python3.9/site-packages/capirca-2.0.6-py3.9.egg/capirca/lib/nftables.py\", line 44, in TabSpacer\n    return (blank_space * number_spaces) + string\nTypeError: can only concatenate str (not \"list\") to str\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

If i use the same term in capiraca directly I have no problem. If I remove the icmp-type it's working :

term base-allow-icmp-in {
  protocol:: icmp
  action:: accept
}

I think the problem is when the module send the values to ansible.