Presence Detection in WLAN

Sunday, September 9. 2018

 I was not content with the network/pingdevice based presence detection openhab2 offers. While it finds and detects smarphones connect to the wlan, it soon gets beaten by some energy-savong sleep modes, so the device does not ping. It may still respond to arping, though.

The following script is used on a linux router with several interfaces where a device miight be reachable. It can be configured from a settings.ini, reads it's sc an targets from a different ini file and reports it's findings via openHab's REST api.

settings.ini:

[settings]
baseUrl=http://koel.intern:8080/rest/items/
interval=30
interfaces=eth0,eth2


baseUrl points to the REST api of the openHab2 server, interfaces is a comma separated list of the interface/s that should get scanned and interval gives the number of seconds the scanner will sleep between to scans

scan.ini:

[feng]
item=presence_feng
MAC=C0:EE:FB:43:A8:ED

[goldAmmer]
item=presence_goldammer
MAC=192.168.123.11


[ente]
item=presence_ente
MAC=192.168.123.99


Each device has its own section with the section name acting as the unique id of the device, item is the openHab item (expected to be a Switch) that should get the result (ON or OFF) and MAC has the MAC or IP of the device 

The scanner is done in python (2.7)
arpscan.py:

#!/usr/bin/env python
#############################

import ConfigParser
import string
import os
import subprocess
import time
import sys

conf={}
devices={}
interfaces=""
scantext=""
grace=3

def get_script_path():
   return os.path.dirname(os.path.realpath(sys.argv[0]))
        
def LoadConfig(file, config={}):
   """
   returns a dictionary with keys of the form
   <section>.<option> and the corresponding values
   """
   config = config.copy(  )
   cp = ConfigParser.ConfigParser(  )
   cp.read(file)
   for sec in cp.sections(  ):
       name = string.lower(sec)
       obj  = { }
       for opt in cp.options(sec):
           obj[string.lower(opt)] = string.strip(
               cp.get(sec, opt))
       config[name]=obj
   return config

def ScanThings():
       scantext=""
       for interface in interfaces:
           p = subprocess.Popen(["arp-scan","-l","-q","-r","3", "-I", interface], stdout=subprocess.PIPE)
           output, err = p.communicate()
           scantext += output
                
       for key in devices:
           device=devices[key]
           url=conf['settings']['baseurl']+device['item']
           if device["mac"].lower() in scantext.lower():
               print key+" ja"
               val = "ON"
               device["tap"]=0
           else:
               print key+" nein"
               device["tap"] = device.get("tap", 0) + 1
               if device["tap"] <= grace:
                   print key+" tap: "+str(device["tap"])
                   val="na"
               else:
                   val="OFF"
                    
           if val != "na":         
               os.system('/usr/bin/curl --silent --header "Content-Type: text/plain" --request POST --data '+val+' '+url)


conf=LoadConfig(get_script_path()+"/"+"settings.ini", conf)
devices=LoadConfig(get_script_path()+"/"+"scan.ini",devices)

interfaces=conf['settings']['interfaces'].split(",")


while 1:
   ScanThings()
   time.sleep(float(conf['settings']['interval']))

 

           

 

           

The script is most useful when run as a daemon. You can easily do this with systemd which uses .service files found in /lib/systemd/system/

arpscan.service:

[Unit]
Description=Run arpscan device detection
After=multi-user.target
 
[Service]
Type=simple
ExecStart=/usr/bin/python /usr/local/bin/presence/arpscan.py
Restart=on-abort
 
[Install]
WantedBy=multi-user.target

The scanner reads settings and scan data, runs an arpscan on each configured interface and finally searches the specified MAC (or IP, just one of the two is needed) in the result.
it needs the linux arp-scan package to be installed, which you can test and confirm by running

arp-scan -l -I eth0

from the commandline. It needs to be run as root.

Some devices may show up oscillating between on and off, to get more stable results the script waits for a number of fails before the "OFF" result is sent. This can be finetuned by the value for grace. 

 

ipv6 bei hetzner

Tuesday, December 30. 2014

 schon schräg. IPv6 humpelt immer noch.

Neuen root server bei hetzner bestellt (EX40 im RZ 21), Debian-77-wheezy-64-minimal drauf. Erste Aktion die neuen IPs auf dns.he.net eingetragen, host erkennt sie sofort, also als naechstes ein ssh auf den neuen Vogel. Dauert, und dauert, und .. Ok, ssh -4 neuerVogel.domain.tld: zap ist er da.

Gleich ein ping6 heise.de und 

PING heise.de(redirector.heise.de) 56 data bytes
From Debian-77-wheezy-64-minimal icmp_seq=1 Destination unreachable: Address unreachable
From Debian-77-wheezy-64-minimal icmp_seq=2 Destination unreachable: Address unreachable
From Debian-77-wheezy-64-minimal icmp_seq=3 Destination unreachable: Address unreachable
^C
--- heise.de ping statistics ---
6 packets transmitted, 0 received, +3 errors, 100% packet loss, time 5030ms
 
Na fein, Tante Google findet mir serverfault.com/questions/477471/ipv6-only-works-after-pinging-the-default-gateway mit einer Problembeschreibung, die ich voll nachvollziehen kann. Nur die dort beschriebene Lösung bleibt hier wirkungslos.
Zahllose google/test/reboot - Zyklen später bleibt als Ergebnis meiner Recherche:
- verblüffend wenige Fundstellen. IPv6 scheint wirklich kaum jemanden zu interessieren.
- der einzige auf meinem Rechner funktionierende Weg ist, den im obigen Link beschriebenen Workaround
  ping6 -I eth0 -c3  fe80::1
mit etwas sleep davor und danach in /etc/rc.local zu packen. slep 1 war zu wenig, sleep 10 tuts scheinbar.
 
Das ist doch kaum zu glauben, dass das Hetzner/debian - Image IPv6 nicht auf Anhieb klaglos hinbekommt sondern ich eine solche Krücke einsetzen muss! 
Vor gefühlt 10+ Jahren habe ich mir IPv6-Tunnel von sixxs und später he.net auf Hetzner-Server gelegt und die waren schneller benutzbar konfiguriert als das 'native' heute ...
 
 

KRDC kann kein vnc

Sunday, August 18. 2013

 Ich hatte den Remote Desktop Client krdc mit pacman -S kdenetwork-krdc allein installiert, aber es ging und ging nicht. Den gewohnten Aufruf aus der konsole lehnte er mit Verweis auf nicht unterstützte URL ab und bei manuelle Auswahl bot er nur RDP aber kein VNC an. Google wusste gar keinen Rat. Die Antwort erriet ich aus der Beschreibung im KDE-Userbase Wiki: Krdc is one of a pair of KDE programs (Krfb is the other) 

Krdc funktioniert nur, wenn kdenetwork-krfb auch installiert ist.

Arch Linux und VirtualBox

Monday, September 24. 2012

 Mal eine Nase in Arch Linux gesteckt und eine vm (unter Virtual Box 4.1.22) damit angelegt. Der erste Schritt der Installation klingt vertraut, man lädt und startet ein Live-Image. Nur, wenn man sich jetzt so was wie Mint vorgestellt hat, grafische Oberfläche und ein freundlicher Button "Installiere mich" - wird man sich etwas die Augen reiben. das Live Image startet (sehr flink!) in eine Konsole und der Rest geht zu Fuß nach den Steps des Beginners Guide. Bei der Suche nach Installationspaketen hilft www.archlinux.org/packages/

Die vm, die per default erstmal mit der "Intel Pro/1000 MT Desktop" Nic und NAT als Netzwerkeinstellung eingerichtet war, hatte ich wie üblich ein den Modus Netwerkbrücke / Bridged Networking" umgestellt, damit die vm von anderen rechnern im Lan erreichbar ist und IPv6 gleich geht. So, und nun bekam ich super lahmen Netwerktransfer. 5-10 KiB/sec, in Spitzen auch mal 15 KiB/s - ging gar nicht. Selbst im laufenden Betrieb zuück nach NAT wechseln, dem GastOS 2 min Zeit zum umstellen geben und der Trnfer sprang auf das 100- bis 300fache.

Googlen auf "arch linux virtualbox slow" ergab nicht viel, verstreute Ratschläge, den hostname in /etc/hosts einzutragen. Meine Massnahmen waren:
- hostname als fqdn setzen
- hostname in /etc/hosts eintragen
- in VBox als Netzwerk-Hardware auf virtio-net wechseln
Die ersten beiden sind ja ohnehin Teil der Installation und änderten auch nichts an dem Problem, der Wechsel auf das virtio - Netzwerk machte dagegen den grossen Unterschied aus. Ich habe später die verschiedenen Netzwerk-Karten der Reihe nach ausprobiert und alle drei Intel-Varianten lieferten die gleiche, schneckenlahme Performance.

copy/paste der Zwischenablage zwischen Host und Guest funktioniert noch nicht, ansonsten unauffällig.


update 3.11.2012:
insgesamt hat mir arch linux bei dem test so gut gefallen, dass ich wenig spaeter auch auf dem host, meinem normalen Arbeitsrechner, auf  Arch umbestiegen bin und damit derzeit recht zufrieden bin. 

Mit IPv6 sind Adressen nun nicht eben knapp und ein Interface kann etliche globale IPs haben - wie kann man Einfluss darauf nehmen, welche davon für ausgehende Verbindungen genutzt wird?

Ich fand ein nützliche Beschreibung der Auswahl, zwei Infos daraus waren mir nützlich:

- Wenn mehrere globale Adressen alle anderen Auswahlkriterien bestanden haben, nimmt Linux die zuletzt hinzugefügte.
- Man kann bestimmte Adressen als "deprecated" markieren, so dass sie bei der Auswahl nicht berücksichtigt werden.
ip -6 addr change 2001:db8:F00::BA2/128 dev eth0 preferred_lft 0
(Hm. So steht's da, aber im Test passiert etwas ganz anderes: die Adresse wird nicht als deprecated markiert, stattdessen steht da nun valid_lft forever preferred_lft forever. Statt dem beabsichtigten 'Mach schnell mal 'ne neue Adresse' ist es ein: 'Nimm jetzt immer diese' geworden, grad das Gegenteil.)

 

Nicht alles geht so, wie ich es erwartet hätte:  eine manuell (in /etc/network/interfaces) vergebene IPV6 und privacy extension. Ich würde halt gern einem Rechner eine 'nette' IPv6 verpassen, was mit dem hex-Zeichensatz und etwas leetspeak ja gut möglich ist. Ein besonders schoenes beispiel sieht man etwa mit host facebook.com  . Und gleichzeitig möchte ich für von dem Rechner ausgehende Verbindungen die privacy extensions aktivieren, also Adressen mit scope global temporary dynamic verwenden. Und das klappt nicht (verlässlich). Nach einem reboot sehe ich zuweilen eine temp Adresse verwandt, aber bald schon ist es doch die manuelle Adresse, die in den Logs auftaucht. 
cat /proc/sys/net/ipv6/conf/eth0/use_tempaddr gibt eine 2 aber ip -6 addr listet nur eine globale Adresse mit valid_lft forever preferred_lft forever.

Ist Autokonfiguration aktiv, dann bleibt die automatische IP, die ja nach einer festen Regel gebildet wird, stabil, solange man nicht mit der MAC herumspielt. (Man erkennt die automatischen IPs daran, dass an der Grenze zum letzten Drittel, also Byte 12 und 13, immer ff:fe steht.) Und dann werden für ausgehende Verbindungen auch die temporären Adressen verwandt. 

 

(Page 1 of 3, totaling 12 entries) » next page