mikrocontroller.net

Forum: PC-Programmierung DNS A-Record automatisch updaten bei United Domains


Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe eine Domain bei United Domains und ich habe hier ein VDSL von 
der Telekom mit Fritzbox und Linuxserver dahinter.
Bis vor ca. zwei Wochen war das ganz bequem, alle paar Monate(!) bekam 
ich von der Telekom eine neue IP, habe diese händisch bei United Domains 
eingetragen und alles war schick.
Irgendetwas hat die Telekom aber jetzt umgestellt, es kam auch vorher 
ein Brief und das VDSL ist jetzt auch schneller, aber ich bekomme jetzt 
deutlich öfter eine neue IP. Es macht also keinen Spaß mehr diese 
händisch einzutragen.

Jetzt suche ich eine Möglichkeit diese automatisch einzutragen. Der 
Server merkt wenn sich die IP ändert, ein Skript startet und schon steht 
im A-Record wieder die aktuelle IP.
Ja, ich könnte Dyndns oder so verwenden, habe ich auch eine Zeit lang 
mit no-ip, aber ich habe hier ssl für die Domain siehe:
https://www.ssllabs.com/ssltest/analyze.html?d=gus.tl
Daher will ich das nicht auf eine andere Domain umleiten.

Jetzt habe ich schon etwas gefunden und zwar das ddns_ud.sh für OpenWRT 
hier:
https://gist.github.com/mueslo/9258f8b75fe942d36ee...
Ich kann natürlich auch ein Skript starten, weiß aber nicht was ich da 
genau anpassen muss. SED verwende ich normalerweise nicht.

Die Fragen:
#domain should contain "domain_id:record_id"
domain_id=$(echo $domain | tr ":" "\n" | sed -n "1p")
record_id=$(echo $domain | tr ":" "\n" | sed -n "2p")
Muss ich erst eine Variable "domain" anlegen?
Was ist die domain_id, was der record_id, wie finde ich die heraus?
Wenn ich eine Whois Abfrage startet steht da schonmal

Domain ID: 1119709-CoCCA

drinnen. Ist das diese ID die ich brauche?
Kann ich bei record_id einfach A reinschreiben, also:
domain_id=1119709-CoCCA
record_id=A

Ich will mich auch nicht unbedingt an dieses gefundene Skript klammern, 
wenn mir jemand den Mechanismus erklärt schreibe ich mir auch selber 
eines, aber ich weiß leider nicht was man Schritt für Schritt machen 
muss um diesen A-Record zu aktualisieren.
Klar ist nur:
IP herausfinden, bei United Domains anmelden, irgendetwas hinschicken.

Vielen Dank!

Autor: Rene F. (renfle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CNAME auf die noip Adresse

Home.domain.tld CNAME dyndns.no-ip.com

Läuft bei mir seit Jahren so, auch mit letsencrypt.

: Bearbeitet durch User
Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann ich machen, aber das SSL Zertifikat gilt ja für die United Domains 
Domain und nicht für den Namen von No-IP.org. Geht das SSL dann trotzdem 
ohne Warnung beim Besucher?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HTTP Redirect geht bei Zertifikaten nicht, aber CNAME arbeitet rein auf 
DNS Basis und geht daher. Abgesehen davon wärs bei Lets Encrypt doch 
egal.

Bei Fritzboxen gibts übrigens über MyFritz auch eine DynDNS-Adresse. Die 
will man zwar nicht dauernd eintippen, erspart aber no-ip.

: Bearbeitet durch User
Autor: Rene F. (renfle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sollte für die United Domain gelten. Ist ja in diesem Sinn keine 
Umleitung.

Anfrage: home.domain.tld
Antwort: Cname dyndns.no-ip.com
Anfrage: dyndns.no-ip.com
Antwort: <IP vom Anschluss>

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, aber da steht:
CNAME (Nur für Subdomains)
Warum geht das nicht für die ganze Domain? Also wenn ein Besucher den 
Domainnamen ohne Subdomain besuchen möchte will ich dass trotzdem SSL 
ohne Warnung funktioniert.

A. K. schrieb:
> Bei Fritzboxen gibts übrigens über MyFritz auch eine DynDNS-Adresse. Die
> will man zwar nicht dauernd eintippen, erspart aber no-ip.

Hab gerade gesehen, dass bei No-Ip expired ist und habe jetzt mal meinen 
Fritzboxnamen als CNAME eingetragen.

Aber auch wenn das eine Lösung ist würde ich rein aus Interesse doch 
gerne noch wissen wie ich das mit einem Skript mache.

Edit:
Ja super. Also ich habe jetzt den Fritz Dyndns namen als CNAME 
eingetragen für beliebige Subdomains. Also *.domain.tld
Wenn man jetzt nur domain.tld im browser eingibt wird diese nicht 
gefunden. Gibt man zusätzliche Subdomain mit ein, z. B. test.domain.tld 
so funktioniert die Weiterleitung wunderbar, aber ich bekomme eine 
Warnung weil das Zertifikat nicht für die Subdomain ausgestellt wurde. 
Tja und genau so eine Warnung will ich vermeiden und ich will aber auch 
niemanden zwingen eine Subdomain mit eintippen zu müssen.
Ich will also doch ein Skript.

: Bearbeitet durch User
Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir niemand sagen was man in dem Skript
https://gist.github.com/mueslo/9258f8b75fe942d36ee...
bei
domain_id=$(echo $domain | tr ":" "\n" | sed -n "1p")
record_id=$(echo $domain | tr ":" "\n" | sed -n "2p")
eintragen soll?
Ich würde das gerne einmalig für meine Domain anpassen wollen.

Vielen Dank!

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> OK, aber da steht:
> CNAME (Nur für Subdomains)
> Warum geht das nicht für die ganze Domain?

Das muss eine Limitation deines DNS Providers sein, den die Technologie 
selbst setzt das nicht vorraus. Du kannst ja mal versuchen was passiert, 
wenn du @ oder . oder nichts dort einträgst. Wenn das nichts nützt, dort 
mal anrufen. Wenn die das dann nicht können sollten, DNS Provider 
wechseln (aber vorher schauen, ob der das dann kann oder sonstige 
unnötige einschränkungen macht). Ich hoste meine DNS halt selbst und hab 
ne statische IP, damit habe ich keine solchen Probleme.

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Kann mir niemand sagen was man in dem Skript
> https://gist.github.com/mueslo/9258f8b75fe942d36ee...
> bei
> domain_id=$(echo $domain | tr ":" "\n" | sed -n "1p")
> record_id=$(echo $domain | tr ":" "\n" | sed -n "2p")
> eintragen soll?

Lass das Script mal, wie es ist. Es scheint mir, als sei vorgesehen, 
dass dieses mit den environment variablen username, password und domain, 
sowie einem Parameter für eine IPv4 addresse gesetzt wird. also z.B. 
'username="benuzername" password="passwort" domain="domainid:recordid" 
./ddns_ud.sh ipv4addresse. Geht auch in einem Scriptfile:
#!/bin/sh

export domain="domainid:recordid"
export username="Benutzername"
export password="Passwort"

./ddns_ud.sh "$1"

Die domainid und recordid sind Parameter, die spezifisch zur united 
domains weboberfläche und interne Rest API sind, und der Identifizierung 
des Dns Recorcs und der Donain dienen. Diese Weboberfläche und APIs 
könnte sich jederzeit ändern.

Es ist gut möglich, das 1119709-CoCCA oder 1119709 aus der whois abfrage 
die domain id ist. Falls nicht, müsste man nach dem Einloggen beim 
Webinterface in den entwickler tools des browsers nachsehen (diese schon 
vor dem einloggen öffnen). Dann im Netzwerk tab nach 
"https://www.united-domains.de/pfapi/dns/domain/ domainid /records" 
ausschau halten, wärend du zur übersicht der DNS Records für deine 
gehst. Klicke den eintrag dann an, und schaue dir im tab für die antwort 
nach, was im feld "id" für den eintrag, den du ändern möchtest, steht.

Alternativ kannst du auch versuchen, die ersten paar Abfragen in der 
Console einzugeben, um die recordid herauszufinden:
domain_id=Deine domain id
username=Benutzername
password=Passwort

csrf=$(/usr/bin/wget --save-cookies $cookiefile --keep-session-cookies --delete-after -qO- "https://www.united-domains.de/login/" | /usr/bin/grep -oP -m 1 "(?<=<input type=\"hidden\" name=\"csrf\" value=\")[^\"]*(?=\"( /)?>)")

csrf=$(/usr/bin/wget --load-cookies $cookiefile --save-cookies $cookiefile --keep-session-cookies --post-data "csrf=$csrf&email=$username&pwd=$password&selector=login&loginBtn=Login" -qO- "https://www.united-domains.de/login/" | /usr/bin/grep -oP -m 1 "(?<=<input type=\"hidden\" name=\"csrf\" value=\")[^\"]*(?=\"( /)?>)")

/usr/bin/wget --load-cookies $cookiefile --save-cookies $cookiefile --keep-session-cookies -qO- "https://www.united-domains.de/pfapi/dns/domain/$domain_id/records"
Die ausgabe dann eventuell durch einen der online json beautifier laufen 
lassen, um es einfacher lesen zu können.

PS: All das oben ist rein aus schlusfolgerungen nach betrachten des 
Codes entstanden, ich habe und kann nichts davon ausprobieren.

Autor: Hmmm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> OK, aber da steht:
> CNAME (Nur für Subdomains)
> Warum geht das nicht für die ganze Domain?

CNAMES dürfen nicht parallel zu weiteren DNS-RRs existieren, und da 
Deine Domain mindestens SOA- und NS-Records hat, ist das nicht 
realisierbar.

Dass einige das trotzdem erlauben, ist also eher ein Bug als ein 
Feature.

> Also wenn ein Besucher den
> Domainnamen ohne Subdomain besuchen möchte will ich dass trotzdem SSL
> ohne Warnung funktioniert.

Einfach den überall etablierten Hostname "www" verwenden?

> gefunden. Gibt man zusätzliche Subdomain mit ein, z. B. test.domain.tld
> so funktioniert die Weiterleitung wunderbar, aber ich bekomme eine
> Warnung weil das Zertifikat nicht für die Subdomain ausgestellt wurde.

Das Zertifikat muss immer zu dem passen, was der User eingibt (z.B. 
www.domain.tld), das hat nichts mit den DNS-RRs zu tun.

Wenn die Erreichbarkeit unter mehreren Hostnames notwendig ist, brauchst 
Du ein Wildcard-Zertifikat oder einen Webserver mit SNI-Support und 
mehrere Zertifikate.

Autor: Hermann K. (r2d2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur CNAME-Problematik: Vielleicht unterstützt dein Provider 
CNAME-Flattening oder ANAME (ist quasi das gleiche). Hier gibts ein paar 
technische Details:
https://blog.cloudflare.com/introducing-cname-flat...

@Script: Du kannst unter dem Github Gist einen Kommentar hinterlassen. 
Stell deine Frage doch einfach da und schau ob dir vielleicht der Autor 
des Scripts antwortet.

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm schrieb:
> CNAMES dürfen nicht parallel zu weiteren DNS-RRs existieren, und da
> Deine Domain mindestens SOA- und NS-Records hat, ist das nicht
> realisierbar.

Also den A-Record Eintrag kann ich auch löschen.

Hmmm schrieb:
> Das Zertifikat muss immer zu dem passen, was der User eingibt (z.B.
> www.domain.tld), das hat nichts mit den DNS-RRs zu tun.

Ja das ist klar.

Hmmm schrieb:
> Einfach den überall etablierten Hostname "www" verwenden?

Will ich eigentlich nicht, ich will nur das was ich bisher händisch 
gemacht habe automatisieren.

Daniel A. schrieb:
> Es scheint mir, als sei vorgesehen,
> dass dieses mit den environment variablen username, password und domain,
> sowie einem Parameter für eine IPv4 addresse gesetzt wird.

OK, muss ich mal gucken.

Daniel A. schrieb:
> Die domainid und recordid sind Parameter, die spezifisch zur united
> domains weboberfläche und interne Rest API sind, und der Identifizierung
> des Dns Recorcs und der Donain dienen. Diese Weboberfläche und APIs
> könnte sich jederzeit ändern.

Das wusste ich nicht.

Also ich bekommen Folgendes:

Zuerst die "domain-list":
{"data":[{"id":"4130393","domain":"gus.tl","configurable":true,"domain_l 
ock_state":{"domain_locked":false,"email_locked":false}}]}

Und dann "subdomain-list" die ist leer oder eben []
Und danach noch die "records":
{"data":{"A":[{"address":"217.85.249.165","id":79295801,"filter_value":" 
gus.tl","ttl":600,"type":"A","standard_value":false,"sub_domain":"","dom 
ain":"gus.tl","webspace":false,"udag_record_type":5}],"MX":[{"prio":10," 
mail_server":"mx00.udag.de","id":49919990,"filter_value":"gus.tl","ttl": 
3600,"type":"MX","standard_value":true,"sub_domain":"","domain":"gus.tl" 
,"webspace":false,"udag_record_type":null},{"prio":20,"mail_server":"mx0 
1.udag.de","id":49919991,"filter_value":"gus.tl","ttl":3600,"type":"MX", 
"standard_value":true,"sub_domain":"","domain":"gus.tl","webspace":false 
,"udag_record_type":null}],"AAAA":[],"TXT":[],"SRV":[],"CNAME":[],"NS":[ 
],"CAA":[{"flag":0,"tag":"issue","value":"letsencrypt.org","id":79295630 
,"filter_value":"gus.tl","ttl":600,"type":"CAA","standard_value":false," 
sub_domain":"","domain":"gus.tl","webspace":false,"udag_record_type":5}] 
}}

Sieht also danach aus als sei der Record "A" und die ID "79295801".

Wenn ich mir das in dem Entwicklerwerkzeug so angucke was ich da an 
United Domains schicke ist das ja nicht viel. Reicht es wenn ich ein 
Skript schreibe das auch genau das dorthin schickt?

Der Login ist eine POST:
https://www.united-domains.de/login

Host: www.united-domains.de
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: https://www.united-domains.de/logout/
Content-Type: application/x-www-form-urlencoded
Content-Length: 153
Cookie: SESSID=n7msi0nm2k6lcaj9rvcnqtbteu; AcceptCookiePolicy=1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

csrf=dfb0593248c55279e76e15d9d504f66a-4141146b93e27726e3e5cf059cd530e4&selector=login&email=gustl87%40gmx.de&pwd=nichtdaspasswort&loginBtn=Login

Danach geht es mit einem GET hierhin:
https://www.united-domains.de/portfolio/a/dns/domain/4130393
Und es folgen
GET domain-list
GET subdomain-list
GET record

Und dann trage ich da eine neue IP ein und klicke auf speichern und es 
gibt ein PUT. Das hat folgenden Inhalt:
{"data":{"address":"217.85.249.165","id":79295801,"filter_value":"gus.tl 
","ttl":600,"type":"A","standard_value":false,"sub_domain":"","domain":" 
gus.tl","webspace":false,"udag_record_type":5}}

Ich denke das kann ich nachbauen mit Python.

: Bearbeitet durch User
Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, also ich schicke einen POST hin für den Login und bekomme Status 200 
zurück.
r = requests.post(url="https://united-domains.de/login", data = PAYLOAD)

Ich bekomme auch ein Cookie. Was ich damit mache und ob das atomatisch 
beim nächsten GET vorgezeigt wird ist mir unklar. Jedenfalls mache ich 
dann ein GET mit der URL für meine Domain
r = requests.get(url ="https://united-domains.de/portfolio/a/dns/domain/4130393")
und bekomme ebenfalls als Status eine 200 zurück.

Dann will ich mir den Record angucken, also:
r = requests.get(url ="https://www.united-domains.de/pfapi/dns/domain/4130393/records")
Und da bekomme ich jetzt ein 401. Was das bedeutet ist mir klar, aber 
nicht wie ich das verhindern kann. Genügt es wenn ich den Cookie 
irgendwie mitschicke? Muss ich das CSRF verwenden?

: Bearbeitet durch User
Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Cookies enthalten in der Regel eine Session ID. Diese dient dem 
Server dazu sich über verschiedene Requests hin Dinge zu merken, wie 
z.B. wer sich angemeldet hat, etc. Die Cookies müssen also beibehalten 
werden. Ein CSRF Token dient dazu zu verhindern, dass andere Webseiten 
Requests senden können unter Verwendung der Session, in der sich der 
User bei der ursprünglichen Seite angemeldet haben. Aufgrund der same 
origin policy können Webseiten nämlich auf die Daten von anderen 
Webseiten zugreifen, und somit den CSRF token nicht auslesen. Somit 
sollte hier immer der zuletzt vom Server gesendete CSRF Token wieder 
mitgesendet werden.

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, muss ich das selber aktiv machen oer macht das dieses requests Modul 
von Python schon automatisch? Muss ich da selber das richtige Cookie 
raussuchen und den richtigen CSRF String?

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> OK, muss ich das selber aktiv machen oer macht das dieses requests Modul
> von Python schon automatisch?
> Muss ich da selber das richtige Cookie raussuchen

Lasse einfach alle drin. Soll anscheinend mit requests.Session() gehen:
https://stackoverflow.com/questions/31554771/how-t...
Nur das session cookie beibehalten kann man nicht allgemein 
implementieren, weil unterschiedliche Seiten unterschiedliche Namen für 
das Cookie verwenden.

> und den richtigen CSRF String?

Nunja, wie der CSRF gesendet/abgefragt wird ist nicht standardisiert, 
deshalb kann eine Library einem nicht abnehmen, diesen auszulesen und 
mitzusenden.


Das ursprüngliche Shellscript hatte all das übrigens schon eingebaut.

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja hatte es, aber hier hat mir niemand geantwortet auf die Fragen dazu 
also schreibe ich eben ein neues Skript.

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mit
s = request.session()

und dann weiter

r = s.post(url)
r = s.get(url)
r = s.get(url)

Also eben jetzt alles mit dieser Session funktioniert genauso nicht. Ich 
bekomme weiterhin 401.

Ich würde auch gerne das fertike Shellskript verwenden, aber da muss ich 
ja irgendwo die domain_id und die record_id eintragen und weiß nicht was 
das sind.

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die hast du doch oben. DomainID: 4130393 RecordID: 79295801 . Also 
einfach die Environmentvariable domain setzen, 'export 
domain="4130393:79295801"', (und die anderen paar variablen noch).

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah OK, danke! Probiere ich nachher mal aus.

Autor: Mario M. (thelonging)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> CNAME (Nur für Subdomains)
> Warum geht das nicht für die ganze Domain?

Weil United Domains das so will:
https://www.heise.de/forum/heise-online/News-Komme...

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, es geht weiter:

Ich versuche also das Shellskript anzupassen. Das geht auch gut, aber es 
braucht jsonfilter. Tja, wo bekommt man das her?

Na klar!
gb@server:~$ sudo add-apt-repository "deb http://dl.bintray.com/benschw/deb wheezy main"
gb@server:~$ sudo apt-get update
.
.
.
sudo apt-get install jsonfilter
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libllvm3.8 linux-headers-4.4.0-130 linux-headers-4.4.0-130-generic linux-image-4.4.0-130-generic linux-image-extra-4.4.0-130-generic
Use 'sudo apt autoremove' to remove them.
The following NEW packages will be installed:
  jsonfilter
0 upgraded, 1 newly installed, 0 to remove and 17 not upgraded.
Need to get 667 kB of archives.
After this operation, 2,565 kB of additional disk space will be used.
WARNING: The following packages cannot be authenticated!
  jsonfilter
Install these packages without verification? [y/N] y
Get:1 http://dl.bintray.com/benschw/deb wheezy/main amd64 jsonfilter amd64 0.1.0-1423152831 [667 kB]
Err:1 http://dl.bintray.com/benschw/deb wheezy/main amd64 jsonfilter amd64 0.1.0-1423152831
  Hash Sum mismatch
Fetched 667 kB in 1s (442 kB/s)    
E: Failed to fetch http://dl.bintray.com/benschw/deb/pool/main/j/jsonfilter/jsonfilter-amd64-0.1.1.deb  Hash Sum mismatch

E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

Tolle Wurst!

Also direkt das .deb geholt:
gb@server:~$ wget https://github.com/benschw/jsonfilter/releases/download/0.1.1/jsonfilter-amd64-0.1.1.deb
.
.
.
jsonfilter-amd64-0.1.1.deb           100%[===================================================================>] 651.43K   894KB/s    in 0.7s    

2018-09-17 18:42:04 (894 KB/s) - 'jsonfilter-amd64-0.1.1.deb' saved [667060/667060]
gb@server:~$ sudo dpkg --install jsonfilter-amd64-0.1.1.deb

Geht auch alles fein, aber wenn ich dann das Skript starte kommt das 
hier:
gb@server:~$ ./dnsupdate.sh 
flag provided but not defined: -e
  -json=false: display output as json
  -keys=false: display each key or index of selected structure on its own line
  -pretty=false: display pretty json (sets -json=true)
  -v=false: display errors
  -values=false: display each value of selected structure on its own line
  -vv=false: display errors and info
UD answered: 
./dnsupdate.sh: 32: ./dnsupdate.sh: write_log: not found
Retval: 127

In der Zeile
record=$(/usr/bin/wget --load-cookies $cookiefile --save-cookies $cookiefile --keep-session-cookies -qO- "https://www.united-domains.de/pfapi/dns/domain/$domain_id/records" | jsonfilter -e "$[\"data\"][\"A\"][@.id=$record_id]" | sed "s/ //g" | sed "s/\"address\":\"[0-9.]\+\"/\"address\":\"$ipv4\"/g")
wird jsonfilter mit dem Parameter -e aufgerufen den die von mir 
installierte Version offensichtlich nicht kennt.

Tja, was mache ich da? Ein man jsonfilter geht auch nicht, das sieht mir 
stark nach längst verlassenem Pfusch aus.

OK, Edit:

Das installierte jsonfilter ist nicht das Passende. Denn: Das jsonfilter 
im Skript ist das für OpenWRT. Tja. Und das kann ich unter einem 
Desktoplinux nicht bauen weil es auf libubox dependet. Man man man, also 
doch ein eigenes Skript schreiben ...

: Bearbeitet durch User
Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt ja genug alternativen. Versuch mal jq, also einfach;
jsonfilter -e "$[\"data\"][\"A\"][@.id=$record_id]"
ersetzen durch:
jq -cM ".data.A|.[].id=$record_id|{data:.[0]}"
Dann sollte es wieder passen.

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

Also einiges scheint zu funktionieren, aber vielleicht nicht alles.
Das Skript bekommt den record und kann ihn ausgeben. Es ersetzt jetzt 
auch die IP.

Aber:
output=$(/usr/bin/wget --load-cookies $cookiefile --method=PUT --header=Content-Type:application/json --header="Http-X-Csrf-Token: $csrf" --body-data=$payload -qO- $url 2>&1)
echo "UD answered: $output"
write_log 7 "UD answered:\n$output"

echo $output | /usr/bin/grep "$ipv4" >/dev/null 2>&1
success=$?
#write_log 7 "Retval: $success"
echo "Retval: $success"

$output bleibt leer. Sprich es wird
UD answered: 
Retval: 127
ausgegeben. Wofür die 127 steht weiß ich nicht.

: Bearbeitet durch User
Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
$? steht für den exit code des vorhergehenden Programs, in dem fall 
grep. Jeder exit code, der nicht 0 ist, zeigt einen Fehler an. Im Fall 
von
'echo $output | /usr/bin/grep "$ipv4" >/dev/null 2>&1' heisst das, dass 
grep die IP nicht in der ausgabe von 'echo $output', also mehr oder 
weniger dem inhalt von output, gefunden hat. Vermutlich hat das Setzen 
der IP also nicht funktioniert.

Ich kenne das Program jsonfilter auch nicht, ich habe mich beim 
resultierenden JSON an den PUT query aus Beitrag 
Beitrag "Re: DNS A-Record automatisch updaten bei United Domains" gehalten. Nachdem 
ich mir das Script nochmal angeschaut habe, habe ich das gefühl, das 
dieser womöglich an eine andere URL ging, als die die das Script 
benutzt.

Also entweder müsste man:
 A) die URL 
'url="https://www.united-domains.de/pfapi/dns/domain/$do...; 
anpassen und 
'payload="{\"record\":$record,\"domain_lock_state\":{\"domain_locked\":f 
alse,\"email_locked\":false}}"'  mit 'payload="$record"' ersetzen
 B) oder den Query anpassen, vermutlich war der {"data":} part bei der 
ursprüglichen url überflüssig. Damit wäre dort der jq Aufruf dann 
einfach nur 'jq -cM ".data.A|.[].id=$record_id|.[0]"'.

Noch etwas anderes, das Probleme machen könnte, sind die fehlenden 
Quotes bei der Zeile:
output=$(/usr/bin/wget --load-cookies $cookiefile --method=PUT --header=Content-Type:application/json --header="Http-X-Csrf-Token: $csrf" --body-data=$payload -qO- $url 2>&1)
sollte
output=$(/usr/bin/wget --load-cookies "$cookiefile" --method=PUT --header=Content-Type:application/json --header="Http-X-Csrf-Token: $csrf" --body-data="$payload" -qO- "$url" 2>&1)
sein.

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel A. schrieb:
> Vermutlich hat das Setzen
> der IP also nicht funktioniert.

Ja, richtig, $output ist leer.

Daniel A. schrieb:
> Noch etwas anderes, das Probleme machen könnte, sind die fehlenden
> Quotes bei der Zeile:

Naja, die fehlen auch bei den Zeilen drüber. Und $record ist OK. Also 
wenn ich mir den ausgeben lasse, dann sehe ich, dass ich da den 
richtigen bekommen habe.
Auch das Ersetzen der IP funktioniert, sprich ich kann mir den 
modifizierten Record ausgeben lassen und der passt.

Daniel A. schrieb:
> B) oder den Query anpassen, vermutlich war der {"data":} part bei der
> ursprüglichen url überflüssig. Damit wäre dort der jq Aufruf dann
> einfach nur 'jq -cM ".data.A|.[].id=$record_id|.[0]"'.

Genau das war etwas weiter oben die Empfehlung statt jsonfilter und das 
scheint zu funktionieren.

Daniel A. schrieb:
> A) die URL
> 'url="https://www.united-domains.de/pfapi/dns/domain/$do...;;
> anpassen und
> 'payload="{\"record\":$record,\"domain_lock_state\":{\"domain_locked\":f
> alse,\"email_locked\":false}}"'  mit 'payload="$record"' ersetzen

Das mit der Payload werde ich jetzt mal probieren.

Autor: Daniel A. (daniel-a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Damit wäre dort der jq Aufruf dann
>> einfach nur 'jq -cM ".data.A|.[].id=$record_id|.[0]"'.
>
> Genau das war etwas weiter oben die Empfehlung statt jsonfilter und das
> scheint zu funktionieren.

Aber mit einem kleinen Unterschied:
jq -cM ".data.A|.[].id=$record_id|{data:.[0]}"
jq -cM ".data.A|.[].id=$record_id|.[0]"

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr fein, jetzt bekomme ich auch etwas in $output.

Also mit
payload="$record"
bleibt $output leer, aber mit
payload="{\"record\":$record,\"domain_lock_state\":{\"domain_locked\":false,\"email_locked\":false}}"
wie im Original bekomme ich
UD answered: {"data":{"address":"217.85.249.165","id":79295801,"filter_value":"gus.tl","ttl":600,"type":"A","standard_value":false,"sub_domain":"","domain":"gus.tl","webspace":false,"udag_record_type":5}}
Retval: 127
als Antwort.

Warum das grep darin das $ipv4 nicht findet ist für mich unklar. In 
Output steht es ja drinnen?!

: Bearbeitet durch User
Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es auch die neue Adresse, die drin steht, oder noch die alte? Es 
wird ja nach der neuen gegrept. Oder könnte es sein, dass grep bei dir 
nicht unter /usr/bin/ ist ('which grep')? Eventuell sollte man die 
absoluten Pfade überall weglassen, und jenachdem eventuell den $PATH 
setzen. $output könnte man auch noch escapen, und statt dem >/dev/null 
könnte man die -q option von grep nutzen.
printf "%s" "$output" | grep -q "$ipv4"

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke! grep liegt tatsächlich in /bin. Weiter oben hatte ich das schon 
angepasst.

Jetzt bekomme ich:
UD answered: {"data":{"address":"217.85.249.165","id":79295801,"filter_value":"gus.tl","ttl":600,"type":"A","standard_value":false,"sub_domain":"","domain":"gus.tl","webspace":false,"udag_record_type":5}}
Retval: 0

Also ich muss jetzt natürlich noch testen ob das wirklich bei united 
domains geschrieben wurde, aber sonst sieht das jetzt gut aus glaube 
ich.

Danke für die Mithilfe!

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du dann noch das angepasste Script posten, falls es 
funktioniert, falls später nochmal jemand diesen Thread findet?

Autor: Gustl B. (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#!/bin/sh
# requires: wget, jq, ca-certificates, grep
#rm /tmp/cookies.txt

cookiefile="/tmp/cookies.txt"
domain="domain_id:record_id"
username="eMail"
password="Passwort"

#domain should contain "domain_id:record_id"
domain_id=$(echo $domain | tr ":" "\n" | sed -n "1p")
record_id=$(echo $domain | tr ":" "\n" | sed -n "2p")

#csrf token for login
csrf=$(/usr/bin/wget --save-cookies $cookiefile --keep-session-cookies --delete-after -qO- "https://www.united-domains.de/login/" | /bin/grep -oP -m 1 "(?<=<input type=\"hidden\" name=\"csrf\" value=\")[^\"]*(?=\"( /)?>)")

ipv4=`wget http://ipecho.net/plain -O - -q ; echo`
echo $ipv4

#login
#TODO: check if login succeeded
csrf=$(/usr/bin/wget --load-cookies $cookiefile --save-cookies $cookiefile --keep-session-cookies --post-data "csrf=$csrf&email=$username&pwd=$password&selector=login&loginBtn=Login" -qO- "https://www.united-domains.de/login/" | /bin/grep -oP -m 1 "(?<=<input type=\"hidden\" name=\"csrf\" value=\")[^\"]*(?=\"( /)?>)")

#get current dns record json object & modify ip
record=$(/usr/bin/wget --load-cookies $cookiefile --save-cookies $cookiefile --keep-session-cookies -qO- "https://www.united-domains.de/pfapi/dns/domain/$domain_id/records" | jq -cM ".data.A|.[].id=$record_id|.[0]" | sed "s/ //g" | sed "s/\"address\":\"[0-9.]\+\"/\"address\":\"$ipv4\"/g")

payload="{\"record\":$record,\"domain_lock_state\":{\"domain_locked\":false,\"email_locked\":false}}"
url="https://www.united-domains.de/pfapi/dns/domain/$domain_id/records"
#send changes
output=$(/usr/bin/wget --load-cookies $cookiefile --method=PUT --header=Content-Type:application/json --header="Http-X-Csrf-Token: $csrf" --body-data=$payload -qO- $url 2>&1)
echo "UD answered: $output"

echo $output | /bin/grep "$ipv4" >/dev/null 2>&1
success=$?
echo "Retval: $success"

return $success

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.