Category Archives: Linux/BSD

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)

Monero Mining on Ubuntu 16.04

Account:

Der einfachste Weg einen Account zu erstellen ist auf mymonero.com. Man muss sich um keine Blockchain kümmern und es ist komplett Anonym. Auf der Seite bekommt man auch seine WalletID die wir bei dem Miner mit angeben müssen. Diese müsst Ihr bei $WALLETID ersetzen. Als Mining Pool nehmen wir monerohash.com

Installation:

apt update
apt install libcurl4-openssl-dev libncurses5-dev pkg-config automake yasm
sysctl -w vm.nr_hugepages=48 # three times more then your cpu cores
cd /opt/
git clone https://github.com/wolf9466/cpuminer-multi
cd cpuminer-multi
./autogen.sh
CFLAGS="-march=native" ./configure
make

Start:

/opt/cpuminer-multi/minerd -a cryptonight -o stratum+tcp://monerohash.com:3333/
-u $WALLETID -p $RANDOM

Reporting:

Falls man mehrere Instanzen am laufen hat, will man diese auch ein bisschen überwachen bzw. wissen was läuft. Dafür habe ich einen kleinen Bot geschrieben der mit der Monerohash IP sich die aktuellen Daten zieht und diese mir in einem Slack Channel sendet. Das ganze gibt es auf github.com.

BlaBlaDNS – Ein Kostenloser DynDNS Anbieter

NOTE: BlaBlaDNS ist jetzt bekannt als TokenDNS.

Ich darf mit Freude verkünden das endlich mein neustes Projekt online gegangen ist. Ein kleiner, aber feiner Dynamic DNS Dienst der natürlich kostenlos ist. Getauft ist das Projekt auf BlaBlaDNS und kann unter www.blabladns.co erreicht werden.

Es gibt schon unzählige DDNS Dienste, aber leider keiner der mir alle Features bot die ich haben wollte. Er sollte sicher sein, schöne API und ich wollte auch IPv6 Rekords sowie die TTL bestimmen können. Konnte ich nicht finden und so musste ich mir einen bauen.
Momentan muss man die API unbedingt benutzen, weil das Webinterface noch keinen Schreibzugriff auf die API hat, aber das wird sich bald ändern.

Wie kann ich also BlaBlaDNS benutzen?

Als erstes muss man sich sicher anmelden und wenn man den API Key hat kann man direkt los legen. Den rest kann man einfach per API machen. Beispiele existieren momentan für curl, aber die Dokumentation wird noch erweitert.

Kleines Beispiel um die Subdomain www5.blabladns.xyz zu registrieren und aktualisieren.

Subdomain Registrieren

curl --get "https://api.blabladns.co/v1/reserve" \
  -d apikey=${apikey} \
  -d name=www5

Rekord Aktualisieren

curl --get "https://api.blabladns.co/v1/update" \
  -d apikey=${apikey} \
  -d name=www5 \
  -d content=$(curl -4 ifconfig.co)

Status

curl --get "https://api.blabladns.co/v1/reserve" \
  -d apikey=${apikey} \
  -d name=www5

Rekord automatisch mit cron aktualisieren

echo "0 * * * * root curl -s --get https://api.blabladns.co/v1/update -d apikey=${apikey} -d name=www5 -d content=$(curl -s -4 ifconfig.co) >/dev/null" > /etc/cron.d/blabladns

Die Features und Möglichkeiten werden in nächster Zeit noch weiter wachsen und wer die Entwicklung weiter verfolgen möchte sollte dem Blog von BlaBlaDNS folgen.
Wünsche? Anregungen? Features? Gerne baue ich die in den Dienst ein! Einfach Melden!