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();
  • Wykop
  • Facebook
  • Twitter

3 Komentarzy

  1. antman on Wrzesień 15th, 2009

    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 ;]

  2. skyman on Wrzesień 17th, 2009

    Ale dzięki temu mam bezpieczniejszy serwer :P
    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ć…

  3. antman on Wrzesień 20th, 2009

    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.

Twój komentarz

Tagi

android autobuser cron google java linux python sieć sms test

linki