Skip to content

About

Ansible collection for automative configuration of OpenWrt devices (without Python).

Resources

Stars

22 stars

Watchers

5 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

Repository files navigation

flyoverhead.openwrt

Version ansible-core License Platform Roles

Configuration of OpenWrt devices over SSH, without Python on the target. Every role drives UCI directly: system, network, wireless, mesh, firewall, DHCP/DNS, Wireguard, policy-based routing, SSH and a Prometheus exporter.

These roles configure a device that already runs OpenWrt. Flashing the firmware is out of scope.

🚀 Quick Start

Requirements

  • ansible-core >=2.16 on the controller

  • Collections: ansible.utils >=2.5.0 (the wireguard role uses ipmath)

  • The gekmihesg.openwrt role. It supplies the uci and opkg modules and the action-plugin monkeypatch that rewrites ansible.builtin.* calls into shell equivalents. Every role here depends on it, and it is resolved through roles_path, not as a collection.

  • Task >=3.20, for the helper targets only

  • SSH access to the device as root

Installation

Installing the dependencies:

ansible-galaxy collection install -r requirements.yml
ansible-galaxy role install -r requirements.yml -p .ansible/roles
pip install -r requirements.txt

Or, equivalently, task install.

Installing the collection itself:

ansible-galaxy collection install git+https://github.com/flyoverhead/ansible-openwrt.git

Roles usage

Full documentation and usage examples of role <role> can be found in roles/<role>/README.md.

Order matters. Run extroot first — it migrates the overlay onto USB and reboots, so anything committed before it lands on the overlay that is about to be replaced. system and network come next, since later roles attach to the interfaces network defines. batman or mesh11sd must precede wireless, because both create wireless interfaces of their own. Everything after that is independent.

Example Playbook

---
- name: configure openwrt devices
  hosts: openwrt
  ignore_unreachable: true
  gather_facts: false

  roles:
    - flyoverhead.openwrt.extroot
    - flyoverhead.openwrt.system
    - flyoverhead.openwrt.network
    - flyoverhead.openwrt.batman
    - flyoverhead.openwrt.wireless
    - flyoverhead.openwrt.wireguard
    - flyoverhead.openwrt.firewall
    - flyoverhead.openwrt.pbr
    - flyoverhead.openwrt.dropbear
    - flyoverhead.openwrt.dhcp
    - flyoverhead.openwrt.node_exporter

gather_facts must be false: fact gathering needs Python, which these devices do not have.

Example Variables

A complete, working configuration for two devices lives under tests/ and is the reference this collection is developed against:

File Contents
tests/group_vars/openwrt.yml Everything shared: network, wireless, mesh, DHCP, Wireguard, firewall, PBR, dropbear
tests/host_vars/archer.yml Per-device settings for a TP-Link Archer C7
tests/host_vars/mikrotik.yml Per-device settings for a MikroTik hAP ac²

That configuration:

  • Enables extroot on an external USB device
  • Creates an IoT network isolated from LAN, and disables the WAN IPv6 interface
  • Builds a B.A.T.M.A.N. mesh, separating LAN and IoT over VLAN ports bat0.2 and bat0.3
  • Replaces the stock APs with LAN (5 GHz) and IoT (2.4 and 5 GHz) APs, with 802.11r fast BSS transition
  • Configures dnsmasq, DHCP pools and static leases
  • Creates one Wireguard interface for inbound remote access and one for routing out through a VPS
  • Sets firewall zones, forwardings, rules and redirects
  • Routes selected domains through the VPS with policy-based routing

🖥 Supported OS

OS Status
OpenWrt 23.05 Supported
OpenWrt 22.03 Supported
OpenWrt 24.10 and newer Not supported — see Gotchas

Tested on:

📦 Roles

Name Description
batman B.A.T.M.A.N. adv mesh interfaces and mesh-capable wpad
dhcp dnsmasq options, DHCP pools and static leases
dropbear Dropbear SSH daemon settings and authorized keys
extroot External root on USB, with overlay migration and restore
firewall Defaults, zones, forwardings, rules, redirects, ipsets, NAT
mesh11sd 802.11s mesh interfaces and the mesh11sd daemon
network Globals, devices, interfaces, rules and routes
node_exporter Prometheus node-exporter-lua and its listen settings
pbr Policy-Based Routing service settings and policies
system Hostname, description, timezone and logging
wireguard Wireguard interfaces and peers, with key generation
wireless Radios and interfaces, including 802.11r fast roaming

⚠️ Gotchas

  • The host group must be named openwrt. The gekmihesg.openwrt vars plugin only rewrites ansible.builtin.* to its shell modules for hosts in a group with that exact name. Outside it, Ansible sends real Python modules to a device that has no Python and every task fails. See gekmihesg/ansible-openwrt.

  • OpenWrt 24.10 replaced opkg with apk. Every role installs packages through opkg, and gekmihesg.openwrt ships no apk wrapper, so package installation fails on 24.10 and newer. The UCI configuration tasks themselves are unaffected.

  • extroot repartitions and reboots. With extroot_enabled: true and no extroot yet configured, the role runs parted and mkfs.ext4 over the whole of extroot_device (sda by default), copies the overlay onto it and reboots the device. Everything on that disk is destroyed. The default is false.

  • batman and mesh11sd remove wpad packages. Both uninstall every variant listed in *_non_mesh_pkgs before installing wpad-mesh-wolfssl. On a device reached over Wi-Fi, that drops the connection.

  • pbr may replace dnsmasq with a snapshot build. If the installed dnsmasq-full is older than pbr_dnsmasq_full_required_version and the release feed has nothing newer, the role removes dnsmasq and installs dnsmasq-full, libubox and libubus from the OpenWrt snapshot feed — mixing snapshot packages into a release install.

  • extroot fetches two scripts from the OpenWrt wiki at run time and executes them, so what runs is whatever the wiki serves that day.

  • Every role is a no-op until configured. All list and dictionary variables default to empty, so a role with no configuration installs its packages (where it has any) and changes nothing else.

🧪 Testing

Devices are defined in tests/inventory.yml, and their variables in tests/group_vars/ and tests/host_vars/.

task provision   # run tests/playbook.yml against the inventory
task lint        # pre-commit over the whole collection
task build       # build the collection tarball

There is no VM harness: OpenWrt roles need real hardware, so provision runs against whatever tests/inventory.yml points at. The playbook reboots every device when it finishes.

📄 License

GPL-3.0-only

roles/batman/files/luci-proto-batman-adv.ipk is a prebuilt OpenWrt package redistributed here, under its own upstream licence.

👤 Author Information

fLy0v3rH34d

TODO

About

Ansible collection for automative configuration of OpenWrt devices (without Python).

Resources

Stars

22 stars

Watchers

5 watching

Forks

Releases

Contributors