Simple Video Chat with jitsi-meet

Oftentimes you have colleagues working on different sites, even different countries and time zones have gotten more and more common in todays world of work.

You can easily keep connected by multiple means like Chat, Email, landline, mobile phones, messaging apps, social networks, VoIP… You get my point.

Most of these means have several disadvantages to consider:

  • no video functionality
  • no sovereignty about the transmitted data
  • no availability of thorough debugging
  • need of dedicated client application

These topics can be tackled by an OpenSource VideoChat Application: jitsi-meet

There is a quick installation guide available, (yes, there are docker images)and you can also try it via a demo system.

The package installs several components: jitsi-videobridge (WebRTC), jitisi-meet (JavaScript), nginx (http access), prosody (XMPP), OpenJDK7 (JRE)

While setting up the system, you’re prompted to configure  the domain name respectively the $IP of the host. In a second step, you’re asked to set a certificate for SSL-encryption.

You’re allowed to use your own certificate or jitsi-meet creates a self-signed certificate for you (this might be handy for having just a quick glance at jitsi-meet)

jitsi-meet then provides an easily accessible chat room for many concurrent user who can (voice)chat, share screens and video chat.

To set up a chat room, simply point your browser (Chrome worked best in our environment) to https://$IP:443 and enter a name for the room into the dialogue box.

You’ll be then redirected to the room and can start setting a password for the room and share the link to your room with others.

This is just a short overview about the possibilities of jitsi-meet, give it a try and have fun!

 

 

 

Tim Albert

Autor: Tim Albert

Tim kommt aus einem kleinen Ort zwischen Nürnberg und Ansbach, an der malerischen B14 gelegen. Er hat in Erlangen Lehramt und in Koblenz Informationsmanagement studiert, wobei seine Tätigkeit als Werkstudent bei IDS Scheer seinen Schwenk von Lehramt zur IT erheblich beeinflusst hat. Neben dem Studium hat Tim sich außerdem noch bei einer Werkskundendienstfirma im User-Support verdingt. Blerim und Sebastian haben ihn Anfang 2016 zu uns ins Managed Services Team geholt, wo er sich nun insbesondere um Infrastrukturthemen kümmert. In seiner Freizeit engagiert sich Tim in der Freiwilligen Feuerwehr - als Maschinist und Atemschutzgeräteträger -, spielt im Laientheater Bauernschwänke und ist auch handwerklich ein absolutes Allroundtalent. Angefangen von Mauern hochziehen bis hin zur KNX-Verkabelung ist er jederzeit einsatzbereit. Ansonsten kocht er sehr gerne – alles außer Hase!

Icinga 2 Best Practice Teil 4: Host Templates und Services

Heute soll es um die Strukturierung von Services und deren Zuordnungen zu Gruppen von Hosts gehen. Ein Host Template kann zur Zusammenfassung von Informationen einer Gruppe von Hosts dienen und damit mehrere unterschiedliche Services für den jeweiligen Host anziehen. Wir wollen in den folgenden Beispielen Linux Hosts überwachen. Dort neben, wie schon in Teil 3 beschrieben, der Belegung der Dateisysteme auch in Abhängigkeit in welchem Netzsegment der Host angeschlossen ist, ob die Zeit synchron zum Zeitserver läuft.

template Host "linux-host" {
  import "generic-host"

  vars.os = "Linux"
  vars.disks["disk /"] = {
    disk_partition = "/"
  }
}

apply Service "time" {
  import "generic-service"

  check_command = "ntp_time"
  command_endpoint = host_name

  assign where host.vars.os == "Linux"
}

Es gibt zwei Netze mit je eigenem Zeitserver. Um dieses abzubilden, definieren wir für jedes Netz ein eigenes Host-Template:

template Host "dmz-net" {
  vars.ntp_address = "172.16.2.99"
}
template Host "lan-net" {
  vars.ntp_address = "172.16.1.99"
}

Diese beiden Templates enthalten nur netzspezifische Informationen, in unserem Beispiel auch nur den jeweilig zuständigen Zeitserver. Der Service-Check time mit dem Plugin check_ntp_time ermittelt die Differenz zwischen der lokalen Zeit des Hosts und der Zeit des NTP-Servers, der in ntp_address angegeben ist. Nun müssen wir für einen Host im internen Netzwerk lan-net nur noch beide Templates zusammen bringen:

object Host "host.example.org" {
  import "linux-host"
  import "lan-net"
  import "postgres-dbms"

  address = "172.16.1.11"
}

Habe wir weitere Services, die abhängig vom Netzsegment unterschiedlich zu konfigurieren sind, können diese Informationen den Netz-Templates hinzugefügt werden. Ein weiteres Beispiel wäre hier die Überwachung unterschiedlicher Domain Name Services. Diese Konzept der Stapelung von Host templates kann natürlich noch weitergeführt werden, z.B. auf Applikationen wie einen Postgresql basierendes Datenbank-Management-Systems bezogen. Ggf. muss jedoch auf die Reihenfolge der Importe geachtet werden, wenn Werte überschrieben werden sollen.

Lennart Betz

Autor: Lennart Betz

Der diplomierte Mathematiker arbeitet bei NETWAYS im Bereich Consulting und bereichert seine Kunden mit seinem Wissen zu Icinga, Nagios und anderen Open Source Administrationstools. Im Büro erleuchtet Lennart seine Kollegen mit fundierten geschichtlichen Vorträgen die seinesgleichen suchen.

Numeric datatypes as primary key in databases

Most likely primary keys in databases are numbers. But what happens, when an administrator uses the wrong numeric data type? In the worst case, databases can’t write down entries anymore.

For example, if an administrator wants to write customer information into the databases and wants to use the customerID itself as the primary key, then the numeric data type “TINYINT” would cause that only 255 entries can be written. But on the other hand the “BIGINT” numeric data type, could be too large for smaller databases.
So when you are setting up a database, you should think about how many entries will be written the next months/years and think about which datatype is the right one for your setup. Also you should think about if you should use the data types unsigned or not. This value will change the range of the datatypes.

Typ signed unsigned
Min Max Min Max
TINYINT -128 +127 0 255
SMALLINT -32.768 +32.767 0 65.535
MEDIUMINT -8.388.608 +8.388.607 0 16.777.215
INT/INTEGER -2.147.483.647 +2.147.483.646 0 4.294.967.295
BIGINT -263 +263 – 1 0 264 – 1

Another example:
If an administrator wants to store 60000 customer information in the database, he should use at least a “SMALLINT”. Should he use the unsigned version or not? Lets have a look.
With the signed data type he has a range from -32.768 up to +32.767, but no customerID (primary key as mentioned above) has a negative number, so a “unsigned SMALLINT” would be necessary.

The case, that you thought about the questions above but your data type got out of range, could happen. There is a way to change the datatype and to increase the range in a simple way.
*ALTER TABLE tablename MODIFY column MEDIUMINT UNSIGNED;*
But remember: The larger your database is, the longer will it take to do such changes!

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz

Home Automation mit Home Assistant

Ich bin vor wenigen Wochen nach Nürnberg umgezogen, um mir die tägliche Zugfahrt von Ansbach her sparen zu können. Aber anstatt wie jeder andere vernünftige Mensch darauf zu schauen, dass Möbel in der Wohnung stehen, habe ich erstmal ein komplettes Wochenende damit verbracht, die Technik meines neuen Zuhauses soweit wie möglich zu automatisieren.

Seitdem mir ein Kollege (hallo Bernd!) schon vor einer ganzen Weile Home Assistant ans Herz gelegt hat, wollte ich dies ausprobieren, habe allerdings nie wirklich Zeit dafür gefunden. Beim Scrollen über 500 unterschiedliche Esszimmertische auf Amazon ändern sich aber die persönlichen Prioritäten ganz schlagartig und ich brauchte eine Abwechslung. Als Erstes habe ich mir in meinem persönlichen Datacenter (andere würden es als Abstellkammer bezeichnen) einen Linux-Container eingerichtet:

Als Hardware habe ich mir für das Projekt folgende Komponenten ausgesucht:

  • Philips Hue Color (E27, dimmbar, bunt, toll)
  • Philips Motion Detector (um die Lampen im Flur und Bad ansteuern zu können)
  • Sonos PLAY:3 (in der Küche und auf meinem Schreibtisch), PLAY:5 (im Wohnzimmer)
  • eQ-3 S 300 TH (Temperatur- und Feuchtigkeitssensor; inzwischen nicht mehr erhältlich, aber hatte ich zufälligerweise aus einem anderen Projekt übrig)
  • iPhone (dient zur Erkennung, ob ich zu Hause bin)
  • GAMMA-SCOUT Geigerzähler (braucht man unbedingt)

Und so sieht das ganze dann aus (inkl. strukturierter Verkabelung):

Ich werde hier niemanden mit der Config-Datei von Home Assistant langweilen, deswegen müsst ihr mir einfach glauben, wenn ich behaupte, dass es ein Kinderspiel ist, die einzelnen Hardware-Bausteine so darin zu integrieren, dass es ein sinnvolles Ganzes ergibt.

Besonders cool sind bei Home Assistant die Möglichkeiten, auf Events zu reagieren. So kann man beispielsweise abhängig vom Sonnenstand die Beleuchtung aktivieren bzw. deaktivieren. Meine Wohnung ist nun so eingestellt, dass automatisch alle Geräte ausgeschaltet werden, sobald ich das Haus verlasse. Wenn ich mich auf dem Weg nach Hause befinde, werden sie wieder eingeschaltet – kurz bevor ich tatsächlich an der Wohnungstür stehe. Dies funktioniert dadurch, dass Home Assistant über “Find my iPhone” weiß, wo ich mich gerade befinde.

Natürlich gibt es dazu auch ein tolles Webinterface, über das man diese Aktionen steuern kann:

Zusätzliche habe ich mir von Happy Bubbles Bluetooth-Beacon-Detektoren bestellt, die hoffentlich im Laufe der nächsten Tage hier eintreffen werden. Danach sollte Home Assistant in der Lage sein, zu erkennen, in welchem Zimmer ich mich aktuell befinde.

Fazit: Nichts zu Essen im Haus – außer Joylent, aber die Beleuchtung lässt sich bis ins letzte Detail steuern. 🙂

Übrigens haben wir in unserem Shop auch Hardware, die sich in eigene Home Automation-Projekte integrieren ließe.

Gunnar Beutner

Autor: Gunnar Beutner

Vor seinem Eintritt bei NETWAYS arbeitete Gunnar bei einem großen deutschen Hostingprovider, wo er bereits viel Erfahrung in der Softwareentwicklung für das Servermanagement sammeln konnte. Bei uns kümmert er sich vor allem um verschiedene Kundenprojekte, aber auch eigene Tools wie inGraph oder Icinga2.

Icinga 2 Best Practice Teil 3: Services überwachen

Nun in Teil 3 dieser Serie werden wir uns näher damit beschäftigen wie in Icinga 2 Services überwacht werden bzw. wie es zu konfigurieren ist, dass bestimmte Services nur auf bestimmten Hosts überwacht werden. Hier bietet Icinga 2 als Neuerung eine regelbasierte Zuweisung an Host-Objekte die definierten Eigenschaften genügen.

apply Service "ping4" {
  import "generic-service"

  check_command = "ping"

  assign where host.address || host.address6
}

So wird hier ein Service ping4 an alle Hosts “gebunden”, die das Attribut address oder address6 definiert haben. Nach diesem recht einfachem Beispiel wenden wir uns auch gleich etwas komplizierterem zu, der Überwachung von Dateisystemen auf einem Linux-System.

apply Service for (filesystem => config in host.vars.disks) {
  import "generic-service"

  check_command = "disk"
  command_endpoint = host.name

  vars += config

  assign where host.vars.os == "Linux"
  ignore where typeof(config) != Dictionary
}

Da hier über das CheckCommand disk, das Plugin check_disk zur Anwendung gelangt, das lokal auf dem zu überwachenden System laufen muss, wird es via command_endpoint auf genau diesem Endpoint angetriggert (siehe hierzu Teil 1 dieser Serie). Ein Host kann mehrere unterschiedlich Dateisysteme beherbergen, deshalb sind diese im Host-Objekt mit dem Custom-Attribute vars.disks zu definieren. Ausserdem muss zusätzlich, wie in dem assign-Statement gefordert, vars.os auf Linux gesetzt sein.

object Host "host.example.org" {
  ...
  vars.os = "Linux"

  vars.disks["disk /"] = {
    disk_partition = "/"
  }
  vars.disks|"disk /tmp"] = {
    disk_partition = "/tmp"
  }
}

Bekanntlich handelt es sich bei vars um ein Dictionary und vars.disks ist eine Darstellungsform eines Keys in diesem Dictionary. Eine andere Form einen Schlüssel anzusprechen ist der Index mit []-Klammern, wie in vars.disks[“disk /”]. Das heißt wir haben hier ein Dictionary in einem Dictionary. Und um es noch auf die Spitze zu treiben weisen wir den einzelnen Keys als Wert wieder jeweils ein Dictionary zu, Perl lässt grüßen. Wozu nun das Ganze? Mit apply Service for wird der Inhalt von vars.disks durchlaufen. Da es sich hierbei um ein Dictionary handelt, wird hier ein for-each verwendet, zu sehen an filesystem => config. Beides sind hier unsere Laufvariablen für die Schleife. Der Variablen filesystem wird jeweils der Key zu gewiesen, also beim ersten Durchlauf “disk /” und beim Zweiten “disk /tmp”, in config dann demnach der zugehörige Wert. Diesen Wert, selbst ein Dictionary, kann als Konfigurations-Dictionary bezeichnet werden, der den jeweiligen Pluginaufruf von disk parametrisiert. Die möglichen Parameter für disk sind sehr gut der Online-Dokumentation zu entnehmen. Wie dies funktioniert und warum die Zeile vars += config hierzu eine zentrale Rolle spielt, wird in Teil 4 erklärt werden. Der Name des Services entspricht standardmäßig dem Inhalt von filesystem.
Selbstverständlich besitzt jedes Linux-System ein Root-Dateisystem und sagen wir, bei uns auch ein eigenes für /tmp. Natürlich möchte man nun nicht für alle seine Hosts immer diese obigen 7 Zeilen angeben müssen, deshalb definieren wir mit diesen ein Host-Template mit der Bezeichnung linux-host. Nun haben Regeln die dumme Eigenheit ihre Ausnahmen zu haben, z.B. hat der Host host.example.org im Gegensatz zu allen anderen Hosts eben kein Dateisystem /tmp. Was dann?

object Host "host.example.org" {
  import "generic-host"

  vars.disks["disk /tmp"] = false
}

Hier wird nun für /tmp die Definition aus dem Template nachträglich überschrieben. Das ignore-Statement in unserer Service-Definition sorgt dafür, dass alle Dateisysteme, denen kein Konfiguration-Dictionary zugewiesen ist, auch nicht als Service in unserer Icinga-Konfiguration landen. Bei typeof handelt es sich um eine Funktion, die die Typesierung einer Variablen ermittelt.

Bis zum nächsten Mal, ihr müsst unbedingt schauen wie es weiter geht. In Teil 4 folgt die etwas theoretische Erklärung wie solche Services jeweils einzeln unterschiedlich parametrisiert werden.

Lennart Betz

Autor: Lennart Betz

Der diplomierte Mathematiker arbeitet bei NETWAYS im Bereich Consulting und bereichert seine Kunden mit seinem Wissen zu Icinga, Nagios und anderen Open Source Administrationstools. Im Büro erleuchtet Lennart seine Kollegen mit fundierten geschichtlichen Vorträgen die seinesgleichen suchen.

Namensauflösung für LXC in Ubuntu 16.04

Um auf Services in einem Container, wie z.B. SSH oder MySQL zuzugreifen, benötigt man ja eigentlich die IP-Adresse des Containers. Mit ein paar Handgriffen kann man aber auch einfach den Hostnamen des Containers, wie im folgenden Beispiel benutzen.

lxc-create -n mysql1.lxc -t ubuntu -- --release=xenial
lxc-start -n mysql1.lxc -d
ssh ubuntu@mysql1.lxc

Um die interne Namensauflösung für die lxc-Domain zu aktivieren, muss folgende Zeile in /etc/default/lxc-net einkommentiert werden und der Dienst lxc-net neugestartet werden.

LXC_DOMAIN=lxc

LXC startet selbst den einfachen DNS- und DHCP-Server dnsmasq für sein Netzwerk, welcher auf die IP-Adresse 10.0.3.1 hört. Diese tragen wir einfach als Nameserver in /etc/resolvconf/resolv.conf.d/head ein:

nameserver 10.0.3.1

Danach muss die Datei resolv.conf mit folgendem Befehl aktualisiert und eventuell laufende Container neugestartet werden.

resolvconf -u
Eric Lippmann

Autor: Eric Lippmann

Eric kam während seines ersten Lehrjahres zu NETWAYS und hat seine Ausbildung bereits 2011 sehr erfolgreich abgeschlossen. Seit Beginn arbeitet er in der Softwareentwicklung und dort an den unterschiedlichen NETWAYS Open Source Lösungen, insbesondere inGraph und im Icinga Team an Icinga Web. Darüber hinaus zeichnet er sich für viele Kundenentwicklungen in der Finanz- und Automobilbranche verantwortlich.