Dynamic IP, Cron i Google Calendar
W oczekiwaniu na kilka mejli postanowiłem pochwalić się konfiguracją swojego domowo/biurowego serwera do dostępu z zewnątrz.
Jedyne łącze jakie da się zdobyć w mojej szerokości geograficznej do zwykła Neozdrada/Net24/cośtam, które jak wszyscy wiedzą mają dynamiczne IP. Do serwera chcę mieć dostęp z każdego miejsca na świecie i o każdej porze. Kiedyś zdarzało mi się dzwonić do któregoś z domowników i prosić o sprawdzenie ip na routerze albo jakimś myip.xxx. Niedawno wpadłem na pomysł wysyłania numeru IP sms’em. Najłatwiejsza darmowa metoda wysyłania sms’ów to wg. mnie Google Calendar. Napisałem więc kilka skryptów, które sprawdzają czy ip serwera się zmieniło i jeśli tak wysyłają nowe IP do kalendarzy zaufanych osób.
Po pierwsze serwer musi się dowiedzieć pod jakim IP jest widoczny na zewnątrz. Można korzystać z istniejących stron podających numer IP komputera, ale parsowanie odpowiedzi mogło by nie być takie łatwe, więc wrzuciłem banalny skrypt na zwykły serwer hostingowy.
myip.php:
<?php print($_SERVER['REMOTE_ADDR']); ?>
Google udostępnia moduły dla Pythona do działania ze swoimi usługami (w tym Kalendarzem), więc najłatwiej było napisać skrypt w Pythonie, który pobrane z internetu IP porówna z poprzednim i wpisze do Kalendarza. Pomógł mi komplet tutoriali w dokumentacji Google Calendar API http://code.google.com/intl/pl/apis/calendar/docs/1.0/developers_guide_python.html
setIp.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #!/usr/bin/python import httplib try: from xml.etree import ElementTree # for Python 2.5 users except ImportError: from elementtree import ElementTree import gdata.calendar.service import gdata.service import atom.service import gdata.calendar import atom import getopt import sys import string import time conn = httplib.HTTPConnection("mój serwer") conn.request("GET", "/myip.php") myip = conn.getresponse().read() conn.close() oldip = file('ip','r').read() print oldip def InsertSingleEvent(calendar_service, title='', content='New IP', where='Proliant', start_time=None, end_time=None): event = gdata.calendar.CalendarEventEntry() event.title = atom.Title(text=title) event.content = atom.Content(text=content) event.where.append(gdata.calendar.Where(value_string=where)) if start_time is None: # Use current time for the start_time and have the event last 1 hour start_time = time.strftime('%Y-%m-%dT%H:%M:00+00:00', time.gmtime(time.time() + 420)) end_time = time.strftime('%Y-%m-%dT%H:%M:00+00:00', time.gmtime(time.time() + 780)) reminder = gdata.calendar.Reminder(minutes=5) reminder._attributes['method'] = 'method' reminder.method = 'sms' event.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time, reminder=reminder)) #event.when.reminder.append(gdata.calendar.Reminder(minutes=5)) new_event = calendar_service.InsertEvent(event, '/calendar/feeds/default/private/full') print 'New single event inserted: %s' % (new_event.id.text,) print '\tEvent edit URL: %s' % (new_event.GetEditLink().href,) print '\tEvent HTML URL: %s' % (new_event.GetHtmlLink().href,) return new_event if oldip != myip: calendar_service = gdata.calendar.service.CalendarService() calendar_service.email = 'nazwa użytkownika' calendar_service.password = 'hasło' calendar_service.source = 'Google-Calendar_myip' calendar_service.ProgrammaticLogin() event = InsertSingleEvent(calendar_service, myip) file('/root/ip','w').write(myip) |
Nic nie stoi na przeszkodzie, żeby linijki 52-58 powtórzyć kilka razy dla różnych użytkowników
Dodawane offsety do czasu (linijka 36) wynika z testów – przy takim offsecie Google zaczął wysyłać do mnie SMS’y.
Ostatnim elementem jest wpis w crontab.
crontab -e*/10 * * * * ipSet.py
Kwiatkiem w tym komplecie będzie jeszcze prosta aplikacja na Androida, która znajdzie w kalendarzu ostatni wpis w kalendarzu i wyśle Intent do ConnectBot’a z naszym nowym IP.
Aplikacja nie jest jeszcze gotowa, ale jakby ktoś chciał się pobawić to kluczowym elementem jest to
final Intent sshIntent = new Intent(android.content.Intent.ACTION_VIEW); sshIntent.setData(Uri.parse("ssh://krzysiek@"+handler.ip+":22/#proliant")); sshIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(Intent.createChooser(sshIntent, "ssh")); finish();
Komentarze (3)
moze czegoś nie rozumiem, ale dlaczego nie skorzystasz z jakiegoś prostego, darmowego klienta dynamicznych domen? np. DynDNS? Zamiast bawić się w słanie IP przez SMSy czy inne zaabwy z Google Calendar, po prostu wpisujesz nazwe swojej dynamicznie aktualizowanej domeny czyli mojanazwa.dyndns.org i juz po klopocie. Jelsi dany program na Andoirdzie nie oblsuguje nazw domen a tylko IP, to rozwiazaniem jest programik o jakze skomplikowanej nazwie chyba “WhoIs”, ktora poda Ci IP z domeny w sposob, dzieki ktoremu latwo go skopiujesz i wkleisz gdzie indziej. Ot i cała filozofia.
Pozdrawiam ;]
Ale dzięki temu mam bezpieczniejszy serwer
Tak na serio to wiele razy walczyłem z DynDNS, najpierw ładnie działało przez parę pierwszych dni, a po pewnym czasie przestawało aktualizować ip.
Zupełnie nie można było na tym polegać…
Nie ma żadnej różnicy w bezpieczeństwie tak naprawdę.
A co do klientów DynDNS – rzeczywiscie niektóre działają bardzo opornie. Dlatego osobiście korzystam z No-IP. Może jest bardziej komercyjne i wersja bezpłatna ma zero opcji, ale za to aktualizator jest porządny.