DdnsAutoLogin
In diesem Artikel geht es um die Möglichkeit, sich bei DynDNS mittels Python-Script automatisch anmelden zu können.
Die neue SLA von DynDNS schreibt allen FreeUser-Accounts vor, sich einmal im Monat online einzuloggen. Anderenfalls werden die eingetragenen Hosts gelöscht und müssen neu eingetragen werden. Alternative hierzu wäre der offizielle Weg, ein Pro-Account für 25$ im Jahr.
Voraussetzungen
- DSM >= 3.2
- Python >= 2.6
Python kann problemlos über das DSM-Paketzentrum gedownloadet und installiert werden.
Das Script: dyndnsAutoLogin
#!/volume1/@appstore/Python/usr/local/bin/python import urllib import urllib2 import cookielib import getopt import sys import logging 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 logging.error('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 = "" logfile = "/var/log/dyndnsAutoLogin.log" 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 logging.basicConfig(filename=logfile,level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y/%m/%d %H:%M:%S') try: opts, args = getopt.getopt(argv, "hu:p:", ["help", "username=","password="]) except getopt.GetoptError: usage() logging.warning('Manual login with incorrect parameters') 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.' logging.info('We have succesfully logged into DynDNS.') else: print 'Login failed' logging.info('Login failed') response = myhtmlsession.openURI(thelogouturl, None) if response == None: sys.exit(0) if __name__ == "__main__": main(sys.argv[1:])
Einstellungen und Parameter
In der "def main" (Zeile 81) lassen sich folgende Einstellungen treffen:
- username: Dein DynDNS Benutzername
- password: Dein DynDNS Passwort
- logfile: Der Pfad zum Logfile (Standardmäßig /var/log/dyndnsAutoLogin.log, hier empfiehlt sich aber ein Pfad, der auch über die File Station erreichbar ist, um das Logfile auch mit der DSM auslesen, bzw herunterladen zu können. Beispielsweise einen Gemeinsamen Ordner)
- hiddenval: Wert für versteckte Elemente in Formularen (bei DynDNS nicht nötig)
- theurl: Die URL zur Login-Seite
- thelogouturl: Die URL zur Logout-Seite
- txdata: Muss auf "None" stehen!
- txheaders: Als welcher Browser sich das Script ausgeben soll (hier Mozilla/4.0)
Wichtig ist hier alles in doppelten Anführungszeichen zu schreiben ( " " )
Für Konsolen-Benutzer: Benutzername und Passwort können auch über die jeweiligen Parameter (-u username -p password) dem Script übergeben werden.
Installation und Einbinden mittels DSM Aufgabenplaner
- Das Script in die Zwischenablage kopieren und in einen Editor seiner Wahl einfügen.
- Einstellungen (Benutzername, Passwort und Logfile) eintragen
- Das Script mit dem Namen "dyndnsAutoLogin" speichern (Wichtig: ohne Dateiendung)
- Kopieren des Scripts auf die NAS. Am besten mit der File Station oder über eine Netzfreigabe in einen Ordner seiner Wahl. (Ich habe es bei mir nach /volume1/install/scripts/ kopiert)
- Aufrufen des Aufgabenplaners in der DSM-Systemsteuerung
- Erstellen / Benutzer-definiertes Skript
- Allgemeine Einstellungen / Vorgang: dyndnsAutoLogin (Beliebiger Name für den Aufgabenplan)
- Allgemeine Einstellungen / Benutzer: root
- Befehl ausführen: /volume1/install/scripts/dyndnsAutoLogin (hier den richtigen absoluten Pfad und Namen zu seinem vorher gespeicherten Script)
- Unter Zeitplan nun das gewünschte Intervall einstellen (Ich empfehle einmal Täglich. Mindestens jedoch mehr als einmal im Monat!)
- Fertig!
Um zu prüfen ob das Script ordnungsgemäß funktioniert liest man einfach in seiner Logfile (/var/log/dyndnsAutoLogin.log) nach. Diese sieht so aus:
2013/05/30 00:00:06 - INFO - We have succesfully logged into DynDNS. 2013/05/30 08:00:05 - INFO - We have succesfully logged into DynDNS. 2013/05/30 16:00:04 - INFO - We have succesfully logged into DynDNS. 2013/05/30 17:36:43 - INFO - Login failed
Häufige Fehler
- Beim Kopieren bzw. Bearbeiten des Scripts wurden Tabs anstelle von Leerzeichen verwendet (1 Tab muss durch 4 Leerzeichen ersetzt werden!)
- Der Benutzername, das Passwort oder die Logfile wurde ohne doppelte Anführungszeichen ( " " ) in das Script eingetragen
- Das Logging funktioniert nicht bei gesetztem relativen Pfad (logfile = "./dyndnsAutoLogin.log") wenn man den Aufgabenplaner benutzt.
- Falsche Python Version installiert. Python < 2.6 wirft folgende Fehlermeldung:
DiskStation> ./dyndnsAutoLogin ./dyndnsAutoLogin:66: Warning: 'as' will become a reserved keyword in Python 2.6 File "./dyndnsAutoLogin", line 66 except IOError as e: ^ SyntaxError: invalid syntax
Wenn Python mittels Paketmanager installiert wurde (>=2.6) und dieser Fehler kommt stimmt möglicherweise der interne symbolische Link auf python2.7 nicht bzw. wurde nicht gesetzt. Dann mal probieren die erste Zeile mit folgender zu ersetzen:
#!/volume1/@appstore/Python/usr/local/bin/python2.7
- 3x3cut0r 17:00, 30. Mai 2013 (CEST)