Neue SLA bei kostenlosen Dyndns Accounts mittels AutoLoginScript umgehen

Status
Für weitere Antworten geschlossen.

3x3cut0r

Benutzer
Mitglied seit
21. Mai 2011
Beiträge
489
Punkte für Reaktionen
11
Punkte
24
Hi
ich bin schon seit geraumer Zeit bei DynDns zwecks statischer IP für meine NAS und co.
Neulich bekam ich eine email von Dyn, in der stand, dass alle Hosts von allen FreeUsern gelöscht werden,
wenn man sich nicht mindestens einmal im Monat in seinen Account einloggt.
Ist schon ein bisschen nervig. Wechseln zu no-ip und co möchte ich jetzt eigentlich nicht, da schon so viele Leute meine DynDns
Adresse kennen (für TeamSpeak und diverse andere Dienste) und ich diese eigentlich behalten möchte.
Jedoch sind mir 25$ im Jahr für einen VIP-Account dafür zu viel, vor allem da es kostenlose Alternativen gibt.

Nach ein bisschen googeln bin ich auf folgenden Blog gestoßen: http://www.zyztematik.org/?p=62
Hier beschreibt ein User, wie er sich ein script geschrieben hat, das sich mit Benutzername und Passwort
(übergeben als Parameter oder fest in der config integriert) in seinen DynDns Account einloggt.
Das, kombiniert mit der crontab würde mein Problem ziemlich elegant lösen, wenn es denn funktionieren würde.

Und jetzt kommt Ihr ins Spiel :eek:

Den einzigen Fehler den ich (zugegeben mit mittelmäßig bis schlechten python Kenntnissen) in dem Script gefunden habe,
ist, das es die Methode usage() nicht gibt. Diese habe ich eben mal eigenhändig eingebaut.
Nichtsdestotrotz ist die eh für die Funktion des Scriptes unerheblich.
Fakt ist es lässt sich zwar ohne Fehlermeldung ausführen macht aber praktisch rein garnichts.

Wäre cool wenn hier ein Fähiger python-Script-Programmierer mal eben drüber schauen könnte und das Script ggfls. an das Linux auf
einer Synology NAS anpassen könnte bzw mir sagen ob sowas überhaupt läuft.
Ich weis zb garnicht ob die ganzen imports überhaupt gehen usw ...

Hier das Script inclusive usage() Methode:
Rich (BBCode):
#!/usr/bin/python

import urllib
import urllib2
import cookielib
import getopt
import sys

def getRandHTMLResponse(response):
	target = "<form id=\'login"
	targetresponse = "<div id=\'loginbox\'"

	response = response[response.find(targetresponse):len(response)]
	return response[response.find(target)+len(target):response.find(target)+len(target):response.find(target)+len(target)+4]

def getHiddenRandHTMLResponse(response):
	target = "<input type=\'hidden\' name=\'multiform\' value=\'"
	targetresponse = "<div id=\'loginbox\'"
	parsedres = response[response.find(targetresponse):len(response)]
	return parsedres[parsedres.find(target)+len(target):parsedres.find(target)+len(target)+34]

def checkLogin(response):
	target = "<title>DynDNS.com - My Account</title>"
	if response.find(target) == -1:
		return False
	return True

def usage():
	print "usage: ./dyndnsAutoLogin [options]"
	print ""
	print "options:"
	print "-h, --help 	 show this help message and exit"
	print "-u, --username   set your DynDns login_username"
	print "-p, --password   set your DynDns login_password"
	print ""
	print "example:"
	print "./dyndnsAutoLogin -u username -p password"

class HTMLSession:
	cj = None
	opener = None
	txHeaders = None

	def __init__(self, txHeaders):
		#The CookieJar will hold any cookies necessary throughout the login process.
		self.cj = cookielib.MozillaCookieJar()
		self.txHeaders = txHeaders
		self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
        	urllib2.install_opener(self.opener)

	def setHeaders(self, txheaders):
		self.txHeaders = txHeaders

	def getHeaders(self):
		return self.txHeaders

	def openURI(self, uri, txdata):
		try:
			req = urllib2.Request(uri, txdata, self.txHeaders)
			# create a request object

			handle = urllib2.urlopen(req)
			# and open it to return a handle on the url

		except IOError as e:
			print 'we failed to open "%s".' % uri

			if hasattr(e, 'code'):
				print 'We failed with error code - %s.' % e.code
			elif hasattr(e, 'reason'):
				print "The error object has the following 'reason' attribute :"
				print e.reason
				print "This usually means the server doesn't exist,'"
				print "is down, or we don't have an internet connection."
				return None
		else:
			return handle.read()

def main(argv):
	username = ""
	password = ""
	hiddenval = ""
	theurl = "https://www.dyndns.com/account/entrance/"
	thelogouturl = "https://www.dyndns.com/account/entrance/?__logout=1"
	txdata = None
	txheaders =  {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
	# fake a user agent, some websites (like google) don't like automated exploration

	try:

		opts, args = getopt.getopt(argv, "hu:p:", ["help", "username=","password="])
	except getopt.GetoptError:
		usage()
		exit(2)
	for opt, arg in opts:
		if opt in ("-h", "--help"):
			usage()
			exit(2)
		elif opt in ("-u", "--username"):
			username = arg
		elif opt in ("-p", "--password"):
			password = arg

	myhtmlsession = HTMLSession(txheaders)
	response = myhtmlsession.openURI(theurl, None)

	if response == None:
		sys.exit(0)

	hiddenval = getHiddenRandHTMLResponse(response)
	txdata = urllib.urlencode({'username':username, 'password':password, 'multiform':hiddenval, 'submit': "Log in"})

	response = myhtmlsession.openURI(theurl, txdata)
	if response == None:
		sys.exit(0)

	#we should sleep here for about 10 seconds.
	if checkLogin(response):
		print('We have succesfully logged into DynDNS.')

	response = myhtmlsession.openURI(thelogouturl, None)
	if response == None:
		sys.exit(0)

if __name__ == "__main__":
	main(sys.argv[1:])

Danke für Hilfe
 

sichler

Benutzer
Mitglied seit
10. Dez 2007
Beiträge
10
Punkte für Reaktionen
0
Punkte
1
Hallo

Und jetzt kommt Ihr ins Spiel :eek:

Den einzigen Fehler den ich (zugegeben mit mittelmäßig bis schlechten python Kenntnissen) in dem Script gefunden habe,
ist, das es die Methode usage() nicht gibt. Diese habe ich eben mal eigenhändig eingebaut.
Nichtsdestotrotz ist die eh für die Funktion des Scriptes unerheblich.
Fakt ist es lässt sich zwar ohne Fehlermeldung ausführen macht aber praktisch rein garnichts.



Danke für Hilfe

das interessiert mich jetzt auch brennend. Ich hab exakt dasselbe Problem. Wäre cool wenn man das Script zum laufen bringt. Oder hast Du das mittlerweile selber geschaft?

Gruss MArtin
 

3x3cut0r

Benutzer
Mitglied seit
21. Mai 2011
Beiträge
489
Punkte für Reaktionen
11
Punkte
24
wirklich weiter bin ich nicht, nein.
auch wenn ich mich jetzt schon ein bisschen in python eingelesen habe ...
zb habe ich herausgefunden, das beim kopieren des scripts vom browser in meinen editor die tabs nicht ersetzt wurden.
python erkennt keine tabs und alles muss per leerzeichen (1 tab=4 leerzeichen) eingerückt werden.
nachdem ich das geändert hatte, kam auch schon der erste syntaxfehler.
und zwar meckerte er, dass das keyword "as" für python 2.6 reserviert ist (nach einer exception in zeile 65) ... dann habe ich versucht das script mit python2.6 und python 2.7 aufzurufen:
Rich (BBCode):
#!/usr/bin/python2.7
dann kam kein fehler mehr, jedoch lief das script ebenso wenig wie vorher ... keine prints, keine fehler, keine reaktion auf parameter oder ähnliches.

nun kann ich jedoch zur genaueren diagnose mal ein paar mehr prints einbauen, um zu schaun wo was genau passiert und evtl nicht geht,
welche methoden aufgerufen werden, welche nicht etc ...
das ging vorher schonmal garnicht wegen den tabs. werd ich heute abend mal testen und dann evtl schon ein bisschen mehr wissen.

gibt es vielleicht auch noch fehlerhafte umbrüche, die es beim kopieren erstellt hat?
komm hier an sonsten echt nicht wirklich weiter.
 

3x3cut0r

Benutzer
Mitglied seit
21. Mai 2011
Beiträge
489
Punkte für Reaktionen
11
Punkte
24
so hab das script nun zum laufen bekommen.
nachdem ich wie oben schon erwähnt, die tabs gegen 4 leerzeichen ersetzt hatte, war auch eine diagnose via prints möglich.

dann war es eigentlich relativ einfach ... als ich mir das script mal näher angeschaut habe fiel mir auf, das die urls nicht mehr passen.
seit DynDNS seine Domain geändert hat (was ich garnicht wusste, bzw mitbekommen hatte ... nämlich von dyndns.com zu dyn.com) musste ich das script folgendermaßen abändern:
Rich (BBCode):
def main(argv):
    username = ""
    password = ""
    hiddenval = ""
    #theurl = "https://www.dyndns.com/account/entrance/"
    #thelogouturl = "https://www.dyndns.com/account/entrance/?__logout=1"
    theurl = "https://account.dyn.com/entrance/"
    thelogouturl = "https://account.dyn.com/entrance/?__logout=1"
    ...

So das fertige script nun hier:
Rich (BBCode):
#!/opt/bin/python2.7

import urllib
import urllib2
import cookielib
import getopt
import sys

def getRandHTMLResponse(response):
    target = "<form id=\'login"
    targetresponse = "<div id=\'loginbox\'"

    response = response[response.find(targetresponse):len(response)]
    return response[response.find(target)+len(target):response.find(target)+len(target):response.find(target)+len(target)+4]

def getHiddenRandHTMLResponse(response):
    target = "<input type=\'hidden\' name=\'multiform\' value=\'"
    targetresponse = "<div id=\'loginbox\'"
    parsedres = response[response.find(targetresponse):len(response)]
    return parsedres[parsedres.find(target)+len(target):parsedres.find(target)+len(target)+34]

def checkLogin(response):
    target = "<title>My Dyn Account</title>"
    if response.find(target) == -1:
        return False
    return True

def usage():
    print "usage: ./dyndnsAutoLogin [options]"
    print ""
    print "options:"
    print "-h, --help 	 show this help message and exit"
    print "-u, --username   set your DynDns login_username"
    print "-p, --password   set your DynDns login_password"
    print ""
    print "example:"
    print "./dyndnsAutoLogin -u username -p password"

class HTMLSession:
    cj = None
    opener = None
    txHeaders = None
    
    def __init__(self, txHeaders):
        #The CookieJar will hold any cookies necessary throughout the login process.
        self.cj = cookielib.MozillaCookieJar()
        self.txHeaders = txHeaders
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
        urllib2.install_opener(self.opener)

    def setHeaders(self, txheaders):
        self.txHeaders = txHeaders

    def getHeaders(self):
        return self.txHeaders

    def openURI(self, uri, txdata):
        try:
            req = urllib2.Request(uri, txdata, self.txHeaders)
            # create a request object

            handle = urllib2.urlopen(req)
            # and open it to return a handle on the url

        except IOError as e:
            print 'we failed to open "%s".' % uri

            if hasattr(e, 'code'):
                print 'We failed with error code - %s.' % e.code
            elif hasattr(e, 'reason'):
                print "The error object has the following 'reason' attribute :"
                print e.reason
                print "This usually means the server doesn't exist,'"
                print "is down, or we don't have an internet connection."
                return None
        else:
            return handle.read()

def main(argv):
    username = ""
    password = ""
    hiddenval = ""
    theurl = "https://account.dyn.com/entrance/"
    thelogouturl = "https://account.dyn.com/entrance/?__logout=1"
    txdata = None
    txheaders =  {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
    # fake a user agent, some websites (like google) don't like automated exploration

    try:
        opts, args = getopt.getopt(argv, "hu:p:", ["help", "username=","password="])
    except getopt.GetoptError:
        usage()
        exit(2)
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            exit(2)
        elif opt in ("-u", "--username"):
            username = arg
        elif opt in ("-p", "--password"):
            password = arg

    myhtmlsession = HTMLSession(txheaders)
    response = myhtmlsession.openURI(theurl, None)

    if response == None:
        sys.exit(0)

    hiddenval = getHiddenRandHTMLResponse(response)
    txdata = urllib.urlencode({'username':username, 'password':password, 'multiform':hiddenval, 'submit': "Log in"})

    response = myhtmlsession.openURI(theurl, txdata)
    if response == None:
        sys.exit(0)
    
    #we should sleep here for about 10 seconds.
    if checkLogin(response):
        print 'We have succesfully logged into DynDNS.'
    else:
        print 'Login failed'

    response = myhtmlsession.openURI(thelogouturl, None)
    if response == None:
        sys.exit(0)

if __name__ == "__main__":
    main(sys.argv[1:])

eine erfolgreiche logout meldung habe ich mir jetzt erspart, da diese ja direkt nach dem erfogreichen login erfolgen würde und mir irgendwie sinnlos erscheint.
aber an sonsten denke ich doch, dass die das script richtig angepasst habe.
wenn jemand kein python 2.7 hat, 2.6 tuts auch ... allerdings ist 2.6 leider erforderlich und <2.6 ist nicht möglich wegen der exception.

das login script funktioniert jetzt entweder mit übergebenen parametern:
Rich (BBCode):
DiskStation>./dyndnsAutoLogin -u benutzername -p passwort
oder man schreibt beides direkt in die config in die "def main".

falls es noch jemanden interessiert hier meine /opt/etc/crontab:
Rich (BBCode):
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/opt/sbin:/opt/bin
#minute hour    mday    month   wday    who     command
*       */8     *       *       *       *       /volume1/install/scripts/dyndnsAutoLogin
er loggt sich jetzt einfach 3 mal am tag in meinen dyndns account ein. wäre zwar nur einmal in monat nötig, aber sicher ist sicher ^^

jo dann hf

gruß
 

casnoff

Benutzer
Mitglied seit
05. Mai 2011
Beiträge
129
Punkte für Reaktionen
1
Punkte
24
Es wäre großartig, wenn Du das vielleicht noch ins Wiki stellen könntest. Das dürfte zukünftig auch noch mehr Personen betreffen und nur im Forum besteht leider die Gefahr, dass es einfach untergehen kann.
 

laszia

Benutzer
Mitglied seit
27. Aug 2012
Beiträge
172
Punkte für Reaktionen
1
Punkte
0
Ich habs über meinen BackupPC gemacht, also über ein AutoIT Script. Dieser wird dann einmal die Woche aufgerufen wenn der BackupPC startet.
Aber dass es über die Syno funzt ist gut zu wissen. :)
 

Synbene

Benutzer
Mitglied seit
06. Mai 2013
Beiträge
168
Punkte für Reaktionen
0
Punkte
0
Es gibt tatsächlich noch eine einfachere Alternative: Die 25$ im Jahr zu zahlen. Das sind etwas mehr als 1 Euro pro Monat (kann sich also jeder hier ohne irgendeinen Verzicht leisten), wenn man die eigene Arbeitszeit für die Entwicklung und Implementierung solcher Skripts mal dagegen rechnet, ist das ein gutes Geschäft.

Sorry für OT.
 

Puppetmaster

Benutzer
Sehr erfahren
Mitglied seit
03. Feb 2012
Beiträge
18.984
Punkte für Reaktionen
624
Punkte
484
25$ entsprächen 1,60 Euro pro Monat (aktueller Devisenkurs), das ist dann schon mehr, als z.B. selfhost.de verlangt.
Im Übrigen:

...wenn man die eigene Arbeitszeit für die Entwicklung und Implementierung solcher Skripts mal dagegen rechnet, ist das ein gutes Geschäft.

Sofern ein solches script "frei" ist, also von jedem benutzt werden darf, hast du auch keine Entwicklungsarbeit.

[/OT]
 

laszia

Benutzer
Mitglied seit
27. Aug 2012
Beiträge
172
Punkte für Reaktionen
1
Punkte
0
Das ganze hat mich 15 minuten gekostet, skript schreiben, testen und implementieren :)
 

Schmitty01

Benutzer
Mitglied seit
19. Aug 2010
Beiträge
28
Punkte für Reaktionen
0
Punkte
1
Hallo,

läßt sich ds Python script auch mit Hilfe des Aufgabenplaners ausführen?

Gerd
 

claas

Benutzer
Mitglied seit
07. Jan 2010
Beiträge
629
Punkte für Reaktionen
0
Punkte
0
Hallo,

danke für das Script.
Es liefert mir leider ein "not found" wenn ich das hier

Rich (BBCode):
DiskStation>./dyndnsAutoLogin -u benutzername -p passwort

eingebe.

Ich habe es auch versucht, indem ich den Pfad im Skript an die Python-Installation aus dem Paketzentrum angepasst habe.

Danke für Hinweise

Claas
 

Schmitty01

Benutzer
Mitglied seit
19. Aug 2010
Beiträge
28
Punkte für Reaktionen
0
Punkte
1
Hi,

Script ausführbar gemacht (chmod +x dyndnsAutoLogin.py)?

Gerd
 

3x3cut0r

Benutzer
Mitglied seit
21. Mai 2011
Beiträge
489
Punkte für Reaktionen
11
Punkte
24
Es liefert mir leider ein "not found" wenn ich das hier ... eingebe
hi
du musst dich natürlich auch in dem ordner befinden, in dem das script liegt!
ein "ls -la" sollte dir eine auflistung des aktuellen ordners liefern. darin muss auch das script auftauchen.
rechte wie schon erwähnt sollten auch gesetzt sein.

oder du rufst das script mit absolutem pfad auf:
Rich (BBCode):
DiskStation>/volume1/pfad/wo/das/script/liegt/dyndnsAutoLogin -u benutzername -p passwort

gruß
 

claas

Benutzer
Mitglied seit
07. Jan 2010
Beiträge
629
Punkte für Reaktionen
0
Punkte
0
Hallo,

danke. Nachdem ich es ausführbar gemacht habe, erhalte ich ein "Permission denied".
Bin als root eingeloggt.
 

claas

Benutzer
Mitglied seit
07. Jan 2010
Beiträge
629
Punkte für Reaktionen
0
Punkte
0
Ach quatsch. Ich hatte es nicht mehr ausführbar gemacht, ich Trottel.

Es kommt immer noch "not found", obwohl der Pfad eindeutig stimmt.
 

3x3cut0r

Benutzer
Mitglied seit
21. Mai 2011
Beiträge
489
Punkte für Reaktionen
11
Punkte
24
was findet er denn nicht? poste mal die komplette meldung bitte.
 

claas

Benutzer
Mitglied seit
07. Jan 2010
Beiträge
629
Punkte für Reaktionen
0
Punkte
0
/volume1/Files/Software/dyndnsAutoLogin
-ash: /volume1/Files/Software/dyndnsAutoLogin: not found

Die erste Zeile dieser Datei habe ich angepasst auf
Code:
#!/@appstore/Python/usr/local/bin/Python2.7
da dort das Python liegt (zumindest hab ich das da gefunden), das man per Paketzentrum installiert.

Aber auch mit deinem Originalskript kommt:

/volume1/Files/Software/dyndnsAutoLogin_orig
-ash: /volume1/Files/Software/dyndnsAutoLogin_orig: not found
bzw. wenn ich es mit Erweiterung aufrufe
/volume1/Files/Software/dyndnsAutoLogin_orig.py
-ash: /volume1/Files/Software/dyndnsAutoLogin_orig.py: not found
 

3x3cut0r

Benutzer
Mitglied seit
21. Mai 2011
Beiträge
489
Punkte für Reaktionen
11
Punkte
24
ok
eins vorneweg mein script heißt dyndnsAutoLogin und nicht dyndnsAutoLogin.py ... das ".py" gibt es nicht und das wird er dann auch nicht finden.
mach mal ein:
Rich (BBCode):
DiskStation>ls -la /volume1/Files/Software/
und poste das ergebnis

und zweitens stimmt der pfad zu deinem python nicht.
ich bin mir ziemlich sicher das er so lauten müsste:
Rich (BBCode):
#!/volume1/@appstore/Python/usr/local/bin/python2.7
wenn nicht mach darauf auch ein "ls -la" und beweis mir das gegenteil :rolleyes:
 

claas

Benutzer
Mitglied seit
07. Jan 2010
Beiträge
629
Punkte für Reaktionen
0
Punkte
0
Kaum macht man's richtig, schon geht's :)
Danke. Der Pfad zum Python war das Problem.
 

raymond

Benutzer
Mitglied seit
10. Sep 2009
Beiträge
4.704
Punkte für Reaktionen
21
Punkte
118
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat