#Auth #python3.4 or newer #use "screen python3 registerIp.py" for better experience then ctrl+a+d and 'screen -r' (see more screen linux command on google) #to stop ctrl + c #interesting url to develope this #help from https://medium.com/greedygame-engineering/an-elegant-way-to-run-periodic-tasks-in-python-61b7c477b679 (but in python 2) #if you want to mount your own server https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-16-04 #https://www.freecodecamp.org/news/send-emails-using-code-4fcea9df63f/ # #This script is designed for who wants the external ip and send it with email. For who want to have services at home #or anywhere with dynamic external ip without paying for dynamic dns #Need a external URL that return only your ip #Tested with python 3.7 in ubuntu 18.04 using outlook account aka @hotmail.com # import urllib.request, threading, getpass, time, signal, datetime, smtplib from datetime import timedelta from string import Template from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText __author__ = "guim1111" #URL which will tell you only the ip URL_GETIP = "https://ident.me" #Time that wait to get again the ip from url in seconds WAIT_TIME_SECONDS = 5 #do not touch LAST_IP = "0" #Edit this if you want to hardcode this (password not recommended) MY_ADDRESS = "" TO_ADDRESS = "" MY_PASSWORD = "" #Edit this for smtp that you want, but recommended this default, (only ports that accept ssl) SMTP_HOST = "smtp-mail.outlook.com" #default for outlook account, gmail need more steps to be used with smtplib SMTP_PORT = "587" #try 25 if doesn't work, ssl smpt port recommended class ProgramKilled(Exception): pass def getIp(): global LAST_IP ip = urllib.request.urlopen(URL_GETIP).read().decode('utf8') now=datetime.datetime.now() if LAST_IP != ip: sendMail(ip) LAST_IP = ip file.write("{} -- {}\n".format(ip, now)) print(f"{ip} detectada! -- {now}") def signalHandler(signum, frame): raise ProgramKilled def sendMail(ip): s = smtplib.SMTP(host=SMTP_HOST, port=SMTP_PORT) s.starttls() s.login(MY_ADDRESS, MY_PASSWORD) msg = MIMEMultipart() msg["From"]=MY_ADDRESS msg["To"]=TO_ADDRESS msg["Subject"]=f"Your ip now is: {ip}" msg.attach(MIMEText(f"Your ip was {LAST_IP}, now it's {ip}", "plain")) s.send_message(msg) del msg s.quit() class Job(threading.Thread): def __init__(self, interval, execute, *args, **kwargs): threading.Thread.__init__(self) self.daemon = False self.stopped = threading.Event() self.interval = interval self.execute = execute self.args = args self.kwargs = kwargs def stop(self): self.stopped.set() self.join() def run(self): while not self.stopped.wait(self.interval.total_seconds()): self.execute(*self.args, **self.kwargs) def checkSMTPCredentials(): global MY_ADDRESS global TO_ADDRESS global MY_PASSWORD if MY_ADDRESS == "": MY_ADDRESS = input("Set a mail from where this script will work: ") TO_ADDRESS = input("Set a mail which will receive the mails (blank = previous email): ") or MY_ADDRESS else: print("There is a mail hardcoded, be sure you put it correct and the mail who will receive") if MY_PASSWORD == "": MY_PASSWORD = getpass.getpass("Set a password of first mail account (this will not be stored in any file): ") else: print("There is a password hardcoded (BE SURE THAT THIS IS WHAT YOU WANT, it's unsecure to put a credentials in any file)") if input("Write 'ok' to continue with this") != "ok": exit(1) print(f"Checking credentials for {SMTP_HOST}") s = smtplib.SMTP(host=SMTP_HOST, port=SMTP_PORT) s.starttls() try: s.login(MY_ADDRESS, MY_PASSWORD) except smtplib.SMTPAuthenticationError: print ("Incorrect username/password for this SMTP!") s.quit() exit(1) s.quit() print("Credentials are correct!") def checkIp(): response = urllib.request.urlopen(URL_GETIP) ip = response.read().decode('utf8') code = response.getcode() if code != 200: print("Something is wrong, the code of conectio is not 200") exit(2) print(f"Statuss 200, your ip is {ip} get from {URL_GETIP}") def main(): file=open("myip.log", "w+") signal.signal(signal.SIGTERM, signalHandler) signal.signal(signal.SIGINT, signalHandler) job = Job(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=getIp) job.start() while True: try: time.sleep(1) except ProgramKilled: print ("Program killed, bye!") job.stop() file.close() break if __name__ == "__main__": #Coment checkSMTPCredentials if you want to automate all without user input with hardcoded credentials (not secure) #Coment checkIp if you don't want to check if web that tell your ip is up or you have internet connectivity checkSMTPCredentials() checkIp() main()