Ansbile ist aktuell das Tool um Netzwerkequipment automatisch konfigurieren zu lassen. Im aktuellen Beispiel wird eine pfSense mittels Playbooks konfiguriert.
Derzeit ist es nicht möglich, virtuelle IPs über Ansible einrichten zu lassen. Clusterkonfigurationen müssen derzeit weiter per Hand eingerichtet werden.
Vorbereitung
Es muss das Modul “pfsensible.core” installiert werden. Ansible muss ebenfalls installiert sein, siehe hier.
Auf der pfSense muss sudo installiert sein.
1
ansible-galaxy collection install pfsensible.core
Es wird folgende Ordnerstruktur angelegt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pfsense/
├── ansible.cfg
├── group_vars
│ └── all.yml
├── hosts
├── pb_pfsense_add_aliases.yml
├── pb_pfsense_add_if_pwf01.yml
├── pb_pfsense_add_if_pwf02.yml
├── pb_pfsense_add_if.yml
├── pb_pfsense_add_lab_net.yml
├── pb_pfsense_add_nat.yml
├── pb_pfsense_add_rules.yml
├── pb_pfsense_add_vlans.yml
├── pb_pfsense_del_aliases.yml
├── pb_pfsense_del_if_pwf01.yml
├── pb_pfsense_del_if_pwf02.yml
├── pb_pfsense_del_if.yml
├── pb_pfsense_del_lab_net.yml
├── pb_pfsense_del_nat.yml
├── pb_pfsense_del_rules.yml
└── pb_pfsense_del_vlans.yml
Ziel
Das Ziel ist es, zwei Netze einzurichten, die per VLAN-Tagging an das interne “LAN-Interface” der Firewall angebunden ist. Diese sollen per NAT auf die WAN-IP übersetzt werden, es soll als Start nur Surfen erlaubt sein.
Konfiguration und Inventory
Die Konfiguration von Ansbile sieht wie folgt aus:
1
2
3
4
5
6
7
8
9
10
[defaults]
inventory=hosts
retry_files_enabled=False
gathering=explicit
host_key_checking=False
action_warnings=False
deprecation_warnings=False
ansible_command_timeout=600
command_timeout=600
ask_pass=True
Das Inventory sieht folgendermaßen aus:
1
2
3
4
5
[dmzfirewall]
pf01 ansible_host=10.10.10.50
[dmzfirewall:vars]
ansible_python_interpreter=auto
Der Interpreter muss auf “auto” gesetzt werden, andernfalls bricht Ansible mit Fehlern ab, sobald mehr als ein Objekt eingerichtet wird.
Playbooks
Folgende Playbooks werden erstellt, um Netze anzulegen.
pb_pfsense_add_vlans.yml
Im ersten Schritt werden VLANs angelegt.
Wichtig: die Items müssen im Modul mit doppelten, geschweiften Klammern ({}) geschrieben werden. Dies gilt für alle Playbooks dieses Artikels.
Leider zeigt Jekyll die Notation nicht richtig an.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
---
- name: create vlans
hosts: dmzfirewall
remote_user: admin
become: yes
become_method: sudo
become_user: root
tasks:
- name: create vlans
pfsensible.core.pfsense_vlan:
interface: "{ item.if }"
vlan_id: "{ item.vid }"
descr: "{ item.descr }"
state: present
loop:
- { if: 'em2', vid: '555', descr: 'LAB_Test55' }
- { if: 'em2', vid: '556', descr: 'LAB_Test56' }
pb_pfsense_add_if.yml
Jetzt werden Interfaces konfiguriert.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
---
- name: create interface pwf01
hosts: pf01
remote_user: admin
become: yes
become_method: sudo
become_user: root
tasks:
- name: create interface on pwf01
pfsensible.core.pfsense_interface:
interface: "{ item.if }"
ipv4_address: "{ item.ipv4 }"
ipv4_prefixlen: "{ item.prefixv4 }"
ipv4_type: static
descr: "{ item.descr }"
state: present
enable: true
loop:
- { if: 'em2.555', ipv4: '172.17.55.1', prefixv4: '24', descr: '17_LAB_Test55' }
- { if: 'em2.556', ipv4: '172.17.56.1', prefixv4: '24', descr: '17_LAB_Test56' }
pb_pfsense_add_aliases.yml
Es werden Aliases angelegt, was das Regelwerk leichter lesbar macht.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
- name: create aliases
hosts: dmzfirewall
remote_user: admin
become: yes
become_method: sudo
become_user: root
tasks:
- name: create host alias(es)
pfsensible.core.pfsense_alias:
name: "{ item.name }"
address: "{ item.address }"
descr: "{ item.descr }"
type: "{ item.type }"
state: present
loop:
- { name: 'VIP_lab_Test55', address: '172.17.55.1', descr: 'GW IP LAB Test55', type: 'host' }
- { name: 'VIP_lab_Test56', address: '172.17.56.1', descr: 'GW IP LAB Test56', type: 'host' }
- { name: 'NET_lab_test55', address: '172.17.55.0/24', descr: 'Netz LAB Test55', type: 'network' }
- { name: 'NET_lab_test56', address: '172.17.56.0/24', descr: 'Netz LAB Test56', type: 'network' }
pb_pfsense_add_nat.yml
Die Netze werden auf die WAN IP genat’ed. Wichtig: die Outbound NAT muss auf manuell gesetzt sein.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
- name: create nat
hosts: dmzfirewall
remote_user: admin
become: yes
become_method: sudo
become_user: root
tasks:
- name: create outbound nat
pfsensible.core.pfsense_nat_outbound:
descr: "{ item.descr }"
interface: "{ item.if }"
address: "{ item.addr }"
source: "{ item.source }"
destination: any
protocol: any
before: bottom
state: present
loop:
- { descr: 'NAT_LAB_Test55', if: 'wan', addr: '10.10.10.10', source: '172.17.55.0/24' }
- { descr: 'NAT_LAB_Test56', if: 'wan', addr: '10.10.10.10', source: '172.17.56.0/24' }
pb_pfsense_add_rules.yml
Jetzt wird das Regelwerk erstellt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
---
- name: create std rule and separators
hosts: dmzfirewall
remote_user: admin
become: yes
become_method: sudo
become_user: root
tasks:
- name: create icmp rule
pfsensible.core.pfsense_rule:
action: pass
interface: "{ item.if }"
ipprotocol: inet
protocol: icmp
icmptype: echorep, echoreq
source: "{ item.source }"
destination: any
name: permit_ping
state: present
with_items:
- { if: '17_LAB_TEST55', source: 'NET_lab_test55' }
- { if: '17_LAB_TEST56', source: 'NET_lab_test56' }
- name: create standard rules
pfsensible.core.pfsense_rule:
action: "{ item.action }"
interface: "{ item.if }"
ipprotocol: "{ item.ipproto }"
protocol: "{ item.protocol }"
source: "{ item.source }"
destination: "{ item.destination }"
destination_port: "{ item.dport }"
name: "{ item.name }"
state: present
loop:
- { action: 'pass', if: '17_LAB_TEST55', ipproto: 'inet', protocol: 'tcp/udp', source: 'NET_lab_test55', destination: 'VIP_lab_Test55', dport: '53', name: 'permit_dns' }
- { action: 'pass', if: '17_LAB_TEST55', ipproto: 'inet', protocol: 'tcp/udp', source: 'NET_lab_test55', destination: 'grp_DNS_Server', dport: '53', name: 'permit_dns_grp' }
- { action: 'pass', if: '17_LAB_TEST55', ipproto: 'inet', protocol: 'udp', source: 'NET_lab_test55', destination: 'VIP_lab_Test55', dport: '123', name: 'permit_ntp' }
- { action: 'pass', if: '17_LAB_TEST55', ipproto: 'inet', protocol: 'udp', source: 'NET_lab_test55', destination: 'grp_NTP_Server', dport: '123', name: 'permit_ntp_grp' }
- { action: 'pass', if: '17_LAB_TEST55', ipproto: 'inet', protocol: 'tcp', source: 'NET_lab_test55', destination: 'any', dport: 'srv_web_tcp', name: 'permit_http_s' }
- { action: 'pass', if: '17_LAB_TEST56', ipproto: 'inet', protocol: 'tcp/udp', source: 'NET_lab_test56', destination: 'VIP_lab_Test56', dport: '53', name: 'permit_dns' }
- { action: 'pass', if: '17_LAB_TEST56', ipproto: 'inet', protocol: 'tcp/udp', source: 'NET_lab_test56', destination: 'grp_DNS_Server', dport: '53', name: 'permit_dns_grp' }
- { action: 'pass', if: '17_LAB_TEST56', ipproto: 'inet', protocol: 'udp', source: 'NET_lab_test56', destination: 'VIP_lab_Test56', dport: '123', name: 'permit_ntp' }
- { action: 'pass', if: '17_LAB_TEST56', ipproto: 'inet', protocol: 'udp', source: 'NET_lab_test56', destination: 'grp_NTP_Server', dport: '123', name: 'permit_ntp_grp' }
- { action: 'pass', if: '17_LAB_TEST56', ipproto: 'inet', protocol: 'tcp', source: 'NET_lab_test56', destination: 'any', dport: 'srv_web_tcp', name: 'permit_http_s' }
- name: create separator general
pfsensible.core.pfsense_rule_separator:
name: General Rules
color: warning
interface: "{ item.if }"
after: top
state: present
with_items:
- { if: '17_LAB_TEST55' }
- { if: '17_LAB_TEST56' }
- name: create separator network
pfsensible.core.pfsense_rule_separator:
name: Network Rules
color: info
interface: "{ item.if }"
after: permit_ping
state: present
with_items:
- { if: '17_LAB_TEST55' }
- { if: '17_LAB_TEST56' }
pb_pfsense_add_lab_net.yml
Alle Playbooks werden zusammengefasst.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- name: setting vlans
import_playbook: pb_pfsense_add_vlans.yml
- name: setting ips
import_playbook: pb_pfsense_add_if.yml
- name: setting alias
import_playbook: pb_pfsense_add_aliases.yml
- name: setting nat
import_playbook: pb_pfsense_add_nat.yml
- name: setting rules
import_playbook: pb_pfsense_add_rules.yml
Damit wurde pfSense mittels Ansible konfiguriert.
Leider gibt es derzeit kein Modul um den DHCP-Server zu aktivieren.
Lediglich statische DHCP-Mappings können per Ansbile eingerichtet werden.