All posts by bert2002

Update Ubuntu von 20.04 to 22.04

Ich bin schon lange nicht mehr in Probleme gelaufen bei OS updates, aber es musste natuerlich bei Ubuntu von 20.04 nach 22.04 ein kleines Problem geben.

Auf 20.04 hatte ich pipewire benutzt und waehrend des updates kam folgendes Problem auf:

libpipwire-0.3.0 : Depends libspa-0.2-modules...

Es konnte nicht mehr updaten und das Problem war das die Installation nicht abgeschlossen werden konnte und der Boot einfach ohne X passiert ist. Was fehlte, war das upstream ppa.

sudo add-apt-repository ppa:pipewire-debian/pipewire-upstream

Anschliessend konnte man mit dem Update wie gewohnt weitermachen.

Google Secure LDAP

Google bietet einen LDAP server and mit dem man andere Systeme anschließen kann. Leider funktioniert ldapsearch erst wenn man TLS 1.3 deaktiviert.

LDAPTLS_CIPHER_SUITE='NORMAL:!VERS-TLS1.3' LDAPTLS_CERT=Google_*.crt LDAPTLS_KEY=Google_*.key ldapsearch -H ldaps://ldap.google.com:636 -b dc=itbert,dc=de '(mail=*)'

Corda Node Migration

Es gibt leider nicht viele Information wenn man einen Corda node auf einen neuen Server migrieren muss. Was man unbedingt braucht ist ein Backup der Datenbank, der Keys – am besten vom ganzen Corda Verzeichnis das alle kritischen Daten enthält (wie auch die Cordaaps).

Was man jedoch nicht braucht ist die nodekeystore.jks. Die wird basierend auf dem Hostnamen (vermutlich) erstellt und muss auf dem neuen System neu erstellt werden. Das passiert automatisch beim starten von Corda. Falls man die Datei nicht löscht wird der Node nicht erkannt und wird von der Map immer wieder gelöscht.

network.PersistentNetworkMapCache. - Removing node with info: NodeInfo(addresses=[xxx.xxx.xxx.x:10002], 

Grafana Image Renderer Konfiguration

Seit Grafana 7.x benutzt Grafana ein grafana-image-renderer oder man benutzt einen docker container dafuer. Ich habe mich für das Plugin entschieden, aber vielleicht wäre der Container einfacher gewesen. Auf Debian 10 braucht das Plugin doch ein paar Abhängigkeiten die nirgendswo zu finden sind.

Installation des Plugins:

grafana-cli plugins install grafana-image-renderer

Installation Abhaengigkeiten:

apt install cups fonts-liberation gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

Wenn man Grafana mit TLS konfiguriert hat muss man entweder den host korrekt setzen, ansonsten bekommt man eine Fehlermeldung weil Grafana versucht nach localhost:3000 zu verbinden.

Error:

grafana-server[25147]: 2020/12/18 07:18:47 http: TLS handshake error from [::1]:55768: remote error: tls: unknown certificate
grafana-server[25147]: t=2020-12-18T07:18:47+0000 lvl=eror msg="Browser request failed" logger=plugins.backend pluginId=grafana-image-renderer method=GET failure=net::ERR_CERT_COMMON_NAME_INVALID url="https://localhost:3000/d-solo/iuCnU9JGz/test?orgId=1&panelId=2&render=1"
grafana-server[25147]: t=2020-12-18T07:18:47+0000 lvl=eror msg="Render request failed" logger=plugins.backend pluginId=grafana-image-renderer url="https://localhost:3000/d-solo/iuCnU9JGz/test?orgId=1&panelId=2&render=1" error="Error: net::ERR_CERT_COMMON_NAME_INVALID at https://localhost:3000/d-solo/iuCnU9JGz/test?orgId=1&panelId=2&render=1"grafana-server[25147]: t=2020-12-18T07:18:47+0000 lvl=eror msg="Failed to render and upload alert panel image." logger=alerting.notifier ruleId=2574 error="Rendering failed: Error: net::ERR_CERT_COMMON_NAME_INVALID at https://localhost:3000/d-solo/iuCnU9JGz/test?orgId=1&panelId=2&render=1"

Konfiguration in /etc/grafana/grafana.ini

[plugin.grafana-image-renderer]
rendering_ignore_https_errors = true

Confluence H2DB korrupiert

Confluence benutzt normalerweise H2DB, eine file based Datenbank. Sollte man nicht in Produktion benutzen, aber so ist das manchmal im Leben. Wenn dann auch noch der Server oder ein filesystem problem auftaucht kann es zu einer korrupten Datenbank kommen. Confluence selber bietet keine tools an um die Datenbank zu reparieren, aber ein findiger Benutzer hat ein gutes tool geschrieben um dieses durchzuführen.

Der Fehler von Confluence:

Cannot connect to h2db
java.lang.RuntimeException: Cannot connect to h2db

Undo MVStore log:

sudo apt install maven
git clone https://github.com/bert2002/h2-recover.git
cd h2-recover
mvn clean package
java -jar target/h2-recover-1.0-SNAPSHOT.jar /path/to/h2.mv.db

Der Standardpfad bei Confluence der Datenbank is in /var/atlassian/application-data/confluence/database/. Vorher nicht vergessen ein Backup zu erstellen.

Docker load vs import

Nachdem man einen Docker container exportiert hat kann man diesen mit docker import oder docker load importieren. Jedoch funktioniert nur docker load correct und import führt zu einem irritierenden Fehler:

$ docker import tools-1597033145.tar.gz tools:latest
sha256:f229b184eb2f0c0f2c59fac86adec2c32ac742a8fc1ea6898f51543dfbf0161b
$ docker run -it tools /bin/bash
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown.
ERRO[0003] error waiting for container: context canceled

Wenn man den Container mit load importiert, funktioniert es einwandfrei. Ich hatte leider noch keine Zeit den unterschied oder Fehler zu untersuchen, aber es hat etwas mit export/import und save/load zu tun. Export erstellt snapshots und save erstellt einen dump.

Reverse SSH Tunnel mit Autossh

Einen SSH Tunnel kann man für viele nützliche Sachen einsetzen und hilft bei authentification und verification von einer Verbindung.

Im Normalfall verbindet man Server1 mit Server2 und jetzt ist es möglich von Server1 nach Server2 den Tunnel zu benutzen.
Ich hatte jetzt das Problem dass die IP von Server2 sich immer veraendert und es keinen offenen Port auf Server2 gibt. Ich musste jedoch von Server1 auf Server2 zugreifen. Dabei hilft uns ein reverse SSH Tunnel. Der Tunnel wird von Server2 aufgebaut nach Server1, aber ich kann von Server1 auf den Tunnel zugreifen.

Das ist schnell und einfach konfiguriert und ist eine einfach systemd konfiguration nachdem man autossh installiert hat.

Datei: /etc/systemd/system/autossh.service

[Unit]
Description=Opens a ssh tunnel and keeps it open
After=network-online.target

[Service]
# AUTOSSH_GATETIME is used to restart ssh within autossh when a connection failed.
Environment=AUTOSSH_GATETIME=0
User=root
ExecStart=/usr/bin/autossh -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l $USERNAME -R $REMOTEPORT:localhost:22 $REMOTEHOST

[Install]
WantedBy=multi-user.target

$USERNAME: Der Benutzername mit dem man sich auf Server1 verbinden möchte.
$REMOTEPORT: Der Port auf dem der Tunnel auf Server1 lauschen soll
$REMOTEHOST: Die Adresse von Server1

Am besten tested man die Verbindung manuell einmal, damit man auch den Hostkey verifiziert (ssh pubkey muss vorher ausgetauscht werden) wird, ansonsten kann man den Dienst aktivieren.

systemctl daemon-reload
systemctl start autossh

Gitlab Projects import nach Searchcode

Die Codesuche in Gitlab selber ist etwas beschraenkt und man muss auf Drittanbieter zurueckgreifen. Ich teste momentan Searchcode. Die Community version is kostenlos und fuer etwas Geld bekommt man mehr funktionen.
Das Problem ist jedoch das man jedes git repository einzeln hinzufuegen muss. Zum Glueck gibt es eine API die das einem abnehmen kann. Dabei exportieren wir die List aus Gitlab und importieren diese automatisch nach Searchcode.

Zum Glueck kann man mit ssh keys arbeiten, jedoch muss man dafuer die Config anpassen.

Datei: ~/.ssh/config

Host gitlab.example.com
	IdentityFile ~/.ssh/id_rsa
	StrictHostKeyChecking no

Anschliessen muss man folgendes Script anpassen und auf dem Server wo Searchcode laeuft ausfuehren.

#!/usr/bin/python
# script: import gitlab projects into searchcode
# author: bert2002
# notes: 

import sys
import os
import json
import urllib2
from hashlib import sha1
from hmac import new as hmac
import urllib2
import json
import urllib
import pprint
import time

# Gitlab Settings
TOKEN = 'SECRET_ACCESS_TOKEN'
GITLAB = 'https://gitlab.example.com/api/v4/'

# Searchcode Settings
publickey = "SECRET_PUBLICKEY"
privatekey = "SECRET_PRIVATEKEY"

print "checking jobs in gitlab"
req = urllib2.Request(GITLAB + 'projects?page=1&per_page=100')
req.add_header('Content-Type', 'application/json')
req.add_header('PRIVATE-TOKEN', TOKEN)
data = json.load(urllib2.urlopen(req))

for project in data:
  job_id = project['id']
  ssh_url_to_repo = project['ssh_url_to_repo']
  name_with_namespace = project['name_with_namespace']
  path_with_namespace = project['path_with_namespace']
  web_url = project['web_url']
  archived = project['archived']

  print("Repository: %s Archived: %s" % (name_with_namespace,archived))

  reponame = name_with_namespace
  repourl = ssh_url_to_repo
  repotype = "git"
  repousername = ""
  repopassword = ""
  reposource = web_url
  repobranch = "master"

  message = "pub=%s&reponame=%s&repourl=%s&repotype=%s&repousername=%s&repopassword=%s&reposource=%s&repobranch=%s" % (
          urllib.quote_plus(publickey),
          urllib.quote_plus(reponame),
          urllib.quote_plus(repourl),
          urllib.quote_plus(repotype),
          urllib.quote_plus(repousername),
          urllib.quote_plus(repopassword),
          urllib.quote_plus(reposource),
          urllib.quote_plus(repobranch)
      )

  sig = hmac(privatekey, message, sha1).hexdigest()
  url = "http://localhost:8080/api/repo/add/?sig=%s&%s" % (urllib.quote_plus(sig), message)
  data = urllib2.urlopen(url)
  data = data.read()
  data = json.loads(data)
  print data['sucessful'], data['message']

  sig = hmac(privatekey, message, sha1).hexdigest()
  url = "http://localhost:8080/api/repo/reindex/?sig=%s&%s" % (urllib.quote_plus(sig), message)
  data = urllib2.urlopen(url)
  data = data.read()
  time.sleep(1)

ESP8266 + OLED Display shows PagerDuty incidents

Seit ein paar Tagen spiele ich mit dem ESP8266 Chip herum. Das ist ein Arduino fähiger Chip mit Wifi. Die Entwicklerboards gibt es schon für knapp 8EUR in Deutschland und sind überraschend leistungsfähig. 
Ich hatte vorher noch nie etwas mit Arduino gemacht, aber dank der vielen verfügbaren Libraries hat man sehr schnell Erfolg mit kleinen Projekten. So habe ich noch ein kleines Display angeschlossen und dieses zeigt mir die offenen incidents bei PagerDuty an. Super schnell und lustig. 

Den Code gibt es auf github.com und hier ein Beispiel:

ESP8266 + Arduino IDE + MacOSX

Das Internet of Things (IoT) immer mehr in unseren Alltag Einfluss nimmt, ist vermutlich jedem klar. Ich wollte auch ein bisschen damit herumspielen und bin dabei auf den Chip ESP8266 gestoßen. Der kleine Chip hat WLAN, verbraucht wenig Strom und kann mittels LUA oder Arduino IDE programmiert werden.

Unter Linux ging das alles sehr schnell und nachdem man die Arduine IDE und das Board Packet installiert hat, kann man direkt loslegen. Unter MacOSX Sierra hatte ich jedoch Probleme dass das Board in der Arduino IDE erkannt wird. Erst nach langem recherchieren bin ich auf einen Treiber gestoßen der funktioniert. 

Den Treiber und mehr gibt es auf kig.re.