Einleitung

Vor kurzem kam mir die Idee einen eigenen kleinen URL Shortener zu betreiben, um einfach längere URLs kürzen zu können. Dies kann zum Beispiel dann von Vorteil sein, wenn man nur begrenzte Textlänge zur Verfügung hat, aber trotzdem längere Links teilen möchte, oder einfach nur einen sich einfach zu merkenden Link für eine komplexe URL braucht. Und da ich meine Dienste gerne selbst kontrolliere, habe ich das mal eben schnell selbst gebaut.

Voraussetzungen und Idee

Da ich grundsätzlich relativ kauffreudig bin, wenn es um neue Domainnamen geht, war auch hier schnell ein passender gefunden und beim Registrar des Vertrauens registriert: bluemedia.re („.re“ in diesem Falle gedacht als Abkürzung für „Redirect“).

Nach der üblichen Einrichtung von DNS und (Standard-) Mail-Adressen fehlte nun noch die Logik, die das eigentliche verkürzen übernimmt. Da ich das ganze Thema so einfach wie möglich halten wollte (nicht noch ein Container – nicht noch eine Datenbank) habe ich mich dazu entschieden die Lösung direkt in Nginx abzubilden. Nginx kommt bei mir fast überall als Reverse-Proxy zum Einsatz, eine Instanz davon kann das daher problemlos mit übernehmen.

Die Konfiguration ist denkbar einfach: Es wird eine Zuordnung zwischen der gewünschten kurzen URI und der eigentlichen Ursprungs-URL erstellt und Nginx löst bei einem Request das Mapping entsprechend auf. Sofern für die angegebene URI keine Zuordnung existiert, wird auf eine Standard-Adresse weitergeleitet. Die Weiterleitung erfolgt mit dem HTTP-Statuscode 302 (Found). Das hat den Vorteil, dass man keine Probleme mit der Indizierung von Suchmaschinen bekommt und sorgt ebenfalls dafür, dass ggf. vorhandene Embeds im Ursprungslink auch noch von z.B. sozialen Netzwerken und Messengern angezeigt werden.

Praktische Umsetzung

Im folgenden ist meine Konfiguration als Beispiel zu sehen. Ich habe zusätzlich noch einen kleinen Endpunkt eingebaut, der einfach nur einen HTTP 200 Status mit dem Text „healthy“ zurückgibt. Das nutze ich zum Beispiel für das Monitoring hinter meine Statusseite.

# Zuordnung URI (bluemedia.re/<URI>) zu Ursprungs-URL
map $uri $link_shortener_redirect_url {
  "/github" "https://github.com/BluemediaGER";
  "/twitter" "https://twitter.com/BluemediaDE";
  "/matrix" "https://matrix.to/#/@bluemedia:chatwire.eu";
  default "https://bluemedia.dev";
}

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

    server_name bluemedia.re;

    access_log /log/link-shortener/access.log;
    error_log /log/link-shortener/error.log warn;

    # Verkürzte TLS-Konfiguration (nur der Vollständigkeit halber)
    ssl_certificate /cert/bluemedia.re/fullchain.cer;
    ssl_certificate_key /cert/bluemedia.re/bluemedia.re.key;

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # Monitoring-Endpunkt für Uptime Kuma
    location /uptime-kuma-healthcheck {
        default_type text/html;
        return 200 "healthy";
    }

    # Weiterleitung zur passenden Ursprungs-URL
    location / {
        return 302 $link_shortener_redirect_url;
    }
}

Das Hinzufügen oder Entfernen von Links benötigt nur eine kurze Anpassung der Map am Anfang der Konfiguration und einen anschließenden Reload von Nginx. Das ist zwar nicht so elegant wie ein schönes Webinterface zur Verwaltung, doch das Ziel der Einfachheit ist damit auf jeden Fall erreicht.