Most routers with custom firmware (Tomato, DD-WRT, OpenWRT, etc) are likely allowing IPTABLES changes. Devices (both wireless and wired) can be permitted, per MAC or per IP, to connect to LAN but prevented from accessing Internet by modifying FORWARD chain.
This can come handy for keeping kids off internet (at least before the age of 5; afterwards they will likely be smarter than you) or keeping on LAN access only rogue devices that are home calling, only allow a device to connect to internet in order to upgrade firmware, etc.
*Router used below is an Asus running Merlin firmware (https://github.com/RMerl/asuswrt-merlin) and some of the specific commands could be different for other brands.
I. On HA host: set login without password and create switch that will kill internet for chosen device
1. Generate keys (take notice on folder used for storing)
1a. If running Hassio, create folder /config/.ssh
if it doesn’t exist in order to preserve keys after reboot (/root/.ssh
gets cleared at boot in my case although it seems to be solved a long time ago https://github.com/hassio-addons/addon-ssh/issues/3).
user@hass:~$ mkdir /config/.ssh
user@hass:~$ ssh-keygen -t rsa
1b. On Hassio change destination to /config/.ssh/id_rsa
instead of /root/.ssh/id_rsa
Don’t set a passphrase (press Enter twice)
2. Create switch configuration
switch:
- platform: command_line
switches:
control_internet_host_a:
command_on: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa [email protected] sh /jffs/scripts/block_host_a.sh
command_off: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa [email protected] sh /jffs/scripts/allow_host_a.sh
Note: on Hassio use:
command_on: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /config/.ssh/id_rsa [email protected] sh /jffs/scripts/block_host_a.sh
command_off: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /config/.ssh/id_rsa [email protected] sh /jffs/scripts/allow_host_a.sh
3. Connect to router at least once from HA machine (most common users are admin or root) and input password:
user@hass:~$ ssh [email protected]
[email protected]'s password:
4. Copy public key to router’s authorized keys (change source of /root/.ssh/id_rsa.pub
to /config/.ssh/id_rsa.pub
if set different in step 1)
user@hass:~$ cat /root/.ssh/id_rsa.pub | ssh [email protected] 'cat >> .ssh/authorized_keys'
[email protected]'s password:
Connecting again from HA host to router (user@hass:~$ ssh [email protected]
) should not require password anymore.
II. On the router: create scripts needed for blocking/allowing internet
*Asus router is holding custom scripts in folder /jffs/scripts
(possibly different on other brands). I’ve used post-mount instead of earlier time in boot below as I’m running adblocker by loading a list of hosts and sometimes not all hosts are updated.
A. Create folder to store keys (probably already exists)
admin@router:/# mkdir -p .ssh
B. Create block host script
admin@router:/# nano /jffs/scripts/block_host_a.sh
#!/bin/sh
iptables -I FORWARD -i br0 -m mac --mac-source 00:00:00:00:00:01 -j DROP
ctrl+x to save
C. Create allow host script
admin@router:/# nano /jffs/scripts/allow_host_a.sh
#!/bin/sh
iptables -D FORWARD -i br0 -m mac --mac-source 00:00:00:00:00:01 -j DROP
D. Make scripts executable
admin@router:/# chmod a+rx /jffs/scripts/block_host_a.sh
admin@router:/# chmod a+rx /jffs/scripts/allow_host_a.sh
E. Choose default start behaviour
Case only wanting to run the block upon request, the above config is sufficient.
E2. Otherwise, in order to block host at router boot, add the content of the block host script to post-mount (or create the file if it doesn’t exist):
admin@router:/# nano /jffs/scripts/post-mount
iptables -I FORWARD -i br0 -m mac --mac-source 00:00:00:00:00:01 -j DROP
(make sure post-mount starts with #!/bin/sh)
E3. In order to delete IPTABLES blocking rule(s) restart firewall or set a script on the router accessible from HA.
admin@router:/# nano /jffs/scripts/temporary_reset_blocking.sh
#!/bin/sh
service restart_firewall
set script as executable:
admin@router:/# chmod a+rx /jffs/scripts/temporary_reset_blocking.sh
Once the router is rebooted, the hosts included in post-mount are prevented from accessing Internet. Individual hosts can then be allowed by running allow_host_a.sh
or all in one sitting by running temporary_reset_blocking.sh
(hosts will be blocked again once router is rebooted or post-mount
executed).