BLog

ImprintImpressum
PrivacyDatenschutz
DisclaimerHaftung
Downloads 

Domain-Name und Dynamic-DNS für den FreeBSD-Home-Server

Um den FreeBSD-Home-Server im Internet sichtbar zu machen, benötigt er einen Domain-Namen. Üblicherweise sind die Internet-Zugänge privater Haushalte mit dynamisch vergebenen IP-Adressen versehen, so daß der Domain-Name unseres Home-Servers über Dynamic-DNS mit der jeweils aktuellen IP-Adresse verknüpft werden muß. Da wir unseren eigenen Home-Mail-Server betreiben wollen, muß der Dynamic-DNS-Dienst ausser der Aktualisierung der IP-Adresse (A-Record) auch die Änderung des MX-Records (Mail EXchanger) erlauben. Schließlich benötigen wir den Zugang zu einem SMTP-Ausgangsserver, der ausgehende E-Mails der besagten Domain entgegennimmt, um sie an den Adressaten weiterzuleiten. Domain-Namen werden von Hosting-Providern entweder als Bestandteil von Hosting-Paketen oder auch separat für überschaubare Gebühren angeboten. Man muß aber genau hinschauen, ob das was man benötigt auch tatsächlich im Paket enthalten ist, im Zweifel muß man nachfragen. Hier noch einmal die Anforderungen an das Domain-Hosting-Paket in der Übersicht:

  1. Dynamic-DNS-Funktion,
  2. Einstellung von A-, AAAA- und MX-Records,
  3. E-Mail-Dienst, um den damit verbundenen SMTP-Server als SMTP-Relay verwenden zu können. Die Hintergründe hierzu werden im Artikel „Home Mail Server with TLS and non-Plaintext Authentication“. erläutert.

Die Dynamic-DNS-Funktion

Viele Domain-Hoster haben ein System analog zur DynDNS-Update-API etabliert. Ich habe meine Domains über die Strato AG registriert, und kann hier daher nur ausführen, wie hiermit Dynamic-DNS auf meinem FreeBSD-Home-Server funktioniert. Ich bitte das nicht als Kaufempfehlung zu verstehen, ich bin vielmehr davon überzeugt, daß andere Hoster mindestens ebenso gute automatische DNS-Update-Funktionen anbieten, ggf. muß man nur deren API genauer studieren.

Hier spiele ich die Prozedur an der allgemein für Beispielzwecke reservierten Domain example.com durch. In den Domain-Einstellungen beim Hosting-Provider muß dafür die Dynamic-DNS-Funktion aktiviert und in der Passwort-Verwaltung auch ein Dynamic-DNS-Passwort eingestellt worden sein. Um nun ein einmaliges Update der IP-Adresse durchzuführen, reicht es aus, die Webseiten-Adresse dyndns.strato.com mit gewissen Parametern analog der o.g. API mit einem Web-Browser aufzurufen:

https://dyndns.strato.com/nic/update?hostname=example.com&myip=123.456.78.90​

Bei anderen Hostern, die die DynDNS-Update-API einsetzen, muß natürlich die Webseiten-Adresse angepaßt werden. Der zu aktualisierende Host-Name example.com muß durch die tatsächliche Domain und die ungültige Beispiel-IP-Adresse 123.456.78.90 durch eine echte öffentliche IP-Adresse ersetzt werden. Jedenfalls wird man im Web-Browser zum Login aufgefordert, sonst könnte ja jeder daherkommen, und unsere DNS-Records ändern:

Nach Anmeldung und erfolgreichem Update steht dann im Browserfenster nur good 123.456.78.90.

Im Mac-Terminal oder im ssh-Terminal des FreeBSD-Home-Servers kann man dann direkt überprüfen, ob die neue IP-Adresse übernommen wurde:

host example.com
>>>>
example.com has address 123.456.78.90
example.com mail is handled by 5 smtpin.rzone.de.

Es ist auf jeden Fall sinnvoll, das gezeigte manuelle Dynamic-DNS-Update und den Host-Check mit der eigenen Domain einmal durchzuführen, und man sollte die Einrichtung des automatischen Updates auf dem FreeBSD-Home-Server erst in Angriff nehmen, nachdem das manuelle Update tatsächlich funktioniert hat.

Automatisches Dynamic-DNS-Update

Die Aufgabe ist eigentlich relativ einfach, nämlich jedesmal wenn sich die dynamische öffentliche IP-Adresse unseres FreeBSD-Home-Servers ändert, muß die Web-Seite, die das Dynamic-DNS-Update durchführt, automatisch aufgerufen werden. Nun ist iin einfacher Web-Seiten-Aufruf nichts anderes als ein HTTP-GET-Request, und wir erstellen uns auf dem FreeBSD-Home-Server eine solche GET-Request-Vorlage. Der Dateiname der Vorlage kann im Grunde beliebig gewählt werden, allerdings ist es zweckmäßig, daß sich die betreffende Domain im Namen wiederfindet, und so kann man später auf einfache Weise weitere Domain-Namen in das automatische Update mit einbeziehen. Also, bitte im folgenden Befehl den Domain-Namen example.com durch den tatsächlichen Domain-Namen, der automatisch aktualisiert werden soll, ersetzen:

nano /root/config/dyndns-example.com.req
GET /nic/update?hostname=example.com&myip=NEWIP HTTP/1.0
Host: dyndns.strato.com
Authorization: Basic ZXhhbXBsZS5jb206TmV2ZXJVc2UxMjM0NTY=
User-Agent: example.com - Mozilla/5.0 (alike) - 11

Wichtig ist die zusätzliche Leerzeile am Ende. Bitte in der GET-Request-Vorlage example.com durch den tatsächlichen Domain-Namen ersetzen. Für den Parameter myip= wird hier nur ein Platzhalter NEWIP eingesetzt. Da der Dynamic-DNS-Update-Web-Server eine Autorisierung verlangt, muß man Login-Namen und Passwort als Base64-kodierte Zeichenfolge mitliefern. Nehmen wir einmal an, daß der Login-Name für das Dynamic-DNS-Update example.com sei, und das Passwort wäre NeverUse123456. Die Base64-kodierte Zeichenfolge ergibt sich daraus über die folgende echo|openssl-Befehlsfolge. Wichtig: Login-Name und Passwort werden durch Doppelpunkt getrennt:

echo -n "example.com:NeverUse123456" | openssl enc -base64
>>>>
ZXhhbXBsZS5jb206TmV2ZXJVc2UxMjM0NTY=​

Die obige echo|openssl-Befehlsfolge muß man natürlich mit den tatsächlichen Login-Daten ausführen und das Ergebnis dann wie gezeigt in die obige GET-Request-Vorlage einfügen.

Im nächsten Schritt erzeugt man das Shell-Script /root/config/dyndns-update.sh:

nano /root/config/dyndns-update.sh

Es wird folgender Inhalt eingesetzt und mit <ctrl>-<o> gespeichert:

#!/bin/sh

for iface in `/sbin/ifconfig -l` ; do
   desc=`/sbin/ifconfig $iface | /usr/bin/sed -n '/.description: /{s///;s/ .*//;p;}'`
   if [ "$desc" == "WAN" ] ; then
      WAN=$iface
   fi
done

if [ -e /var/tmp/currentIP ] ; then
   currentIP=`/bin/cat /var/tmp/currentIP`
else
   currentIP=
fi

if [ "$1" == "" ] ; then
   if [ "$WAN" != "" ] ; then
      newIP=`/sbin/ifconfig $WAN | /usr/bin/sed -n '/.inet /{s///;s/ .*//;p;}'`
   fi
else
   newIP=$1
fi

if [ "$newIP" == "" ] || [ "$newIP" == "$currentIP" ] ; then
   echo "dyndns: nochg $currentIP"

else
   if [ "$currentIP" = "" ] ; then
      echo "dyndns: updating to $newIP"
   else
      echo "dyndns: updating from $currentIP to $newIP"
   fi

   /usr/bin/sed "s/NEWIP/$newIP/" /root/config/dyndns-example.com.req \
   | /usr/bin/openssl s_client -connect dyndns.strato.com:443 -tls1_2 -cipher HIGH -CAfile /usr/local/share/certs/ca-root-nss.crt -quiet -crlf

#  if [ "$?" = "0" ] ; then
#     Hier können bei Bedarf weitere Update-Requests eingefügt werden
#     /usr/bin/sed "s/NEWIP/$newIP/" /root/config/dyndns-beispiel.de.req \
#     | /usr/bin/openssl s_client -connect dyndns.strato.com:443 -tls1_2 -cipher HIGH -CAfile /usr/local/share/certs/ca-root-nss.crt -quiet -crlf
if [ "$?" = "0" ] ; then echo "$newIP" > /var/tmp/currentIP fi # fi fi

Mit <ctrl>-<x> verläßt man den Kommandozeileneditor nano(1). Das Shell-Script muß schließlich noch ausführbar gemacht werden:

chmod ugo+x /root/config/dyndns-update.sh

Wir können das Script jetzt auch gleich schon einmal testen - bitte eine gültige IP-Adresse anstelle von 123.456.78.90 eingeben:

/root/config/dyndns-update.sh 123.456.78.90
>>>>
depth=3 C = ZA, ST = Western Cape, L = Cape Town, O = Thawte Consulting cc, OU = Certification Services Division, CN = Thawte Premium Server CA, emailAddress = premium-server@thawte.com
verify return:1
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU = "(c) 2006 thawte, Inc. - For authorized use only", CN = thawte Primary Root CA
verify return:1
depth=1 C = US, O = "Thawte, Inc.", CN = Thawte SSL CA
verify return:1
depth=0 C = DE, ST = Berlin, L = Berlin, O = Strato AG, OU = Rechenzentrum, CN = *.strato.com
verify return:1
HTTP/1.0 200 OK
Date: Thu, 04 Sep 2014 22:07:56 GMT
Server: Apache/1.3.41 (Unix) mod_deflate/1.0.21 mod_perl/1.31 mod_ssl/2.8.31 OpenSSL/0.9.8o
Connection: close
Content-Type: text/plain; charset=ISO-8859-1

good 123.456.78.90
read:errno=0

Mein FreeBSD-Home-Server erhält seine dynamische öffentliche IP-Adresse via DHCP vom Kabelmodem meines Internet-Diensteanbieters, und so kann ich das obige Dynamic-DNS-Update-Script einfach in das dhclient-script(8) /etc/dhclient-exit-hooks aufnehmen:

nano /etc/dhclient-exit-hooks
#!/bin/sh

case "$new_ip_address" in
10.*) ;;
172.1[6-9].* | 172.2[0-9].* | 172.3[0-1].*) ;;
192.168.*) ;;
"") ;;
*)
    /root/config/dyndns-update.sh $new_ip_address
    ;;
esac

Die Exit-Hooks müssen ausführbar gemacht werden:

chmod ugo+x /etc/dhclient-exit-hooks

Dadurch ist sichergestellt, daß bei jeder DHCP-Lease-Aktualisierung auch das Dynamic-DNS-Update-Script aufgerufen wird. Dieses überprüft zunächst, ob sich die öffentliche IP-Adresse geändert hat, und wenn ja, dann schickt es die eingetragenen Update-Request-Vorlagen der Reihe nach mit der neuen IP-Adresse per HTTPS an den Dynamic-DNS-Update-Server.

Im Falle von PPPoE klinkt man das Dynamic-DNS-Update-Script in den Verbindungsaufbau ein. Jedenfalls bleibt somit der Domain-Name unseres FreeBSD-Home-Servers automatisch mit seiner jeweiligen aktuellen öffentlichen IP-Adresse verknüpft.

Schließlich ist es sinnvoll, das Dynamic-DNS-Update-Script auch beim Hochfahren des Computers einmal aufzurufen zu lassen, dazu fügt man dessen Aufruf an das Start-Script /etc/rc.local an:

echo "/root/config/dyndns-update.sh" >> /etc/rc.local

Copyright © Dr. Rolf Jansen - 2015-10-05 18:37:09

PROMOTION