Cut Internet temporarily in a device in your LAN

Just and one firewall, config the URLF and it´s done.
HA its nice but do not try to invent the wheel

1 Like

Could you elaborate a bit more?

I could see two scripts per device or maybe better per child. One to start the spoof and one to stop it.

with one toggle:
SPOOF_CHILD ON/OFF
when it goes to ON start the script
when it goes to OFF kill the script

Then we have lots of options:

  • The automation that you have would still work.
  • Manual kill switch :slight_smile:
  • Start now for x minutes
  • WiFi free Dinner Time
1 Like

That is a very smart strategy because, as you say, the options for automation increase. However, we have to think how to face the new situation because I know how to start the spoof (nohup sudo arpspoof […]) but I only know how to stop ALL of them (sudo killall arpspoof). Maybe it is possible to retain the PID of the arpspoof in order to kill it properly (sudo kill -9 PID). I’m going to think about it because, definitely, more automation flexibility is achived as you point out. Thanks!

Just guessing here:
create a little script that has just this line (accepting all the parameters) per child

SPOOF_CHILD1.sh

arpspoof -i ${INTERFACE} -t ${CHILD1_ADRS} ${ROUTER_ADRS}

then call it like

nohup sudo SPOOF_CHILD1.sh <parameters> > /dev/null 2>&1 &

and kill it like this:

sudo killall SPOOF_CHILD1.sh

this is all untested. I need to find a way to install arpspoof on my unraid box

@nodecentral , @datamonkey , thanks for your suggestions.

@datamonkey , while your approach may also work I already started to make modifications yesterday and have reached the solution explained below. So here are the changes to the first post:

Update to 2 devices and manual disconnection
Ok, so what I try to accomplish is summarized in the card shown in the next figure. The red box joins the elements needed to make a programmed control of the disconnection while the blue one corresponds to the manual (and immediate) disconnection/connection.

Let’s start explaining this card, which is saved, in my case, in .homeassistant/includes/groups/internet_control.yaml:

internet:
  name: 'Internet'
  control: hidden
  entities:
    - automation.disconnect_ipad_1_prog
    - automation.disconnect_ipad_2_prog
    - input_slider.internet_cut_time
    - input_slider.internet_cut_hour
    - input_slider.internet_cut_minutes
    - sensor.internetcuttime
    - switch.internet_ipad1
    - switch.internet_ipad2

It consists of the same three input_sliders explained earlier in this post and have not been modified. The sensor created to easily visualize the moment when the disconnection will happen remains the same, too.

The first two elements of the card is the automation for the programmed disconnection. Keep in mind that it is an automation with configurable starting and duration times on the fly; so no need to restart HA when re-programming the disconnection. I have these two entries in my automations.yaml file:

- id: id031
  alias: 'Disconnect iPad 1 (prog)'
  trigger:
    platform: time
    minutes: '/5'
    seconds: '0'
  condition:
    condition: template
    value_template: '{{ ((now().strftime("%s") | int ) | timestamp_custom("%H:%M")) == states.sensor.internetcuttime.state  }}'
  action:
    - service: shell_command.cut_internet_ipad1

- id: id032
  alias: 'Disconnect iPad 2 (prog)'
  trigger:
    platform: time
    minutes: '/5'
    seconds: '0'
  condition:
    condition: template
    value_template: '{{ ((now().strftime("%s") | int ) | timestamp_custom("%H:%M")) == states.sensor.internetcuttime.state  }}'
  action:
    - service: shell_command.cut_internet_ipad2

Programmed Internet disconnection can be applied to one or both devices. With the current setup only one program per day is allowed and, if both devices are activated, they will run with the same timing settings.
As in my previous post, the automation calls a shell_command that is in the file .homeassistant/includes/shell_commands/cut_internet.yaml and has been modified to include two devices:

cut_internet_ipad1: '/home/homeassistant/.homeassistant/includes/shell_scripts/control_internet.sh DE:VI:CE:ONE:MAC {{ states.input_slider.internet_cut_time.state }}'

cut_internet_ipad2: '/home/homeassistant/.homeassistant/includes/shell_scripts/control_internet.sh DE:VI:CE:TWO:MAC {{ states.input_slider.internet_cut_time.state }}'

which calls a complete renewed bash script with two arguments: MAC and programmed disconnection time. I have the bash scripts stored in .homeassistant/includes/shell_scripts folder and the file control_internet.sh is now:

#!/bin/bash
# Examples:
# Activate spoofing given a MAC address
# ./control_internet AA:BB:CC:DD:EE:FF on
# Deactivate spoofing given a MAC address
# ./control_internet AA:BB:CC:DD:EE:FF off
# Activate spoofing for 10 minutes given a MAC address
# ./control_internet AA:BB:CC:DD:EE:FF 10
CHILD_MAC=$1
INTERFACE=eth0
ROUTER_ADRS=192.168.0.1
if [ "$2" = "on" ]
then
# Activating manual spoof
    CHILD_ADRS=$(nmap -sP ${ROUTER_ADRS}/24 >/dev/null && arp -an | grep ${CHILD_MAC} | awk '{print $2}' | sed 's/[()]//g')
    sudo arpspoof -i ${INTERFACE} -t ${CHILD_ADRS} ${ROUTER_ADRS} > /dev/null 2>&1 & echo $! > /tmp/manualspoof-${CHILD_MAC}.pid
elif [ "$2" = "off" ]
then
# Deactivating manual spoof
    sudo pkill -P `cat /tmp/manualspoof-${CHILD_MAC}.pid`
    rm /tmp/manualspoof-${CHILD_MAC}.pid
else
# Activate temporarily spoof
    CUT_TIME=$2
    CHILD_ADRS=$(nmap -sP ${ROUTER_ADRS}/24 >/dev/null && arp -an | grep ${CHILD_MAC} | awk '{print $2}' | sed 's/[()]//g')
    sudo arpspoof -i ${INTERFACE} -t ${CHILD_ADRS} ${ROUTER_ADRS} > /dev/null 2>&1 & echo $! > /tmp/progspoof-${CHILD_MAC}.pid
    sleep ${CUT_TIME}m
    sudo pkill -P `cat /tmp/progspoof-${CHILD_MAC}.pid`
    rm /tmp/progspoof-${CHILD_MAC}.pid
fi

When the second argument is not “on” or “off” we assume that it is the programmed disconnection time (in minutes) and the else part of the script is run. This part is very similar to the script posted initially with some modifications to retrieve the PID of the arpspoof process, saving it in a temp file in order to kill the process when the disconnection time passes. What about the “on” or “off” conditions? Keep on reading.

The two last switches in the card account for manual (and instantaneous) disconnection as @datamonkey suggested. They are command line switches that I place in .homeassistant/includes/switches/manual_control_internet.yaml and contains:

# Internet manual disconnect switches
- platform: command_line
  switches:
    internet_ipad1:
      command_on: "/home/homeassistant/.homeassistant/includes/shell_scripts/control_internet.sh DE:VI:CE:ONE:MAC on"
      command_off: "/home/homeassistant/.homeassistant/includes/shell_scripts/control_internet.sh DE:VI:CE:ONE:MAC off"
      friendly_name: Disconnect iPad 1 (manual)

- platform: command_line
  switches:
    internet_ipad2:
      command_on: "/home/homeassistant/.homeassistant/includes/shell_scripts/control_internet.sh DE:VI:CE:TWO:MAC on"
      command_off: "/home/homeassistant/.homeassistant/includes/shell_scripts/control_internet.sh DE:VI:CE:TWO:MAC off"
      friendly_name: Disconnect iPad 2 (manual)

As you can observe each switch uses one MAC and calls the bash script commented before but in this case the second argument is “on” or “off”; to active the spoofing or stop it. Again, we save the PID information to a temp file in order to know which process we have to kill.

If we want to have a toogle switch in the frontend and not two separate lighting bolt icons, we have to add to our customization file this:

switch.internet_ipad1:
  assumed_state: false
switch.internet_ipad2:
  assumed_state: false

Extrapolation to more devices should be straightforward since no modification to the bash script is needed; just add the elements in the frontend and make slight modifications to the corresponding files. I have tested it and it works for me, although maybe there are combinations that I haven’t tried. Thanks for reading.

1 Like

I am trying this command - nmap -sP 192.168.0.124 >/dev/null && arp -an | grep xx:xx:xx:xx | awk ‘{print $2}’ | sed ‘s/[()]//g’

but i am not getting nay results. Tried 2-3 mac address connected to wlan0. I have given static IP to ipads.

Assuming your router IP is 192.168.0.1 it lacks a / symbol, that is:

nmap -sP 192.168.0.1/24

Assuming your router IP is 192.168.0.124 it lacks a /24 string, that is:

nmap -sP 192.168.0.124/24

Could that be the issue?

Oh sorry that was a typo . I am giving command with 192.168.0.1/24 . If i do nmap -nsP 192.168.0.1/24 it is showing the ip i am using for ipads

Good to know! I’m looking at the man page for nmap and it’s huge. I found this: In previous releases of Nmap, -sn was known as -sP.
So maybe the args that I used in nmap (which I took somewhere on the Internet) are outdated or do not fit in every situation. So, thanks for telling that nmap -nSP works for you. As stated in my disclaimer, unfortunately, I’m good at Google-fu but my knowledge in these topics is very limited :pensive:

:slight_smile: You got me wrong. I only get result of all the network’s ip’s connected to the router if i give command nmap -nsP 192.168.0.1/24 but if i give nmap -sP 192.168.0.1/24 >/dev/null && arp -an | grep xx:xx:xx:xx | awk ‘{print $2}’ | sed ‘s/[()]//g’ i get nothing on the screen.

Ok, it seems I’m also rather limited at understanding other people :slight_smile:
In my case I obtain the same output using nmap -nsP or nmap -sP:

Starting Nmap 6.47 ( http://nmap.org ) at 2017-06-21 09:49 CEST
Nmap scan report for 192.168.0.1
Host is up (0.0058s latency).
Nmap scan report for 192.168.0.8
Host is up (0.0017s latency).
Nmap scan report for 192.168.0.192
Host is up (0.012s latency).
Nmap scan report for 192.168.0.196
Host is up (0.045s latency).
Nmap scan report for 192.168.0.197
Host is up (0.024s latency).
Nmap scan report for 192.168.0.200
Host is up (0.010s latency).
Nmap done: 256 IP addresses (6 hosts up) scanned in 3.47 seconds

The only difference is the time it takes to scan: 15.76 seconds (with -sP) and 3.47 seconds (with -nsP)
Anyway, what happens if you type arp -an?
I get this:

[...]
? (192.168.0.86) at <incomplete> on eth0
? (192.168.0.61) at <incomplete> on eth0
? (192.168.0.71) at <incomplete> on eth0
? (192.168.0.34) at <incomplete> on eth0
? (192.168.0.192) at JUST:SOME:MAC:ADD:RESS:HERE [ether] on eth0
? (192.168.0.10) at <incomplete> on eth0
[...]

I got it working… Thanks :slight_smile:

1 Like

Impressed! I had some functionality on my router similar to this, but it did not work very well.

So I installed the Dinnertime Pluss app ( http://www.dinnertimeapp.com ) on each of the childrens devices. It works ok, but sometimes stops responding.

The kids really hate it, but it was last resort before selling their devices. They really got addicted …

1 Like

What was your work around?

nmap -sn 192.168.1.1/24 >/dev/null && arp -an | grep [redacted mac] | awk ‘{print $2}’ | sed ‘s/[()]//g’

This only loops back to the command line, without greping anything out.

Can’t check sd card crashed again just created whole system again 2 days back :frowning: . Waiting for new power supply and ssd card.

FYI, back when I was using the raspberry Pi’s as my HA system, I used one of these to eliminate power supply issues, outage/brown-outs:

https://www.amazon.com/gp/product/B00MQSMEEE/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1

Worked well for me. Ran it for hours!

You could try this in the command line: arp -an
I get this:

[...]
? (192.168.0.86) at <incomplete> on eth0
? (192.168.0.61) at <incomplete> on eth0
? (192.168.0.71) at <incomplete> on eth0
? (192.168.0.34) at <incomplete> on eth0
? (192.168.0.192) at JUST:SOME:MAC:ADD:RESS:HERE [ether] on eth0
? (192.168.0.10) at <incomplete> on eth0
[...]

Later we could see why the grep pipe does not work.

This is just what i’m looking for, but i only need the option to switch OFF and ON the internet connection for the iPads.
Is it enough to just use the new control_internet.sh script and the command line switches?
Per

That’s it @perevers , that should be enough to get it working. I’m assuming that you have arpspoof installed and that the next one-line code gives you an IP address when you type it in the command line (other users found some issues):

nmap -sP ROUTER_ADRS/24 >/dev/null && arp -an | grep CHILD_MAC | awk '{print $2}' | sed 's/[()]//g'

Good luck and don’t hesitate to ask if you get stuck.