mirror of
https://github.com/openwrt/packages.git
synced 2025-02-14 13:48:04 +00:00
379 lines
14 KiB
Markdown
379 lines
14 KiB
Markdown
# OpenWrt package feed for etherwake-nfqueue
|
||
|
||
|
||
## Wake up computers on netfilter match
|
||
|
||
This repository contains the OpenWrt package feed for
|
||
[etherwake-nfqueue](https://github.com/mister-benjamin/etherwake-nfqueue),
|
||
a fork of the **etherwake** Wake-on-LAN client, with support to send magic
|
||
packets only after a queued packet is received from the Linux *nfnetlink_queue*
|
||
subsystem.
|
||
|
||
When running **etherwake-nfqueue** on a residential gateway or other type of
|
||
router, it can wake up hosts on its network based on packet filtering rules.
|
||
|
||
For instance, when your set-top box wants to record a TV programme and
|
||
tries to access a network share on your NAS, which is in sleep or standby mode,
|
||
**etherwake-nfqueue** can wake up your NAS. Or when you set up port forwarding
|
||
to a host on your home network, **etherwake-nfqueue** can wake up your host
|
||
when you try to access it over the Internet.
|
||
|
||
The documentation below is mostly OpenWrt specific. For more information on
|
||
etherwake-nfqueue itself and use case examples, please consult its
|
||
[Readme](https://github.com/mister-benjamin/etherwake-nfqueue/blob/master/README.md).
|
||
|
||
|
||
## Building the package
|
||
|
||
Currently, no pre-built packages are provided. The following assumes that you
|
||
already have a working OpenWrt build system for your target device.
|
||
|
||
If you haven't, you can follow one of these guides:
|
||
|
||
* If you only want to compile packages, and no firmware image:
|
||
[Build system – Installation](https://openwrt.org/docs/guide-developer/build-system/install-buildsystem) and
|
||
[Using the SDK](https://openwrt.org/docs/guide-developer/using_the_sdk)
|
||
|
||
* To quickly build a firmware image off a development snapshot:
|
||
[Quick Image Building Guide](https://openwrt.org/docs/guide-developer/quickstart-build-images)
|
||
|
||
* Or when you are completely new to using build systems:
|
||
[Beginners guide to building your own firmware](https://openwrt.org/docs/guide-user/additional-software/beginners-build-guide)
|
||
|
||
### Dependencies
|
||
|
||
**etherwake-nfqueue** depends on these OpenWrt packages:
|
||
|
||
* libnetfilter-queue
|
||
* iptables-mod-nfqueue
|
||
|
||
They will be automatically selected and compiled for you. If they are not
|
||
installed on your target device, *opkg* will try to resolve dependencies with
|
||
packages in the repositories.
|
||
|
||
### Adding the package feed
|
||
|
||
First, you need to add the **etherwake-nfqueue** package feed to your build
|
||
system. In the root directory of your OpenWrt build system, find the file
|
||
*feeds.conf* (or *feeds.conf.default* if the former shouldn't exist) and add
|
||
the following line to it:
|
||
|
||
```
|
||
src-git ethernfq https://github.com/mister-benjamin/etherwake-nfqueue-openwrt.git
|
||
```
|
||
|
||
Then update and install the package feed:
|
||
```
|
||
user@host:~/openwrt$ scripts/feeds update ethernfq
|
||
user@host:~/openwrt$ scripts/feeds install -a -p ethernfq
|
||
```
|
||
|
||
After that, enter OpenWrt's configuration menu
|
||
```
|
||
user@host:~/openwrt$ make menuconfig
|
||
```
|
||
and enable **etherwake-nfqueue** in the **Network** sub-menu. It can either be selected
|
||
as built-in (\*) or module (M), depending on your decision to include it into a
|
||
firmware image or just build the *opkg* package for installation.
|
||
|
||
Then you should be able to compile the package:
|
||
```
|
||
user@host:~/openwrt$ make package/etherwake-nfqueue/compile
|
||
```
|
||
|
||
The path of the resulting package depends on your selected *Target System*.
|
||
In case of the Linksys WRT1200AC, it can be found here:
|
||
```
|
||
bin/packages/arm_cortex-a9_vfpv3/ethernfq/etherwake-nfqueue_2019-09-10-67e9d4ca-1_arm_cortex-a9_vfpv3.ipk
|
||
```
|
||
|
||
|
||
## Installation
|
||
|
||
One way to install the package is by simply copying it over to the device with *scp*:
|
||
```
|
||
user@host:~$ scp etherwake-nfqueue_2019-09-10-67e9d4ca-1_arm_cortex-a9_vfpv3.ipk root@gateway:~
|
||
```
|
||
And then, install it on the device:
|
||
```
|
||
root@gateway:~# opkg install etherwake-nfqueue_2019-09-10-67e9d4ca-1_arm_cortex-a9_vfpv3.ipk
|
||
```
|
||
|
||
|
||
## Configuration
|
||
|
||
### WoL Targets
|
||
|
||
After a fresh installation, no target is configured. Targets are referred
|
||
to as the hosts to wake up. Multiple targets can coexist.
|
||
|
||
Targets can be configured with OpenWrt's UCI.
|
||
|
||
For example, to add a target called **nas**, with MAC address
|
||
**00:25:90:00:d5:fd**, which is reachable over the VLAN configured
|
||
on **eth0.3**, issue this command sequence on your router:
|
||
|
||
```
|
||
uci add etherwake-nfqueue target
|
||
uci set etherwake-nfqueue.@target[-1].name=nas
|
||
uci set etherwake-nfqueue.@target[-1].mac=00:25:90:00:d5:fd
|
||
uci set etherwake-nfqueue.@target[-1].interface=eth0.3
|
||
uci commit
|
||
```
|
||
|
||
For each target, one instance of **etherwake-nfqueue** will be started.
|
||
|
||
Each instance should bind to a different *nfnetlink_queue*. A queue can
|
||
be referenced by its queue number. Counting starts from 0, which is the default.
|
||
To use a different queue, provide the **nfqueue_num** option. The
|
||
following could have been added to the sequence above to use queue 1 instead
|
||
of 0:
|
||
|
||
```
|
||
uci set etherwake-nfqueue.@target[-1].nfqueue_num=1
|
||
```
|
||
|
||
The necessity of a queue number will probably become clear, when the iptables
|
||
rules are configured in section [Setup firewall rules](#setup-firewall-rules).
|
||
|
||
The full list of options for a target is:
|
||
|
||
| Option | Required | Description |
|
||
| ----------- | -------- | ------------------------------------------------ |
|
||
| name | no | Name of the target, e.g. name=example |
|
||
| mac | yes | MAC address of the host to wake up, e.g. mac=00:22:44:66:88:aa |
|
||
| nfqueue_num | no | The queue number used for receiving filtered packets, default is nfqueue_num=0 |
|
||
| interface | no | The interface used for sending the magic packet, default is interface=eth0 |
|
||
| broadcast | no | Send magic packet to broadcast address, default is broadcast=off |
|
||
| password | no | Set a password (required by some adapters), e.g. password=00:22:44:66:88:aa or 192.168.1.1 |
|
||
| enabled | no | Optionally disable the target, default is enabled=true |
|
||
|
||
After committing your changes, the settings are persisted to
|
||
*/etc/config/etherwake-nfqueue*. This is an illustrative example:
|
||
```
|
||
config etherwake-nfqueue 'setup'
|
||
option sudo 'off'
|
||
option debug 'off'
|
||
|
||
config target
|
||
option name 'nas'
|
||
option mac '00:25:90:00:d5:fd'
|
||
option interface 'eth0.3'
|
||
|
||
config target
|
||
option name 'xyz-board'
|
||
option mac '00:25:90:00:d5:fc'
|
||
option nfqueue_num '1'
|
||
option enabled 'false'
|
||
|
||
config target
|
||
option name 'ip-camera'
|
||
option mac '00:25:90:00:d5:fb'
|
||
option nfqueue_num '2'
|
||
option interface 'eth0.3'
|
||
option broadcast 'on'
|
||
option password '00:25:90:00:d5:fb'
|
||
```
|
||
|
||
When all target(s) are configured, restart the *etherwake-nfqueue* service:
|
||
```
|
||
/etc/init.d/etherwake-nfqueue restart
|
||
```
|
||
|
||
### Setting up filters
|
||
|
||
Without any firewall rules which tell the kernel to match and add packets
|
||
to a *nfnetlink_queue*, **etherwake-nfqueue** will never send out a magic
|
||
packet to wake its target.
|
||
|
||
#### Prerequisites
|
||
|
||
In order to let the *netfilter* framework of the kernel see the packets,
|
||
they need to pass through the router. This is usually not the case when
|
||
hosts are on the same subnet and don't require network layer routing.
|
||
The data will only pass through the router's switch on the link layer.
|
||
|
||
As a consequence, we can only use packets as a trigger which need to be
|
||
routed or bridged by the router. Packets being forwarded between WAN
|
||
and LAN are of that type. For other SOHO use cases, partitioning your
|
||
network by means of subnets or VLANs might be necessary. The latter
|
||
is often used to set up a DMZ.
|
||
|
||
For VLANs:
|
||
|
||
* There's a mini howto referring to the **LuCI Web Interface**
|
||
*(Network -> Switch)* way of configuring VLANs:
|
||
[How-To: Creating an additional virtual switch on a typical home router](https://openwrt.org/docs/guide-user/network/vlan/creating_virtual_switches)
|
||
|
||
* The manual approach is documented here:
|
||
[VLAN](https://openwrt.org/docs/guide-user/network/vlan/switch_configuration)
|
||
|
||
Guides to setup a DMZ can be found here:
|
||
|
||
* [Guide to set up DMZ via LUCI](https://forum.openwrt.org/t/guide-to-set-up-dmz-via-luci/21616)
|
||
|
||
* [fw3 DMZ Configuration Using VLANs](https://openwrt.org/docs/guide-user/firewall/fw3_configurations/fw3_dmz)
|
||
|
||
The physical switch layout is device specific. E.g. the layout for the Linksys
|
||
WRT AC Series is documented
|
||
[here](https://oldwiki.archive.openwrt.org/toh/linksys/wrt_ac_series#switch_layout).
|
||
|
||
|
||
Using two LANs or VLANs with the same network address and bridging them again
|
||
is a trick to setup a transparent (or bridging) firewall on the same subnet.
|
||
This way, packets can be seen by *netfilter* on the router even if the
|
||
packets are not routed. Unfortunately this doesn't help when the host
|
||
which we want to wake up is offline, as the ARP requests for the destination
|
||
IP address are not answered and thus the client trying to reach out to its
|
||
destination will not send any *network layer* packets. We could use *arptables*
|
||
instead to wake the host when someone requests its MAC address, but this
|
||
would probably happen too often and no fine-grained control would be possible.
|
||
|
||
As a workaround, it might be possible to configure a static ARP entry on your
|
||
router (untested), e.g. with:
|
||
```
|
||
ip neigh add 192.168.0.10 lladdr 00:25:90:00:d5:fd nud permanent dev eth0.3
|
||
```
|
||
Note that this requires the *ip-full* OpenWrt package to be installed.
|
||
|
||
To make your firewall rules work with bridging, you need to install the
|
||
*kmod-br-netfilter* package and add `net.bridge.bridge-nf-call-iptables=1`
|
||
to */etc/sysctl.conf*.
|
||
|
||
|
||
#### Setup firewall rules
|
||
|
||
One way to setup custom firewall rules in OpenWrt is through its
|
||
*/etc/firewall.user* script. This file can also be edited by means of
|
||
the **LuCI Web Interface** *(Network -> Firewall -> Custom Rules)*.
|
||
|
||
The file is interpreted as a shell script, so we can simply use **iptables**
|
||
to add our custom firewall rules.
|
||
|
||
Notice the comment
|
||
```
|
||
# Internal uci firewall chains are flushed and recreated on reload, so
|
||
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
|
||
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.
|
||
```
|
||
|
||
Refer to [Packet flow](https://oldwiki.archive.openwrt.org/doc/uci/firewall#packet_flow)
|
||
for usable chains. In the example below, the chains *forwarding_lan_rule* and
|
||
*forwarding_wan_rule* are used. To inspect the rule sets of the different tables, one can
|
||
use
|
||
|
||
```
|
||
iptables --list # default is --table filter
|
||
iptables --table nat --list
|
||
iptables --table mangle --list
|
||
iptables --table raw --list # requires kmod-ipt-raw
|
||
```
|
||
|
||
The following is an example of what could be added to */etc/firewall.user*:
|
||
|
||
```
|
||
iptables --insert forwarding_lan_rule\
|
||
--protocol tcp --in-interface=br-lan --out-interface=eth0.3\
|
||
--destination 192.168.0.10 --destination-port 445\
|
||
--match conntrack --ctstate NEW\
|
||
--match limit --limit 3/hour --limit-burst 1\
|
||
--jump NFQUEUE --queue-num 0 --queue-bypass\
|
||
--match comment --comment "Wake up NAS on LAN SMB"
|
||
iptables --insert forwarding_lan_rule\
|
||
--protocol tcp --in-interface=br-lan --out-interface=eth0.3\
|
||
--destination 192.168.0.11 --match multiport --destination-ports 515,54921,631\
|
||
--match conntrack --ctstate NEW\
|
||
--match limit --limit 3/hour --limit-burst 1\
|
||
--jump NFQUEUE --queue-num 0 --queue-bypass\
|
||
--match comment --comment "Wake up NAS on print request"
|
||
iptables --insert forwarding_lan_rule\
|
||
--protocol udp --in-interface=br-lan --out-interface=eth0.3\
|
||
--destination 192.168.0.11 --destination-port 161\
|
||
--match conntrack --ctstate NEW\
|
||
--match limit --limit 3/hour --limit-burst 1\
|
||
--jump NFQUEUE --queue-num 0 --queue-bypass\
|
||
--match comment --comment "Wake up NAS on print request"
|
||
iptables --insert forwarding_wan_rule\
|
||
--protocol tcp --in-interface=eth1.2 --out-interface=eth0.3\
|
||
--destination 192.168.0.10 --destination-port 22\
|
||
--match conntrack --ctstate NEW\
|
||
--match limit --limit 3/hour --limit-burst 1\
|
||
--jump NFQUEUE --queue-num 0 --queue-bypass\
|
||
--match comment --comment "Wake up NAS on WAN SSH"
|
||
```
|
||
|
||
In this example, packets are filtered based on the protocol, their input
|
||
and output interfaces, their destination (IP address) and their destination
|
||
port(s).
|
||
|
||
The option `--match conntrack --ctstate NEW` only matches packets of a new
|
||
connection and `--match limit --limit 3/hour --limit-burst 1` limits the
|
||
amount of packets that are matched. The latter option roughly matches
|
||
only one packet per 20 minutes. The intention here is to not be too intrusive
|
||
and avoid sending a lot of magic packets.
|
||
|
||
The `--jump NFQUEUE --queue-num 0` options tell the *netfilter*
|
||
framework to enqueue a matching packet to the NFQUEUE number 0. In this
|
||
example, all four rules send the matching packets into queue 0. The
|
||
additional option `--queue-bypass` helps in the situation, when
|
||
**etherwake-nfqueue** isn't running. Packets will then be handled
|
||
as if the rule wasn't present.
|
||
|
||
|
||
## Disabling targets
|
||
|
||
To disable targets, first find their index:
|
||
```
|
||
uci show etherwake-nfqueue
|
||
```
|
||
|
||
Then set its *enabled* option to false and restart the service.
|
||
For index 0, it can be done like this:
|
||
```
|
||
uci set etherwake-nfqueue.@target[0].enabled=false
|
||
/etc/init.d/etherwake-nfqueue restart
|
||
```
|
||
|
||
|
||
## Troubleshooting
|
||
|
||
### Debug mode
|
||
|
||
In order to see what's going on in syslog and get some debug output when
|
||
starting the service, enable etherwake-nfqueue's debug mode:
|
||
```
|
||
uci set etherwake-nfqueue.setup.debug=on
|
||
```
|
||
In another user session tail the log:
|
||
```
|
||
logread -f
|
||
```
|
||
And then restart the service:
|
||
```
|
||
/etc/init.d/etherwake-nfqueue restart
|
||
```
|
||
|
||
### Inspect netfilter
|
||
|
||
To inspect the working of your firewall rules, you can print statistics
|
||
of the chains you used, e.g.:
|
||
```
|
||
iptables --verbose --list forwarding_lan_rule
|
||
```
|
||
|
||
If you happen to have the *procps-ng-watch* package installed, you can watch
|
||
them:
|
||
```
|
||
watch iptables --verbose --list forwarding_lan_rule
|
||
```
|
||
|
||
To see, if your queues are in place, use:
|
||
```
|
||
cat /proc/net/netfilter/nfnetlink_queue
|
||
```
|
||
|
||
## Potential improvements
|
||
|
||
* Add **LuCI Web Interface** configuration frontend for *targets* and *filter rules*
|
||
* Add an option to set *nice* values for instances
|