Dies ist eine mobil optimierte Seite, die schnell lädt. Wenn Sie die Seite ohne Optimierung laden möchten, dann klicken Sie auf diesen Text.

NO-IP Account-Renew Script 1.0

    Nobody is reading this thread right now.
Habe seit 3-4 Tagen das Problem, dass die IP-Adresse nicht aktualisiert wird. Mein Account ist in der FRITZ!Box eingetragen.

Hat nichts mit dem Script zu tun, aber dachte, dass die FRITZ!Box auch von den Umstellungen betroffen ist
 
Naja, und mit dieser Ankündigung Seitens no-ip.com hat sich wohl jedes Script gesteurte Verfahren erübrigt....zumindest ab dem Zeitpunkt an dem 2FA zwingend vorgschrieben wird.
 
Zuletzt bearbeitet:
Das ist Freiwillig wie auf den meisten Seiten.
Von daher...
 
Naja, auf der FAQ Seite steht folgendes
Does No-IP Require 2FA?

While we don’t currently require No-IP accounts to have 2FA enabled, we strongly suggest that you enable it. 2FA is a simple solution to help keep your No-IP account secure.
Jetzt weiss ich nicht, ob man hier genau sieht, daß das "require" kursiv geschrieben ist.......da kann man sich shcon vorstellen, daß es eventuell doch irgendwann zwingend wird......aber ja, man wird sehen......vielleicht überrascht du (DarkstarXxX) uns ja doch noch vorher mit einer funktionierenden Version deines Scriptes....wäre toll .
 
Tut mir leid, aber von mir wird es auf absehbare Zeit nichts mehr in diese Richtung geben.
 
Ich bastel gerade an dem Skript und kann schon aktualisieren. Ob es dauerhaft funktioniert, kann ich nicht beurteilen...
Eine Einschränkung hat das ganze noch: Das eMail Passwort muss ASCII kodiert sein. Ansonsten gibt es einen Fehler...
Du musst Regestriert sein, um das angehängte Bild zusehen.
Das Skript macht ein Login und schaut, ob der Code eingegeben werden muss. Dann wird per IMAP im Postfach nach 25 Sekunden Wartezeit nach der Verifikations Mail gesucht und der Code extrahiert. Dieser wird dann im Formular auf der Webseite eingegeben und dann werden die Hosts aktualisiert.

Besteht denn Interesse? Wenn ja, kann ich das Skript hier in den nächsten Tage Posten
 

Anhänge

Du musst angemeldet sein, um die Anhangsliste zu sehen.
Zuletzt bearbeitet von einem Moderator:
Habe noch ein wenig gebastelt und stelle das Skript mal hier ein.
Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
### *|--------------------------------|* ###
### *| NO-IP Account-Renew Script 1.0 |* ###
### *|   (c) by DarkStarXxX @ DEB     |* ###
### *|--------------------------------|* ###

# Modifiziert von MegaV0lt @ DEB
# - Benötigt Python 3
# - Umstellung auf 'mechanicalsoup.StatefulBrowser()'
# - Prüfung, ob Konfig-Datei existiert
# - Umstellung auf *.ini konfiguration
# - Konfiguration (*.ini) kann als Parameter übergeben werden
# - Automatisches Eintragen des Verifizierungs-Codes
VERSION=250206  # JJMMDD

# Modifiziert von SLASH @ DEB
# - Skript nutzt nun python3 direkt (#!/usr/bin/env python3)
# - Update für eMail-imports

# Modifiziert von bl0w @DEB

# Wichtiger Hinweis: Externe Konfiguration
# Die Login-Daten für No-IP und eMail können aus einer externen Datei, welche in
# der Variable "CONFIG_FILE" definiert werden muss gelesen werden.
# Bitte dort die Daten eintragen
CONFIG_FILE = 'NOIP_Account_Renew.ini'  # Im gleichen Verzeichnis wie das Skript!
#CONFIG_FILE = ''  # Kann abgeschaltet werden, in dem man CONFIG_FILE = '' setzt.

# Die Konfiguration kann dem Skript auch als Parameter übergeben werden:
# NOIP-Account-Renew MyIni.ini

# Oder die Variablen hier ausfüllen!
USERNAME = ''    # No-IP Benutzername
PASSWORD = ''    # No-IP Passwort
FROMADRESS = ''  # eMail-Sender / Benutzername
TOADRESS = ''    # eMail-Empfänger
SMTPSERVER = ''  # SMTP-Serveradresse ("" zum deaktivieren)
SMTPPORT = ''    # SMTP-Port (Z. B. 25)
SMTPPASS = ''    # Server verlangt Autentification ("" zum deaktivieren)
IMAPSERVER = ''  # IMAP-Serveradresse ("" zum deaktivieren)
IMAPPORT = ''    # IMAP-Port (Z. B. 993)
IMAPPASS = ''    # IMAP-Passwort ("" zum deaktivieren)

# Vorgaben
LOG_FILE = ''  # Kein Log, wenn nächste Zeile auskommentiert ist
#LOG_FILE = '/var/log/NOIP_renew.log'  # Dateiname wird auch für die eMail verwendet
MAIL_SUBJECT = 'NO-IP Account Updater'  # Betreff der Status eMail
MAIL_BODY = 'NO-IP Account-Renew #{VERSION} hat Ihr NO-IP Konto für weitere 30 Tage aktualisiert.\n\n'  # Text in der eMail
HOST_URL = 'https://www.noip.com/members/dns/'
RESULT_STR = []
DEBUG = False  # Debug-Modus

import platform        # Python-Version
import importlib       # Konfiguration
import mechanicalsoup  # Browser
import time            # Zeit
import ssl             # SSL
import re              # Regex
import imaplib         # eMail
import email           # eMail
if hasattr(ssl, '_create_unverified_context'):
  ssl._create_default_https_context = ssl._create_unverified_context

# Funktion: update_host() - Für jeden Host "Modify" klicken
def update_host(str_host, browser):
  global RESULT_STR
  host_id = after(str_host, '=')  # Alle Zeichen nach dem '='

  browser.select_form(nr=00) ; browser.submit_selected()
  response = browser.get_current_page()
  update_status = None
  if response.find('Update will be applied') == 'None' :  # Prüfen, ob es geklappt hat
    update_status = '[FEHLER]'
  else:
    update_status = '[OK]'

  if LOG_FILE:
    ts = time.strftime("%d.%m.%Y %H:%M:%S")  # Zeitstempel für das Log (19.10.2016 12:51:30)
    f1 = open(LOG_FILE, 'a+')
    print(f'{ts}: Update für Host-ID: {host_id} {update_status}', file=f1)  # Ausgabe in das Log
    f1.close()

  print(f'Update für Host-ID: …{host_id[-2:]} {update_status}')  # Ausgabe auf der Konsole (und cron)
  RESULT_STR.append('…' + host_id[-2:] + ' {update_status}')     # Für die eMail
  return

# Funktion: after() - Liefert Zeichenkette nach Zeichen a
def after(value, a):
  pos_a = value.rfind(a)           # Position des gesuchten Zeichens
  if pos_a == -1: return value     # Nicht gefunden: Ganzer Wert zurück!
  adjusted_pos_a = pos_a + len(a)  # Alles nach dem gefundenen Zeichen
  if adjusted_pos_a >= len(value): return ''
  return value[adjusted_pos_a:]

# Funktion: get_verification_code() - Liefert den Verifizierungscode aus der eMail
def get_verification_code(from_address, imap_server, imap_pass, timeout=30, debug=False):
  start_time = time.time()
  while True:
    time.sleep(5)  # 5 Sekunden warten
    try:
      mail = imaplib.IMAP4_SSL(imap_server)
      mail.login(from_address, imap_pass)
      mail.select('inbox')  # Posteingang
      status, messages = mail.search(None, '(HEADER Subject "No-IP Verification Code:")')
      if status == 'OK' and messages[0]:
        latest_id = messages[0].split()[-1]
        _, data = mail.fetch(latest_id, '(RFC822)')
        message = email.message_from_bytes(data[0][1])
        verification_code = message['subject'].split()[-1]
        mail.close(); mail.logout()
        return verification_code

    except Exception as e:
      if debug: print(f'Fehler: {e}')

    if time.time() - start_time > timeout:
      raise TimeoutError('FEHLER: Keine eMail mit Verifications Code gefunden!')


###* Start *###
print(f'NO-IP Account-Renew #{VERSION} (Python: {platform.python_version()})')

# Wenn eine  *.ini als Parameter übergeben wurde, diese verwenden
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?', action='store')
args = parser.parse_args()
if args.filename is not None: CONFIG_FILE = args.filename

if CONFIG_FILE:
  from pathlib import Path
  my_conf = Path(CONFIG_FILE)
  if my_conf.is_file():  # Datei vorhanden?
    print('Verwende Konfiguration aus:', my_conf)
    import configparser
    config = configparser.ConfigParser(interpolation=None)
    with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
      config.read_file(f)
    USERNAME = config['NOIP']['USERNAME'] ; PASSWORD = config['NOIP']['PASSWORD']
    FROMADRESS = config['MAIL']['FROMADRESS'] ; TOADRESS = config['MAIL']['TOADRESS']
    SMTPSERVER = config['MAIL']['SMTPSERVER'] ; SMTPPORT = config['MAIL']['SMTPPORT']
    SMTPPASS = config['MAIL']['SMTPPASS']
    IMAPSERVER = config['MAIL']['IMAPSERVER'] ; IMAPPORT = config['MAIL']['IMAPPORT']
    IMAPPASS = config['MAIL']['IMAPPASS']
  else: print(f'FEHLER: Konfiguration {my_conf} nicht gefunden!') ; quit()

# Prüfen, ob benötigte Werte konfiguriert sind
if not USERNAME: print('FEHLER: USERNAME ist nicht konfiguriert!') ; quit()
if not PASSWORD: print('FEHLER: PASSWORD ist nicht konfiguriert!') ; quit()
if not IMAPSERVER: print('FEHLER: IMAPSERVER ist nicht konfiguriert!') ; quit()
if not IMAPPASS: print('FEHLER: IMAPPASS ist nicht konfiguriert!') ; quit()
if not FROMADRESS: print('FEHLER: FROMADRESS ist nicht konfiguriert!') ; quit()

# Browser Optionen
browser = mechanicalsoup.StatefulBrowser(
  soup_config={'features': 'lxml'},  # Verwenden des lxml HTML parser
  raise_on_404=True,
  user_agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.2228.0 Safari/537.36',
)

# Seite öffnen (noip.com)
print('Log-In… ', end='')  # Kein Zeilenumbruch
browser.open(HOST_URL)
if DEBUG:
  response = browser.get_current_page()
  with open('response_host_url.html', 'w', encoding='utf-8') as f:
    f.write(str(response))

# Login mit Benutzername und Passwort
browser.select_form(nr=2)
browser['username'] = USERNAME
browser['password'] = PASSWORD
browser.submit_selected()

# Login OK?
response = browser.get_current_page()
if DEBUG:
  with open('response_login.html', 'w', encoding='utf-8') as f:
    f.write(str(response))

verification_code = None
if str(response).find(USERNAME.lower()) == -1:
  if DEBUG: print(f'Benutzername {USERNAME.lower()} nicht gefunden!')
  if str(response).find('Check your email for a verification code') == -1:
    if DEBUG: print('Formular für Verifications Code nicht gefunden!')
    print('FEHLER: Login nicht erfolgreich!')
    quit()
  else:
    print('Warte auf Verifications Code eMail…')
    verification_code = get_verification_code(FROMADRESS, IMAPSERVER, IMAPPASS, 30, debug=DEBUG)
    # Rückgabe ist der Code oder ein Timeout Error
    #if not verification_code:
    #  print('FEHLER: Verifications Code nicht gefunden!')
    #  quit()
else:
  print('OK!')

# Verifications Code eingeben
if verification_code is not None:
  browser.select_form('#challenge_form')
  browser["challenge_code"] = verification_code

  # Checkbox 'Trust this device' aktivieren
  page = browser.get_current_page()
  checkbox = page.find('input', {'id': 'trust_device_checkbox'})
  if checkbox:
    checkbox['checked'] = 'checked'

  browser.submit_selected()

  # Login nach Code eingabe OK?
  response = browser.get_current_page()
  if DEBUG:
    with open('response_after_code_entry.html', 'w', encoding='utf-8') as f:
      f.write(str(response))

  if str(response).find(USERNAME.lower()) == -1:
    print('FEHLER: Login nach Code eingabe nicht erfolgreich!')
    quit()
  else:
    print('Eingabe des Verifications Code erfolgreich!')

# Links in Array speichern (Modify)
mylink = []  # Leeres Array
for link in browser.links(link_text='Modify'):
  mylink += [link]

# Anzeigen wie viele Links gefunden wurden
if not mylink:
  print('FEHLER: Keine Hosts gefunden!')
  quit()
else:
  print(f'Gefundene Hosts: {len(mylink)}. Starte Update…')

# Links klicken und Updaten
for link in mylink:
  target = link.attrs['href']
  browser.open_relative(target)  # Zur Seite gehen
  update_host(target, browser)   # Host updaten


###* SMTP Abschnitt *###
if not SMTPSERVER: quit()  # Nur wenn SMTPSERVER gesetzt ist

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

msg = MIMEMultipart()

msg['From'] = FROMADRESS ; msg['To'] = TOADRESS
msg['Subject'] = MAIL_SUBJECT

body = MAIL_BODY
for result in RESULT_STR:
  body = str(body) + str(result) + '\n'

msg.attach(MIMEText(body, 'plain'))

if LOG_FILE:
  filename = after(LOG_FILE, '/')  # Dateiname ohne Pfad
  attachment = open(LOG_FILE, 'rb')
  part = MIMEBase('application', 'octet-stream')
  part.set_payload((attachment).read())
  encoders.encode_base64(part)
  part.add_header('Content-Disposition', 'attachment; filename= %s' % filename)
  msg.attach(part)

# Beispiel: Server Addresse und TCP Port: '192.168.1.1', 25
server = smtplib.SMTP(SMTPSERVER, SMTPPORT)
server.starttls()

# Server verlangt Autentification (Nur wenn SMTPPASS gesetzt ist)
if SMTPPASS: server.login(FROMADRESS, SMTPPASS)

text = msg.as_string()
server.sendmail(FROMADRESS, TOADRESS, text)
server.quit()

Die Ausgabe ist dann wenn alles klappt in etwa so:

Code:
NO-IP Account-Renew #250206 (Python: 3.12.3)
Verwende Konfiguration aus: NOIP_Account_Renew.ini
Log-In… Warte auf Verifications Code eMail…
Eingabe des Verifications Code erfolgreich!
Gefundene Hosts: 3. Starte Update…
Update für Host-ID: …90 [OK]
Update für Host-ID: …97 [OK]
Update für Host-ID: …07 [OK]

Wichtig ist, dass die werte in der Ini in ASCII sind. Dei Datei selbst kann gerne in UTF-8 gespeichert werden
 
Zuletzt bearbeitet von einem Moderator:
Danke für deine Arbeit

kannst du bitte die NOIP_Account_Renew.ini als Rohdatei senden?

Edit: Hat sich erledigt, geht ja auch im Script

Durchlauf OK, aber es wurde heute noch kein Code benötigt

dann mal in ein paar Tagen schauen
 
Zuletzt bearbeitet:
Ok, hier bitteschön

INI:
# Konfiguration für NOIP-Account-Renew
#
# Kommentare nur am Zeilenanfang
# Werte ohne Anführungszeichen

# No-IP-Daten (Benutzername / Passwort)
[NOIP]
USERNAME =
PASSWORD =

# eMail-Daten
[MAIL]
FROMADRESS =
TOADRESS =
SMTPSERVER =
SMTPPORT =
SMTPPASS =
IMAPSERVER =
IMAPPORT =
IMAPPASS =

Benötigt werden USERNAME und PASSWORD für das Login bei NoIP
Zusätzlich für die Abfrage der eMail werden IMAPSERVER, IMAPPASS und FROMADDRESS benötigt
 
Für die Nutzung dieser Website sind Cookies erforderlich. Du musst diese akzeptieren, um die Website weiter nutzen zu können. Erfahre mehr…