Den JOOQ Parser verwenden

Hier ein praktisches Beispiel wie man den Parser von JOOQ verwenden kann. Gegeben sei ein String der einen Select enthält.

select name from books

Dieser soll aber mit Hilfe vom der JOOQ DSL um ein LIMIT und ein OFFSET von jeweils 10 erweitert werden.

Zunächst muss der Parser den String in DSL Objekt parsen, welches dann mit der DSL entsprechend modifiziert werden kann.

dsl.selectFrom(dsl.parser().parse("select name from books"))
  .limit(10)
  .offset(10)
  .fetch();

Hinweis: Ein kleiner Nachteil ist, dass der Parser den SQL String verstehen muss. Zur Zeit werden noch nicht alle Feinheiten der diversen Dialekte unterstützt.

Weitere Einsatzmöglichkeiten

Da der Parser viele Dialekte versteht, kann man das SQL mit JOOQ transpellieren, dass heißt von den einem Dialekt in einen anderen transformieren.

Wireguard Netzwerk

Die prinzipielle Einrichtung von Wireguard habe ich in dem Artikel Wireguard beschrieben. Es ging um die die Point to Point Einrichtung mehrerer Clients die auf einen PC, der als Server fungiert, zugreifen. Die Clients konnten sich untereinander nicht sehen.

Im folgenden möchte ich beschreiben, wie man ein VPN Netz aufbaut in dem sich die Clients untereinander verbinden können. Damit Clients in dem privaten Netzwerk sich über Hostname ansprechen können, wird ein zentraler DNS Server eingerichtet. Hierfür verwende ich einen vorhandenen OpenWRT Router.

Aufbau des Netzwerkes

Das Netzwerk ist auf mehrere Standorte verteilt. Es gibt einen zentralen Linux PC der die Rolle des Wireguard Servers einnimmt. Die Rolle einnimmt, weil es per se keinen Wireguard Server gibt. Es ist die Konfiguration die ihn zur Zentrale werden lässt. Damit dieser erreichbar ist, ist ein DynDNS Dienst oder eine feste IP Adresse von Nöten. Dieses ist aber nicht Bestandteil dieses Artikels. Hier verwaise ich zum Beipsiel auf den Artikel DynDNS mit Duck DNS.

Der Server bekommt in dem VPN die Adresse 10.0.0.1. Der Server ist für das Routing unter den Clients verantwortlich. Das heißt er leitet eingehende Pakete an die anderen Clients weiter. Hierfür muss das IP Forwarding aktiviert und einfache Regeln für die FORWARD Chain von IPTABLES angelegt werden.

Die Clients stellen eine Reihe von Laptops, Workstations und weiteren Servern da. Die Client erhalten durchnummerierte IP Adressen beginnend mit 10.0.0.2/32. In meinem Setup sind es aktuell 6 weitere PCs die in dem VPN vorhanden sind.

Konfiguration von Wireguard

Im Folgenden werde ich das Schema wie Clients und der Server einzurichten sind erläutern. Wenn das Schema bekannt ist, dann ist es leicht weitere Clients hinzuzufügen.

Einrichtung auf dem Server

Das Schema ist eigentlich recht einfach. Es muss allerdings auf die Subnetzmaske bei der Angabe der IP Adressen genau geachtet werden. Die Server Adresse ist mit /24 und die Clients mit /32 anzugeben.

[Interface]
PrivateKey = PrivateKeyDesServers
ListenPort = 32768
Address = 10.0.0.1/24

# Allow routing between clients
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT

#
# Client 1
#
[Peer]
PublicKey = PublicKeyDesClient
AllowedIPs = 10.0.0.2/32

#
# Client 2
#
[Peer]
PublicKey = PublicKeyDesClient
AllowedIPs = 10.0.0.3/32

#
# Client 3
#
[Peer]
PublicKey = PublicKeyDesClient
AllowedIPs = 10.0.0.4/32

.
.
.

#
# Client 7
#
[Peer]
PublicKey = PublicKeyDesClient
AllowedIPs = 10.0.0.7/32

Einrichtung der Clients

Es ist hierbei wichtig zu wissen, dass nur ein Client das gesamte Subnetz beanspruchen darf! Sonst funktioniert das ganze nicht. Das heißt auf den Clients sind explizit die Adresse einzutragen mit denen der Client kommunizieren darf. Dieses macht aber nur bei kleineren Netzen einen Sinn.

[Interface]
PrivateKey = PrivateKeyDesClients
Address = 10.0.0.3/24
DNS = 10.0.0.7

[Peer]
PublicKey = PublicKeyDesServers
AllowedIPs = 10.0.0.1/32, 10.0.0.2/32, 10.0.0.5/32, 10.0.0.6/32, 10.0.0.7/32
EndPoint = myname.dyndns.org:32222
PersistentKeepalive = 25

Wichtig ist das alle Clients mit 10.0.0.X/32 angegeben werden.

IP Forwarding Aktivierung

Das allgemeine IP Forwarding bzw. auf Geräteebene aktivieren habe ich bereits in dem Wireguard Artikel beschreiben.

Firewall Regeln

Damit die Pakete nun auch an die Client weitergeleitet werden, muss in der FORWARD Chain das In-/Output auf dem Wireguard Interface zulassen. Dieses kann mit dem PostUp in der Konfiguration automatisch nach dem Starten der Verbindung durchgeführt werden.

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT

Verbindungsaufbau

Für den automatischen Verbindungsaufbau muss die Option PersistentKeepalive gesetzt werden, damit ein Paket Verbindung öffnet.

Einrichtung von DNS

Auf dem Client habe ich die Konfiguration mit dem KDE NetworkManager durchgeführt. Bei der Wireguard Konfiguration habe ich nun die Adresse des DNS Servers eingetragen, der für das interne Netzt zuständig ist. Die Konfiguration der statische Hostnames beschriebt ein andere Artikel.

Testen der Namesauflösung

Auf http://openwrt/cgi-bin/luci/admin/network/dhcp unter Local Server mit /XXXX.duckdns.org/ Anfrage an die Domain nach außen unterbinden, da diese sonst von DuckDNS beantwortet werden würden und somit die IPV6 Adresse genommen wird, was zu Fehlern führt.

Certbot und DuckDNS

Der Certbot kann die Eingerichten Domänen auch automatisch aktualisieren. Dazu ist für ausgefallene Anwendungszwecke ein Hooksystem integriert, sodass das Aktualisieren der Zertifikate auch unter besonderen Umständen funktioniert.

Wie der Titelschon beschreibt, will ich hier die Automatisation der Erneuerung der Zertifikate mit dem Certbot auf einer DuckDNS Domäne demonstrieren. In diesem Artikel habe ich die Einrichtung von DuckDNS bereits erleutert. Als Zeitgeber setze ich den Systemd Timer ein.

Manuelles ReNew

Die Zertifikate die LetsEncrypt ausstellt haben immer nur einen Gültigskeitszeitraum von genau 3 Monaten. Das heißt alle 3 Monate muss das Zertifikat erneuert und in den WebServer deployt werden, da sonst weiterhin die Aĺten abgelaufenen Zertifikate ausgeliefert werden und somit die Seiten von den Browsern als nicht vertrauenswürdig eingestuft werden.

Für DuckDNS bietet sich die Verifikationsmethode DNS01 an. Bei dieser Methode wird ein TXT Record im DNS Server erwartet. Dieses sogenannte Challenge muss vor der Überprüfung gesetzt werden. Hierfür wird das PRE Hook verwendet, um das Secret in DuckDNS zu setzen.

Die Informationen zu den Hooks kann man hier nachlesen.

Die Skripte die in den Hooks eingesetzt werden in einem Unterverzeichnis /duckdns im Ordner /etc/letsencrypt abgelegt.

Der PRE Hook

Dieses Skript wird in der Vorbereitung der Verifikation der Domäne ausgeführt. Es muss beim dem DNS01 Verfahren, also zum setzen der Challenge im DNS Server, genutzt werden. Dieses Skript hängen wir in den PRE Hook mit dem Parameter –manual-auth-hook ein. Dieser erwartet Pfad zu dem folgenden Skript…

Die Datei set_acme_challenge.sh in /etc/letsencrypt/duckdns/

#!/bin/bash

token="TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT"

# log
echo "renewal of $CERTBOT_DOMAIN with challenge $CERTBOT_VALIDATION" 

# set acme challenge
curl -s "https://www.duckdns.org/update?domains=$CERTBOT_DOMAIN&token=$token&txt=$CERTBOT_VALIDATION"

Im Log werden in den meisten Fällen aufgeführt werden, dass das Aktualisieren nicht durchgeführt worden ist, weil das Zertifikat noch länger als 30 Tage gültig ist. Erst wenn die Gültigkeitsdauer klein 30 Tage ist, dann wird der Certbot eine Aktualisierung durchführen.

DNS Server Aufräumen

Nachdem das Challenge verifiziert worden ist, wird das Challenge auf dem DNS Server von DuckDNS nicht mehr benötigt. Das heißt es kann wieder gelöscht werden. Dazu verwenden wird den Hook –manual-cleanup-hook Parameter.

Die Datei clanup_acme_challenge.sh in /etc/letsencrypt/duckdns/

#!/bin/bash

# DuckDNS Token
token="TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT" 

# clear acme challenge
curl -s "https://www.duckdns.org/update?domains=$CERTBOT_DOMAIN&token=$token&txt=$CERTBOT_VALIDATION&clear=true

Das aktuelle Zertifikat dem WebServer bekannt machen

Nachdem nun der Certbot das aktuelle Zertifikat bereitgestellt hat, dann muss das dem WebServer bekannt gemacht werden. Da ich den NginX WebServer einsetze, muss ich also ein systemctl reload nginx.service ausführen. Dies übergeben wir einfach direkt dem Deploy-Hook mit

--deploy-hook "systemctl reload nginx.service"

Der komplette Aufruf

Wenn wir jetzt alles zusammenführen, dann ergibt sich folgender Aufruf:

certbot renew --manual-auth-hook=/etc/letsencrypt/duckdns/set_acme_challenge.sh --manual-cleanup-hook=/etc/letsencrypt/duckdns/clear_acme_challenge.sh --deploy-hook "systemctl reload nginx.service"

Für Debuggingzwecke empfiehlt es sich sich noch den DRY RUN Modus mit dem Parameter –dry-run zu aktivieren.

Den Systemd Timer anlegen

Der certbot.service:

[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --manual-auth-hook=/etc/letsencrypt/duckdns/set_acme_challenge.sh --manual-cleanup-hook=/etc/letsencrypt/duckdns/clear_acme_challenge.sh --deploy-hook "systemctl reload nginx.service"

Der certbot.timer:

[Unit]
Description=Twice daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=0/12:00:00
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target

Log

Das Log kann mit journalctl -n50 -fu certbot.service eingesehen werden:

Nov 24 14:14:04 server systemd[1]: Starting Let's Encrypt renewal...
Nov 24 14:14:07 server certbot[2160]: Saving debug log to /var/log/letsencrypt/letsencrypt.log
Nov 24 14:14:07 server certbot[2160]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nov 24 14:14:07 server certbot[2160]: Processing /etc/letsencrypt/renewal/XXXX.duckdns.org.conf
Nov 24 14:14:07 server certbot[2160]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nov 24 14:14:08 server certbot[2160]: Cert not yet due for renewal
Nov 24 14:14:08 server certbot[2160]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nov 24 14:14:08 server certbot[2160]: The following certs are not due for renewal yet:
Nov 24 14:14:08 server certbot[2160]:   /etc/letsencrypt/live/XXXX.duckdns.org/fullchain.pem expires on 2020-02-21 (skipped)
Nov 24 14:14:08 server certbot[2160]: No renewals were attempted.
Nov 24 14:14:08 server certbot[2160]: No hooks were run.
Nov 24 14:14:08 server certbot[2160]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nov 24 14:14:08 server systemd[1]: certbot.service: Succeeded.
Nov 24 14:14:08 server systemd[1]: Started Let's Encrypt renewal.

Ein Plugin für SEO

Google hat ein offizielles Plugin SiteKit für WordPress vorgestellt mit dem man einen einfachen Zugriff auf diverse Metriken von Google bekommen kann. Es werden verschiedene Dienste von Google integriert, so dass man einen schnellen überblick über die Page bekommt ohne WordPress zu verlassen.

Die Installation

Die Installation ist super einfach und nach ein paar Mausklicks auch schon abgeschlossen.

Die Metriken

Das Google SiteKit Plugin zeigt übersichtlich die Metriken von Google Analytics, Search Console und PageSpeed Insight hübsch aufbereitet an.

Resümee

Das Plugin macht – trotz der noch recht jungen Geschichte – schon einen sehr guten Eindruck und hilft dem User Zeit zu sparen, da alle wichtigen Informationen auf einen Blick angezeigt werden.

Das Problem mit dem Mixed-Content

Mixed-Content wird in den gängigen Browsern seit geraumer Zeit geblockt. Leider taucht das Problem nach dem Update von dem Docker Image von KeyCloak in der Version 7.0 nach 8.0 auf. Ein Blick mit dem Browser zeigt schnell warum die Console nicht mehr lädt.

Zuvor hatte ich das Problem innerhalb des Containers gelöst (siehe KeyCloak). Die nun gezeigte Variante halte ich für sauberer.

Wie kann das Mixed-Content Problem gelöst werden?

Wie ich in KeyCloak Artikel beschrieben habe, muss das Anlegen des Docker Containers angepasst werden. Es muss zusätzlich die Environmentvariable PROXY_ADDRESS_FORWARDING auf true gesetzt werden.

Danach lädt die Console von KeyCloak in der neusten Version wieder einwandfrei.

Releases

Wenn ein Projekt auf GitHub eine neue Version veröffentlich, bekommt man das nicht unbedingt gleich mit. Ich nutze daher einen Dienst von GitHub und abonniere mir einen RSS-Feed von den Releases.

FEED URL

Wie kommt man an die Feed URL? Es ist ganz einfach. Gehen Sie auf die Releases Seite von dem gewünschten GitHub Projekt. Fügen Sie nun am Ende der URL noch .atom an und schon haben sie die URL für den Feed.

JSON

Der Aufruf von Restschnittstellen im Browser zeigt oftmals unformatiertes JSON an. Das macht das lesen der Response schwierig und dadurch implizit auch fehleranfälliger.

Chrome Plugin

Natürlich gibt es dafür schon Lösungen. Es gibt eine ganze Reihe von Plugins für Firefox und Chrome. Ich verwende
JSONView. Dieses kann das JSON parsen und verwendet hierfür intern jsonlint. Die Ausgabe ist nun übersichtlich und wird ordentlich dargestellt. Das Plugin ist performant und das Anzeigen von JSON Antworten macht richtig spaß.

Build Environment anzeigen

Welche Klassen sind im Classpath während des Buildvorgangs?

jre11 ./gradlew buildEnvironment

jre11 ist ein kurzes Shellskript welches mir die Java Umgebung in der Version 11 für das Programm zur Verfügung stellt und ist daher optional.

Welche Klassen werden in einer bestimmten Konfiguration geladen?

Gradle bindet je nach Aufgabe unterschiedliche Klassen ein. Welche sind diese? Das ist zum Beispiel die Frage die man sich stellt, wenn die Ausführung des Code Generators von Jooq unter JDK 11 nicht funktioniert.

Mit –configuration kann man den Dependency Tree auf eine Konfiguration einschränken. Hier ist es also die jooqRuntime die uns interressiert.

jre11 ./gradlew dependencies --configuration jooqRuntime

> Task :dependencies

------------------------------------------------------------
Root project
------------------------------------------------------------

jooqRuntime - The classpath used to invoke the jOOQ generator. Add your JDBC drivers or generator extensions here.
+--- org.jooq:jooq-codegen -> 3.11.5
|    +--- org.jooq:jooq:3.11.5
|    |    \--- javax.xml.bind:jaxb-api:2.2.12 -> 2.3.1
|    |         \--- javax.activation:javax.activation-api:1.2.0
|    \--- org.jooq:jooq-meta:3.11.5
|         \--- org.jooq:jooq:3.11.5 (*)
+--- org.xerial:sqlite-jdbc:3.23.1
+--- com.sun.xml.bind:jaxb-core:2.3.0.1
\--- com.sun.xml.bind:jaxb-impl:2.3.0.1

(*) - dependencies omitted (listed previously)

In dem Beipiel benötigt der Code Generator JAXB, welche ja aus dem JDK entfernt worden ist. So kann überprüft werden, ob die Klassen geladen werden.

Am 30.11.2018 hat Syntevo den Java basierenden Git Client SmartGIT 18.2.0 veröffentlicht. Das Update von SmartGit wird, wie die Installation mit einem Paketmanager für das UserRepository von Arch Linux (z.B. yaourt), gefunden und installiert. Im AUR Repository ist die aktuelle Version zu finden.

yaourt –noconfirm -S smartgit

Das Changelog ist sehr umfangreich. Ein Dialog fragt jetzt Syntevo das Log View als Hauptfenster zu setzen. Diese Einstellung lässt sich in den Einstellungen wieder rückgängig machen. Aus dem Log lässt sich jetzt ein Stash über das Kontextmenü auch anwenden. Syntevo setzt jetzt auf die JSCH SSH Implementation, anstatt wie bisher SSHJ. Ürsprünglich wurde Git mit im Bundle ausgeliefert, aber man hat den Plan nach zu vielen Problemen verworfen und SmartGIT wird wieder ohne Git ausgeliefert. Beim Clonen wird, eine sich im Clipboard befindliche URL, in das URL Feld eingetragen.

Die Konfiguration wird nun unter ~/.config/smartgit gespeichert und Update Dateien landen unter ~/.local/share/smartgit.

Wie in den letzten Versionen von SmartGIT auch, muss man zunächst wieder die Art der Verwendung angeben und eine eingebaute Verzögerung abwarten, bevor man das Programm nutzen kann.