Node „pcap“ Module – Error: „socket: Operation not permitted“ – Fehler wenn PcapSession geöffnet wird

Für unixartige Betriebssysteme stellt die Bibliothek „libpcap“ (packet capture library) Funktionen zur Verfügung, um den Datenverkehr, welcher über die Netzwerkschnittstellen läuft, mitzuschneiden und zu analysieren. Das JavaScript Modul „pcap“ stellt die entsprechenden Bindungen (engl. Bindings) für diese Bibliothek zur Verfügung. Diese können dann mit Node.js verwendet werden.

Problem

Diese Bibliothek wird gerne in Node.js Modulen, wie z. B. dem Amazon Dashbutton Adapter für ioBroker, verwendet. Da die libpcap Bibliothek auf Funktionen des Betriebssystems zugreift, kann es zu folgender Fehlermeldung kommen, wenn der Code ausgeführt wird.

Error: socket: Operation not permitted

Der Benutzer, durch den der Code ausgeführt wurde, besitzt anscheinend nicht die notwendigen Rechte.

Am Beispiel des Amazon Dashbutton Adapters, würde dann folgende Fehlermeldung im Log auftauchen.

error   at Adapter. (/opt/iobroker/node_modules/iobroker.amazon-dash/main.js:50:29)
error   at Object.exports.createSession (/opt/iobroker/node_modules/iobroker.amazon-dash/node_modules/pcap/pcap.js:123:12)
error   at new PcapSession (/opt/iobroker/node_modules/iobroker.amazon-dash/node_modules/pcap/pcap.js:49:39)
error   Error: socket: Operation not permitted
error   uncaught exception: socket: Operation not permitted

Lösung

Um das Problem zu lösen, müssen die Dateisystem „Capabilities“ für das Programm „node“ angepasst werden. Dies kann durch das Kommandozeilen-Tool „setcap“ erreicht werden.
Hierzu muss folgender Befehl in der Kommandozeile ausgeführt werden.

sudo setcap 'cap_net_raw,cap_net_admin+eip' $(readlink -f $(which node))

Mit dem Tool „getcap“ kann geprüft werden, ob alles korrekt gesetzt wurde. Hierzu muss folgender Befehl in der Kommandozeile ausgeführt werden.

sudo getcap $(readlink -f $(which node))

Dies Ausgabe sollte dann z. B. so aussehen:

/usr/bin/nodejs = cap_net_admin,cap_net_raw+eip

Hier noch eine kurze Erklärung aus der Dokumentation

 In many distributions you can use the 'setcap' utility to add capabilities to individual files.
 CAP_NET_RAW: 
       Allow use of RAW and PACKET sockets.
 CAP_NET_ADMIN:
       Allow various network-related operations (e.g. setting privileged socket options, enabling multicasting, setting promiscuous mode, interface configuration, modifying routing tables).
       The “+eip” means you’re adding the file capability sets Effective, Inherited and Permitted.
       
       Each thread has three capability sets containing zero or more of the above capabilities: 
		 The three file capability sets are:
             e: Effective  -  The capabilities used by the kernel to perform permission checks for the thread. 
             i: Inherited  -  The capabilities preserved across an execve(2). A child created via fork(2) inherits copies of its parent's capability sets. See below for a discussion of the treatment of capabilities during exec(). Using capset(2), a thread may manipulate its own capability sets, or, if it has the CAP_SETPCAP capability, those of a thread in another process.
             p: Permitted  -  The capabilities that the thread may assume (i.e., a limiting superset for the effective and inheritable sets). If a thread drops a capability from its permitted set, it can never re-acquire that capability (unless it exec()s a set-user-ID-root program).


Prüfung

Um zu prüfen, ob das pcap Module korrekt funktioniert, kann die im Module mitgelieferte Bespieldatei „network_grep.js“ über die Kommandozeile ausgeführt werden. Diese Datei befindet sich z. B. im Ordner „node_modules“ unter pcap/examples/network_grep.js

Beispiel Befehl:

node /opt/iobroker/node_modules/pcap/examples/network_grep.js

Hier sollte dann folgender Fehler NICHT mehr auftreten:

/opt/iobroker/node_modules/pcap/pcap.js:49
        this.link_type = this.session.open_live(this.device_name, this.filter, this.buffer_size, this.outfile, packet_ready, this.is_monitor);

Error: socket: Operation not permitted
    at new PcapSession (/opt/iobroker/node_modules/pcap/pcap.js:49:39)
    at Object.exports.createSession (/opt/iobroker/node_modules/pcap/pcap.js:123:12)
    at Object.<anonymous> (/opt/iobroker/node_modules/pcap/examples/network_grep.js:2:25)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:427:7)

OData V4 – Implementierung eines Services unter Java EE mittels Apache Olingo

Aktuell beschäftige ich mich damit, wie Daten strukturiert von einer Java EE Anwendung abgerufen und einem Client zur Verfügung gestellt werden können. Bisher habe ich RESTful Web Services implementiert, welche die Daten im JSON-Format geliefert bzw. verarbeiten haben. Hierzu wurde z. B. das Jersey Framework (Referenzimplementierung) verwendet, welches die Java API for RESTful Web Services (JAX-RS) Spezifikation implementiert. Dabei ist zwar JSON ist ein kompaktes und schlankes Datenaustauschformat, jedoch war es hier umständlich weitere Metadaten zu integrieren.

Auf der Suche nach möglichen Lösungansätzen bin ich auf das Open Data Protocol (OData) gestoßen. Dieses Protokol wurde von Microsoft entworfen und definiert einen Standard, um einen strukturierten Datenaustausch zu ermöglichen. Die Schwerpunkte des Protokols liegen grundsätzlich bei der Server-zu-Server-Kommunikation und der Möglichkeit, einen angebotenen Service mittels einen Servicedokuments und des Datenmodells (EDM) einzubinden zu können.

Die ersten OData Versionen 1-3 wurden per Microsoft Open Specification Promise freigegeben. Die Version 4.0 wurde nach der Übergabe an OASIS und dessen Weiterentwicklung, am 26. Februar 2014 freigegeben.

Im OData-Standard werden u. a. die Definition des Datenmodells per Entity Data Model (EDM), der Datenaustausch mittels Services im Service Document und die Datenformate wie z. B. Atom und JSON festgelegt. Zusätzlich sind Funktionen in Form der System Query Options, Service Operations und Batch Processing definiert. Dadurch ist es mittels Query-Anfragen ($filter, $select, $top ..) möglich, die Datenmenge einzugrenzen und somit nur die notwendigen Daten abzurufen. Die Bearbeitung der Daten kann mit CRUD-Operationen nach den REST-Prinzipien erfolgen.

OData Java-Bibliotheken

Die Recherche nach Java-Bibliotheken, welche die OData V4 Spezifikation implementieren, war leider etwas ernüchternd. Im Vergleich zu anderen Programmiersprachen (wie z. B. .NET) konnte ich nur eine Handvoll an Bibliotheken finden, die erstmal vielversprechend aussahen. Leider stellte sich schnell heraus, dass die Meisten davon nur die OData Spezfikationen von Version 1-3 implementiert haben. In die engere Auswahl kam somit mich eigentlich nur das SDL OData Framework und die Apache Olingo Projekt.

SDL OData Framework

Das SDL OData Framework implementiert die OData V4 Spezifikation und bietet nicht nur die serverseitige Komponente, sondern auch die Möglichkeit zur Entwicklung eines OData Java Clients. Ein weiterer Pluspunkt ist, dass es sowohl eine JPA Erweiterung gibt, sowie die Möglichkeit das EDM mittels Java-Annotationen zu definieren. Leider scheint dieses Framework hauptsächlich in Verbindung mit Spring bzw. Spring Boot gedacht zu sein und ist somit im Java EE Umfeld eher umständlich einzusetzen.

Apache Olingo Bibliotheken

Das Apache Olingo Projekt besteht aus einer Sammlung von Java und JavaScript Bibliotheken und bietet aktuell Support für die OData V2 und die OData V4 Version. Leider bietet aktuell nur die OData V2 Implementierung einen JPA Prozessor und die Unterstützung für Java-Annotationen zur Definition des EDM an. Die Implementierung des V4 Standards selbst, scheint für mich aber ausgereift, deshalb lohnte es sich, die Bibliotheken etwas detailierter zu betrachten.

Beispielprojekt: Java EE – OData V4 Service mittels Apache Olingo

Auf Basis des Tutorials „Basic Tutorial: Create an OData V4 Service with Olingo“ habe ich ein kleines Beispielprojekt erstellt. Die Java EE Web-Anwendung stellt einen OData V4 Service bereit, welcher mit Hilfe der Apache Olingo Bibliothek erstellt wurde.

Eigene EDM Java-Annotationen

Um die Erstellung des OData Services etwas flexibler zu haben, wurden eigene Java-Annotationen und ein spezieller Annotationen-Prozessor erstellt, um auch in Version 4 die Definition des EDM mittels Annotationen zu ermöglichen.

Quellcode

Der komplette Quellcode für dieses Projekt, kann in meinem GitHub Repository gefunden werden:
GitHub: ODataV4 – JavaEE – Example – Apache Olingo

PrimeFaces Dialog: Größe (Breite & Höhe) dynamisch am Viewport (Browserfenster) anpassen

Verwendet eine Webanwendung Dialoge, kann es sinnvoll sein, die Größe dynamisch am Viewport (Anzeigebereich) des Browserfensters anpassen zu lassen. Die JSF Bibliothek PrimeFaces liefert bereits eine fertige Dialog Komponente als Overlay mit, bei der die Größe eingestellt werden kann.

Größenangabe in Prozent (%)

Leider nützt es nichts, einfach die Angaben der Breite und/oder Höhe in Prozent anzugeben, da dies nicht den gewünschten Effekt mit sich bringt. Die Höhe richtet sich nicht nach der Relation zum Browserfenster, sondern nach dem Inhalt des Dialogs.

Facelet

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <title>Viewport height/width example</title>
    </h:head>

    <h:body style="background-color: #cacaca">
        <p:dialog visible="true" height="80%" width="80%">
            dialog with percentage height (80%) and width (80%)
        </p:dialog>     
    </h:body>  
</html>

Ergebnis:

Größenangabe in Prozent (%)

Größenanpassung mit JavaScript

Um die Größe trotzdem dynamisch am Viewport anpassen zu können, musste bisher eine Lösung über JavaScript erstellt werden, womit die Größe dynamisch berechnet und angepasst wird. Zusätzlich musste auch auf die Größenänderung des Viewports reagiert werden, wenn z. B. die Größe es Browserfensters verändert wurde. Diese Methode funktioniert zwar, ist aber umständlich. Deshalb werde ich hier nicht detailierter darauf eingehen.

Größenangabe mit CSS3 Viewport Units

In CSS3 gibt es einige neue Einheiten für relative Maße, womit u. a. die Breite beziehungsweise die Höhe in Relation zum Anzeigebereich angegeben werden kann.

  • vw (Viewport-Breite)
    100vw entspricht der vollen Breite des Viewports (Anzeigebereichs).
  • vh (Viewport-Höhe)
    100vh entspricht der vollen Höhe des Viewports (Anzeigebereichs).

Mit diesen Möglichkeiten erziehlt man dann auch sehr einfach den gewünschten Effekt.

Facelet

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <title>Viewport height/width example</title>
    </h:head>

    <h:body style="background-color: #cacaca">
        <p:dialog visible="true" height="80vh" width="80vw">
            dialog with viewport height (80vh) and width (80vh)
        </p:dialog>       
    </h:body>  
</html>

Ergebnis:

Größenangabe mittels Viewport Unit (vh/vw)

Browser Support
Die Viewport Units „vw“ und „vh“ werden von allen modernen Browsern unterstützt. Im Microsoft Internet Explorer funktioniert dies ab Version 9, im Mozilla Firefox ab Version 19 und im Google Chrome ab Version 20.
Weitere Informationen findet man hier.

Vergleich Prozent vs. Viewport Units

Hier noch der direkte Vergleich zwischen der Angabe in Prozent und der Viewport Units.

Vergleich Prozent vs. Viewport Units

Live Beispiel
Primefaces Dialog – Vergleich Prozent vs. Viewport Units

Mehrere (Sub)-Projekte / Unterverzeichnisse als einzelne Jobs mit Travis CI ausführen

Eine einfache und kostengünstige Methode, um eine kontinuierliche Integration für öffentliche Projekte auf GitHub durchzuführen, ist mittels der Travis CI Continuous Integration (CI) Plattform. Zur Ausführung muss im Wurzelverzeichnis des Git-Repositories eine YAML-Datei mit dem Namen .travis.yml erstellt werden, welche die Travis Konfiguration für das Projekt enthält.

Manchmal befinden sich aber mehrere (Sub)-Projekte in einem Git-Repository, welche in unterschiedliche Unterverzeichnisse zu finden sind.

Verzeichnisstruktur

Repository
|
|– Project1
|– Project2

Mittels Travis CI ist es möglich, auch für diese (Sub)-Projekte eine kontinuierliche Integration sicherzustellen.

Einfache Lösungsmöglichkeit

Als einfachste Möglichkeit, führt man die entsprechenden Build-Befehle im „Build Lifecycle“ für jedes (Sub)-Projekt nacheinander aus. Wichtig ist hierbei, dass vorher immer in den entsprechenden Projektordner mittels „cd ../ProjektOrdner“ Befehl gewechselt wird.

script: cd project1 && npm install && npm test && cd ../project2 && npm install && npm test

Elegantere Lösungsmöglichkeit

Eine deutlich elegantere Lösung ist es, für die einzelnen Projekte die Möglichkeit der Build Matrix von Travis zu nutzen. Der große Vorteil dabei ist, dass für jedes (Sub)-Projekt ein eigener Build-Job erstellt wird, welcher seinen eigenen Status bzw. Ergebniss besitzt.

Hierzu werden die Pfade der einzelnen (Sub)-Projekte als Umgebungsvariablen im Abschnit „env“ angegeben.

env:
  - PROJECT_DIR=project1
  - PROJECT_DIR=project2

script: cd $PROJECT_DIR && npm install && npm test

Zu beachten ist hier, dass immer der gleiche Schlüssel wie z. B. „PROJECT_DIR“ verwendet wird. Anstelle des eigentlichen Projektpfades wird dieser dann als Variable „$PROJECT_DIR“ im „script“ Befehl angegeben. Travis führt nun den Build Lifecycle mehrmals mit jeder definierten Umgebungsvariable als eigenen Build-Job (parallel) aus.

Beispiel-Projekt

Projekt: https://github.com/mesche/angular-collection
Travis CI Konfiguration: https://github.com/mesche/angular-collection/blob/master/.travis.yml
Travis CI Build: https://travis-ci.org/mesche/angular-collection

Status-Bilder (Badges) je Build-Job

Leider bietet Travis CI nur die Möglichkeit, ein Status-Bild (auch Badge genannt) pro Repository zu erzeugen, welches man dann z. B. in der Readme.md Datei auf GitHub einfügen kann.

Möchte man aber für jeden einzelnen Build-Job ein Badge erzeugen, kann man folgendes GitHub-Projekt verwenden: Travis Matrix Build Badges

Veeam Endpoint Backup Free – Einstellungen und Daten komplett zurücksetzen

Nachdem ich auf eine neue Windows Version geupdated hatte, funktionierte bei mir Veeam Endpoint Backup Free nicht mehr korrekt. Daher entfernte ich die vorhandene Installation, um das Programm komplett neu zu installieren. Ich musste dann aber feststellen, dass nicht alles komplett zurückgesetzt wurde. Die Einstellungen und die Anzeige von bereits erstellen Backups waren immer noch vorhanden.

Ich habe aber folgende Möglichkeit gefunden, um Veeam Endpoint Backup komplett zurückzusetzen.

Warnung: Dabei gehen auch alle Einstellungen / Log-Information etc. verloren.

1. Veeam Endpoint Backup Windows-Dienst/Service stoppen

  • „Windows-Taste + R“ drücken
  • „services.msc“ eingeben und mit „OK“ bestätigen
  • In der Dienste-Verwaltung von Windows den Eintrag „Veeam Endpoint Backup“ suchen und mittels rechter Maustaste und „Stop“ den Dienst beenden.

2. Registry-Schlüssel Eintrag „Recreatedatabase“ ändern

  • „Windows-Taste + R“ drücken
  • „regedit.exe“ eingeben und mit „OK“ bestätigen
  • Folgenden Schlüssel suchen:
    Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Veeam\Veeam Endpoint Backup

  • Eintrag „Recreatedatabase“ öffnen und den Wert (DWORD (32 bit) auf „1“ ändern. Sollte der Eintrag nicht vorhanden sein, muss dieser als DWORD (32 bit) neu angelegt werden.

3. Veeam Endpoint Backup Dienst starten

Jetzt kann der Windows-Dienst wieder gestartet werden. Hierzu kann wie bei Schritt 1 vorgegangen werden. Anstelle von „Stop“ muss „Start“ ausgeführt werden.

4. Ein paar Minuten warten, damit die Datenbank neu erstellt werden kann

5. Wert des Eintrags „Recreatedatabase“ prüfen

Es sollte geprüft werden, ob der Wert des Eintrags „Recreatedatabase“ wieder korrekt auf „0“ zurückgesetzt wurde. Sollte dies nicht der Fall sein, muss dies manuell geändert werden. Hierzu muss der Windows-Dienst nochmal gestoppt werden. Dann kann der Wert wie in Schritt 2 beschrieben auf „0“ gesetzt werden und der Windows-Dienst wieder gestartet werden.

6. Starten von Veeam Endpoint Backup

Beim nächsten Start von Veeam Endpoint Backup sollten jetzt alle Einstellungen und Daten zurückgesetzt worden sein.

Das entsprechende Ticket zu diesem Problem findet man unter:
https://www.veeam.com/kb2057