Kurze Erklärung zu DNS SRV-Records

Der Artikel war eigentlich als Erklärung wie SRV-Rekords funktionieren für einen anderen Artikel geacht, ist aber dann so lang geworden, dass er jetzt ein eigener ist.

Eine Domain kann verschiedene Dienste anbieten, wie zum Beispiel Instant-Messaging (xmpp, Matrix), Telekommunikation (sip), Verzeichnisdiensten (LDAP) usw.
All diese Dienste verwenden ggf. die gleiche Domain, z.B. example.com, man hat dann also zum Beispiel eine JID: shellkraut@example.com (XMPP-Benutzername), eine SIP-URI: +4930124567@example.com usw.
Die Dienste teilen sich alle die gleiche Domain, aber können auf ganz verschiedenen Servern laufen, ggf. gibt es auch mehrere Server pro Dienst die nach einer bestimmten Priorisierung (Fallback) benutzt werden sollen und eventuell werden auch nicht die Standard-Ports der Dienste benutzt.
Man könnte auf Client-Seite natürlich neben der eigentlichen Benutzerkennung, auch die zu verwendendenden Server konfigurieren, also für sip zum Beispiel:

  • sip1.example.com:4866 Priorität 1

  • sip2.example.com:4866 Priorität 1

  • fallback.otherprovider.com:5062 Priorität 100

Das ist aber fehleranfällig wenn es manuell, und ggf. durch einen Laien passiert und auch nicht sonderlich bequem.
Ein Problem ist auch, dass sich diese Daten u.U. irgendwann ändern. Die Domain eines Dienstanbieters/der eigenen Firma bleibt in der Regel gleich, aber die konkreten Server auf denen die Dienste laufen ändern sich mit der Zeit - hat man dann kein Provisioning/automatische Konfiguration der Clients wird es sehr schnell unlustig. Hinzu kommt Clients benutzen häufig weitere Protokolle, im Falle von Voice-over-IP-Telefonen (SIP) zum Beispiel LDAP um ein Adressbuch zur Verfügung zu stellen oder TURN um Verbindungen (wenn kein B2BUA verwendet wird) zu ermöglichen wo beide Clients einer Verbindung hinter NAT sitzen. Die Liste der zu konfigurierenden Server-Adressen wird also schnell lang.

Hier kommen SRV-Records in DNS ins Spiel:

_sip._tls.example.com. 3600 IN SRV 0 100 4866 sip1.example.com.
_sip._tls.example.com. 3600 IN SRV 0 50  4866 sip2.example.com.
_sip._tls.example.com. 3600 IN SRV 100 5 4866 fallback.otherprovider.com

Software kann anhand eines Domain-Namens und dem Wissen welche Art von Dienst sie kontaktieren will ermitteln welchen Server sie kontaktieren muss.

Ein SIP-Client (Voice-over-IP-Telefon) z.B. konfiguriert mit dem Nutzernamen '+4930124567@example.com' weiß das es einen SIP-Server unter 'example.com' unter Nutzung von TLS als Transport-Protokoll kontaktieren will.
Entsprechend kann es eine DNS-Abfrage "Typ: srv" für den Namen: '_sip._tls.example.com' durchführen und bekommt oben stehende Liste als Antwort.

Aufbau eines SRV-Records

Der einzelne Eintrag ist wie oben stehend aufgebaut:

  • die ersten 3 Felder bilden den FQDN den der Abfragende (also die Client-Software) zusammenbaut und abfragt, er enthält:

    • gesuchte Applikations-Protokoll (z.B. sip, xmpp, ldap)

    • das gewünschte Transport-Protokoll (z.B. tls, tcp, udp)

    • die Domain für die gesucht wird (z.B. example.com)

    • die "_" sind dabei fest vorgegeben und Teil des Formats

  • TTL → Gültigkeitsdauer (für Caching) des Eintrags in Sekunden

  • Record-Type → SRV, definiert den Typ des DNS-Eintrags - hier SRV - ähnlich wie es "A", "AAA", "MX" usw. gibt

  • Priority → Eintrag mit der niedrigsten Priorität wird genutzt. Nur wenn der Server dort nicht erreichbar ist, werden nacheinander die Einträge mit höherer Priorität geprüft.

    • Einträge mit der niedrigsten Priorität sind die Haupt-Einträge, alle anderen dienen als Backup für Ausfälle

    • Einträge mit gleicher Priorität (in der Liste oben die ersten beiden) werden gleichberechtigt benutzt (Lastverteilung), die genaue Verteilung des Verkehrs hängt vom Protokoll und dem Eintrag in Weight ab

  • Weight → Verteilung der Anfragen innerhalb der gleichen Priorität auf Server.

    • Einträge mit höherer Weight, bekommen eine anteilig höherere Menge an Anfragen

      • Hinweis: das bezieht sich auf die Anfragen des gleichen Clients, jeder Client nimmt die Zählung einzeln vor. Sendet A 3 Requests gehen 2 an sip1 und 1 an sip2, sendet B und C je 1 Request gehen beide a sip1 (höhere Priorität) → in Summe hat sip1 also 4 Requests erhalten und sip2 nur 1. Der Nutzen als Load-Balancing-Mechanismus ist also begrenzt (und sowiso von der korrekten Implementierung auf Client-Seite abhängig)

      • Was als Anfrage zählt hängt hier auch von der Implementierung um Client und den Vorgaben des Application-Protokolls ab. Es kann z.B. sein das mehrere Anfragen die zu einer Sitzung gehören alle an den gleichen Server gehen und die Verteilung auf Sitzungs-Basis → 2 Sitzungen an sip1, 1 an sip2 erfolgt

    • 0 sollte vermieden werden. Gibt es mehrere Einträge mit verschiedener Weight bekommen die mit 0 ggf. keinen Verkehr → deaktiviert

    • in obigem Beispiel bekommt sip1 2 von 3 Anfragen und sip2 1

  • Port → der Port unter dem der Dienst erreichbar ist

  • Host → DNS-Name des Servers der den Dienst anbietet

    • der FQDN an dieser Stelle muss sich in einen A- oder AAA-Record auflösen lassen. Umwege über weitere Auflösungen → CNAME usw. sind nicht zulässig