bimdata.ferm

Ansible 角色 Ferm

这个角色安装和配置 Ferm。

要求

  • 此角色仅在 Ansible >= 2.9 上经过测试。

角色变量

您可以在Ferm 文档中找到每个选项的更多信息。

用于安装的变量:

变量 默认值 描述
ferm_pkg_name ferm Ferm 的 APT 包名称。
ferm_svc_name ferm 启动/停止守护进程的 Ferm 服务名称。

用于一般配置的变量:

变量 默认值 描述
ferm_main_conf_file /etc/ferm/ferm.conf Ferm 主配置文件路径。
ferm_rules_path /etc/ferm/ferm.d Ferm 规则目录路径。

默认规则将存储在主配置文件中,然后将加载配置目录中定义的所有规则。这使您可以定义其他不由此角色管理的规则(如果将 ferm_delete_unknown_rules 设置为 false)。

用于规则配置的变量:

变量 默认值 描述
ferm_delete_unknown_rulefiles true 删除不由此角色管理的 ferm_rules_path 中的规则。
ferm_default_domains ['ip', 'ip6'] 当规则未指定域时,使用此域。
ferm_default_table filter 当规则未指定表时,使用此表。

用于规则定义的变量:

变量 默认值 描述
ferm_input_policy DROP Ferm 默认输入策略。
ferm_output_policy ACCEPT Ferm 默认输出策略。
ferm_forward_policy DROP Ferm 默认转发策略。
_ferm_rules "{{ lookup('template', 'get_vars.j2', template_vars=dict(vartype='rule')) }}" 定义所有 Ferm 规则的字典列表。
_ferm_vars "{{ lookup('template', 'get_vars.j2', template_vars=dict(vartype='var')) }}" 定义所有 Ferm 变量的字典列表。
_ferm_functions "{{ lookup('template', 'get_vars.j2', template_vars=dict(vartype='function')) }}" 定义所有 Ferm 功能的字典列表。
_ferm_hooks "{{ lookup('template', 'get_vars.j2', template_vars=dict(vartype='hook')) }}" 定义所有 Ferm 钩子的字典列表。

在大多数情况下,您不应该修改以 '_' 开头的变量。 模板用于构建这些包含其他变量的列表。

  • _ferm_rules 会聚合所有符合此正则表达式的变量:^ferm_.+_rule(s)?$
  • _ferm_vars 会聚合所有符合此正则表达式的变量:^ferm_.+_var(s)?$
  • _ferm_functions 会聚合所有符合此正则表达式的变量:^ferm_.+_function(s)?$
  • _ferm_hooks 会聚合所有符合此正则表达式的变量:^ferm_.+_hook(s)?$

每个符合这些正则表达式的变量必须是:

  • 定义一个规则/变量/功能/钩子的字典
  • 定义一个或多个规则/变量/功能/钩子的字典列表。

这样可以让您在多个 group_vars 中定义变量,并为多个组中的主机累加这些变量,而不需要重写完整的列表。

用于定义默认规则集的变量:

  • 这个配置 INPUT 表的默认规则集:
    ferm_default_inputs:
      - "policy {{ ferm_input_policy }};"
      - interface lo ACCEPT;
      - "mod conntrack ctstate (RELATED ESTABLISHED) ACCEPT;"
    
  • 这个配置 OUTPUT 表的默认规则集:
    ferm_default_outputs:
      - "policy {{ ferm_output_policy }};"
      - outerface lo ACCEPT;
      - "mod conntrack ctstate (RELATED ESTABLISHED) ACCEPT;"
    
  • 这个配置 FORWARD 表的默认规则集:
    ferm_default_forwards: []
    

Debian 11 默认使用 iptables-nft,而这不受 Ferm 支持。 自 Debian 11 起,Ferm 忽略替代设置,强制使用 iptables-legacy(https://github.com/MaxKellermann/ferm/issues/47)

变量 默认值 描述
ferm_iptables_path /usr/sbin/iptables-legacy iptables-legacy 的路径。
ferm_ip6tables_path /usr/sbin/ip6tables-legacy ip6tables-legacy 的路径。
ferm_arptables_path /usr/sbin/arptables-legacy arptables-legacy 的路径。
ferm_ebtables_path /usr/sbin/ebtables-legacy ebtables-legacy 的路径。

这些变量仅在版本 > 10 的 Debian 主机上使用。 它将使用 alternative 系统配置操作系统,以设置 ferm_iptables_pathferm_ip6tables_pathferm_arptables_pathferm_ebtables_path 的默认 iptables 命令。

变量定义

一个 ferm 变量可以这样定义:

ferm_webports_var:
  name: web_ports
  content:
    - 80
    - 443

ferm_hosts_vars
  - name: web_front_addr
    content:
      - 172.29.10.100
      - 2a01:baaf::100

钩子定义

一个 ferm 钩子可以这样定义:

ferm_fail2ban_hooks:
  - comment: Fail2ban hooks
    content: post "type fail2ban-server > /dev/null && (fail2ban-client ping > /dev/null && fail2ban-client reload > /dev/null || true) || true";
  - content: flush "type fail2ban-server > /dev/null && (fail2ban-client ping > /dev/null && fail2ban-client reload > /dev/null || true) || true";

规则定义

规则可以以两种方式定义:

ferm_web_rules:
  - name: "web_server"
    content:
      - domains: ['ip']        # 可省略,将使用 ferm_default_domains
        chains: ['INPUT']      # 可省略,将使用 ferm_default_table
        rules:
          - proto tcp dport ($web_ports) mod comment comment "web server" ACCEPT

或者您可以定义原始规则:

ferm_web_rules:
  - name: "web_server"
    raw_content: |
      domain (ip) table filter {
        chain (INPUT) {
          proto tcp dport ($web_ports) mod comment comment "web server" ACCEPT;
        }
      }

功能定义

一个 ferm 功能可以这样定义:

ferm_dnat_function:
  comment: "Easy DNAT (DNAT+filter rules)"
  content: |
    @def &EASY_DNAT($wan_ip, $proto, $port, $dest) = {
      domain ip table nat chain PREROUTING daddr $wan_ip proto $proto dport $port DNAT to @ipfilter($dest);
      domain (ip ip6) table filter chain FORWARD outerface $dmz_iface daddr $dest proto $proto dport $port ACCEPT;
    }

然后,您需要使用原始规则来使用它,类似这样:

ferm_dnat_rules:
  - name: "80-dnat-rules"
    raw_content: |
      # HTTP(S) web_front
      &EASY_DNAT($main_public_ip, tcp, (80 443), $web_front_addr);

Docker 示例

Docker 和其他软件可能希望管理自己的 iptables 规则。这是可能的,但有一些限制。以下是 Docker 的示例:

# 在规则使用之前,不能在 FORWARD 定义任何规则,以保留所有
# Docker 配置的规则
ferm_default_forwards: []

# 保留 docker 规则
ferm_docker_preserve_rules:
  - name: 99-docker-users.ferm
    content:
      - domains: ['ip']
        chains: ['DOCKER-USER']
        rules:
          - "RETURN;"
  - name: 00-docker-preserve.ferm
    content:
      - domains: ['ip']
        chains:
          - DOCKER
          - DOCKER-INGRESS
          - DOCKER-ISOLATION-STAGE-1
          - DOCKER-ISOLATION-STAGE-2
          - FORWARD
        rules:
          - "@preserve;"
      - domains: ['ip']
        table: nat
        chains:
          - DOCKER
          - DOCKER-INGRESS
          - PREROUTING
          - OUTPUT
          - POSTROUTING
        rules:
          - "@preserve;"

@preserveferm 使用的特殊单词。它会使用 iptables-save 保存之前的规则,然后提取保留链中的所有规则并将它们插入到新的规则中。

依赖关系

示例剧本

group_vars/all.yml 中:

ferm_webports_var:
  name: web_ports
  content:
    - 80
    - 443

group_vars/web.yml 中:

ferm_web_rules:
  - name: "web_server"
    content:
      - chains: ['INPUT']
        rules:
          - proto tcp dport ($web_ports) mod comment comment "web server" ACCEPT

group_vars/router.yml 中:

ferm_interface_vars:
  - name: wan_iface
    content: ['eth0']
  - name: dmz_iface
    content: ['eth1']
  - name: lan_iface
    content:
      - eth2
      - eth3

ferm_ips_vars:
  - name: main_public_ip
    content: ['1.2.3.4']
  - name: web_front_addr
    content:
      - 10.0.0.100
      - 2a01:baaf::100

ferm_dnat_function:
  comment: "Easy DNAT (DNAT+filter rules)"
  content: |
    @def &EASY_DNAT($wan_ip, $proto, $port, $dest) = {
      domain ip table nat chain PREROUTING daddr $wan_ip proto $proto dport $port DNAT to @ipfilter($dest);
      domain (ip ip6) table filter chain FORWARD outerface $dmz_iface daddr $dest proto $proto dport $port ACCEPT;
    }

ferm_dnat_rules:
  - name: "80-dnat-rules"
    raw_content: |
      # HTTP(S) web_front
      &EASY_DNAT($main_public_ip, tcp, $web_ports, $web_front_addr);

playbook.yml 中:

- hosts: all
  gather_facts: True
  become: yes
  roles:
    - bimdata.ferm

许可证

BSD

作者信息

BIMData.io

关于项目

This role installs and configures ferm.

安装
ansible-galaxy install bimdata.ferm
许可证
mit
下载
45k
拥有者