====== Home-Server ====== ===== DynDNS ===== Gelegentlich ist es eine gute Idee, einen Server zu Hause einzurichten und ihn dann aus dem Internet erreichbar zu machen. Das nennt sich "Home-Server". Hat man seinen Internetzugang bei der [[http://www.telekom.de|Telekom]] oder bei [[http://www.1und1.de|1und1]], dann ist das mit einem [[http://selfhost.de/|DynDNS-Account]] ganz einfach zu realisieren. Komplizierter wird es, wenn man seinen Internetzugang bei [[http://www.unitymedia.de/|Unitymedia]] hat. Mit einem Internetzugang von Unitymedia, bei dem man eine Fritz!Box bekommen hat, **benötigt man einen DynDNS-Anbieter, der IPv6 unterstützt**. deutsche DynDNS-Anbieter: * [[http://selfhost.de/]] - der beste, kann aber kein IPv6 * [[http://spdns.de/]] - kann IPv6 ===== ddclient ===== **Achtung: ddclient ist ziemlich buggy, wenn Cloudflare als DNS zum Einsatz kommt, empfehle ich das selbstgeschriebene Skript weiter unten (Stand ddclient 3.9.1)** * [[https://github.com/ddclient/ddclient]] - originale Konfigurationsvorlage findet man im repo unter dem Namen: **ddclient.conf.in** * IPv6 und manche DNS Anbieter (z.B. Cloudflare) brauchen noch weitere Abhängigkeiten. Siehe [[https://github.com/ddclient/ddclient#installation|Installation]]. ==== Konfigurationsdateien ==== daemon=0 syslog=yes pid=@runstatedir@/ddclient.pid ssl=yes ipv6=no login=E-MAIL password=API-KEY-TOKEN use=cmd, cmd='curl --ipv4 http://checkip.dyndns.org/', cmd-skip='Current IP Address: ' #use=web, web='http://checkip.dyndns.org/', web-skip='Current IP Address: ' protocol=cloudflare, zone=EXAMPLE.COM, ttl=1, EXAMPLE.COM daemon=0 syslog=yes pid=@runstatedir@/ddclient.pid ssl=yes ipv6=yes login=E-MAIL password=API-KEY-TOKEN use=cmd, cmd='curl --ipv6 http://checkipv6.dyndns.org/', cmd-skip='Current IP Address: ' #use=web, web='http://checkipv6.dyndns.org/', web-skip='Current IP Address: ' protocol=cloudflare, zone=EXAMPLE.COM, ttl=1, EXAMPLE.COM === IPv6 auf der von Debian gepatchten Version (z.B. Ubuntu) === daemon=0 syslog=yes pid=@runstatedir@/ddclient.pid ssl=yes ipv6=yes login=E-MAIL password=API-KEY-TOKEN ### usev6 only works with debian's patched version in apt repos usev6=if, if='eth0', if-skip='inet6 ' protocol=cloudflare, zone=EXAMPLE.COM, ttl=1, EXAMPLE.COM ==== Benutzung ==== Aufruf (IPv4 & IPv6): ddclient -daemon 0 -file /etc/ddclient/ddclientv4.conf -force && ddclient -daemon 0 -file /etc/ddclient/ddclientv6.conf -force Debuggen (IPv4 & IPv6) ddclient -daemon=0 -file /etc/ddclient/ddclientv4.conf -force -debug -noquiet -verbose && ddclient -daemon 0 -file /etc/ddclient/ddclientv6.conf -force -debug -noquiet -verbose ddclient soll stündlich statt täglich ausgeführt werden mv /usr/local/etc/periodic/daily/ddclient_force /usr/local/etc/periodic/hourly/ alternativ: nur den einzelnen Befehl in crontab hinzufügen 0 * * * * ddclient -daemon 0 -file /etc/ddclient/ddclientv4.conf -force && ddclient -daemon 0 -file /etc/ddclient/ddclientv6.conf -force ===== DynDNS-Client selbst gebaut ===== ==== Cloudflare ==== neuste Version auf GitHub: [[https://github.com/masterflitzer/cloudflare-ddns.git]] Abhängigkeiten: ''links'' und ''jq'' Cron: @reboot root cloudflare-ddns.sh > /var/log/cloudflare-ddns.log 2>&1 @hourly root cloudflare-ddns.sh > /var/log/cloudflare-ddns.log 2>&1 === Skript === > apt install links curl jq API_TOKEN=1234567893feefc5f0q5000bfo0c38d90bbeb ZONE_NAME=example.com #!/bin/bash ##### Variables CONFIG_FILE="$(dirname "$0")/$(basename -- "$0" .sh).ini" INTERVAL="5" COUNTER="10" # boolean # if "true" the dns record for the root domain will be updated UPDATE_ROOT_DOMAIN="true" # multiple record names (subdomains) to be updated # separated by space, e.g. "www mail smtp" RECORD_NAME_V4="" RECORD_NAME_V6="" TTL="1" PROXIED="false" # stable base URL for all Version 4 HTTPS endpoints API_ENDPOINT="https://api.cloudflare.com/client/v4" # custom API-Token (not global API-Key) # permissions needed: #dns_records:edit API_TOKEN="$(cat "$CONFIG_FILE" | grep -E "^API_TOKEN=" | head -1 | cut -d "=" -f2)" # when you want to update "www.example.com", "www" is the RECORD_NAME and "example.com" is the ZONE_NAME ZONE_NAME="$(cat "$CONFIG_FILE" | grep -E "^ZONE_NAME=" | head -1 | cut -d "=" -f2)" COUNTER_V4="$COUNTER" COUNTER_V6="$COUNTER" ##### Functions links_IPv4() { IP_V4="$(links -dump http://checkip.dyndns.org/ | tr -s '[ :]' '\n' | egrep '[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+')" #IPv4="1.1.1.1" } links_IPv6() { IP_V6="$(links -dump http://checkipv6.dyndns.org/ | tr -s ' ' '\n' | egrep '[0-9a-f]+[:]+[0-9a-f]+[:]*')" #IPv6="2606:4700:4700::1111" } ##### Script ### Get IPs printf "\n#==============================================================================#\n\n" echo -n "Determining IPv4 address" links_IPv4 while test -z "$IP_V4" -a "$COUNTER_V4" -gt "0" do echo -n '.' COUNTER_V4="$(echo "$COUNTER_V4"|awk '{print $1-1}')" sleep $INTERVAL links_IPv4 done echo echo -n "Determining IPv6 address" links_IPv6 while test -z "$IP_V6" -a "$COUNTER_V6" -gt "0" do echo -n '.' COUNTER_V6="$(echo "$COUNTER_V6"|awk '{print $1-1}')" sleep $INTERVAL links_IPv6 done echo echo "IPv4: $IP_V4" echo "IPv6: $IP_V6" printf "\n#==============================================================================#\n\n" ### Get Zone ID ZONE_ID="$(curl -s -X GET "${API_ENDPOINT}/zones" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" 2>/dev/null | jq -r ".result[] | select(.name == \"${ZONE_NAME}\") | .id")" ### Get Record ID (IPv4) RECORD_ID_V4="$(curl -s -X GET "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" 2>/dev/null | jq -r ".result[] | select((.name == \"${ZONE_NAME}\") and (.type == \"A\")) | .id")" ### Get Record ID (IPv6) RECORD_ID_V6="$(curl -s -X GET "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" 2>/dev/null | jq -r ".result[] | select((.name == \"${ZONE_NAME}\") and (.type == \"AAAA\")) | .id")" echo "Record Name = $ZONE_NAME" echo "ZONE_ID = $ZONE_ID" echo "Record ID (IPv4) = $RECORD_ID_V4" echo "Record ID (IPv6) = $RECORD_ID_V6" ### Set IP printf "\n#==============================================================================#\n\n" if test $UPDATE_ROOT_DOMAIN == "true" then echo "IPv4: Updating DNS Record to '$IP_V4'" curl -s -X PUT "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records/${RECORD_ID_V4}" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" --data "{\"type\":\"A\",\"name\":\"${ZONE_NAME}\",\"content\":\"${IP_V4}\",\"ttl\":${TTL},\"proxied\":${PROXIED}}"; echo printf "\n#------------------------------------------------------------------------------#\n\n" echo "IPv6: Updating DNS Record to '$IP_V6'" curl -s -X PUT "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records/${RECORD_ID_V6}" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" --data "{\"type\":\"AAAA\",\"name\":\"${ZONE_NAME}\",\"content\":\"${IP_V6}\",\"ttl\":${TTL},\"proxied\":${PROXIED}}"; echo fi ### Set IP for Record Names printf "\n#==============================================================================#\n\n" if test ! -z "${RECORD_NAME_V4// }"; then printf "IPv4: Subdomains\n\n"; fi COUNTER="0" for RECORD_NAME in $RECORD_NAME_V4 do if test $COUNTER -gt 0; then printf "\n#------------------------------------------------------------------------------#\n\n"; fi RECORD_ID="$(curl -s -X GET "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" 2>/dev/null | jq -r ".result[] | select((.name == \"${RECORD_NAME}.${ZONE_NAME}\") and (.type == \"A\")) | .id")" echo "Record Name = $RECORD_NAME.$ZONE_NAME" echo "Record ID = $RECORD_ID" echo "Updating DNS Record to '$IP_V4'" curl -s -X PUT "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records/${RECORD_ID}" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" --data "{\"type\":\"A\",\"name\":\"${RECORD_NAME}.${ZONE_NAME}\",\"content\":\"${IP_V4}\",\"ttl\":${TTL},\"proxied\":${PROXIED}}"; echo let "COUNTER += 1" done if test $COUNTER -gt 0; then printf "#==============================================================================#\n\n" fi if test ! -z "${RECORD_NAME_V6// }"; then printf "IPv6: Subdomains\n\n"; fi COUNTER="0" for RECORD_NAME in $RECORD_NAME_V6 do if test $COUNTER -gt 0; then printf "\n#------------------------------------------------------------------------------#\n\n"; fi RECORD_ID="$(curl -s -X GET "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" 2>/dev/null | jq -r ".result[] | select((.name == \"${RECORD_NAME}.${ZONE_NAME}\") and (.type == \"AAAA\")) | .id")" echo "Record Name = $RECORD_NAME.$ZONE_NAME" echo "Record ID = $RECORD_ID" echo "Updating DNS Record to '${IP_V6}'" curl -s -X PUT "${API_ENDPOINT}/zones/${ZONE_ID}/dns_records/${RECORD_ID}" -H "Authorization: Bearer ${API_TOKEN}" -H "Content-Type: application/json" --data "{\"type\":\"AAAA\",\"name\":\"${RECORD_NAME}.${ZONE_NAME}\",\"content\":\"${IP_V6}\",\"ttl\":${TTL},\"proxied\":${PROXIED}}"; echo let "COUNTER += 1" done if test $COUNTER -gt 0; then printf "#==============================================================================#\n\n" fi ==== Selfhost ==== Wird dagegen der Internetzugang per Horizon-//Box// bereitgestellt, dann kann man dort keinen DynDNS-Account eintragen und muss sich einen DynDNS-Client selber bauen. hierfür sind folgende Schritte abzuarbeiten: - Home-Server mit fester IP im LAN (z.B. 192.168.0.2) konfigurieren, der Server darf keine DHCP-Adresse bekommen, da sich diese u.u. ändern kann; - in der Horizon-//Box// muss unter ''FORTGESCHRITTEN / Weiterleitung'' eine Port-Weiterleitung eingerichtet werden, z.B.: * ''| 80 | 192.168.0.2 | 80 | TCP |'' - sinnvoll wäre auch ein Portweiterleitung für den Port 443 aber natürlich nur, wenn man seine Web-Seite SSL-verschlüsselt hat - jetzt wird ein DynDNS-Zugang benötigt, den kann man u.a. bei [[http://www.selfhost.de|selfhost]] bekommen; - beim DynDNS-Anbieter eine Umleitung einrichten und das vergebene Passwort merken, man kann sich bei [[http://www.selfhost.de|selfhost]] auch schon eine Update-URL generieren, von der nur die IP entsprechend jedesmal angepasst werden muss; - beispielsweise sieht das bei [[https://secure.selfhost.de/cgi-bin/selfhost?p=faq&show=59|selfhost]] so aus: * ''http://3075846:geheim@carol.selfhost.de/nic/update?myip=139.110.183.137'' - man kann es auch automatisieren, dann würde der Kommandozeilenaufruf von Linux aus so aussehen: * ''links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://www.meine-aktuelle-ip.de/ | awk '/Ihre aktuelle IP Adresse:/{print $NF}')'' - die Kommandozeile kann man dann in die ''crontab'' eintragen und einmal am Tag ausführen lassen, damit wäre der selbst gebaute DynDNS-Client fertig; - **Wichtig ist hierbei noch, dass er nicht zu oft ausgeführt wird, da einige Anbieter nur ein IP-Update pro Tag zulassen!** hier noch ein paar alternative Kommandozeilenaufrufe für Linux, die theoretisch alle das gleiche bewirken sollten: links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://www.ip-secrets.info/ | awk '/Ihre aktuelle IP-Adresse:/{print $NF}') links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://www.wieistmeineip.de/ | sed -n '/Ihre IP-Adresse lautet:/,/[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*/p' | awk '/[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*/{print $NF}') links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://www.meine-aktuelle-ip.de/ | awk '/Ihre aktuelle IP Adresse:/{print $NF}') links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://www.meineip.de/ | sed -n '/Meine IP-Adresse lautet:/,/[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*/p' | awk '/[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*/{print $NF}') links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://meineipadresse.de/ | fgrep 'Meine o:ffentliche' | tr -s ' ' '\n' | awk '/[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*/{print $NF}') links -dump http://3075846:geheim@carol.selfhost.de/nic/update?myip=$(links -dump http://www.heise.de/netze/tools/meine-ip-adresse/ | awk '/Ihre Anfrage kommt von der IP-Adresse:/{print $NF}') Statt ''"3075846"'' und ''"geheim"'' sind die eigenen Zugangsdaten für den DynDNS-Account anzugeben. Und nicht vergessen!\\ Es muss unbedingt der ''PATH'' angegeben werden, denn sonst kann der CRON-Dienst das Programm ''links'' nicht finden.\\ Da diese Kommandos mit Linux und FreeBSD funktionieren sollen, kann ich hier den absoluten Pfad nicht angeben. Denn der ''links''-Pfad ist bei Linux und FreeBSD unterschiedlich.