This project adheres to Semantic Versioning and human-readable changelog.

The current role maintainer is drybjed

debops.ferm master - unreleased


  • Add a variable which can be used to restrict what network interfaces can be used for connections from Ansible Controller. [gaudenz]


  • Reject other protocols besides TCP and UDP on IPv6 networks at the end of the chain. [gaudenz]
  • Packets blocked due to rate limits will be now dropped instead of being rejected by default. [gaudenz]

debops.ferm v0.2.2 - 2016-12-01




  • Don’t create duplicate forward rules when an interface has both an IPv4 and an IPv6 address. [ypid]
  • Allow DHCPv6 responses for clients. [ypid]


  • Use item.rule_state in the role defaults instead of the hereby deprecated item.when and item.delete. See discussion. item.delete and item.when are currently still supported for backwards compatibility. [ypid]
  • Deprecated item.role, use item.by_role instead. Applies for: Default rules. [ypid]

debops.ferm v0.2.1 - 2016-04-21


  • Rename item.state parameter to item.rule_state to avoid collision with iptables state module support. [drybjed]

debops.ferm v0.2.0 - 2016-04-20


  • Support item.state key in ferm_*_rules variables to add or remove firewall rules. [drybjed]


  • Rename all role variables to put them in their own namespace. [drybjed]

debops.ferm v0.1.6 - 2016-04-20


  • Create base documentation files, clean up default variables. [ganto, drybjed]


  • Enable the firewall if ansible_local and local Ansible facts are undefined. This will ensure that the role works on hosts which don't have it applied yet. [drybjed]
  • Renamed ferm_.*rules to ferm__.*rules and ferm_forward to ferm__forward. Old names are currently still supported to not break stuff while updating the code which depends on the old names. [ypid]


  • Remove ferm_local_tags variable and its use in ferm_enabled. This solution was needed when the POSIX capability detection was located in the tasks. Because now the templating is done in default variables which can be easily overridden by Ansible inventory, having a separate way of affecting POSIX capability detection is unnecessary.

debops.ferm v0.1.5 - 2016-02-20


  • Restart fail2ban when firewall rules are flushed, in case it's set up on the host. [bleuchtang]
  • Restart ferm only when the firewall rules have been modified, to not rest the firewall counters on every Ansible run. [Logan2211, drybjed]

debops.ferm v0.1.4 - 2016-02-07


  • Add a way to copy custom files to remote hosts before starting the firewall. This allows users to add custom scripts that generate firewall rules in case of more esoteric environments. [drybjed]


  • Change the sysctl configuration from a handler to a conditional task. This should make sure debops.ferm works on older operating systems. [drybjed]
  • Move the logic that enables or disables ferm to a default variable to consolidate it in one place. [drybjed]
  • Fix deprecation warnings in Ansible 2.1.0. [drybjed]
  • Change the way debops.ferm disables ferm support to avoid idempotency issues with ansible_managed variable. [drybjed]
  • Change what variable debops.ferm looks for when checking if ferm should be enabled depending on current host capabilities. Now role will check the status in ansible_local.tags variable which is configured by the debops.core role. [drybjed]
  • Do not remove or generate firewall rules when ferm is disabled to improve Ansible performance. [drybjed]

debops.ferm v0.1.3 - 2015-11-13


  • Add set of predefined ferm variables used by other Ansible roles. [drybjed]


  • Redesign hook support. Instead of patching the ferm init script, use internal @hook commands to run scripts in specific directories using run-parts. [drybjed]

debops.ferm v0.1.2 - 2015-11-12


  • Add support for different "weight classes" of rules.

    This should help manage order of firewall rules. Each rule can specify its own weight class along with weight, the class will be checked in the ferm_weight_map dictionary, if a corresponding entry is found, its weight will be used for that rule, if not, the weight specified in the rule will be used instead. [drybjed]

  • Add hashlimit filter, move filtering rules.

    New hashlimit filter allows configuration of firewall rules using hashlimit module.

    Existing firewall rules which filtered ICMP and TCP SYN packets, defined in /etc/ferm/ferm.conf, have been moved to their own configuration files in /etc/ferm/rules/filter/input/ directory. [drybjed]

  • Add accept filter template which can be used to create rules that match interfaces, ports, remote IP addresses/subnets and can accept the packets, reject, or redirect to a different chain. [drybjed]

  • Add a separate &log() ferm function and use it for logging packets in other ferm rules. [drybjed]

  • Add item.interface_present and item.outerface_present parameters to active rule template. These parameters check if specified network interfaces exist before adding the firewall rules. [drybjed]


  • Move firewall rules into rules/ subdirectory.

    All directories in /etc/ferm/ that contain firewall rules in different chains have been moved to /etc/ferm/rules/ subdirectory for more readability.

    This is an incompatible change, check on a test host first to see what will happen.

    This change will recreate all rule directories and all default firewall rules. If you added your own rules in Ansible inventory or other roles, make sure that you re-run these roles to recreate their rules as well. To not create duplicate firewall rules, ferm will only include rules from the new directories. [drybjed]

  • Rename conntrack list, rebalance rule weight.

    This change will create new conntrack rules with different filenames due to changed weight of the rules and addition of "weight classes". Make sure to remove the old rules manually to not create duplicates. [drybjed]

  • Rename ferm variable to ferm_enabled.

    This change is needed to avoid issues with Ansible templating the ferm package in lists with contents of the ferm variable.

    If you have ferm disabled anywhere (set to False), you will need to change the name of the variable in inventory to the new one before running this role. Otherwise there should be no changes necessary. [drybjed]

  • Move the default loopback accept iptables rule to the new directory-based setup. [drybjed]

  • Rename the ferm_filter_domains default variable to ferm_domains to indicate that it is used in all firewall contexts, not just the "filter" table. [drybjed]

  • Redesign the directory structure of ferm configuration.

    Different parts of the firewall configuration will be stored and managed in /etc/ferm/ferm.d/ directory instead of various subdirectories. This makes management of configuration simpler and more flexible to adapt to different environments.

    Existing firewall configuration in /etc/ferm/filter-input.d/ will be included by default, so the already configured firewalls still work. This will change after roles are converted to the new firewall configuration style. [drybjed]

  • Update configuration templates in templates/etc/ferm/ferm.d/ role directory. A few new templates have been added which will generate rules that were defined in /etc/ferm/ferm.conf configuration files. [drybjed]

  • Split /etc/ferm/ferm.conf config into parts.

    Static firewall configuration in /etc/ferm/ferm.conf has been split into separate files in /etc/ferm/ferm.d/ directory. Each firewall rule is generated using templates, defined in default variables, which makes it easier to change or redesign the firewall from scratch.

    Some default variables have been renamed to better indicate their use in the firewall configuration. [drybjed]

  • Switch Ansible Controller accept rules to new configuration structure. [drybjed]

  • Rule definitions can now specify item.role_weight parameter which is added after item.role parameter. This allows to set the same item.weight for all rules of a particular Ansible role and still lets you order rules within the role itself. [drybjed]

  • Change default hashlimit rule target to RETURN, this allows packets to be filtered further in the firewall instead of accepting them right away. [drybjed]

  • Change default recent rule target to NOP, this ensures that if no other target is specified, rule will still be added to the firewall. [drybjed]

  • Convert forward firewall rules to the new ferm configuration. [drybjed]


  • Remove ferm.d/chain.conf.j2 Ansible template as well as other unused templates. Functionality of this template is replaced by ferm.d/accept.conf.j2 template. [drybjed]

debops.ferm v0.1.1 - 2015-10-08


  • Add support for ferm init script hooks.

    ferm supports "hooks" in its configuration which allow to run custom commands, however only three hooks are supported at this time:

    • "pre" - commands are executed before rules are applied,
    • "post" - commands are executed after rules are applied,
    • "flush" - commands are executed after rules are flushed.

    However for certain use cases this is not enough.

    This patch adds support for running custom scripts during different points in the ferm init script:

    • "pre-start" - before ferm service is started,
    • "post-start" - after ferm service is started,
    • "pre-reload" - before ferm service is reloaded,
    • "post-reload" - after ferm service is reloaded,
    • "pre-stop" - before ferm service is stopped,
    • "post-stop" - after ferm service is stopped.

    This should provide sufficient methods to manipulate firewall dynamically outside of ferm itself and allow to correctly preserve ip(6)tables rules when ferm is restarted or reloaded. [drybjed]

  • Add a ferm_default_rules list variable with a set of default firewall rules for all hosts.

    Connection tracking rules from main ferm configuration file are moved to the new directory-based rule structure. They are defined in a separate list variable included in ferm_default_rules. [drybjed]

  • Add support for specifying incoming and outgoing network interfaces in filter/conntrack.conf.j2 template. [drybjed]

  • Add "custom" rule template. [drybjed]


  • Switch debops.ferm from using ferm binary directly to restarting and stopping ferm system service. [drybjed]

  • Due to the huge number of subdirectories in /etc/ferm/ that need to be created, their creation is moved to a separate shell script, which will be run once at the first install of the ferm firewall.

    Script creates new directory structure for firewall rules. [drybjed]

  • Enable support for the new, directory-based iptables rules management system. New item.category and item.table rule arguments allow to specify the source template and destination firewall table where rules should be generated. Rules are defined in existing ferm_*_rules list variables.

    Old rules are still supported to enable easy transition to the new system. [drybjed]

  • Fix missing closing bracket. [drybjed]

  • Copy init-hooks.patch file to remote host and patch it from there to fix issues with patch module on older versions of Ansible. [drybjed]

  • Move tasks that patch ferm init script to separate task list and add a condition that only does the patching if ferm is enabled. [drybjed]

debops.ferm v0.1.0 - 2015-09-04


  • Add Changelog [drybjed]
  • Add rule template for simple DMZ-like redirection from public to private IPv4 addresses. [drybjed]
  • Add rule option to specify custom names in rule filenames. [drybjed]
  • Add support for fail2ban. If fail2ban-server is installed and is currently active, ferm will reload fail2ban rules after firewall configuration is finished. [drybjed]
  • Add a workaround Ansible emitting true and false as boolean values. [drybjed]
  • Add Ansible tags to tasks that manage the firewall rules to make reloading of them faster. [drybjed]


  • Move the ferm package into ferm_packages list and rewrite the task to only use the list variable without Jinja templating. This fixes the "It is unnecessary to use '{{' in loops" error. [drybjed]