Rewrites unter Nginx loggen

In der Konfiguration für den Webserver Nginx bzw. dessen Seiten, ist es möglich Rewrite-Direktiven zu nutzen. Damit können URLs umgeschrieben werden. Ein Beispiel für eine solche Direktive wäre z.B.

try_files $uri $uri/ @rewrite;

location @rewrite {
  rewrite ^/(.*)$ /index.php?_url=/$1;
}

Wenn dieser Rewrite zur Anwendung kommt, erscheint leider keine Meldung in den Nginx-Logs access.log und error.log. Um das Logging für Rewrites zu aktivieren, muss die Option:

rewrite_log on;

im server-Block der Konfiguration, welche unter /etc/nginx/sites-available/ zu finden ist, aktiviert werden. Daneben muss die Logging-Severity, also die Schwere der Events die geloggt werden sollen, angepasst werden. Dazu wird folgende Option dem server-Block hinzugefügt:

error_log /var/log/nginx/error.log notice;

Wenn die Log-Datei nun angeschaut wird, so finden sich dort für jeden Rewrite entsprechende Meldungen:

2019/05/29 08:35:30 [notice] 16054#16054: *127817 “^/(.*)$” matches “/name/german”, client: 82.193.248.37, server: api.example.com, request: “GET /name/german HTTP/1.1”, host: “api.example.com”
2019/05/29 08:35:30 [notice] 16054#16054: *127817 rewritten data: “/index.php”, args: “_url=/name/german”, client: 82.193.248.37, server: api.example.com, request: “GET /name/german HTTP/1.1”, host: “api.example.com”

REST-APIs unter Apache und Nginx betreiben

Eine der wesentlichen Eigenschaften von REST-APIs bzw. RESTful-Webservices ist ihre Adressierbarkeit von Ressourcen. Wenn ich z.B. über eine API verfüge, welche mir Namen generiert, so kann es in dieser API unterschiedliche Ressourcen geben:

GET https://api.example.com/name/german/
GET https://api.example.com/name/polish/

Rufe ich nun eine der beiden Ressourcen mit dem HTTP-Verb GET auf so erhalte ich entweder einen deutschen oder einen polnischen Namen von dieser Beispiel-API. Für den Webserver ergibt sich allerdings das Problem, das der Ordner name und die entsprechenden Unterordner nicht existieren. Das einzige was in diesem Beispiel existiert ist eine index.php-Datei, welche unter der URL:

https://api.example.com/index.php

zu finden ist. Damit die REST-API ordnungsgemäß funktioniert, müssen die entsprechenden Aufrufe zur index.php-Datei umgebogen werden. Bei dem Webserver Apache kann dies über eine .htaccess-Datei mit folgendem Inhalt erledigt werden:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>

Diese Datei sollte dabei im gleichen Verzeichnis wie die Datei index.php liegen. Bei Nginx muss stattdessen die Konfiguration der Domain bzw. der Seite angepasst werden. Diese Konfigurationen sind unter /etc/nginx/sites-available/ zu finden. Dort muss folgende Konfiguration hinzugefügt werden:

try_files $uri $uri/ @rewrite;

location @rewrite {
	   rewrite ^/(.*)$ /index.php?_url=/$1;
}

Hinterlegt werden muss die Konfiguration in einem server-Block derselben. In diesem Fall würde die URL bzw. der Aufruf:

GET https://api.example.com/name/german/

intern in die URL:

https://api.example.com/index.php?_url=name/german/

umgeschrieben und vom Webserver geladen. Dadurch landen die Aufrufe wieder bei der Datei index.php und können verarbeitet werden.

LanguageTool-Server unter Ubuntu aufsetzen

Für die freie Grammatik- und Rechtschreibprüfung LanguageTool existieren eine Reihe von Add-ons, unter anderem für den Browser Firefox.

Standardmäßig nutzen diese Add-ons den vom Projekt bereitgestellten Server unter languagetool.org. Nicht jeder möchte seine Daten zur Korrektur an Dritte schicken und so besteht die Möglichkeit einen eigenen Server aufzusetzen. Dieser kann lokal betrieben oder auf einem eigenen Server installiert werden. In diesem Artikel soll die Installation unter Ubuntu beschrieben werden. Im ersten Schritt muss sich auf dem Server eingeloggt und dort ein neuer Nutzer angelegt werden:

adduser languagetool
su languagetool
cd

Nachdem der Nutzer angelegt wurde und in das entsprechende Home-Verzeichnis des Nutzers gewechselt wurde, kann das LanguageTool heruntergeladen und entpackt werden:

wget https://languagetool.org/download/LanguageTool-4.5.zip
unzip LanguageTool-4.5.zip
mv LanguageTool-4.5 server
rm LanguageTool-4.5.zip

Neben dem LanguageTool, werden noch sogenannte N-Gramme heruntergeladen. Diese dienen der Verbesserung der Erkennungsleistung des LanguageTool. Sie belegen knapp 27 GiB auf der Festplatte, müssen aber nicht zwingend installiert werden:

mkdir ngrams

wget https://languagetool.org/download/ngram-data/ngrams-de-20150819.zip
wget https://languagetool.org/download/ngram-data/ngrams-en-20150817.zip
wget https://languagetool.org/download/ngram-data/ngrams-es-20150915.zip
wget https://languagetool.org/download/ngram-data/ngrams-fr-20150913.zip
wget https://languagetool.org/download/ngram-data/ngrams-nl-20181229.zip

unzip ngrams-de-20150819.zip
unzip ngrams-en-20150817.zip
unzip ngrams-es-20150915.zip
unzip ngrams-fr-20150913.zip
unzip ngrams-nl-20181229.zip

rm ngrams-de-20150819.zip
rm ngrams-en-20150817.zip
rm ngrams-es-20150915.zip
rm ngrams-fr-20150913.zip
rm ngrams-nl-20181229.zip

Damit ist das LanguageTool installiert. Ein erster Test kann erfolgen, indem der Server mittels:

java -cp languagetool-server.jar org.languagetool.server.HTTPServer --port 8081

gestartet wird. Über Curl können erste Testdaten an den Server gesendet werden:

curl --data "language=en-US&text=a first test" http://localhost:8081/v2/check

In meinem Setup wird der Server auf dem Port 8081 (oder einem beliebigen anderen Port betrieben) und ist über einen Reverse Proxy, in diesem Fall Nginx, erreichbar. Dazu muss die Konfiguration angepasst werden:

nano /etc/nginx/sites-available/example

In der Nginx-Konfigurationsdatei wird nun folgende Konfiguration hinterlegt:

server {
        listen   443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc/letsencrypt/live/api.example.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.example.org/privkey.pem;

        root /var/www/example/api;
        index index.php index.html index.htm;

        server_name api.example.org;

        # proxy for languagetool
        location /languagetool/ {
                proxy_pass http://localhost:8081/v2/;
        }
}

Nachdem die Konfiguration für Nginx hinterlegt wurde, wird Nginx neugestartet:

nginx restart

Über den Browser kann die API nun getestet werden:

https://api.example.org/languagetool/check?language=en-US&text=Wong wong wong

Damit ist die Konfiguration des LanguageTool allerdings noch nicht abgeschlossen. Für den produktiven Betrieb wird eine Konfigurationsdatei unter /home/languagetool/server/ erstellt:

nano languagetool.cfg

Diese Datei wird mit folgendem Inhalt befüllt:

languageModel=/home/languagetool/ngrams

Damit der Service automatisch startet, wird eine systemd-Unit angelegt:

nano /etc/systemd/system/languagetool.service

Diese Datei wird mit folgendem Inhalt befüllt:

[Unit]
Description=LanguageTool
After=syslog.target
After=network.target

[Service]
Type=simple
User=languagetool
Group=languagetool
WorkingDirectory=/home/languagetool/server
ExecStart=/usr/bin/java -cp /home/languagetool/server/languagetool-server.jar org.languagetool.server.HTTPServer --config languagetool.cfg --port 3001 --allow-origin "*"
Restart=always
Environment=USER=git HOME=/home/languagetool

[Install]
WantedBy=multi-user.target

Nachdem die Datei angelegt wurde, wird sie aktiviert und anschließend der Service gestartet:

systemctl enable languagetool
service languagetool start

Zum Test der N-Gramme kann folgende URL aufgerufen:

https://api.example.org/languagetool/check?language=en-US&text=I%20want%20to%20go%20their.

werden. Wenn keine N-Gramme installiert oder konfiguriert sind, kommt ein relativ kurzes JSON als Antwort zurück:

{“software”:{“name”:”LanguageTool”,”version”:”4.5″,”buildDate”:”2019-03-26 11:37″,”apiVersion”:1,”premium”:false,”premiumHint”:”You might be missing errors only the Premium version can find. Contact us at supportlanguagetoolplus.com.”,”status”:””},”warnings”:{“incompleteResults”:false},”language”:{“name”:”English (US)”,”code”:”en-US”,”detectedLanguage”:{“name”:”English (US)”,”code”:”en-US”,”confidence”:0.9999997}},”matches”:[]}

Sind die N-Gramme erfolgreich installiert und konfiguriert, wird das LanguageTool mit einem längeren Response antworten:

{“software”:{“name”:”LanguageTool”,”version”:”4.5″,”buildDate”:”2019-03-26 11:37″,”apiVersion”:1,”premium”:false,”premiumHint”:”You might be missing errors only the Premium version can find. Contact us at supportlanguagetoolplus.com.”,”status”:””},”warnings”:{“incompleteResults”:false},”language”:{“name”:”English (US)”,”code”:”en-US”,”detectedLanguage”:{“name”:”English (US)”,”code”:”en-US”,”confidence”:0.9999997}},”matches”:[{“message”:”Statistics suggests that ‘there’ (as in ‘Is there an answer?’) might be the correct word here, not ‘their’ (as in ‘It’s not their fault.’). Please check.”,”shortMessage”:””,”replacements”:[{“value”:”there”,”shortDescription”:”as in ‘Is there an answer?'”}],”offset”:13,”length”:5,”context”:{“text”:”I want to go their.”,”offset”:13,”length”:5},”sentence”:”I want to go their.”,”type”:{“typeName”:”Other”},”rule”:{“id”:”CONFUSION_RULE”,”description”:”Statistically detect wrong use of words that are easily confused”,”issueType”:”non-conformance”,”category”:{“id”:”TYPOS”,”name”:”Possible Typo”}},”ignoreForIncompleteSentence”:false,”contextForSureMatch”:3}]}

Damit ist der Server komplett eingerichtet. Nun kann der eigene Server bei entsprechenden Add-ons eingerichtet und genutzt werden.

Nachdem der Server aufgesetzt wurde, können entsprechende Add-ons umgestellt werden

Das gleiche Setup kann natürlich genutzt werden, einen solchen Server lokal auf dem eigenen Ubuntu-Rechner zu installieren.

WebDAV unter Nginx einrichten

Der freie Webserver Nginx beherrscht nicht nur das gewöhnliche Ausliefern von Daten über HTTP und HTTPS, sondern verfügt daneben über weitere Module. Mit einem dieser Module kann WebDAV für eine Ressource bereitgestellt werden. Dazu muss die Konfiguration der jeweiligen Seite unter /etc/nginx/sites-available/ angepasst werden. In diesem Beispiel wäre dies:

nano /etc/nginx/sites-available/example

Zur dieser Konfigurationsdatei wird folgende Konfiguration hinzugefügt:

server {
        listen   443 ssl;
        listen [::]:443 ssl;

        ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;

        root /var/www/example;

        server_name example.org;

        location / {
                dav_methods     PUT DELETE MKCOL COPY MOVE;
                dav_ext_methods   PROPFIND OPTIONS;
                dav_access    user:rw group:rw all:rw;

                autoindex     on;
        }
}

In diesem Fall wird für die Domain example.org die WebDAV-Unterstützung aktiviert. Dateien können hierbei ohne weitere Authentifizierung herunter- und hochgeladen werden. Soll WebDAV abgesichert werden, so geschieht das über den Basic authentication. Dazu wird dem location-Part folgendes hinzugefügt:

auth_basic "restricted";
auth_basic_user_file /var/www/example/.htpasswd;

Die .htpasswd-Datei kann mit dem Tool htpasswd erstellt werden:

htpasswd -c .htpasswd nutzer1

Bei der Nutzung wird das gewünschte Passwort erfragt. Soll ein weiterer Nutzer hinzugefügt werden, so muss der Parameter -c entfernt werden:

htpasswd .htpasswd nutzer2

Anschließend wird die Konfiguration von Nginx mittels:

service nginx reload

aktualisiert. Danach kann WebDAV für die Ressource verwendet werden.

Standard-Editor für Git setzen

Wenn das Versionsverwaltungsystem Git im Terminal bzw. auf der Konsole genutzt wird, so wird unter anderem im Falle des Befehls:

git commit

ein Editor geöffnet (in diesem Fall, zur Eingabe der Commit-Nachricht). Der betreffende Editor wird durch die Git-Konfiguration bestimmt. Innerhalb der Konfiguration definiert der Parameter core.editor den zu nutzenden Editor. Um einen Editor zu setzen, z.B. nano muss folgender Befehl genutzt werden:

git config --global core.editor "nano"

Damit wird der Editor nano in der globalen Git-Konfiguration hinterlegt und fortan als Standard-Editor für Git im Terminal genutzt.