Ereshkigal

 view release on metacpan or  search on metacpan

docs/kurs/openwrt.md  view on Meta::CPAN

# openwrt — OpenWrt fw4 via UCI

Blocks on an OpenWrt router by way of fw4, configured through UCI
rather than by writing firewall rules directly. Two `config ipset`
sections and the `config rule` sections that drop on them are added to
`/etc/config/firewall`; fw4 renders each ipset into an nftables set in
its own `inet fw4` table.

The kur drives either the machine it runs on or a router across the
network. Leave `host` unset and it runs `uci`, `fw4`, and `nft`
locally; set it and everything goes over ubus JSON-RPC instead. Remote
is the usual choice, since OpenWrt ships no perl and so cannot host a
kur of its own.

```toml
[kur.sshd]
backend   = "openwrt"
ports     = [ "22" ]
protocols = [ "tcp" ]

[kur.sshd.options]
host     = "192.0.2.1"
user     = "blocker"
password = "hunter2"
zone     = "wan"
kill     = 1
```

## Router-side setup — required first for remote mode

Local mode needs none of this. Remote mode needs all of it, once per
router.

- Install the rpcd pieces. `uhttpd-mod-ubus` puts ubus on the web
  server; `rpcd-mod-file` provides the `file` object every `nft` and
  `fw4` call rides on.

```shell
apk add uhttpd-mod-ubus rpcd-mod-file

# on releases still using opkg
opkg update && opkg install uhttpd-mod-ubus rpcd-mod-file
```

- Confirm uhttpd serves the ubus endpoint, which is the path the kur
  posts to. Installing `uhttpd-mod-ubus` sets it, so this is a check
  rather than a step: `uci get uhttpd.main.ubus_prefix` should answer
  `/ubus`.

- Install the ACL as
  `/usr/share/rpcd/acl.d/net-firewall-blockerhelper.json`, then
  `/etc/init.d/rpcd reload`. Nothing grants `file` `exec` by default,
  so without it every `nft` and `fw4` call comes back as ubus
  permission denied.

```json
{
    "net-firewall-blockerhelper": {
        "description": "Net::Firewall::BlockerHelper openwrt backend",
        "read": {
            "ubus": { "uci": [ "get" ] },
            "uci": [ "firewall" ]
        },
        "write": {
            "ubus": {
                "uci": [ "add", "set", "delete", "order", "commit" ],
                "file": [ "exec" ]
            },
            "uci": [ "firewall" ],
            "file": {
                "/usr/sbin/nft": [ "exec" ],
                "/sbin/fw4": [ "exec" ]
            }
        }
    }
}
```

- Point a login at that ACL. The stock `root` entry in
  `/etc/config/rpcd` carries `list read '*'` and `list write '*'`, so
  it picks the new ACL up on its own and the default `user = "root"`
  needs nothing further. A dedicated account is the better idea and
  wants its own section, naming the ACL group — the top level key of
  the JSON above. `/etc/init.d/rpcd restart` afterwards.

```
config login
	option username 'blocker'
	option password '$p$blocker'
	list read 'net-firewall-blockerhelper'
	list write 'net-firewall-blockerhelper'
```

`$p$blocker` means the password of the system user of that name, out
of `/etc/shadow`; a crypt(3) hash or a plain string may be given
instead.

`/usr/share/rpcd/acl.d/` survives a reboot but is not carried across a
sysupgrade — add the file's path to `/etc/sysupgrade.conf`, or remote
mode starts answering permission denied after the next firmware
upgrade. `/etc/config/rpcd`, and so the login, is kept by default.

## What it creates

In `/etc/config/firewall`, with `S4`/`S6` being `<prefix>_<name>_4`



( run in 0.673 second using v1.01-cache-2.11-cpan-16aabcbfbcb )