From bb55664283ec2686c99c0606bd0bb7b5055463ae Mon Sep 17 00:00:00 2001 From: Matzman Date: Thu, 26 Mar 2026 08:57:55 +0100 Subject: [PATCH] . --- host_vars/opnsense.homelan | 59 + majanetschek-vpn.mci.edu.ovpn | 119 ++ opnsense | 5 + opnsense.yml | 209 +++ roles/opnsense/defaults/main.yml | 166 +++ roles/opnsense/tasks/dhcp.yml | 46 + roles/opnsense/tasks/firewall-aliases.yml | 15 + roles/opnsense/tasks/firewall-defaults.yml | 251 ++++ roles/opnsense/tasks/firewall-rules.yml | 27 + roles/opnsense/tasks/interfaces.yml | 36 + roles/opnsense/tasks/main.yml | 66 + roles/opnsense/tasks/nat.yml | 29 + roles/opnsense/tasks/openvpn-clients.yml | 64 + roles/opnsense/tasks/system.yml | 13 + roles/opnsense/tasks/unbound.yml | 67 + roles/opnsense/tasks/wireguard.yml | 47 + test02.yml | 12 + testing02 | 5 + tmp | 1435 ++++++++++++++++++++ 19 files changed, 2671 insertions(+) create mode 100644 host_vars/opnsense.homelan create mode 100644 majanetschek-vpn.mci.edu.ovpn create mode 100644 opnsense create mode 100644 opnsense.yml create mode 100644 roles/opnsense/defaults/main.yml create mode 100644 roles/opnsense/tasks/dhcp.yml create mode 100644 roles/opnsense/tasks/firewall-aliases.yml create mode 100644 roles/opnsense/tasks/firewall-defaults.yml create mode 100644 roles/opnsense/tasks/firewall-rules.yml create mode 100644 roles/opnsense/tasks/interfaces.yml create mode 100644 roles/opnsense/tasks/main.yml create mode 100644 roles/opnsense/tasks/nat.yml create mode 100644 roles/opnsense/tasks/openvpn-clients.yml create mode 100644 roles/opnsense/tasks/system.yml create mode 100644 roles/opnsense/tasks/unbound.yml create mode 100644 roles/opnsense/tasks/wireguard.yml create mode 100644 test02.yml create mode 100644 testing02 create mode 100644 tmp diff --git a/host_vars/opnsense.homelan b/host_vars/opnsense.homelan new file mode 100644 index 0000000..1ed9c2a --- /dev/null +++ b/host_vars/opnsense.homelan @@ -0,0 +1,59 @@ +--- +opnsense_api_key: "uTaG84sB3dhZtBgTxXV3oXh0aD5dhsR8xxfRYjP6SeAhmYM055dvo89BlfrpLTE01Rwwm7FVZLwZiTiS" +opnsense_api_secret: "nrFEVYPBBcuan53v+BBOwUWaBGMEt03+mbU2SZq0q0K90CX2w1h18fsFBiLCNa91yEFQZUSyuWPlx4Yp" +opnsense_ssl_verify: false + +opnsense_openvpn_static_keys: + - name: MCI-VPN-TLS-CRYPT + mode: crypt + key: | + -----BEGIN OpenVPN Static key V1----- + a68d0dba3e2efe7e83c3887cc7fcb759 + c86a6b4984ea7ffa230dafe1fb4e9ca7 + 66f3667fe75fd8d368b9a0aae7024603 + f88cf00baf1eab326b222b4321e9cddd + 8b287265c3ee2d0053193dea1dbdda75 + e869c7d7d580c0b42421bb5a1af22f80 + 4d058aebc2cf1d8c83cc88948807fbf9 + 3bfc122cab4a650f258f7a57716daa95 + da3898acfd80481b9d81e9b3d07aeea0 + 11b6c6508324ef89c6812028c345f274 + f6a51c669c49295e07e8385435f713c0 + 5eaa46b3ccb69888a5b477df79675d66 + 365c4ce5f7684984980731d5eacd0a1a + 77a9449533076c098cde36c45e54342e + 27a920724f64eddeb16dcef134adb4b9 + e0bcaa4ade9ebf2c45d679bd016f7f2e + -----END OpenVPN Static key V1----- + +opnsense_openvpn_clients: + - name: MCI-VPN + enabled: false + remote: + - vpn.mci.edu:1194 + - 193.171.232.106:1194 + - 193.171.232.107:1194 + - "[2001:628:2260:850::106]:1194" + - "[2001:628:2260:850::107]:1194" + protocol: udp + mode: tap + ca: MCI-VPN-CA # import CA cert in WebUI first: System → Trust → Authorities + certificate: majanetschek # import client cert+key in WebUI first: System → Trust → Certificates + key: "MCI-VPN-TLS-CRYPT [crypt (Encrypt and authenticate all control channel packets)]" # workaround: oxlorg.opnsense uses endswith() matching + authentication: SHA384 + verify_remote_certificate: true + username: "majanetschek" + password: "1234" + keepalive_interval: "20" + keepalive_timeout: "60" + renegotiate_time: "3600" + log_level: 1 + # NOTE: The following options must be set manually in OPNsense WebUI + # under VPN → OpenVPN → Clients → Edit → Custom options: + # ncp-disable + # tls-version-min 1.2 + # tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 + # cipher AES-256-GCM + # remote-cert-ku e0 + # reneg-bytes 104857600 + # reneg-pkts 100000 diff --git a/majanetschek-vpn.mci.edu.ovpn b/majanetschek-vpn.mci.edu.ovpn new file mode 100644 index 0000000..364cc13 --- /dev/null +++ b/majanetschek-vpn.mci.edu.ovpn @@ -0,0 +1,119 @@ +#openvpn für majanetschek +tls-client +remote-cert-tls server +allow-recursive-routing +ifconfig-nowarn +ncp-disable +dev tap +proto udp +auth-user-pass +client + +cipher AES-256-GCM +auth SHA384 + +verb 1 + +keepalive 20 60 + +reneg-bytes 104857600 +reneg-pkts 100000 +reneg-sec 3600 + + +persist-key + +tls-version-min 1.2 +tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 + +remote-cert-ku e0 + + +-----BEGIN CERTIFICATE----- +MIIC6zCCAkygAwIBAgIULeThdNwAHGD0XQggppFxVDgd+3QwCgYIKoZIzj0EAwMw +RjEoMCYGA1UECgwfTUNJIE1hbmFnZW1lbnQgQ2VudGVyIElubnNicnVjazEaMBgG +A1UEAwwRTUNJIFZQTiBSb290IENBIDEwHhcNMjAwOTAyMDgyODQxWhcNMzAwODMx +MDgyODQxWjBGMSgwJgYDVQQKDB9NQ0kgTWFuYWdlbWVudCBDZW50ZXIgSW5uc2Jy +dWNrMRowGAYDVQQDDBFNQ0kgVlBOIFJvb3QgQ0EgMTCBmzAQBgcqhkjOPQIBBgUr +gQQAIwOBhgAEALqR4Lihw47A96tXIO9x/emm0bVyeWg1nrzsKHrsFM/bxmNkGlp+ +x+yxkcWLkHdHFKqwxu9EZjNQZY14BYnSRjE6AdnPTemChMZuD/QVWhj1QIXtSB32 +TaE+hdGPcNuysAWSGCeMCk/ZKPa6Uyf9f+lqNReQBGpb/385Zlt+PVlElit9o4HU +MIHRMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW +BBRIxhLvChAQ19yDSwlXtgV5O831JTAsBgNVHREEJTAjgQt2cG5AbWNpLmVkdYYU +aHR0cHM6Ly92cG4ubWNpLmVkdS8wXgYDVR0eAQH/BFQwUqBQMC6kLDAqMSgwJgYD +VQQKDB9NQ0kgTWFuYWdlbWVudCBDZW50ZXIgSW5uc2JydWNrMA6CDHZwbjEubWNp +LmVkdTAOggx2cG4yLm1jaS5lZHUwCgYIKoZIzj0EAwMDgYwAMIGIAkIBmFMTiKaf +gVzp8lKs9uQ/pq8ms2JUCjt2QcBuK0QyUG2fMvC1bBge+j7HYYSVsxx7fm+Lr0/y +3ZToJaNJryMSdGUCQgFcHuzWXQM95c1ZSM/horpQvdrOxx9JQXn1BibZe3o1RWIa +xypwPnGHV/KnikIzrHUCcFVB2/jqXPCeZNSvKCTDPQ== +-----END CERTIFICATE----- + + +-----BEGIN CERTIFICATE----- +MIICnTCCAf+gAwIBAgIUJ6zCEdrglrqL/8qnj5gaqQTF15EwCgYIKoZIzj0EAwMw +RjEoMCYGA1UECgwfTUNJIE1hbmFnZW1lbnQgQ2VudGVyIElubnNicnVjazEaMBgG +A1UEAwwRTUNJIFZQTiBSb290IENBIDEwHhcNMjAwOTA0MTAxNzA0WhcNMzAwOTAy +MTAxNzA0WjBaMSgwJgYDVQQKDB9NQ0kgTWFuYWdlbWVudCBDZW50ZXIgSW5uc2Jy +dWNrMRcwFQYDVQQLDA5NQ0kgVlBOIENsaWVudDEVMBMGA1UEAwwMbWFqYW5ldHNj +aGVrMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE9WwWxvk44Lh07ivf2kEnM7HJ2daC +fjK/v9xBBIRA4nEJrv8nU//2Cw+EXDO6Ewrua4rOnZ2qosV0wJKhbpfnk5XYbquK +ACePOXnZ4teFnEf1ToJhBbOzuDHKH0FDqpZlo4GZMIGWMB8GA1UdIwQYMBaAFEjG +Eu8KEBDX3INLCVe2BXk7zfUlMCwGA1UdEgQlMCOBC3ZwbkBtY2kuZWR1hhRodHRw +czovL3Zwbi5tY2kuZWR1LzAOBgNVHQ8BAf8EBAMCBeAwFgYDVR0lAQH/BAwwCgYI +KwYBBQUHAwIwHQYDVR0OBBYEFBth2m1Rp0i8qlHhciG8cLSmSZqYMAoGCCqGSM49 +BAMDA4GLADCBhwJCASGvkGCOVQ1HfYMVwrBJYLqV/XTqwIW+bFPvaRFLjjSBB7V7 +Q32ziQNmRzS6Yh8KVdYEtibrHfw2zalAra6OZyi3AkEIcCj2iizYDuNFyf47B3tP +bmWDWlXMdoVjRewDpcPDyy8BqlcHny9WOLcPwl1YqFeHzVgamglTDDMawBi5QgDU +4g== +-----END CERTIFICATE----- + + +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,A1D526070600C0577D6F6683D9E530A6 + +2DPAkQov+AMjUNw6FFC2QOSrGjJqXeZ4IC0xzkWwPbP/z8GyVBZhUJbKTxnwOVoo +TJWJ7BRoujRFKiV+RS42zl5UKH23BwouLZOVgZU6BXLuW6kPJy+ocHE2pDM+k3rT +quGrfZFmGMMFB+va9g2dI6ZY1FPxnCdYu6qsRmeubDbIZlAQ3+e/mB//IxxWSoCd +ULSYsFCTcB5AQTF1sQTjIu3wzM7pAVFwqPKynTjiChc= +-----END EC PRIVATE KEY----- + + +# +# 2048 bit OpenVPN static key +# +-----BEGIN OpenVPN Static key V1----- +a68d0dba3e2efe7e83c3887cc7fcb759 +c86a6b4984ea7ffa230dafe1fb4e9ca7 +66f3667fe75fd8d368b9a0aae7024603 +f88cf00baf1eab326b222b4321e9cddd +8b287265c3ee2d0053193dea1dbdda75 +e869c7d7d580c0b42421bb5a1af22f80 +4d058aebc2cf1d8c83cc88948807fbf9 +3bfc122cab4a650f258f7a57716daa95 +da3898acfd80481b9d81e9b3d07aeea0 +11b6c6508324ef89c6812028c345f274 +f6a51c669c49295e07e8385435f713c0 +5eaa46b3ccb69888a5b477df79675d66 +365c4ce5f7684984980731d5eacd0a1a +77a9449533076c098cde36c45e54342e +27a920724f64eddeb16dcef134adb4b9 +e0bcaa4ade9ebf2c45d679bd016f7f2e +-----END OpenVPN Static key V1----- + + + + remote vpn.mci.edu 1194 udp + + + remote 193.171.232.106 1194 udp + + + remote 193.171.232.107 1194 udp + + + remote 2001:628:2260:850::106 1194 udp + + + remote 2001:628:2260:850::107 1194 udp + diff --git a/opnsense b/opnsense new file mode 100644 index 0000000..d78004a --- /dev/null +++ b/opnsense @@ -0,0 +1,5 @@ + +localhost ansible_connection=local ansible_python_interpreter="{{ansible_playbook_python}}" host_ip_addr="10.61.1.20" host_base_domain="localhost" + +[opnsense] +opnsense.homelan ansible_host=10.61.0.240 ansible_connection=local diff --git a/opnsense.yml b/opnsense.yml new file mode 100644 index 0000000..f970515 --- /dev/null +++ b/opnsense.yml @@ -0,0 +1,209 @@ +--- +- hosts: opnsense + gather_facts: false + roles: + - role: opnsense + vars: + opnsense_dhcp_interfaces: + - lan + - opt2 + - opt3 + + opnsense_self_address: 10.61.0.240 # OPNsense LAN IP + opnsense_lan_interface: lan + opnsense_dmz_interface: opt1 + opnsense_guest_interface: opt2 + opnsense_iot_interface: opt3 + + opnsense_iot_internet_allowed: + - 192.168.20.10 # smart TV + - 192.168.20.11 # printer + + # --- VLANs --- + opnsense_vlans: + - interface: vtnet0 + tag: 1 + description: LAN + - interface: vtnet0 + tag: 10 + description: DMZ + - interface: vtnet0 + tag: 11 + description: GUEST + - interface: vtnet0 + tag: 20 + description: IoT + + # --- Unbound --- + opnsense_unbound_hosts: + - hostname: airq-livingroom + domain: homelan + description: AirQ Luftsensor + records: + - value: 10.63.1.177 + aliases: + - alias: api + - domain: homelan.matzman.net + + - hostname: ha + domain: homelan + description: Home Assistant + records: + - value: 10.61.1.75 + - type: AAAA + value: "fd30:882:6101:1::75" + aliases: + - domain: homelan.matzman.net + - alias: mqtt + - alias: mqtt + domain: homelan.matzman.net + + - hostname: ha + domain: iot.homelan + description: Home Assistant IoT VLAN + records: + - value: 10.63.1.75 + - type: AAAA + value: "fd30:882:6120:1::75" + aliases: + - domain: iot.homelan.matzman.net + - alias: mqtt + - alias: mqtt + domain: iot.homelan.matzman.net + + - hostname: helios4 + domain: iot.homelan + description: Home Assistant IoT VLAN + records: + - value: 10.61.1.190 + - type: AAAA + value: "fd30:882:6101:1::190" + aliases: + - domain: iot.homelan.matzman.net + - alias: mqtt + - alias: mqtt + domain: iot.homelan.matzman.net + + - hostname: octopi + domain: homelan + description: OctoPi Raspi + records: + - value: 10.63.1.70 + - type: AAAA + value: "fd30:882:6120:1::70" + aliases: + - alias: octoprint + + - hostname: opnsense + domain: homelan + description: OPNsense Router + records: + - value: 10.61.0.250 + - type: AAAA + value: "fd30:0882:6101::250" + aliases: + - alias: pfsense + - alias: ntp + + - hostname: opnsense + domain: iot.homelan + description: OPNsense Router IoT VLAN + records: + - value: 10.63.0.250 + - type: AAAA + value: "fd30:0882:6120::250" + aliases: + - alias: pfsense + - alias: ntp + + - hostname: prusa-core-one + domain: homelan + description: Prusa Core One 3D-Printer + records: + - value: 10.63.1.84 + + - hostname: vhost0 + domain: homelan + description: vhost0 Server + records: + - value: 10.61.0.100 + - type: AAAA + value: "fd30:0882:6101::100" + aliases: + - alias: vhost0 + domain: homelan.matzman.net + - alias: nas3 + + - hostname: vhost1 + domain: homelan + description: vhost1 Server + records: + - value: 10.61.0.110 + - type: AAAA + value: "fd30:0882:6101::110" + aliases: + - alias: vhost1 + domain: homelan.matzman.net + - alias: comic-utils + - alias: homepage + - alias: komf + - alias: komga + - alias: uptime + - alias: traefik + - alias: jdownloader + - alias: transmission + - alias: lanraragi + - alias: influxdb + - alias: influxdb + domain: homelan.matzman.net + - alias: nas0 + + - hostname: vhost1 + domain: iot.homelan + description: vhost1 Server IoT VLAN + records: + - value: 10.63.0.110 + - type: AAAA + value: "fd30:0882:6120::110" + aliases: + - alias: vhost1 + domain: iot.homelan.matzman.net + - alias: influxdb + - alias: influxdb + domain: iot.homelan.matzman.net + + - hostname: vserver0 + domain: wg0.homelan + description: vserver0 wg0 interface + records: + - value: 10.71.1.4 + + 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 + + # --- WireGuard --- + opnsense_wireguard_enabled: false + + opnsense_wireguard_servers: + - name: wg0 + private_key: "MGChy8PrvKTHWC7nzvLwuHQP/uxhNA5FUhLm5NTgfE8=" + port: 51820 + allowed_ips: + - 10.0.0.1/24 + peers: [] + enabled: true + + opnsense_wireguard_peers: + - name: client1 + public_key: "NjmYVK0BWDhQzaODqqoWHNgdtPQyNMJwhCJyEingln8=" + allowed_ips: + - 10.0.0.2/32 + servers: [wg0] + keepalive: 25 + enabled: true diff --git a/roles/opnsense/defaults/main.yml b/roles/opnsense/defaults/main.yml new file mode 100644 index 0000000..43deec4 --- /dev/null +++ b/roles/opnsense/defaults/main.yml @@ -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: [] diff --git a/roles/opnsense/tasks/dhcp.yml b/roles/opnsense/tasks/dhcp.yml new file mode 100644 index 0000000..2fd72a0 --- /dev/null +++ b/roles/opnsense/tasks/dhcp.yml @@ -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 }}" diff --git a/roles/opnsense/tasks/firewall-aliases.yml b/roles/opnsense/tasks/firewall-aliases.yml new file mode 100644 index 0000000..690fa4d --- /dev/null +++ b/roles/opnsense/tasks/firewall-aliases.yml @@ -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 }}" diff --git a/roles/opnsense/tasks/firewall-defaults.yml b/roles/opnsense/tasks/firewall-defaults.yml new file mode 100644 index 0000000..64528d3 --- /dev/null +++ b/roles/opnsense/tasks/firewall-defaults.yml @@ -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 diff --git a/roles/opnsense/tasks/firewall-rules.yml b/roles/opnsense/tasks/firewall-rules.yml new file mode 100644 index 0000000..7ad8c17 --- /dev/null +++ b/roles/opnsense/tasks/firewall-rules.yml @@ -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 }}" diff --git a/roles/opnsense/tasks/interfaces.yml b/roles/opnsense/tasks/interfaces.yml new file mode 100644 index 0000000..b854d3f --- /dev/null +++ b/roles/opnsense/tasks/interfaces.yml @@ -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 }}" diff --git a/roles/opnsense/tasks/main.yml b/roles/opnsense/tasks/main.yml new file mode 100644 index 0000000..ce7617d --- /dev/null +++ b/roles/opnsense/tasks/main.yml @@ -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] diff --git a/roles/opnsense/tasks/nat.yml b/roles/opnsense/tasks/nat.yml new file mode 100644 index 0000000..127d338 --- /dev/null +++ b/roles/opnsense/tasks/nat.yml @@ -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 }}" diff --git a/roles/opnsense/tasks/openvpn-clients.yml b/roles/opnsense/tasks/openvpn-clients.yml new file mode 100644 index 0000000..ccc2876 --- /dev/null +++ b/roles/opnsense/tasks/openvpn-clients.yml @@ -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 +# reneg-bytes +# reneg-pkts +# +# Known limitation: oxlorg.opnsense resolves the tls-crypt key by matching +# the END of the API value string, which has the format: +# " [ ()]" +# 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 diff --git a/roles/opnsense/tasks/system.yml b/roles/opnsense/tasks/system.yml new file mode 100644 index 0000000..35c66ca --- /dev/null +++ b/roles/opnsense/tasks/system.yml @@ -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 diff --git a/roles/opnsense/tasks/unbound.yml b/roles/opnsense/tasks/unbound.yml new file mode 100644 index 0000000..aa5951d --- /dev/null +++ b/roles/opnsense/tasks/unbound.yml @@ -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 }}" diff --git a/roles/opnsense/tasks/wireguard.yml b/roles/opnsense/tasks/wireguard.yml new file mode 100644 index 0000000..dffb2e7 --- /dev/null +++ b/roles/opnsense/tasks/wireguard.yml @@ -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 }}" diff --git a/test02.yml b/test02.yml new file mode 100644 index 0000000..d21cc51 --- /dev/null +++ b/test02.yml @@ -0,0 +1,12 @@ +--- + +- hosts: opnsense.homelan + connection: local # execute modules on controller + gather_facts: false + tasks: + - name: Example + oxlorg.opnsense.alias: + firewall: "{{ ansible_host }}" # or use a per-host variable to store the FQDN.. + api_key: "{{ firewall.key }}" + api_secret: "{{ firewall.secret }}" + diff --git a/testing02 b/testing02 new file mode 100644 index 0000000..6ac57cf --- /dev/null +++ b/testing02 @@ -0,0 +1,5 @@ + +localhost ansible_connection=local ansible_python_interpreter="{{ansible_playbook_python}}" host_ip_addr="10.61.1.20" host_base_domain="localhost" + +[vhosts] +vserver1.matzman.net ansible_connection=ssh ansible_user=root host_ip_addr="185.242.113.24" host_base_domain="vserver1.matzman.net" diff --git a/tmp b/tmp new file mode 100644 index 0000000..f3ee5ac --- /dev/null +++ b/tmp @@ -0,0 +1,1435 @@ + +PLAY [opnsense] **************************************************************** + +TASK [opnsense : debug] ******************************************************** +ok: [opnsense.homelan] => { + "msg": [ + [ + { + "aliases": [ + { + "alias": "api" + }, + { + "domain": "homelan.matzman.net" + } + ], + "description": "AirQ Luftsensor", + "domain": "homelan", + "hostname": "airq-livingroom", + "records": [ + { + "value": "10.63.1.177" + } + ] + }, + { + "alias": "api" + } + ], + [ + { + "aliases": [ + { + "alias": "api" + }, + { + "domain": "homelan.matzman.net" + } + ], + "description": "AirQ Luftsensor", + "domain": "homelan", + "hostname": "airq-livingroom", + "records": [ + { + "value": "10.63.1.177" + } + ] + }, + { + "domain": "homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "domain": "homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "homelan.matzman.net" + } + ], + "description": "Home Assistant", + "domain": "homelan", + "hostname": "ha", + "records": [ + { + "value": "10.61.1.75" + }, + { + "type": "AAAA", + "value": "fd30:882:6101:1::75" + } + ] + }, + { + "domain": "homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "domain": "homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "homelan.matzman.net" + } + ], + "description": "Home Assistant", + "domain": "homelan", + "hostname": "ha", + "records": [ + { + "value": "10.61.1.75" + }, + { + "type": "AAAA", + "value": "fd30:882:6101:1::75" + } + ] + }, + { + "alias": "mqtt" + } + ], + [ + { + "aliases": [ + { + "domain": "homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "homelan.matzman.net" + } + ], + "description": "Home Assistant", + "domain": "homelan", + "hostname": "ha", + "records": [ + { + "value": "10.61.1.75" + }, + { + "type": "AAAA", + "value": "fd30:882:6101:1::75" + } + ] + }, + { + "alias": "mqtt", + "domain": "homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "Home Assistant IoT VLAN", + "domain": "iot.homelan", + "hostname": "ha", + "records": [ + { + "value": "10.63.1.75" + }, + { + "type": "AAAA", + "value": "fd30:882:6120:1::75" + } + ] + }, + { + "domain": "iot.homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "Home Assistant IoT VLAN", + "domain": "iot.homelan", + "hostname": "ha", + "records": [ + { + "value": "10.63.1.75" + }, + { + "type": "AAAA", + "value": "fd30:882:6120:1::75" + } + ] + }, + { + "alias": "mqtt" + } + ], + [ + { + "aliases": [ + { + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "Home Assistant IoT VLAN", + "domain": "iot.homelan", + "hostname": "ha", + "records": [ + { + "value": "10.63.1.75" + }, + { + "type": "AAAA", + "value": "fd30:882:6120:1::75" + } + ] + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "Home Assistant IoT VLAN", + "domain": "iot.homelan", + "hostname": "helios4", + "records": [ + { + "value": "10.61.1.190" + }, + { + "type": "AAAA", + "value": "fd30:882:6101:1::190" + } + ] + }, + { + "domain": "iot.homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "Home Assistant IoT VLAN", + "domain": "iot.homelan", + "hostname": "helios4", + "records": [ + { + "value": "10.61.1.190" + }, + { + "type": "AAAA", + "value": "fd30:882:6101:1::190" + } + ] + }, + { + "alias": "mqtt" + } + ], + [ + { + "aliases": [ + { + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "mqtt" + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "Home Assistant IoT VLAN", + "domain": "iot.homelan", + "hostname": "helios4", + "records": [ + { + "value": "10.61.1.190" + }, + { + "type": "AAAA", + "value": "fd30:882:6101:1::190" + } + ] + }, + { + "alias": "mqtt", + "domain": "iot.homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "alias": "octoprint" + } + ], + "description": "OctoPi Raspi", + "domain": "homelan", + "hostname": "octopi", + "records": [ + { + "value": "10.63.1.70" + }, + { + "type": "AAAA", + "value": "fd30:882:6120:1::70" + } + ] + }, + { + "alias": "octoprint" + } + ], + [ + { + "aliases": [ + { + "alias": "pfsense" + }, + { + "alias": "ntp" + } + ], + "description": "OPNsense Router", + "domain": "homelan", + "hostname": "opnsense", + "records": [ + { + "value": "10.61.0.250" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::250" + } + ] + }, + { + "alias": "pfsense" + } + ], + [ + { + "aliases": [ + { + "alias": "pfsense" + }, + { + "alias": "ntp" + } + ], + "description": "OPNsense Router", + "domain": "homelan", + "hostname": "opnsense", + "records": [ + { + "value": "10.61.0.250" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::250" + } + ] + }, + { + "alias": "ntp" + } + ], + [ + { + "aliases": [ + { + "alias": "pfsense" + }, + { + "alias": "ntp" + } + ], + "description": "OPNsense Router IoT VLAN", + "domain": "iot.homelan", + "hostname": "opnsense", + "records": [ + { + "value": "10.63.0.250" + }, + { + "type": "AAAA", + "value": "fd30:0882:6120::250" + } + ] + }, + { + "alias": "pfsense" + } + ], + [ + { + "aliases": [ + { + "alias": "pfsense" + }, + { + "alias": "ntp" + } + ], + "description": "OPNsense Router IoT VLAN", + "domain": "iot.homelan", + "hostname": "opnsense", + "records": [ + { + "value": "10.63.0.250" + }, + { + "type": "AAAA", + "value": "fd30:0882:6120::250" + } + ] + }, + { + "alias": "ntp" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost0", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas3" + } + ], + "description": "vhost0 Server", + "domain": "homelan", + "hostname": "vhost0", + "records": [ + { + "value": "10.61.0.100" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::100" + } + ] + }, + { + "alias": "vhost0", + "domain": "homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost0", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas3" + } + ], + "description": "vhost0 Server", + "domain": "homelan", + "hostname": "vhost0", + "records": [ + { + "value": "10.61.0.100" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::100" + } + ] + }, + { + "alias": "nas3" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "comic-utils" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "homepage" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "komf" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "komga" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "uptime" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "traefik" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "jdownloader" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "transmission" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "lanraragi" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "influxdb" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "homelan.matzman.net" + }, + { + "alias": "comic-utils" + }, + { + "alias": "homepage" + }, + { + "alias": "komf" + }, + { + "alias": "komga" + }, + { + "alias": "uptime" + }, + { + "alias": "traefik" + }, + { + "alias": "jdownloader" + }, + { + "alias": "transmission" + }, + { + "alias": "lanraragi" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "homelan.matzman.net" + }, + { + "alias": "nas0" + } + ], + "description": "vhost1 Server", + "domain": "homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.61.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6101::110" + } + ] + }, + { + "alias": "nas0" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "vhost1 Server IoT VLAN", + "domain": "iot.homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.63.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6120::110" + } + ] + }, + { + "alias": "vhost1", + "domain": "iot.homelan.matzman.net" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "vhost1 Server IoT VLAN", + "domain": "iot.homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.63.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6120::110" + } + ] + }, + { + "alias": "influxdb" + } + ], + [ + { + "aliases": [ + { + "alias": "vhost1", + "domain": "iot.homelan.matzman.net" + }, + { + "alias": "influxdb" + }, + { + "alias": "influxdb", + "domain": "iot.homelan.matzman.net" + } + ], + "description": "vhost1 Server IoT VLAN", + "domain": "iot.homelan", + "hostname": "vhost1", + "records": [ + { + "value": "10.63.0.110" + }, + { + "type": "AAAA", + "value": "fd30:0882:6120::110" + } + ] + }, + { + "alias": "influxdb", + "domain": "iot.homelan.matzman.net" + } + ] + ] +} + +PLAY RECAP ********************************************************************* +opnsense.homelan : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +