Achtung, die deutsche Dokumentation wird nicht weiter gepflegt. Bitte die englische Doku nutzen.
Diese Rolle definiert:
Im Folgenden eine Übersicht, die im OpenWrt Wiki näher erläutert werden.
ansible Variablenname: | OpenWrt Flag Name: | Standardwert: |
---|---|---|
openwrt_firewall_default_synflood_protect |
synflood_protect | 1 |
openwrt_firewall_default_flow_offloading |
flow_offloading | 0 |
openwrt_firewall_default_flow_offloading_hw |
flow_offloading_hw | 0 |
openwrt_firewall_default_forward |
forward | REJECT |
openwrt_firewall_default_input |
input | ACCEPT |
openwrt_firewall_default_output |
output | ACCEPT |
openwrt_firewall_default_drop_invalid |
drop_invalid | - |
openwrt_firewall_default_synflood_rate |
synflood_rate | - |
openwrt_firewall_default_synflood_burst |
synflood_burst | - |
openwrt_firewall_default_tcp_syncookies |
tcp_syncookies | - |
openwrt_firewall_default_tcp_ecn |
tcp_ecn | - |
openwrt_firewall_default_tcp_window_scaling |
tcp_window_scaling | - |
openwrt_firewall_default_accept_redirects |
accept_redirects | - |
openwrt_firewall_default_accept_source_route |
accept_source_route | - |
openwrt_firewall_default_custom_chains |
custom_chains | - |
openwrt_firewall_default_tcp_reject_code |
tcp_reject_code | - |
openwrt_firewall_default_any_reject_code |
any_reject_code | - |
Konvention in dieser Collection ist Zonennamen komplett groß zu schreiben, z.B. WAN. In Ansible Variablennamen gilt diese Konvention nicht.
Zonen sind der Kern der Firewall Logik. Für den Fall, dass entweder
gelten die globalen Regeln für Input, Output und Forward. Dies sollte für einen ordentlichen Betrieb jedoch niemals der Fall sein.
Deswegen müssen Zonen mit Interfaces verbunden werden, so dass für Pakete eine Entscheidung getroffen werden kann, was damit passieren soll.
Mehr über die grundsätzliche Funktionsweise der Firewall in OpenWrt hier.
Die Ansible Collection für OpenWrt installiert in den Standard Einstellungen mehr Zonen als es bei einer Grundinstallation von OpenWrt der Fall ist.
Beschreibung | Standard Zonenname |
Zonenname überschreibbar über Variable |
Default masq |
Default logging |
Logging überschreibbar über Variable |
---|---|---|---|---|---|
Uplink zum Internet | WAN | openwrt_firewall_default_wanzone |
1 | 1 | openwrt_firewall_default_wanzone_logging |
Vernetzung mit Nachbarn | NEIGHBOURS | openwrt_firewall_default_neighbourszone |
0 | 1 | openwrt_firewall_default_wanzone_logging |
Gäste, z.B. für Gäste Wifii | GUESTS | openwrt_firewall_default_guestszone |
0 | 1 | openwrt_firewall_default_guestszone_logging |
lokale Teilnehmer unter eigener Gewalt, tendenziell vertrauenswürdig | LAN | openwrt_firewall_default_lanzone |
0 | 1 | openwrt_firewall_default_lanzone_logging |
Services / Server | DMZ | openwrt_firewall_default_dmzzone |
0 | 1 | openwrt_firewall_default_dmzzone_logging |
Verwaltung, z.B. IPMI oder Switche, Access Points | MGMT | openwrt_firewall_default_mgmtzone |
0 | 1 | openwrt_firewall_default_mgmtzone_logging |
Diese vordefinierten Zonen kommen mit einem Standard Regelwerk. Eine Zuordnung zu einem Interface fehlt. Diese muss nur für Zonen vorgenommen werden, die man tatsächlich nutzen möchte. Zonen die keinem Interface zugewiesen sind finden keine Anwendungim im Firewallbetrieb.
Auf Ansible ebene existieren diese Möglichkeiten Zonen zu definieren oder zu deaktivieren.
Die Standardzonen sind in der Ansible Rolle als Defaults definiert in Form von dict Variablen, Beispiel:
openwrt_firewall_zonesdefault:
WAN:
forward: "REJECT"
input: "REJECT"
output: "ACCEPT"
log: "1"
masq: "1"
mtu_fix: "1"
Möchte man ein dict Attribute hinzufügen (interfaces) oder ein Attribute ändern (forward) für einen Host, so muss man diese dict Variable referenzieren und setzen. Mit dieser Methode überschreibt oder ergänzt man die Defaultwerte der Collection. Beispiel:
openwrt_firewall_zonesdefault:
WAN:
interfaces:
- "wan"
- "wan6"
forward: "ACCEPT"
Damit diese Definitionen übernommen werden können, muss die ansible.cfg diesen Parameter beinhalten:hash_behaviour=merge
hash_behaviour=merge ist deprecated. Statt dessen muss man über einen Task in das Playbook zum Ausführen der Firewall Rolle integrieren:
---
- hosts: platforms_openwrt
pre_tasks:
- name: combine default zones with manual settings
set_fact:
openwrt_firewall_zonesdefault: "{{ openwrt_firewall_zonesdefault | combine(openwrt_firewall_zones_forelle, recursive=true) }}"
when: openwrt_firewall_zones_forelle is defined
become: true
roles:
- imp1sh.ansible_openwrt.ansible_openwrtfirewall
Für die Interface Zuordnung werden die logischen Interface Namen aus /etc/network/interfaces verwendet, die in der Ansible collection innerhalb der Rolle ansible_openwrtnetwork über die Variableopenwrt_network_interfaces
definiert werden. Beispiel:
openwrt_network_interfaces:
wan:
device: "eth1"
proto: "dhcp"
wan6:
device: "@wan"
proto: "dhcpv6"
Einzelne Zonen kann man in Ansible deaktivieren, so dass sie erst garnicht im Frontend des OpenWrt Zielsystems erscheinen, Beispiel:
openwrt_network_zonesdefault:
MGMT:
disabled: true
Die Standardzonen bei dieser Ansible OpenWrt Collection sind umfangreich und für manche Umgebungen nicht geeignet. Man kann die Standardzonen global deaktivieren:
openwrt_firewall_setdefaultzones: false
Man darf hierbei nicht vergessen eigene Zonen zu definieren. Die Standard Firewallregeln dieser Collection werden ebenfalls nicht gesetzt, sofern man nicht doch noch Zonen anlegt, die den Namen der Standardzonen tragen. Wichtig scheint hierbei besonders die Zone WAN, da die Collection - ebenso wie OpenWrt seblst - Standardregeln für diese Zone mitbringt.
Nutzt man jedoch ausschließlich eigene Zonen muss man selber für die Firewallregeln sorgen, ansonsten kann man schnell Probleme mit zu restriktiven Firewall bekommen, so dass zum Beispiel sogar DHCP Requests von der Firewall nicht beantwortet werden.
Neben den vordefinierten Firewall Zonen kann man eigene Zonen anlegen. Diese dürfen mit den Standardzonen Namen nicht kollidieren. Man kann sie in Ansible entweder auf Host- oder auf Gruppen Ebene definieren.
Ein Beispiel um auf Host Ebene eine Firewallzone namens PRINTERS zu erstellen, die dem Interface printers zugewiesen wird.
openwrt_firewall_zoneshost:
PRINTERS:
forward: “REJECT”
input: “REJECT”
output: “ACCEPT”
log: “0”
interfaces:
- “printers”
Für Zonen die für mehrere Hosts in einer Gruppe gelten sollen, müssen diese in ./group_vars/allhosts.yml
angelegt werden. Beispiel für alle Hosts in der Gruppe gruppe1. Damit das funktioniert müssen die hosts den entsprechenden Gruppen über das Ansible Inventory zugeordnet sein.
openwrt_firewall_zonesgroup:
gruppe1:
SPEZIAL1:
forward: "ACCEPT"
input: "ACCEPT"
output: "ACCEPT
log: “0”
interfaces:
- "spezial1"
DMZ2:
forward: "ACCEPT"
input: "ACCEPT"
output: "ACCEPT"
log: “0”
GUESTS2:
forward: "REJECT"
input: "REJECT"
output: "ACCEPT"
log: “0”
FRITZ:
forward: "REJECT"
input: "REJECT"
output: "ACCEPT"
log: “1”
masq: 1
mtu_fix: 1
interfaces:
- "fritz1"
- "fritz2"
Forwardings in OpenWrt werden über eine SRC und eine DEST Angabe definiert. Die Teilnehmer aus der Zone SRC dürfen dadurch ungefiltert auf die Teilnehmer der Zone DEST zugreifen.
Forwardings werden durch die Rolle nur dann gesetzt, wenn sowohl die SRC- als auch die DEST-Zone existieren.
Die Rolle Firewall sieht in den Standardeinstllungen nur ein Forwarding vor und das ist von der Zone LAN auf WAN, damit der Internetzugriff gewährleistet ist. Weitere Forwardings müssen angelegt werden.
Diese Forwardings werden in den Host-Variablen definiert und haben somit nur Gültigkeit für eben jene Firewall, Beispiel:
openwrt_firewall_forwardingshost:
- src: “MGMT”
dest: “WAN”
Die Forwardings auf Gruppenebene werden in group_vars/allhosts.yml
definiert. Um sie einer bestimmten Gruppe zuzuordnen, wird der Gruppenname den Regeln übergeordnet, hier gruppe1 und gruppe2:
openwrt_firewall_forwardingsgroup:
gruppe1:
- src: “MEINEZONE1”
dest: “wan”
gruppe2:
- src: “MEINEZONE2”
dest: “WAN”
Regeln dienen dazu Pakete entsprechend zu behandeln mit der Aktion DROP, REJECT oder ACCEPT. Bei der Definition der Regeln kann bei der Angabe der Zone (src oder dest) ein * eingetragen werden, wenn die Regeln für alle Zonen gelten soll. Lässt man dest ganz weg wird daraus eine Input Regel, d.h. sie bezieht sich auf Traffic, der für die Firewall selbst bestimmt ist.
Gesetzt werden Regeln durch die Ansible Rolle nur dann, wenn referenzierte Zonen in einer Regel tatsächlich definiert sind.
Regeln müssen mindestens diese beiden Parameter enthalten:
Andere Parameter sind optional.
Die Ansible Collection kommt mit einer Reihe vordefinierter Regeln. Diese unterscheiden sich etwas von den OpenWrt Standardregeln. Zum Einen werden Forwards für ICMPv6 Pakete offener durchgeleitet entsprechend der RFC4890 Vorgaben. Zum Anderen sind mehr Regeln nötig, da es mehr vordefinierte Zonen gibt.
Die vordefinierten Regeln kann man sich hier ansehen unter der Variable openwrt_firewall_rulesdefault
.
Beispiel für diverse Regeln auf Ansible Hostebene.
openwrt_firewall_ruleshost:
"zabbix1_anywhere":
family: "ipv6"
src: "WAN"
src_ip:
- "{{ hostvars['zabbix1.example.com']['netinterfaces']['ens18']['ip6'] | ipaddr('address') }}"
dest: "*"
proto:
- "tcp"
dest_port: "10050"
target: "ACCEPT"
"admin_accept wan":
family: "ipv6"
src: "WAN"
target: "ACCEPT"
proto:
- "all"
src_ip:
- "2001:1234:4321::/48"
- "2a01:affe::/32"
"SECURE to MGMT ssh":
family: "ipv6"
src: "SECURE"
dest: "MGMT"
target: "ACCEPT"
proto:
- "tcp"
dest_port: "22"
Eine vollständige Erklärung der möglichen Parameter in der OpenWrt Firewall Doku nachsehen.
Um Firewallregeln auf Ansible Gruppenebene zu definieren editiert man die group_vars der Gruppe allhosts. Jedes OpenWrt System in Ansible sollte Mitglied dieser Gruppe sein.
openwrt_firewall_rulesgroup:
openwrtaccesspoints:
"Admin Access":
src: "MGMT"
proto: "all"
target: "ACCEPT"
openwrtrouter:
"LAN to MGMT HTTP Admins":
src: "LAN"
dest: "MGMT"
proto: "tcp"
port: "80"
src_ip:
- "1.2.3.5"
- "2a01:4:6::1"
target: "ACCEPT"
Port Weiterleitungen (SNAT / DNAT) werden über die Ansible Variablen openwrt_firewall_redirectsgroup bzw. openwrt_firewall_redirectshost definiert. Die genaue Funktionsweise wird in der Openwrt Dokumentation für Redirects genauer erklärt.
openwrt_firewall_redirectshost:
"jabber 5222 chathost1":
proto:
- "tcp"
src: "WAN"
dest: "MEINS"
src_dip: "5.123.321.82"
dest_ip: "10.10.102.19"
src_dport: 5222
target: "DNAT"
Bei einer DNAT Regel ist das Attribut src ein Pflichtfeld.
Bei einer SNAT Regel sind die Attribute src_dip sowie dest Pflichtfelder.
Source NAT sollte nicht als Ersatz für IP Masquerading verstanden werden, da die Bearbeitung länger dauert. Statt dessen sollten in der Zonendefinition die Attribute masq und mtu_fix genutzt werden.