| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung |
| home-server [2021-07-29 13:37:24] – [ddclient] david | home-server [2023-04-22 15:12:23] (aktuell) – [Cloudflare] manfred |
|---|
| | ====== 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 ==== |
| | |
| | <code properties /etc/ddclient/ddclientv4.conf> |
| | 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 |
| | |
| | </code> |
| | |
| | <code properties /etc/ddclient/ddclientv6.conf> |
| | 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 |
| | |
| | </code> |
| | |
| | === IPv6 auf der von Debian gepatchten Version (z.B. Ubuntu) === |
| | |
| | <code properties /etc/ddclient/ddclientv6.conf> |
| | 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 |
| | |
| | </code> |
| | |
| | |
| | ==== 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 |
| | |
| | <code c cloudflare-ddns.ini> |
| | API_TOKEN=1234567893feefc5f0q5000bfo0c38d90bbeb |
| | ZONE_NAME=example.com |
| | </code> |
| | |
| | <code c cloudflare-ddns.sh> |
| | #!/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 |
| | </code> |
| | |
| | |
| | ==== 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. |
| |