DynDNS

Aus LaborWiki
Wechseln zu: Navigation, Suche
 
DynDNS

Release status: experimental [box doku]

Description DynDNS-Einträge für Laboranten
Author(s)  julijane




Es war der Wunsch geäußert worden, einen DynDNS-Dienst für Laboranten zu betreiben. Ein solches System ist nun testweise in Betrieb.

dyn.labor-bochum.net

Hostnamen können unter der Subdomain dyn.labor-bochum.net eingetragen werden. Dabei gibt es keine Benutzerverwaltung, sondern das zu verwendende Passwort wird als SHA1-Hash über den Hostnamen und einen geheimen Schlüssel gebildet. Das Passwort kann mit einem Programm ermittelt werden, welches den Systemadministratoren zur Verfügung steht.

Zugang bekommen

Den gewünschten Hostnamen überlegen und einen der Systemadministratoren ansprechen.

Benutzung

Das Setzen und aktualisieren von Einträgen geschieht über einen einfachen Request per HTTP oder HTTPS (empfohlen).

https://das-labor.org/dyndns/dyndns.pl?hostname=HOSTNAME&password=PASSWORD&rrtype=RRTYPE&rr=RR[&ttl=TTL]

Hierbei sind folgende Werte zu ersetzen:

  • HOSTNAME - der verwendete Hostname komplett, z.B. kjuliane.dyn.labor-bochum.net
  • PASSWORD - der zu diesem Hostnamen passende Hash, bei der Administration erfragen
  • RRTYPE - der zu setzende/ändernde Eintragstyp. Möglich sind: A (IPv4-Adresse), AAAA (IPv6-Adresse), MX (Verweis auf Mailserver) und TXT (Freitext)
  • RR - der zu setzende Wert. Beispiele: IPv4 "1.2.3.4", IPv6 "2001:1234:5678::9a0b", MX "10 mail.do.main".
  • TTL - dieser Wert steuert optional die per DNS mitgeteilte Gültigkeit des Eintrages. Standardmäßig wird 300 Sekunden (5 Minuten) gesetzt. Ein Wert unter 60 Sekunden kann nicht gewählt werden.

Technische Umsetzung

Wer sich so etwas selber bauen will, so funktionierts:

  • Es wird ein BIND DNS-Server vorausgesetzt.
  • Es muß für die DNS-Updates ein Schlüssel erzeugt werden:

    dnssec-keygen -a HMAC-MD5 -b 512 -n HOST irgendeinstring

    Aus der erzeugten Datei (z.B. Kirgendeinstring.+123+12345.private) wird der Wert aus der Zeile "Key:" benötigt.
  • In der BIND-Config wird dieser Schlüssel hinzugefügt und dann in der Zone diesem ein Update von Einträgen in der gewünschten Subdomain erlaubt:

    key "userdyndns" {
      algorithm hmac-md5;
      secret "der key von zuvor";
    };

    zone "labor-bochum.net" IN {
      [...]
      update-policy {
        grant userdyndns wildcard *.dyn.labor-bochum.net. A AAAA MX TXT;
       };
      [...]
    };

  • Nun können unter Verwendung des erzeugten Schlüssel Einträge hinzugefügt und aktualisiert werden.

Programmcode

Folgendes CGi-Skript liegt auf dem Webserver:

#!/usr/bin/perl
use CGI;
use Net::DNS;
use Net::DNS::Update;
use Digest::SHA1 qw(sha1_hex);

print "Content-Type: text/plain\n\n";

my $q = new CGI;
$hostname = $q->param('hostname');
$rr = $q->param('rr');
$rrtype = uc($q->param('rrtype'));
$password = $q->param('password');
$ttl = $q->param('ttl') || 300;
$ttl = 60 if ( $ttl < 60 );

if ( $hostname !~ /\.dyn\.labor-bochum.net$/ or
     $rrtype !~ /^(A|AAAA|MX|TXT)$/ ) {
  print "FAIL Go away\n";
  exit;
}

my $secret = '<hier einen geheimen Schlüssel eintragen>';
if ( $password ne sha1_hex($secret.$hostname) ) {
  print "FAIL Wrong password\n";
  exit;
}


my $key_name = 'userdyndns';
my $key_data = '<hier den erzeugten Schlüssel für die DNS Updats eintragen>';

my $update = Net::DNS::Update->new('labor-bochum.net');
$update->push(update => rr_del("$hostname $rrtype"));
$update->push(update => rr_add("$hostname $ttl $rrtype $rr"));
$update->sign_tsig($key_name, $key_data);

my $res = Net::DNS::Resolver->new;
$res->nameservers('das-labor.org');

my $reply = $res->send($update);
 
if ($reply) {
  my $rcode = $reply->header->rcode;
  if ( $rcode eq 'NOERROR' ) {
    print "OK Update ok\n";
  }
  else {
    print "FAIL $rcode\n";
  }
} else {
  print 'FAIL ', $res->errorstring, "\n";
}

Mit diesem kurzen Code kann das Passwort ermittelt werden:

#!/usr/bin/perl
use Digest::SHA1 qw(sha1_hex);
($hostname) = @ARGV;

die "get-dyndns-password <hostname>.dyn.labor-bochum.net\n"
  if ( $hostname !~ /\.dyn\.labor-bochum.net$/ );

my $secret = '<der geheime Schlüssel aus dem CGI>';

print "Password:\n";
print sha1_hex($secret.$hostname), "\n\n";