I am sure I am not the only person out there who is running a website (or some kind of externally accessible server) on their home machine. I am also sure that I am not the only one doing the above with an Internet service that does not provide a static IP. As such, your IP can change at any point that the ISP’s servers deem necessary.
I know I have been in a situation where my assigned IP changes without me noticing and, all of a sudden, my website is not accessible anymore because the DNS servers point to the old IP address enough times that it was time for me to come up with some notification mechanism.
Below is a very short script that can be used to query one of the many online services that will return information about your connection, and email you the new IP address (if it has changed). Anyone with a Python installation on their server can download the script and create a cron job that will check the assigned IP periodically and send a notification when it changes.
#!/usr/bin/python
#
# Copyright (c) 2010 Mitko Haralanov. All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import httplib
import smtplib
import email.MIMEText as email
import getpass
import getopt
import socket
from os.path import basename
def get_old (filename):
ip = None
try:
fd = open (filename, 'r')
ip = fd.readline ().strip ()
fd.close ()
except IOError: pass
return ip
def set_old (filename, ip):
try:
fd = open (filename, 'w')
fd.write (ip.strip () + "\n")
fd.close ()
except IOError: pass
def mail (ip, mail_server, from_address, to_address,
username=None, password=None):
text = "External IP changed to: %s"%ip
msg = email.MIMEText (text)
msg["Subject"] = "IP Change"
msg["To"] = to_address
msg["From"] = from_address
smtp = smtplib.SMTP (mail_server)
if username and password:
try: smtp.login (username, password)
except (SMTPHeloError,
SMTPAuthenticationError,
SMTPException), e:
print "Login error:",e
smtp.quit ()
return
try:
resp = smtp.sendmail (msg['From'], msg["To"],
msg.as_string ())
except (smtplib.SMTPRecipientsRefused,
smtplib.SMTPHeloError,
smtplib.SMTPSenderRefused,
smtplib.SMTPDataError), e:
print "Sendmail Error:",e
smtp.quit ()
return
def usage (msg=None):
_ = basename (sys.argv[0])
if msg: print msg
print _,"[-f <file>] [-s <smtp server>] [-o <from address>]"
print " "*len (_),"[-e <to address>] [-u <username>] [-p <password>] [-h]"
return
def main ():
exip_file = ".exip"
server = None
from_address = None
to_address = None
username = None
password = None
try: opts, args = getopt.getopt (sys.argv[1:], "f:s:o:e:u:p:hdl:t:",
[])
except getopt.GetopError, e:
usage (e)
sys.exit (1)
for opt, value in opts:
if opt == '-f': exip_file = value
if opt == '-s': server = value
if opt == '-o': from_address = value
if opt == '-e': to_address = value
if opt == '-u': username = value
if opt == '-p': password = value
if opt == '-l': logfile = value
if opt == '-h':
usage ()
sys.exit (0)
old = get_old (exip_file)
conn = httplib.HTTPConnection ("ifconfig.me")
try: conn.request ("GET", "/all/json")
except socket.error: return 1
resp = conn.getresponse ()
data = eval (resp.read ())
ip = data.get ("ip_addr", None)
if ip != old:
password = getpass.getpass ("Password: ")
mail (ip, server, from_address, to_address,
username, password)
set_old (exip_file, ip)
return 0
if __name__ == "__main__":
main ()

This is exactly what I’m looking for, although on my ubuntu home server I’m getting the following errors:
root@kieron-server:~/scripts# python checkip.py
Password:
Traceback (most recent call last):
File “checkip.py”, line 119, in
main ()
File “checkip.py”, line 114, in main
username, password)
File “checkip.py”, line 62, in mail
msg.as_string ())
File “/usr/lib/python2.6/smtplib.py”, line 685, in sendmail
self.ehlo_or_helo_if_needed()
File “/usr/lib/python2.6/smtplib.py”, line 509, in ehlo_or_helo_if_needed
if not (200 <= self.ehlo()[0] <= 299):
File "/usr/lib/python2.6/smtplib.py", line 382, in ehlo
self.putcmd(self.ehlo_msg, name or self.local_hostname)
File "/usr/lib/python2.6/smtplib.py", line 318, in putcmd
self.send(str)
File "/usr/lib/python2.6/smtplib.py", line 310, in send
raise SMTPServerDisconnected('please run connect() first')
smtplib.SMTPServerDisconnected: please run connect() first
Any idea what I need to do? Sorry, I'm a little new to this, but in exactly the same situation as you with the DNS issues etc.
Regards
The reason you are getting this message is that you are not calling the script with the ‘-s’, ‘-o’, and -’e’ options. Therefore, the SMTP lib does not have the server which to connect to.
I am getting this error. Running python 2.7 on win32. Any ideas?
C:\>python ip.py
Traceback (most recent call last):
File “ip.py”, line 19, in
import httplib
File “C:\Python27\lib\httplib.py”, line 79
import mimetools
File “C:\Python27\lib\mimetools.py”, line
import tempfile
File “C:\Python27\lib\tempfile.py”, line 3
from random import Random as _Random
ImportError: cannot import name Random