Bis vor kurzem habe ich dyn.com als Lösung für meine dynamische DNS Domäne genutzt. Leider ist dyn.com für eine Domäne zu teuer geworden seit Oracle Dyn übernommen hat. Ich wollte jedoch nicht einfach den Anbieter wechseln, lieber wäre mir eine "eigene" Lösung gewesen, um unabhängig zu sein von den Launen eines Dienstleisters.

Per Zufall bin ich dann über diese Blog Artikel gestossen:

In diesen Artikeln wird erklärt, wie AWS Route 53 als kostengünstige dynamische DNS Lösung eingesetzt werden kann. Ich habe dies ausprobiert und es ist relativ einfach umzusetzen, wenn man sich mit AWS (cli) und AWS Route 53 schon auskennt.

Ich habe eine veränderte Version der Scripts aus dem Original-Artikel erstellt:

Anpassen müsst ihr folgende Variablen:

Ihr könnt natürlich alles andere auch anpassen im Script, ich will nur noch auf folgende Variablen aufmerksam machen:

  • aws_profile => Hier könnt ihr das AWS Profil angeben, falls ihr mehrer nutzt: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
  • aws_binary_path => Pfad zu eurem AWS cli. Je nach Installation unterschiedlich. Bei Nutzung mit cron teilweise nötig um die PATH Variable richtig zu setzen.
  • IPFILE=> Pfad/Dateiname in welcher die IPv4 des letzten Laufs gespeichert wird.
  • COMMENT => Kommentar welcher beim aktualisieren des DNS-Eintrages bei AWS Route 53 gespeichert wird.

Ein weiterer interessanter Abschnitt im Script ist das herausfinden der externen IPv4-Adresse:

# Get the external IP address
# https://unix.stackexchange.com/questions/22615/how-can-i-get-my-external-ip-address-in-a-shell-script
# example1: dig @resolver1.opendns.com A myip.opendns.com +short -4
# example2: dig @ns1-1.akamaitech.net ANY whoami.akamai.net +short -4
# example3: dig @ns1.google.com TXT o-o.myaddr.l.google.com +short -4 | sed -e 's#"##g'
IPv4=$(dig @resolver1.opendns.com A myip.opendns.com +short -4)
Externe IPv4-Adresse bestimmen mit dig

Es gibt viele Möglichkeiten die externe IPv4-Adresse zu bestimmen, wichtig jedoch ist, dass dies zuverlässig funktioniert und sich nicht über die Zeit ändert. Im Kommentar sind einige Beispiele und ein Link zu einem Thread der sich diesem Thema widmet. Eine alternative zu dig wäre auch mit curl die IPv4 zu bestimmen, z.B. mit: curl https://ipinfo.io/ip

Script ausführen

Wenn ihr das Script das erste mal ausführt und noch keine IPv4 im IPFILE gespeichert ist, wird versucht der AWS Route 53 DNS-Eintrag zu aktualisieren. Um die Aktualisierung der DNS-Eintrages zu forcieren, müsst ihr also nur das IPFILE löschen.

> ./updateRoute53DNSRecord.sh
[Sat Mar 21 21:25:48 UTC 2020] Starting "./updateRoute53DNSRecord.sh"
External Ipv4 has changed to xxx.yyy.zzz.000
{
    "ChangeInfo": {
        "Id": "/change/C0917505C6U6425KAQMX",
        "Status": "PENDING",
        "SubmittedAt": "2020-03-21T21:25:50.110000+00:00",
        "Comment": "Auto updating @ Sat Mar 21 21:25:48 UTC 2020"
    }
}
AWS Route 53 record "supportblog.ch" with type "A" has been updated with value "xxx.yyy.zzz.000" in zone ABCD0987EFGC91 
[Sat Mar 21 21:25:50 UTC 2020] Script finished 
Ausgabe falls AWS Route 53 DNS-Eintrag aktualisiert wurde bzw. die IPv4 hat sich geändert
> ./updateRoute53DNSRecord.sh
[Sat Mar 21 21:25:40 UTC 2020] Starting "./updateRoute53DNSRecord.sh"
External IPv4 is still the same.
[Sat Mar 21 21:25:40 UTC 2020] Script finished
Ausgabe falls kein DNS-Eintrag aktualisiert wurde bzw. die IPv4 hat sich nicht geändert

Zugriffskontrolle DNS Zone

Es ist zusätzlich ratsam einen Benutzer mit programmgesteuertem Zugriff (programmatic access user) zu erstellen und diesen im AWS-cli Profil einzurichten.

Dem Benutzer mit programmgesteuertem Zugriff sollte noch eine AWS IAM Policy, die nur Änderungen von Einträgen in einer angegebene Zone erlaubt, angefügt werden:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": "arn:aws:route53:::hostedzone/<your zone id>"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "route53:ListHostedZonesByName",
            "Resource": "*"
        }
    ]
}
IAM Policy AWS Route 53 - Zoneneinschränkung

Crontab einrichten

Schlussendlich könnt ihr noch einen Cronjob einrichten um die Ausführung des Scripts zu automatisieren:

*/30 * * * * /root/updateRoute53DNSRecord.sh >> /root/updateRoute53DNSRecord.log
/root/updateRoute53DNSRecord.sh alle 30 Minuten ausführen