Алё! Сервер! Скинь свой айпи!

Как то мне приспичило зайти на Raspberry Pi домашнюю по SSH через интернет. IP дома динамический. Спросить некого, а зайти надо. Тогда ограничился доступом к домашнему NAS, а на будущее надо бы что то организовать – SSH то приятнее, чем только доступ к файлам через Tapinn. Cтатья о том, как организовать доступ к домашнему серверу через интернет.

Внимание!

Реализация данной идеи повысит вероятность несанкционированного доступа к вашим личным данным! Будьте осторожны, не пренебрегайте элементарной безопасностью!

И так, что имеем:

  • Доступ в интернет из домашней сети остуществляется через маршрутизатор HG520b, выданный провайдером.
  • Малинка (Raspberry PI) с установленной системой Raspbian (тот же debian практически) подключена к коммутатору.
  • Доступ к сети интернет естественно есть.
  • Пока что малинка работает торент-качалкой и иногда подвергается всяким зловещим экспериментам. К малинке в локальной сети подключаюсь по SSH при необходимости.

Напрямую к серверам в локальной сети через интернет подключиться проблематично – внешний IP ведь на всех один. Поэтому идем в настройки маршрутизатора, заходим в Basic->NAT->Virtual Server. Добавляем локальный айпи малинки (в моем случае 192.168.1.99) и порт 22. Выглядит это как то так:

На других роутерах должно быть как то похоже.

Внешний IP я посмотрел на вкладке Status->Service Information:

Для чистоты эксперимента выхожу в сеть через мобильник с ноута, вбиваю в командной строке (все ip вымышлены):

user@user-TravelMate-P253:~$ ssh root@23.116.183.241
root@23.116.183.241's password:
Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Fri Jul 11 15:50:14 2014 from 37.223.115.22
root@raspberrypi:~#

Короче всё красиво, но есть одно большое НО – провайдер каждые трое суток рвет соединение, да и с питанием могут быть перебои. IP динамический, меняется при каждом подключении. Поэтому решено было реализовать такую схему: завожу серверу (будем называть Raspberry PI так) ящик на gmail, посылаю ему сообщение (типа дай мне свой IP), сервер присылает мне на ящик айпи.

Важно!

В принципе можно использовать и существующий ящик – но это как то небезопасно, особенно если кто то левый сможет получить доступ малинке. Ну по части безопасности – тут каждый решает для себя сам. Я думаю каждый раз при удачном либо не удачном логине по ssh сервер должен посылать мне письмо. Так я сразу узнаю о попытке входа. Ещё как вариант – запретить вход через ssh по паролю, сгенерировать ключи и не париться.

С отправкой писем проблем нету – нахожу в гугле первый попавшийся скрипт – python так python – меняю адреса, пароли на свои.. Собственно для этого я и создавал отдельный ящик, пароль сохранил в чистом виде, но даже если кого то угораздит получить доступ к ящику – ничего особенного он там не увидит. Прежде чем приступить к настройке скриптов, устанавливаем необходимые программы:

apt-get install getmail4
apt-get install sendmail
apt-get install procmail

Sendmail и getmail понятно для чего, procmail будет запускать тот или иной скрипт в зависимости от каких то слов в теме входящего письма

Далее работаем под пользователем pi в его домашнем каталоге /home/pi/.

Создаем папку /home/pi/sendmyip/ и кидаем туда следующий наш скрипт, слегка изменив:

import time
import commands
import re
import smtplib
 
####--[COFIGURATION]
server = 'smtp.gmail.com' #smtp адрес сервер gmail
server_port = '587' #порт сервера
 
username = 'serv40email@gmail.com' #gmail аккаунт
password = 'veryhardpassword' #пароль для gmail
 
fromaddr = 'serv40email@gmail.com' #от кого письмо
toaddr = 'admin@gmail.com' #кому отправлять
message = 'RPi's address: ' #текст сообщения
####--[/COFIGURATION]
 
#в оригинальном скрипте для получения IP использовался
#ifconfig, у меня так не прокатит, поэтому для вычисления ip
#решил использовать сайт myip.ru, вообще подойдет любой другой.
#команда находит три айпишника, я их уже не фильтровал - лениво как то
#наш искомый будет последним.

time.sleep(30)
 
#Короче загружаем страничку и извлекаем все ip адреса из нее..
found_ips = []
ips = re.findall( r'[0-9]+(?:.[0-9]+){3}', commands.getoutput("wget http://myip.ru -O /home/pi/sendmyip/t.html && cat /home/pi/sendmyip/t.html"))
for ip in ips:
  if ip.startswith("255") or ip.startswith("127") or ip.endswith("255"):
    continue
  found_ips.append(ip)
 
message += ", ".join(found_ips)
headers = ["From: " + fromaddr,
           "To: " + toaddr,
           "MIME-Version: 1.0",
           "Content-Type: text/html"]
headers = "rn".join(headers)
 
server = smtplib.SMTP(server + ':' + server_port) 
server.ehlo()
server.starttls() 
server.ehlo()
server.login(username,password) 
server.sendmail(fromaddr, toaddr, headers + "rnrn" +  message) 
server.quit()

Сначала я ломал голову, как с наименьшими усилиями получить ip прямо с роутера, но потом сделал проще – в сети полно сервисов, показывающих ip адрес клиента – выбрал самый простой и поменял скрипт соответствующим образом (строка 28). Скрипт выбирает все ip из веб странички и отправляет их по адресу. Можно, конечно отладить, чтобы отсылался только один ip, но мне стало лень – и так работает :).

Проверяем скрипт:

python /home/pi/sendmyip/sendip.py

Весело звякнул телефон – письмо пришло, всё работает. Осталось всего ничего – автоматизировать получение почты и запуск этого скрипта по определенному условию.

Переходим к настройке getmail. Открываем /etc/getmailrc.

Если такого нет – создаем новый. Содержимое файла:

[retriever]
type = SimpleIMAPSSLRetriever
server = imap.gmail.com
username =serverpi40@gmail.com
password =veryhardpassword
mailboxes = ("INBOX",)
port = 993
[destination]
type = MDA_external
path = /usr/bin/procmail
unixfrom = True
user=pi
[options]
received = false
delivered_to = false
read_all = false
verbose = 0 

username и password подставляем от реального ящика, который завели ранее.

В секции [destination] указано, что почту будет обрабатывать procmail

переходим к его настройке:

/etc/procmailrc

PATH=/bin:/usr/bin:/usr/local/bin
 
MAILDIR=/home/pi/Mail
 
LOGNAME=mailservlog
 
ORGMAIL=$MAILDIR/emergency
PYT = /usr/bin/python
:0
* ^Subject:.*(give me the IP)
|$PYT /home/pi/sendmyip/sendip.py

В последней строке путь к скриптам отправки адреса, если что то меняли, нужно указать свой путь.

В 10-й строке указана фраза “give me the IP”. При наличии этой фразы в теме письма будет запускаться наш скрипт. Проверяем его работу отправкой письма на ящик сервера, в теме указываем give me the IP, в консоли выполняем getmail -r /etc/getmailrc (Выполнять нужно от имени любого пользователя кроме root. Через рута скорее всего откажется работать), через несколько секунд получаем письмо с айпишником. Всё работает. Осталось добавить задание в планировщик. От имени пользователя “pi” выполняем:

crontab -e

добавляем в открывшийся файл строку:

*/5 * * * * /usr/bin/getmail -r /etc/getmailrc

На всякий случай перезапускаю cron. Теперь почта будет автоматически проверяться каждые 5 минут и при появлении ключевой фразы, я буду получать ip адрес малинки, что мне и требовалось.

На мой взгляд, довольно удобный велосипед без всяких промежуточных серверов и минимумом затраченного времени на настройку – за пол часа попивая кофе с бутербродами можно не спеша всё организовать. Развивая тему, можно давать малинке задания на закачку определенных торентов, отправив email соответствующий запрос, включать/отключать какое-то оборудование, передавать команды контроллеру, например, включить насос отопления и поддерживать определенную температуру в комнате, при наличии датчиков – проверить состояние и выслать отчет по открытым закрытым дверям, прислать фото с камеры и т д и т п.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>