This commit is contained in:
2026-03-26 08:57:55 +01:00
parent 2b1ca2d5be
commit bb55664283
19 changed files with 2671 additions and 0 deletions
+166
View File
@@ -0,0 +1,166 @@
#SPDX-License-Identifier: MIT-0
---
# --- Connection ---
# opnsense_firewall defaults to ansible_host from inventory
opnsense_firewall: "{{ ansible_host }}"
opnsense_api_key: "" # set in Ansible Vault
opnsense_api_secret: "" # set in Ansible Vault
opnsense_ssl_verify: true
opnsense_api_port: 443
# --- System settings ---
opnsense_hostname: opnsense
opnsense_domain: homelan
opnsense_timezone: Europe/Vienna
opnsense_dns_servers:
- 1.1.1.1
- 8.8.8.8
# --- Gateways ---
# opnsense_gateways:
# - name: WAN_GW
# interface: wan
# gateway: 192.168.1.1
# ip_protocol: inet
# default_gw: true
opnsense_gateways: []
# --- VLANs ---
# opnsense_vlans:
# - interface: vtnet0
# tag: 10
# description: LAN
opnsense_vlans: []
# --- Network topology ---
# OPNsense interface names as assigned in WebUI (Interfaces → Assignments)
opnsense_lan_interface: lan
opnsense_dmz_interface: opt1
opnsense_guest_interface: opt2
opnsense_iot_interface: opt3
# OPNsense's own IP address — used as DNS target in firewall rules
# Set this to OPNsense's LAN IP (e.g. 192.168.1.1)
opnsense_self_address: ""
# IoT hosts allowed internet access — list of IPs for iot_internet_allowed alias
opnsense_iot_internet_allowed: []
# --- Firewall aliases ---
# opnsense_aliases:
# - name: rfc1918
# type: network
# content:
# - 10.0.0.0/8
# - 172.16.0.0/12
# - 192.168.0.0/16
# description: Private networks
opnsense_aliases: []
# --- Firewall rules ---
# opnsense_rules:
# - description: Allow LAN to internet
# interface: [lan]
# direction: in
# action: pass
# source_net: lan
# destination_net: any
# protocol: any
# enabled: true
opnsense_rules: []
# --- NAT (outbound / masquerade) ---
# opnsense_nat_source_rules:
# - description: Masquerade LAN to WAN
# interface: wan
# source_net: 192.168.0.0/24
# target: interface
# enabled: true
opnsense_nat_source_rules: []
# --- DHCP server ---
opnsense_dhcp_enabled: false
opnsense_dhcp_interfaces: []
opnsense_dhcp_fw_rules: false
# opnsense_dhcp_subnets:
# - subnet: 192.168.1.0/24
# pools:
# - 192.168.1.100 - 192.168.1.200
# gateway: [192.168.1.1]
# dns: [192.168.1.1]
# domain: homelan
# description: LAN
opnsense_dhcp_subnets: []
# opnsense_dhcp_reservations:
# - ip: 192.168.1.10
# mac: "aa:bb:cc:dd:ee:ff"
# hostname: myhost
# subnet: 192.168.1.0/24
# description: My host
opnsense_dhcp_reservations: []
# --- Unbound DNS resolver ---
opnsense_unbound_enabled: true
opnsense_unbound_port: 53
opnsense_unbound_dnssec: true
opnsense_unbound_register_dhcp_leases: false
opnsense_unbound_register_dhcp_static_mappings: false
opnsense_unbound_register_system_records: true
# Host overrides — aliases are sub-properties of each host entry.
# alias.domain defaults to the parent host's domain if not set.
# alias.target is auto-set to hostname.domain of the parent host.
# opnsense_unbound_hosts:
# - hostname: vhost0
# domain: homelan
# records:
# - value: 10.61.0.100 # type defaults to A
# - type: AAAA
# value: "fd30:882:6101:1::1"
# aliases:
# - alias: web
# - alias: api
# - hostname: vhost1
# domain: homelan
# records:
# - value: 10.61.0.110
opnsense_unbound_hosts: []
# Selective forwards — leave empty to resolve everything from root servers
# opnsense_unbound_forwards:
# - domain: homelan
# target: 10.61.0.1
# description: Local domain
# - domain: internal.example.com
# target: 192.168.1.53
# description: Internal DNS
opnsense_unbound_forwards: []
# --- OpenVPN clients ---
opnsense_openvpn_static_keys: []
opnsense_openvpn_clients: []
# --- WireGuard ---
opnsense_wireguard_enabled: true
# opnsense_wireguard_servers:
# - name: wg0
# private_key: "{{ vault_wg_private_key }}"
# port: 51820
# allowed_ips:
# - 10.0.0.1/24
# peers: []
# enabled: true
opnsense_wireguard_servers: []
# opnsense_wireguard_peers:
# - name: client1
# public_key: "CLIENT_PUBLIC_KEY"
# allowed_ips:
# - 10.0.0.2/32
# servers: [wg0]
# keepalive: 25
# enabled: true
opnsense_wireguard_peers: []
+46
View File
@@ -0,0 +1,46 @@
---
- name: Configure DHCP general settings
oxlorg.opnsense.dhcp_general:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
enabled: "{{ opnsense_dhcp_enabled }}"
interfaces: "{{ opnsense_dhcp_interfaces }}"
fw_rules: "{{ opnsense_dhcp_fw_rules }}"
- name: Configure DHCP subnets
oxlorg.opnsense.dhcp_subnet:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [subnet]
subnet: "{{ item.subnet }}"
auto_options: false
pools: "{{ item.pools | default([]) }}"
gateway: "{{ item.gateway | default([]) }}"
dns: "{{ item.dns | default([]) }}"
domain: "{{ item.domain | default('') }}"
domain_search: "{{ item.domain_search | default([]) }}"
ntp_servers: "{{ item.ntp_servers | default([]) }}"
description: "{{ item.description | default(omit) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_dhcp_subnets }}"
- name: Configure DHCP reservations
oxlorg.opnsense.dhcp_reservation:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
ip: "{{ item.ip }}"
mac: "{{ item.mac }}"
subnet: "{{ item.subnet | default(omit) }}"
hostname: "{{ item.hostname | default(omit) }}"
description: "{{ item.description | default(omit) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_dhcp_reservations }}"
+15
View File
@@ -0,0 +1,15 @@
---
- name: Configure firewall aliases
oxlorg.opnsense.alias:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
type: "{{ item.type | default('host') }}"
content: "{{ item.content | default([]) }}"
description: "{{ item.description | default(omit) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_aliases }}"
+251
View File
@@ -0,0 +1,251 @@
---
# Default aliases
- name: Configure default firewall aliases
oxlorg.opnsense.alias:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
type: "{{ item.type }}"
content: "{{ item.content | default([]) }}"
description: "{{ item.description | default(omit) }}"
enabled: "{{ item.enabled | default(true) }}"
state: present
loop:
- name: rfc1918
type: network
content:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
description: Private IPv4 networks
- name: iot_internet_allowed
type: host
content: "{{ opnsense_iot_internet_allowed }}"
description: IoT hosts allowed internet access
# LAN rules
- name: LAN - allow all
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: LAN - allow all
sequence: 100
action: pass
interface: ["{{ opnsense_lan_interface }}"]
direction: in
source_net: "{{ opnsense_lan_interface }}"
destination_net: any
protocol: any
# GUEST rules
- name: GUEST - allow DNS to OPNsense
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: GUEST - allow DNS to OPNsense
sequence: 100
action: pass
interface: ["{{ opnsense_guest_interface }}"]
direction: in
source_net: "{{ opnsense_guest_interface }}"
destination_net: "{{ opnsense_self_address }}"
destination_port: "53"
protocol: TCP/UDP
- name: GUEST - block private networks
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: GUEST - block private networks
sequence: 200
action: block
interface: ["{{ opnsense_guest_interface }}"]
direction: in
source_net: "{{ opnsense_guest_interface }}"
destination_net: rfc1918
- name: GUEST - allow internet
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: GUEST - allow internet
sequence: 300
action: pass
interface: ["{{ opnsense_guest_interface }}"]
direction: in
source_net: "{{ opnsense_guest_interface }}"
destination_net: any
# IoT rules
- name: IoT - allow DNS to OPNsense
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: IoT - allow DNS to OPNsense
sequence: 100
action: pass
interface: ["{{ opnsense_iot_interface }}"]
direction: in
source_net: "{{ opnsense_iot_interface }}"
destination_net: "{{ opnsense_self_address }}"
destination_port: "53"
protocol: TCP/UDP
- name: IoT - block private networks
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: IoT - block private networks
sequence: 200
action: block
interface: ["{{ opnsense_iot_interface }}"]
direction: in
source_net: "{{ opnsense_iot_interface }}"
destination_net: rfc1918
- name: IoT - allow internet for selected hosts
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: IoT - allow internet for selected hosts
sequence: 300
action: pass
interface: ["{{ opnsense_iot_interface }}"]
direction: in
source_net: iot_internet_allowed
destination_net: any
- name: IoT - block all
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: IoT - block all
sequence: 400
action: block
interface: ["{{ opnsense_iot_interface }}"]
direction: in
source_net: any
destination_net: any
# DMZ rules
- name: DMZ - allow DNS to OPNsense
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: DMZ - allow DNS to OPNsense
sequence: 100
action: pass
interface: ["{{ opnsense_dmz_interface }}"]
direction: in
source_net: "{{ opnsense_dmz_interface }}"
destination_net: "{{ opnsense_self_address }}"
destination_port: "53"
protocol: TCP/UDP
- name: DMZ - block LAN access
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: DMZ - block LAN access
sequence: 200
action: block
interface: ["{{ opnsense_dmz_interface }}"]
direction: in
source_net: "{{ opnsense_dmz_interface }}"
destination_net: "{{ opnsense_lan_interface }}"
- name: DMZ - block GUEST access
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: DMZ - block GUEST access
sequence: 210
action: block
interface: ["{{ opnsense_dmz_interface }}"]
direction: in
source_net: "{{ opnsense_dmz_interface }}"
destination_net: "{{ opnsense_guest_interface }}"
- name: DMZ - block IoT access
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: DMZ - block IoT access
sequence: 220
action: block
interface: ["{{ opnsense_dmz_interface }}"]
direction: in
source_net: "{{ opnsense_dmz_interface }}"
destination_net: "{{ opnsense_iot_interface }}"
- name: DMZ - allow internet
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: [description]
description: DMZ - allow internet
sequence: 300
action: pass
interface: ["{{ opnsense_dmz_interface }}"]
direction: in
source_net: "{{ opnsense_dmz_interface }}"
destination_net: any
+27
View File
@@ -0,0 +1,27 @@
---
- name: Configure firewall rules
oxlorg.opnsense.rule:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: "{{ item.match_fields | default(['description']) }}"
description: "{{ item.description }}"
sequence: "{{ item.sequence | default(1) }}"
action: "{{ item.action | default('pass') }}"
quick: "{{ item.quick | default(true) }}"
interface: "{{ item.interface | default(['lan']) }}"
direction: "{{ item.direction | default('in') }}"
ip_protocol: "{{ item.ip_protocol | default('inet') }}"
protocol: "{{ item.protocol | default('any') }}"
source_net: "{{ item.source_net | default('any') }}"
source_port: "{{ item.source_port | default(omit) }}"
source_invert: "{{ item.source_invert | default(false) }}"
destination_net: "{{ item.destination_net | default('any') }}"
destination_port: "{{ item.destination_port | default(omit) }}"
destination_invert: "{{ item.destination_invert | default(false) }}"
log: "{{ item.log | default(true) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_rules }}"
+36
View File
@@ -0,0 +1,36 @@
---
# NOTE: Interface assignment is not available via the OPNsense API and cannot
# be automated with this role. After VLANs are created by this task, you must
# manually assign them in the WebUI under Interfaces → Assignments, then
# configure each interface (IP address, description) under Interfaces → [name].
# This only needs to be done once during initial setup.
- name: Configure VLANs
oxlorg.opnsense.interface_vlan:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
interface: "{{ item.interface }}"
tag: "{{ item.tag }}"
description: "{{ item.description | default(omit) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_vlans }}"
- name: Configure gateways
oxlorg.opnsense.gateway:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
interface: "{{ item.interface }}"
gateway: "{{ item.gateway }}"
ip_protocol: "{{ item.ip_protocol | default('inet') }}"
default_gw: "{{ item.default_gw | default(false) }}"
far_gw: "{{ item.far_gw | default(false) }}"
monitor_disable: "{{ item.monitor_disable | default(false) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_gateways }}"
+66
View File
@@ -0,0 +1,66 @@
#SPDX-License-Identifier: MIT-0
#
# OPNsense role — manages OPNsense via oxlorg.opnsense REST API (no SSH)
# Collection: oxlorg.opnsense, tested with OPNsense 26.1.2
#
# Inventory: opnsense file, ansible_connection=local (API-based, no SSH)
# Playbook: opnsense.yml
#
# DNS: Unbound (independent resolver, selective forwards supported)
# DHCP: Kea (dnsmasq disabled)
# VPN: WireGuard + OpenVPN clients
#
# Known API limitations in OPNsense 26.1.2 — must be set manually in WebUI:
# - System general settings (hostname, timezone, DNS)
# - Interface assignment and IP configuration
# - Outbound NAT mode (set to Hybrid manually)
# - Config backup restore
# - OpenVPN custom options (ncp-disable, tls-cipher, etc.)
# - CA and client certificates (System → Trust)
#
# Firewall design:
# - LAN: full access
# - GUEST: DNS to OPNsense, internet only, isolated from other VLANs
# - IoT: DNS to OPNsense, internet only for hosts in iot_internet_allowed alias
# - DMZ: DNS to OPNsense, internet access, isolated from LAN/GUEST/IoT
#
---
- name: Configure OPNsense system settings
ansible.builtin.import_tasks: system.yml
tags: [opnsense-system]
- name: Configure OPNsense interfaces
ansible.builtin.import_tasks: interfaces.yml
tags: [opnsense-interfaces]
- name: Configure OPNsense default firewall rules
ansible.builtin.import_tasks: firewall-defaults.yml
tags: [opnsense-firewall-defaults, opnsense-firewall]
- name: Configure OPNsense firewall aliases
ansible.builtin.import_tasks: firewall-aliases.yml
tags: [opnsense-aliases, opnsense-firewall]
- name: Configure OPNsense firewall rules
ansible.builtin.import_tasks: firewall-rules.yml
tags: [opnsense-rules, opnsense-firewall]
- name: Configure OPNsense NAT
ansible.builtin.import_tasks: nat.yml
tags: [opnsense-nat, opnsense-firewall]
- name: Configure OPNsense DHCP
ansible.builtin.import_tasks: dhcp.yml
tags: [opnsense-dhcp]
- name: Configure OPNsense Unbound DNS
ansible.builtin.import_tasks: unbound.yml
tags: [opnsense-unbound, opnsense-dns]
- name: Configure OPNsense OpenVPN clients
ansible.builtin.import_tasks: openvpn-clients.yml
tags: [opnsense-openvpn]
- name: Configure OPNsense WireGuard
ansible.builtin.import_tasks: wireguard.yml
tags: [opnsense-wireguard]
+29
View File
@@ -0,0 +1,29 @@
---
# NOTE: Outbound NAT mode (automatic/hybrid/manual) is not available via the
# API. Set it manually once in the WebUI under Firewall → NAT → Outbound → Mode.
# Recommended: Hybrid — allows automatic rules plus the custom rules below.
- name: Configure outbound NAT rules
oxlorg.opnsense.nat_source:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: "{{ item.match_fields | default(['description']) }}"
description: "{{ item.description }}"
sequence: "{{ item.sequence | default(1) }}"
interface: "{{ item.interface }}"
target: "{{ item.target }}"
target_port: "{{ item.target_port | default(omit) }}"
no_nat: "{{ item.no_nat | default(false) }}"
ip_protocol: "{{ item.ip_protocol | default('inet') }}"
protocol: "{{ item.protocol | default('any') }}"
source_net: "{{ item.source_net | default('any') }}"
source_port: "{{ item.source_port | default(omit) }}"
destination_net: "{{ item.destination_net | default('any') }}"
destination_port: "{{ item.destination_port | default(omit) }}"
log: "{{ item.log | default(false) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_nat_source_rules }}"
+64
View File
@@ -0,0 +1,64 @@
---
# OpenVPN client instances and TLS static keys.
#
# Prerequisites — must be done manually in OPNsense WebUI before running:
# - Import CA certificates: System → Trust → Authorities
# - Import client certificates: System → Trust → Certificates
# (includes the private key — decrypt it first if encrypted)
#
# After running — set manually in WebUI per client under
# VPN → OpenVPN → Clients → Edit → Custom options:
# ncp-disable
# tls-version-min 1.2
# tls-cipher <cipher>
# cipher <cipher>
# reneg-bytes <n>
# reneg-pkts <n>
#
# Known limitation: oxlorg.opnsense resolves the tls-crypt key by matching
# the END of the API value string, which has the format:
# "<name> [<mode> (<description>)]"
# Since the name is at the beginning, matching by name alone does not work.
# Workaround: pass the full value string as the key parameter, e.g.:
# key: "MCI-VPN-TLS-CRYPT [crypt (Encrypt and authenticate all control channel packets)]"
- name: Configure OpenVPN static (tls-crypt) keys
oxlorg.opnsense.openvpn_static_key:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
mode: "{{ item.mode | default('crypt') }}"
key: "{{ item.key }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_openvpn_static_keys }}"
no_log: true
- name: Configure OpenVPN clients
oxlorg.opnsense.openvpn_client:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
remote: "{{ item.remote }}"
protocol: "{{ item.protocol | default('udp') }}"
mode: "{{ item.mode | default('tun') }}"
ca: "{{ item.ca | default(omit) }}"
certificate: "{{ item.certificate | default(omit) }}"
key: "{{ item.key | default(omit) }}"
authentication: "{{ item.authentication | default(omit) }}"
verify_remote_certificate: "{{ item.verify_remote_certificate | default(false) }}"
username: "{{ item.username | default(omit) }}"
password: "{{ item.password | default(omit) }}"
keepalive_interval: "{{ item.keepalive_interval | default(omit) }}"
keepalive_timeout: "{{ item.keepalive_timeout | default(omit) }}"
renegotiate_time: "{{ item.renegotiate_time | default(omit) }}"
log_level: "{{ item.log_level | default(3) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_openvpn_clients }}"
no_log: true
+13
View File
@@ -0,0 +1,13 @@
---
# NOTE: OPNsense does not expose general system settings (hostname, domain,
# timezone, DNS) via the API. These must be configured manually via the WebUI
# under System → Settings → General.
- name: Disable dnsmasq (using Unbound for DNS and Kea for DHCP)
oxlorg.opnsense.dnsmasq_general:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
enabled: false
+67
View File
@@ -0,0 +1,67 @@
---
- name: Configure Unbound general settings
oxlorg.opnsense.unbound_general:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
enabled: "{{ opnsense_unbound_enabled }}"
port: "{{ opnsense_unbound_port }}"
dnssec: "{{ opnsense_unbound_dnssec }}"
register_dhcp_leases: "{{ opnsense_unbound_register_dhcp_leases }}"
register_dhcp_static_mappings: "{{ opnsense_unbound_register_dhcp_static_mappings }}"
register_system_records: "{{ opnsense_unbound_register_system_records }}"
- name: Configure Unbound host overrides
oxlorg.opnsense.unbound_host:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: "{{ item[1].match_fields | default(['hostname', 'domain', 'record_type']) }}"
hostname: "{{ item[0].hostname }}"
domain: "{{ item[0].domain }}"
record_type: "{{ item[1].type | default('A') }}"
value: "{{ item[1].value }}"
description: "{{ item[0].description | default(omit) }}"
enabled: "{{ item[0].enabled | default(true) }}"
state: "{{ item[1].state | default('present') }}"
loop: "{{ opnsense_unbound_hosts | subelements('records') }}"
- name: Configure Unbound host override aliases
oxlorg.opnsense.unbound_host_alias:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
match_fields: "{{ item[1].match_fields | default(['alias', 'domain']) }}"
alias: "{{ item[1].alias | default(item[0].hostname) }}"
domain: "{{ item[1].domain | default(item[0].domain) }}"
target: "{{ item[0].hostname }}.{{ item[0].domain }}"
description: "{{ item[1].description | default(omit) }}"
state: "{{ item[1].state | default('present') }}"
loop: "{{ opnsense_unbound_hosts | subelements('aliases', skip_missing=True) }}"
tags: debug01
- debug:
msg: "{{ opnsense_unbound_hosts | subelements('aliases', skip_missing=True) }}"
tags: debug02
- name: Configure Unbound selective forwards
oxlorg.opnsense.unbound_forward:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
domain: "{{ item.domain }}"
target: "{{ item.target }}"
port: "{{ item.port | default(53) }}"
forward_tcp: "{{ item.forward_tcp | default(false) }}"
description: "{{ item.description | default(omit) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_unbound_forwards }}"
+47
View File
@@ -0,0 +1,47 @@
---
- name: Enable WireGuard
oxlorg.opnsense.wireguard_general:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
enabled: "{{ opnsense_wireguard_enabled }}"
- name: Configure WireGuard servers
oxlorg.opnsense.wireguard_server:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
private_key: "{{ item.private_key }}"
port: "{{ item.port | default(51820) }}"
allowed_ips: "{{ item.allowed_ips }}"
mtu: "{{ item.mtu | default(1420) }}"
dns_servers: "{{ item.dns_servers | default([]) }}"
disable_routes: "{{ item.disable_routes | default(false) }}"
peers: "{{ item.peers | default([]) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_wireguard_servers }}"
- name: Configure WireGuard peers
oxlorg.opnsense.wireguard_peer:
firewall: "{{ opnsense_firewall }}"
api_key: "{{ opnsense_api_key }}"
api_secret: "{{ opnsense_api_secret }}"
ssl_verify: "{{ opnsense_ssl_verify }}"
api_port: "{{ opnsense_api_port }}"
name: "{{ item.name }}"
public_key: "{{ item.public_key }}"
psk: "{{ item.psk | default(omit) }}"
allowed_ips: "{{ item.allowed_ips }}"
server: "{{ item.server | default(omit) }}"
port: "{{ item.port | default(omit) }}"
keepalive: "{{ item.keepalive | default(omit) }}"
servers: "{{ item.servers | default([]) }}"
enabled: "{{ item.enabled | default(true) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ opnsense_wireguard_peers }}"