Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
28e220d1b7
|
|||
|
38f0aa699f
|
|||
|
120547b1b8
|
|||
|
17db139125
|
+87
-15
@@ -1,20 +1,92 @@
|
|||||||
## RouterOS Ansible
|
# Ansible
|
||||||
|
|
||||||
This directory contains the new Ansible automation for the MikroTik router.
|
Idempotent configuration management for the home-lab network devices.
|
||||||
|
|
||||||
- Transport: RouterOS API (`community.routeros` collection), not SSH CLI scraping.
|
## Devices
|
||||||
- Layout: one playbook (`playbooks/routeros.yml`) importing domain task files from `tasks/`.
|
|
||||||
- Goal: idempotent convergence using `community.routeros.api_modify` for managed paths.
|
|
||||||
|
|
||||||
### Quick start
|
| Host | Group | IP | Playbook |
|
||||||
|
|---|---|---|---|
|
||||||
|
| crs418 (MikroTik CRS418) | `mikrotik` | 192.168.255.10 | `playbooks/routeros.yml` |
|
||||||
|
| dlink (OpenWrt AP) | `openwrt` | 192.168.255.11 | `playbooks/openwrt.yml` |
|
||||||
|
|
||||||
1. Install dependencies:
|
Both devices are reachable on the MGMT network (192.168.255.0/24) once fully set up.
|
||||||
- `ansible-galaxy collection install -r ansible/requirements.yml`
|
|
||||||
- `python -m pip install librouteros hvac`
|
|
||||||
2. Configure secret references in `ansible/vars/routeros-secrets.yml`.
|
|
||||||
3. Store required fields in OpenBao under configured KV path.
|
|
||||||
4. Export token (`OPENBAO_TOKEN` or `VAULT_TOKEN`).
|
|
||||||
5. Run:
|
|
||||||
- `ANSIBLE_CONFIG=ansible/ansible.cfg ansible-playbook ansible/playbooks/routeros.yml`
|
|
||||||
|
|
||||||
More details and design rationale: `docs/ansible/routeros-design.md`.
|
## Dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-galaxy collection install -r requirements.yml
|
||||||
|
pip install librouteros hvac
|
||||||
|
```
|
||||||
|
|
||||||
|
Collections used:
|
||||||
|
|
||||||
|
- `community.routeros >= 3.16.0` — MikroTik API modules
|
||||||
|
- `community.hashi_vault >= 7.1.0` — OpenBao/Vault secret lookup
|
||||||
|
- `community.openwrt >= 1.0.0` — OpenWrt UCI and shell modules
|
||||||
|
|
||||||
|
## MikroTik (routeros)
|
||||||
|
|
||||||
|
Secrets are fetched at runtime from OpenBao. No credentials are stored in files.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_TOKEN=... # or OPENBAO_TOKEN
|
||||||
|
ansible-playbook playbooks/routeros.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Secret layout expected in OpenBao (KVv2, mount `secret`):
|
||||||
|
|
||||||
|
| Path | Fields |
|
||||||
|
|---|---|
|
||||||
|
| `routeros_api` | `username`, `password` |
|
||||||
|
| `wan_pppoe` | `username`, `password` |
|
||||||
|
| `router_tailscale` | `container_password` |
|
||||||
|
|
||||||
|
## OpenWrt dlink AP
|
||||||
|
|
||||||
|
The dlink needs a one-time initialisation before it can be managed through MikroTik.
|
||||||
|
There are two playbooks:
|
||||||
|
|
||||||
|
### Step 1 — `dlink-init.yml` (once, PC directly connected)
|
||||||
|
|
||||||
|
Run this while your PC is plugged into one of the dlink **LAN ports** with the
|
||||||
|
device still on its factory IP (192.168.1.1). MikroTik must **not** be in the
|
||||||
|
picture yet.
|
||||||
|
|
||||||
|
What it does:
|
||||||
|
- Reconfigures switch0 so the **WAN port** becomes a VLAN trunk:
|
||||||
|
- untagged → VLAN 1 (MGMT, 192.168.255.0/24)
|
||||||
|
- tagged → VLAN 2 (LAN, 192.168.0.0/24)
|
||||||
|
- Adds `mgmt` interface: static 192.168.255.11/24, gateway 192.168.255.10
|
||||||
|
- Reconfigures `lan` to a bridge on eth0.2 with no IP (AP mode)
|
||||||
|
- Removes routed `wan`/`wan6` interfaces
|
||||||
|
- Commits and reloads network in the background
|
||||||
|
|
||||||
|
After the reload the device is no longer reachable at 192.168.1.1.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook playbooks/dlink-init.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2 — connect dlink WAN port to MikroTik ether3
|
||||||
|
|
||||||
|
Plug the **dlink WAN port** into **MikroTik ether3**.
|
||||||
|
|
||||||
|
If the MikroTik config hasn't been applied yet, do it now:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export VAULT_TOKEN=...
|
||||||
|
ansible-playbook playbooks/routeros.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
MikroTik ether3 is configured to send MGMT traffic untagged and VLAN 2 (LAN)
|
||||||
|
tagged, which matches what dlink expects on its WAN port.
|
||||||
|
|
||||||
|
### Step 3 — `openwrt.yml` (ongoing, via MikroTik)
|
||||||
|
|
||||||
|
All subsequent runs connect to 192.168.255.11 through MikroTik:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook playbooks/openwrt.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This is the idempotent main playbook. Run it any time to converge configuration.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[defaults]
|
[defaults]
|
||||||
inventory = inventory/hosts.yml
|
inventory = inventory/hosts.yml
|
||||||
|
roles_path = roles
|
||||||
host_key_checking = False
|
host_key_checking = False
|
||||||
retry_files_enabled = False
|
retry_files_enabled = False
|
||||||
result_format = yaml
|
result_format = yaml
|
||||||
|
|||||||
@@ -4,3 +4,9 @@ all:
|
|||||||
hosts:
|
hosts:
|
||||||
crs418:
|
crs418:
|
||||||
ansible_host: 192.168.255.10
|
ansible_host: 192.168.255.10
|
||||||
|
openwrt:
|
||||||
|
hosts:
|
||||||
|
dlink:
|
||||||
|
ansible_host: 192.168.255.11
|
||||||
|
ansible_user: root
|
||||||
|
ansible_ssh_port: 22
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
# One-time initialisation playbook for the dlink OpenWrt AP.
|
||||||
|
#
|
||||||
|
# Run this while your PC is directly connected to a dlink LAN port
|
||||||
|
# (factory IP 192.168.1.1, no MikroTik in the picture yet).
|
||||||
|
#
|
||||||
|
# Applies the same network and firewall config as the main openwrt role,
|
||||||
|
# then reloads network in the background. Skips wireless (requires Vault).
|
||||||
|
#
|
||||||
|
# After this playbook finishes the device is no longer reachable at 192.168.1.1.
|
||||||
|
# Plug the WAN port into MikroTik ether3 and use playbooks/openwrt.yml for all
|
||||||
|
# further configuration.
|
||||||
|
|
||||||
|
- name: dlink — one-time network initialisation
|
||||||
|
hosts: openwrt
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
ansible_host: "192.168.1.1"
|
||||||
|
ansible_user: root
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Verify connectivity
|
||||||
|
community.openwrt.ping:
|
||||||
|
|
||||||
|
# import_tasks (static) is used instead of include_tasks (dynamic) so that
|
||||||
|
# handler names referenced via notify in the imported files are silently
|
||||||
|
# ignored rather than causing an error — no handlers are defined in this
|
||||||
|
# play, and the explicit nohup reload below replaces them for the init case.
|
||||||
|
- name: Network configuration
|
||||||
|
ansible.builtin.import_tasks: ../roles/openwrt/tasks/network.yml
|
||||||
|
|
||||||
|
- name: Firewall configuration
|
||||||
|
ansible.builtin.import_tasks: ../roles/openwrt/tasks/firewall.yml
|
||||||
|
|
||||||
|
- name: Reload network in background (device will drop off 192.168.1.1)
|
||||||
|
community.openwrt.nohup:
|
||||||
|
command: /etc/init.d/network reload
|
||||||
|
ignore_unreachable: true
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
# Main OpenWrt playbook. Connects to dlink on its permanent management IP
|
||||||
|
# (192.168.255.11 via MikroTik ether3). Run dlink-init.yml first if the
|
||||||
|
# device has not been initialised yet.
|
||||||
|
- name: Configure OpenWrt
|
||||||
|
hosts: openwrt
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- role: openwrt
|
||||||
@@ -4,9 +4,6 @@
|
|||||||
gather_facts: false
|
gather_facts: false
|
||||||
connection: local
|
connection: local
|
||||||
|
|
||||||
vars_files:
|
|
||||||
- ../vars/routeros-secrets.yml
|
|
||||||
|
|
||||||
pre_tasks:
|
pre_tasks:
|
||||||
- name: Load router secrets from OpenBao
|
- name: Load router secrets from OpenBao
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
@@ -63,30 +60,5 @@
|
|||||||
force_no_cert: true
|
force_no_cert: true
|
||||||
encoding: UTF-8
|
encoding: UTF-8
|
||||||
|
|
||||||
tasks:
|
roles:
|
||||||
- name: Preflight checks
|
- role: routeros
|
||||||
ansible.builtin.import_tasks: ../tasks/preflight.yml
|
|
||||||
|
|
||||||
- name: Base network configuration
|
|
||||||
ansible.builtin.import_tasks: ../tasks/base.yml
|
|
||||||
|
|
||||||
- name: WAN and tunnel interfaces
|
|
||||||
ansible.builtin.import_tasks: ../tasks/wan.yml
|
|
||||||
|
|
||||||
- name: Hardware and platform tuning
|
|
||||||
ansible.builtin.import_tasks: ../tasks/hardware.yml
|
|
||||||
|
|
||||||
- name: RouterOS container configuration
|
|
||||||
ansible.builtin.import_tasks: ../tasks/containers.yml
|
|
||||||
|
|
||||||
- name: Addressing configuration
|
|
||||||
ansible.builtin.import_tasks: ../tasks/addressing.yml
|
|
||||||
|
|
||||||
- name: Firewall configuration
|
|
||||||
ansible.builtin.import_tasks: ../tasks/firewall.yml
|
|
||||||
|
|
||||||
- name: Routing configuration
|
|
||||||
ansible.builtin.import_tasks: ../tasks/routing.yml
|
|
||||||
|
|
||||||
- name: System configuration
|
|
||||||
ansible.builtin.import_tasks: ../tasks/system.yml
|
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ collections:
|
|||||||
version: ">=3.16.0"
|
version: ">=3.16.0"
|
||||||
- name: community.hashi_vault
|
- name: community.hashi_vault
|
||||||
version: ">=7.1.0"
|
version: ">=7.1.0"
|
||||||
|
- name: community.openwrt
|
||||||
|
version: ">=1.0.0"
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
# Hostname for the AP
|
||||||
|
openwrt_hostname: dlink
|
||||||
|
|
||||||
|
# Timezone (POSIX TZ string used by OpenWrt)
|
||||||
|
openwrt_timezone: CET-1CEST,M3.5.0,M10.5.0/3
|
||||||
|
|
||||||
|
# Management interface and IP (statically assigned on VLAN 1 / eth0.1)
|
||||||
|
openwrt_mgmt_ip: 192.168.255.11
|
||||||
|
openwrt_mgmt_prefix: 24
|
||||||
|
openwrt_mgmt_gateway: 192.168.255.10
|
||||||
|
|
||||||
|
# DNS servers for the AP itself
|
||||||
|
openwrt_dns_servers:
|
||||||
|
- 192.168.0.1
|
||||||
|
|
||||||
|
# SSH authorised keys (list of public key strings)
|
||||||
|
openwrt_ssh_authorized_keys: []
|
||||||
|
|
||||||
|
# NTP servers
|
||||||
|
openwrt_ntp_servers:
|
||||||
|
- 0.pl.pool.ntp.org
|
||||||
|
- 1.pl.pool.ntp.org
|
||||||
|
|
||||||
|
# Packages to install
|
||||||
|
openwrt_packages: []
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Reload network
|
||||||
|
community.openwrt.nohup:
|
||||||
|
command: /etc/init.d/network reload
|
||||||
|
ignore_unreachable: true
|
||||||
|
|
||||||
|
- name: Reload firewall
|
||||||
|
community.openwrt.service:
|
||||||
|
name: firewall
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Reload wireless
|
||||||
|
community.openwrt.command:
|
||||||
|
cmd: wifi reload
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
# This device is a pure AP — no routing, no NAT, no internet-facing interface.
|
||||||
|
#
|
||||||
|
# Zones:
|
||||||
|
# mgmt — management interface (192.168.255.11)
|
||||||
|
# input: ACCEPT (SSH, ping reachable from MGMT network)
|
||||||
|
# forward: REJECT (nothing routes through mgmt)
|
||||||
|
#
|
||||||
|
# lan — client bridge (eth0.2, LAN ports)
|
||||||
|
# input: REJECT (clients cannot SSH into the AP itself)
|
||||||
|
# forward: ACCEPT (traffic passes through to MikroTik for firewalling)
|
||||||
|
#
|
||||||
|
# iot — IoT bridge (eth0.5, wifi only)
|
||||||
|
# input: REJECT (IoT devices cannot reach the AP itself)
|
||||||
|
# forward: ACCEPT (traffic passes through to MikroTik, which allows
|
||||||
|
# internet only and blocks all internal networks)
|
||||||
|
#
|
||||||
|
# No forwarding rules between zones — all inter-zone policy is on MikroTik.
|
||||||
|
|
||||||
|
- name: Configure firewall
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: import
|
||||||
|
merge: false
|
||||||
|
config: firewall
|
||||||
|
value: |
|
||||||
|
package firewall
|
||||||
|
|
||||||
|
config defaults
|
||||||
|
option syn_flood '1'
|
||||||
|
option input 'REJECT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'REJECT'
|
||||||
|
|
||||||
|
config zone
|
||||||
|
option name 'mgmt'
|
||||||
|
list network 'mgmt'
|
||||||
|
option input 'ACCEPT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'REJECT'
|
||||||
|
|
||||||
|
config zone
|
||||||
|
option name 'lan'
|
||||||
|
list network 'lan'
|
||||||
|
option input 'REJECT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'ACCEPT'
|
||||||
|
|
||||||
|
config zone
|
||||||
|
option name 'iot'
|
||||||
|
list network 'iot'
|
||||||
|
option input 'REJECT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-ICMP-mgmt'
|
||||||
|
option src 'mgmt'
|
||||||
|
option proto 'icmp'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
notify: Reload firewall
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
- name: Preflight — verify connectivity
|
||||||
|
ansible.builtin.import_tasks: preflight.yml
|
||||||
|
|
||||||
|
- name: System configuration
|
||||||
|
ansible.builtin.import_tasks: system.yml
|
||||||
|
|
||||||
|
- name: Network configuration
|
||||||
|
ansible.builtin.import_tasks: network.yml
|
||||||
|
|
||||||
|
- name: Firewall configuration
|
||||||
|
ansible.builtin.import_tasks: firewall.yml
|
||||||
|
|
||||||
|
- name: Wireless configuration
|
||||||
|
ansible.builtin.import_tasks: wireless.yml
|
||||||
|
|
||||||
|
- name: Package management
|
||||||
|
ansible.builtin.import_tasks: packages.yml
|
||||||
|
when: openwrt_packages | length > 0
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
# Network layout:
|
||||||
|
# MikroTik ether3 ↔ dlink WAN port (switch0 port4)
|
||||||
|
# MikroTik sends MGMT traffic untagged, vlan2 (LAN) and vlan5 (IOT) tagged.
|
||||||
|
#
|
||||||
|
# switch0 VLAN table:
|
||||||
|
# VLAN 1 (MGMT): CPU(6) tagged, WAN(4) untagged → eth0.1 → mgmt
|
||||||
|
# VLAN 2 (LAN): CPU(6) tagged, WAN(4) tagged, LAN1-4(0-3) untagged → eth0.2 → br-lan → lan
|
||||||
|
# VLAN 5 (IOT): CPU(6) tagged, WAN(4) tagged → eth0.5 → br-iot → iot
|
||||||
|
#
|
||||||
|
# Interfaces:
|
||||||
|
# mgmt — static 192.168.255.11/24 on eth0.1, management
|
||||||
|
# lan — bridge (br-lan) on eth0.2, LAN clients via LAN ports
|
||||||
|
# iot — bridge (br-iot) on eth0.5, IoT clients via wifi only
|
||||||
|
|
||||||
|
- name: Configure network
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: import
|
||||||
|
merge: false
|
||||||
|
config: network
|
||||||
|
value: |
|
||||||
|
package network
|
||||||
|
|
||||||
|
config interface 'loopback'
|
||||||
|
option device 'lo'
|
||||||
|
option proto 'static'
|
||||||
|
list ipaddr '127.0.0.1/8'
|
||||||
|
|
||||||
|
config globals 'globals'
|
||||||
|
option ula_prefix 'fd4d:508e:899a::/48'
|
||||||
|
|
||||||
|
config switch
|
||||||
|
option name 'switch0'
|
||||||
|
option reset '1'
|
||||||
|
option enable_vlan '1'
|
||||||
|
|
||||||
|
config switch_vlan
|
||||||
|
option device 'switch0'
|
||||||
|
option vlan '1'
|
||||||
|
option vid '1'
|
||||||
|
option description 'mgmt'
|
||||||
|
option ports '4 6t'
|
||||||
|
|
||||||
|
config switch_vlan
|
||||||
|
option device 'switch0'
|
||||||
|
option vlan '2'
|
||||||
|
option vid '2'
|
||||||
|
option description 'lan'
|
||||||
|
option ports '0 1 2 3 4t 6t'
|
||||||
|
|
||||||
|
config switch_vlan
|
||||||
|
option device 'switch0'
|
||||||
|
option vlan '5'
|
||||||
|
option vid '5'
|
||||||
|
option description 'iot'
|
||||||
|
option ports '4t 6t'
|
||||||
|
|
||||||
|
config device
|
||||||
|
option name 'br-lan'
|
||||||
|
option type 'bridge'
|
||||||
|
list ports 'eth0.2'
|
||||||
|
|
||||||
|
config interface 'mgmt'
|
||||||
|
option device 'eth0.1'
|
||||||
|
option proto 'static'
|
||||||
|
option ipaddr '{{ openwrt_mgmt_ip }}/{{ openwrt_mgmt_prefix }}'
|
||||||
|
option gateway '{{ openwrt_mgmt_gateway }}'
|
||||||
|
option dns '{{ openwrt_dns_servers | join(" ") }}'
|
||||||
|
|
||||||
|
config interface 'lan'
|
||||||
|
option device 'br-lan'
|
||||||
|
option proto 'none'
|
||||||
|
|
||||||
|
config device
|
||||||
|
option name 'br-iot'
|
||||||
|
option type 'bridge'
|
||||||
|
list ports 'eth0.5'
|
||||||
|
|
||||||
|
config interface 'iot'
|
||||||
|
option device 'br-iot'
|
||||||
|
option proto 'none'
|
||||||
|
|
||||||
|
notify: Reload network
|
||||||
|
|
||||||
|
- name: Commit network config
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: commit
|
||||||
|
key: network
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
- name: Install packages
|
||||||
|
community.openwrt.opkg:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
loop: "{{ openwrt_packages }}"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Verify connectivity to OpenWrt device
|
||||||
|
community.openwrt.ping:
|
||||||
|
|
||||||
|
- name: Gather OpenWrt facts
|
||||||
|
community.openwrt.setup:
|
||||||
|
register: openwrt_facts
|
||||||
|
|
||||||
|
- name: Show device info
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Managing {{ inventory_hostname }} ({{ openwrt_facts.ansible_facts.ansible_system | default('OpenWrt') }})"
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
- name: Set hostname
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: set
|
||||||
|
key: system.@system[0].hostname
|
||||||
|
value: "{{ openwrt_hostname }}"
|
||||||
|
|
||||||
|
- name: Set timezone
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: set
|
||||||
|
key: system.@system[0].timezone
|
||||||
|
value: "{{ openwrt_timezone }}"
|
||||||
|
|
||||||
|
- name: Configure NTP servers
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: set
|
||||||
|
key: system.ntp.server
|
||||||
|
value: "{{ openwrt_ntp_servers }}"
|
||||||
|
|
||||||
|
- name: Commit system config
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: commit
|
||||||
|
key: system
|
||||||
|
|
||||||
|
- name: Set SSH authorized keys
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: set
|
||||||
|
key: "dropbear.@dropbear[0].authorized_keys"
|
||||||
|
value: "{{ openwrt_ssh_authorized_keys | join('\n') }}"
|
||||||
|
when: openwrt_ssh_authorized_keys | length > 0
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
- name: Load IoT WiFi password from OpenBao
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
openwrt_iot_wifi_password: >-
|
||||||
|
{{
|
||||||
|
lookup(
|
||||||
|
'community.hashi_vault.vault_kv2_get',
|
||||||
|
openbao_fields.iot_wifi.path,
|
||||||
|
engine_mount_point=openbao_kv_mount
|
||||||
|
).secret[openbao_fields.iot_wifi.password_key]
|
||||||
|
}}
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Configure IoT WiFi interface (szafa, WPA2, network iot)
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: section
|
||||||
|
config: wireless
|
||||||
|
type: wifi-iface
|
||||||
|
name: iot_radio0
|
||||||
|
find:
|
||||||
|
device: radio0
|
||||||
|
ssid: szafa
|
||||||
|
value:
|
||||||
|
device: radio0
|
||||||
|
network: iot
|
||||||
|
mode: ap
|
||||||
|
ssid: szafa
|
||||||
|
encryption: psk2
|
||||||
|
key: "{{ openwrt_iot_wifi_password }}"
|
||||||
|
disabled: '0'
|
||||||
|
replace: true
|
||||||
|
notify: Reload wireless
|
||||||
|
|
||||||
|
- name: Enable radio0
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: set
|
||||||
|
key: wireless.radio0.disabled
|
||||||
|
value: '0'
|
||||||
|
notify: Reload wireless
|
||||||
|
|
||||||
|
- name: Commit wireless config
|
||||||
|
community.openwrt.uci:
|
||||||
|
command: commit
|
||||||
|
key: wireless
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
# Secret references only; actual values are loaded from OpenBao/Vault at runtime.
|
||||||
|
|
||||||
|
openbao_kv_mount: secret
|
||||||
|
|
||||||
|
openbao_fields:
|
||||||
|
iot_wifi:
|
||||||
|
path: openwrt_iot_wifi
|
||||||
|
password_key: password
|
||||||
@@ -24,9 +24,11 @@
|
|||||||
- address: 192.168.3.1/24
|
- address: 192.168.3.1/24
|
||||||
interface: vlan3
|
interface: vlan3
|
||||||
network: 192.168.3.0
|
network: 192.168.3.0
|
||||||
|
- address: 192.168.5.1/24
|
||||||
|
interface: vlan5
|
||||||
|
network: 192.168.5.0
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure IPv6 addresses
|
- name: Configure IPv6 addresses
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -43,6 +45,8 @@
|
|||||||
- address: 2001:470:61a3:100::1/64
|
- address: 2001:470:61a3:100::1/64
|
||||||
advertise: false
|
advertise: false
|
||||||
interface: vlan4
|
interface: vlan4
|
||||||
|
- address: ::ffff:ffff:ffff:ffff/64
|
||||||
|
from-pool: pool1
|
||||||
|
interface: vlan5
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
- name: dockers
|
- name: dockers
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure VLAN interfaces
|
- name: Configure VLAN interfaces
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -26,9 +25,12 @@
|
|||||||
comment: SERVER LAN
|
comment: SERVER LAN
|
||||||
interface: bridge1
|
interface: bridge1
|
||||||
vlan-id: 4
|
vlan-id: 4
|
||||||
|
- name: vlan5
|
||||||
|
comment: IOT
|
||||||
|
interface: bridge1
|
||||||
|
vlan-id: 5
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure interface lists
|
- name: Configure interface lists
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -38,7 +40,6 @@
|
|||||||
comment: contains interfaces facing internet
|
comment: contains interfaces facing internet
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure interface list members
|
- name: Configure interface list members
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -52,7 +53,6 @@
|
|||||||
list: wan
|
list: wan
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure bridge ports
|
- name: Configure bridge ports
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -67,6 +67,9 @@
|
|||||||
- bridge: bridge1
|
- bridge: bridge1
|
||||||
interface: ether2
|
interface: ether2
|
||||||
pvid: 2
|
pvid: 2
|
||||||
|
- bridge: bridge1
|
||||||
|
interface: ether3
|
||||||
|
comment: OpenWrt AP (dlink)
|
||||||
- bridge: bridge1
|
- bridge: bridge1
|
||||||
interface: ether8
|
interface: ether8
|
||||||
pvid: 4
|
pvid: 4
|
||||||
@@ -82,16 +85,18 @@
|
|||||||
interface: ether11
|
interface: ether11
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure bridge VLAN membership
|
- name: Configure bridge VLAN membership
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
path: interface bridge vlan
|
path: interface bridge vlan
|
||||||
data:
|
data:
|
||||||
- bridge: bridge1
|
- bridge: bridge1
|
||||||
tagged: sfp-sfpplus2
|
tagged: sfp-sfpplus2,ether3
|
||||||
untagged: ether1,ether2,ether9
|
untagged: ether1,ether2,ether9
|
||||||
vlan-ids: 2
|
vlan-ids: 2
|
||||||
|
- bridge: bridge1
|
||||||
|
tagged: bridge1,ether3
|
||||||
|
vlan-ids: 5
|
||||||
- bridge: bridge1
|
- bridge: bridge1
|
||||||
tagged: sfp-sfpplus2
|
tagged: sfp-sfpplus2
|
||||||
untagged: ether10
|
untagged: ether10
|
||||||
@@ -101,7 +106,6 @@
|
|||||||
vlan-ids: 4
|
vlan-ids: 4
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure IPv4 pools
|
- name: Configure IPv4 pools
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -113,9 +117,11 @@
|
|||||||
- name: dhcp_pool1
|
- name: dhcp_pool1
|
||||||
ranges: 192.168.255.1-192.168.255.9,192.168.255.11-192.168.255.254
|
ranges: 192.168.255.1-192.168.255.9,192.168.255.11-192.168.255.254
|
||||||
comment: MGMT DHCP pool
|
comment: MGMT DHCP pool
|
||||||
|
- name: dhcp_pool2
|
||||||
|
ranges: 192.168.5.50-192.168.5.250
|
||||||
|
comment: IOT DHCP pool
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure DHCP servers
|
- name: Configure DHCP servers
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -131,9 +137,13 @@
|
|||||||
interface: bridge1
|
interface: bridge1
|
||||||
lease-time: 30m
|
lease-time: 30m
|
||||||
comment: MGMT
|
comment: MGMT
|
||||||
|
- name: dhcp3
|
||||||
|
address-pool: dhcp_pool2
|
||||||
|
interface: vlan5
|
||||||
|
lease-time: 30m
|
||||||
|
comment: IOT
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure DHCP networks
|
- name: Configure DHCP networks
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -145,9 +155,11 @@
|
|||||||
- address: 192.168.255.0/24
|
- address: 192.168.255.0/24
|
||||||
dns-none: true
|
dns-none: true
|
||||||
gateway: 192.168.255.10
|
gateway: 192.168.255.10
|
||||||
|
- address: 192.168.5.0/24
|
||||||
|
dns-server: 192.168.5.1
|
||||||
|
gateway: 192.168.5.1
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
# TODO: IPv6 pools are useful when we have dynamic prefix, but we don't
|
# TODO: IPv6 pools are useful when we have dynamic prefix, but we don't
|
||||||
# We can remove it now
|
# We can remove it now
|
||||||
@@ -160,7 +172,6 @@
|
|||||||
prefix-length: 64
|
prefix-length: 64
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure DNS
|
- name: Configure DNS
|
||||||
community.routeros.api_find_and_modify:
|
community.routeros.api_find_and_modify:
|
||||||
@@ -192,7 +203,6 @@
|
|||||||
type: internal
|
type: internal
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure UPnP global settings
|
- name: Configure UPnP global settings
|
||||||
community.routeros.api_find_and_modify:
|
community.routeros.api_find_and_modify:
|
||||||
@@ -214,7 +224,6 @@
|
|||||||
type: internal
|
type: internal
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure IPv6 ND defaults
|
- name: Configure IPv6 ND defaults
|
||||||
community.routeros.api_find_and_modify:
|
community.routeros.api_find_and_modify:
|
||||||
@@ -29,7 +29,6 @@
|
|||||||
value: y
|
value: y
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure container mounts
|
- name: Configure container mounts
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -43,7 +42,6 @@
|
|||||||
src: /tmp1/tailscale-root
|
src: /tmp1/tailscale-root
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure tailscale container
|
- name: Configure tailscale container
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -63,4 +61,3 @@
|
|||||||
workdir: /
|
workdir: /
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
@@ -53,6 +53,11 @@
|
|||||||
comment: Allow from SRV to CAM
|
comment: Allow from SRV to CAM
|
||||||
in-interface: vlan4
|
in-interface: vlan4
|
||||||
out-interface: vlan3
|
out-interface: vlan3
|
||||||
|
- action: accept
|
||||||
|
chain: forward
|
||||||
|
comment: Allow from IOT to internet only
|
||||||
|
in-interface: vlan5
|
||||||
|
out-interface-list: wan
|
||||||
- action: accept
|
- action: accept
|
||||||
chain: forward
|
chain: forward
|
||||||
comment: Allow from dockers to everywhere
|
comment: Allow from dockers to everywhere
|
||||||
@@ -136,6 +141,17 @@
|
|||||||
dst-port: 53
|
dst-port: 53
|
||||||
in-interface: dockers
|
in-interface: dockers
|
||||||
protocol: tcp
|
protocol: tcp
|
||||||
|
- action: accept
|
||||||
|
chain: input
|
||||||
|
comment: Allow DNS from IOT
|
||||||
|
dst-port: 53
|
||||||
|
in-interface: vlan5
|
||||||
|
protocol: udp
|
||||||
|
- action: accept
|
||||||
|
chain: input
|
||||||
|
dst-port: 53
|
||||||
|
in-interface: vlan5
|
||||||
|
protocol: tcp
|
||||||
- action: accept
|
- action: accept
|
||||||
chain: input
|
chain: input
|
||||||
comment: Allow BGP from SRV
|
comment: Allow BGP from SRV
|
||||||
@@ -368,6 +384,11 @@
|
|||||||
comment: Allow from SRV to CAM
|
comment: Allow from SRV to CAM
|
||||||
in-interface: vlan4
|
in-interface: vlan4
|
||||||
out-interface: vlan3
|
out-interface: vlan3
|
||||||
|
- action: accept
|
||||||
|
chain: forward
|
||||||
|
comment: Allow from IOT to internet only
|
||||||
|
in-interface: vlan5
|
||||||
|
out-interface-list: wan
|
||||||
- action: accept
|
- action: accept
|
||||||
chain: forward
|
chain: forward
|
||||||
comment: Allow from dockers to everywhere
|
comment: Allow from dockers to everywhere
|
||||||
@@ -445,6 +466,17 @@
|
|||||||
dst-port: 53
|
dst-port: 53
|
||||||
in-interface: dockers
|
in-interface: dockers
|
||||||
protocol: tcp
|
protocol: tcp
|
||||||
|
- action: accept
|
||||||
|
chain: input
|
||||||
|
comment: Allow DNS from IOT
|
||||||
|
dst-port: 53
|
||||||
|
in-interface: vlan5
|
||||||
|
protocol: udp
|
||||||
|
- action: accept
|
||||||
|
chain: input
|
||||||
|
dst-port: 53
|
||||||
|
in-interface: vlan5
|
||||||
|
protocol: tcp
|
||||||
- action: accept
|
- action: accept
|
||||||
chain: input
|
chain: input
|
||||||
comment: Allow BGP from SRV
|
comment: Allow BGP from SRV
|
||||||
@@ -13,6 +13,9 @@
|
|||||||
- default_name: ether2
|
- default_name: ether2
|
||||||
config:
|
config:
|
||||||
comment: Wifi środek
|
comment: Wifi środek
|
||||||
|
- default_name: ether3
|
||||||
|
config:
|
||||||
|
comment: OpenWrt AP (dlink)
|
||||||
- default_name: ether8
|
- default_name: ether8
|
||||||
config:
|
config:
|
||||||
comment: Serwer
|
comment: Serwer
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
- name: Preflight checks
|
||||||
|
ansible.builtin.import_tasks: preflight.yml
|
||||||
|
|
||||||
|
- name: Base network configuration
|
||||||
|
ansible.builtin.import_tasks: base.yml
|
||||||
|
|
||||||
|
- name: WAN and tunnel interfaces
|
||||||
|
ansible.builtin.import_tasks: wan.yml
|
||||||
|
|
||||||
|
- name: Hardware and platform tuning
|
||||||
|
ansible.builtin.import_tasks: hardware.yml
|
||||||
|
|
||||||
|
- name: RouterOS container configuration
|
||||||
|
ansible.builtin.import_tasks: containers.yml
|
||||||
|
|
||||||
|
- name: Addressing configuration
|
||||||
|
ansible.builtin.import_tasks: addressing.yml
|
||||||
|
|
||||||
|
- name: Firewall configuration
|
||||||
|
ansible.builtin.import_tasks: firewall.yml
|
||||||
|
|
||||||
|
- name: Routing configuration
|
||||||
|
ansible.builtin.import_tasks: routing.yml
|
||||||
|
|
||||||
|
- name: System configuration
|
||||||
|
ansible.builtin.import_tasks: system.yml
|
||||||
@@ -64,7 +64,6 @@
|
|||||||
routing-table: main
|
routing-table: main
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure BGP templates
|
- name: Configure BGP templates
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -96,4 +95,3 @@
|
|||||||
templates: klaster
|
templates: klaster
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
user: "{{ routeros_pppoe_username }}"
|
user: "{{ routeros_pppoe_username }}"
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure 6to4 tunnel interface
|
- name: Configure 6to4 tunnel interface
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
remote-address: 216.66.80.162
|
remote-address: 216.66.80.162
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
|
|
||||||
- name: Configure veth interface for containers
|
- name: Configure veth interface for containers
|
||||||
community.routeros.api_modify:
|
community.routeros.api_modify:
|
||||||
@@ -41,4 +39,3 @@
|
|||||||
comment: Tailscale container
|
comment: Tailscale container
|
||||||
handle_absent_entries: remove
|
handle_absent_entries: remove
|
||||||
handle_entries_content: remove_as_much_as_possible
|
handle_entries_content: remove_as_much_as_possible
|
||||||
ensure_order: true
|
|
||||||
Reference in New Issue
Block a user