DX168B

<<< Назад

Как я развернул домашний сервер с MajorDoMo ч. 2

Данная статья является продолжением цикла. В данной статье будет рассказано о моей домашней сети, в которой работает мой сервер. Из данной статьи читатели смогут познакомиться с организацией домашней сети и прочей сетевой шелухи.

В предыдущей статье я рассказывал о том, как я поднял домашний сервер. Однако, сервер подразумевает работу в сети. И от этой сети, от её возможностей и её защищенности будет зависеть работа сервисов на данном сервере.

Почти любое IT направление начинается с того, что сначала оно рождается в виде "лишь бы заработало" и только потом ведется работа над безопасностью. Наше направление - это Internet of Things (IoT). И эта учаcть не обошла стороной и его. Сети IoT нужно защищать даже от домашних пользователей. Точнее, от их устройств. Неизвестно, какой вирус могут подхватить на свои планшето/смартфоно/компьютеры ваши домочадцы и на что этот вирус будет способен. А многие устройства умного дома не имеют должной защиты от хакинга. Даже сам проект MajorDoMo.

Организуя систему умного дома, (компоненты которой пренепременнейшим образом будут использовать домашнюю сеть) в первую очередь следует позаботиться о нормальном роутере. Нет, не такой нужен, который со 100500 WiFi антеннами и супермощным процессором. Нормальный роутер - это тот, который надежен и позволяет очень гибко настроить сеть. Я для своей сети выбрал роутер Mikrotik hAP AC Lite. Эта мелкая коробочка умеет такое, что не снилось ни одному D-Link'у, ни Asus'у, ни TP-Link'у. Они могут посоревноваться только в том случае, если зарядить их прошивкой OpenWRT. Но Mikrotik - это больше для профессионалов. Для дома может подойти и что-то наподобие Zyxel Keenetic, если конечно он даст те сетевые возможности, которые будут описаны ниже.

В умном доме должны быть минимум две почти изолированные друг от друга подсети.
В одной подсети находятся пользователи со своими гаджетами, в другой - инфраструктура умного дома.
Более-менее серьезный роутер позволит это реализовать.

Как это сделано у меня

У меня настроены три подсети.

  1. Основная, где сидят все домашние пользователи со своими гаджетами - 192.168.0.0/24
    К этой подсети нужно относиться как к публичной и выдавать ограниченный доступ к другим подсетям. Вплоть до ограничения по типу протокола и порта.

  2. Сеть умного дома - 192.168.222.0/24
    Именно тут живут все умные датчики, лампочки, выключатели и даже сам сервер. Ну и мой ПК тоже тут.
    IP сервера: 192.168.222.254

  3. VPN подсеть - 172.16.0.0/16. У меня белый IP, потому на роутере запущен IPSec/L2TP VPN сервер.

У первых двух подсетей реализованы и отдельные WiFi сети. Сеть для датчиков скрывает свой SSID, чтобы не привлекать внимание посторонних.
В роутерах Mikrotik, как и в прошивках OpenWRT, можно создавать произвольное количество WiFi сетей на одном физическом WiFi интерфейсе.
В этом случае для этих сетей создаются виртуальниые интерфейсы, с которыми можно работать почти как с физическими.

Изоляция
Все сетевые пакеты, проходящие через роутер, проходят через фаерфол. Это что-то типа фейс-контроля в клубах.
У охранников есть свод критериев, по которым они принимают решение о пропуске. Мордой не вышел, значит не пройдешь.
Firewall в Mikrotik очень похож на линуксовый iptables. Я бы даже сказал, что они братья-близнецы,
но у Mikrotik'овского фаервола функционала побогаче будет. Однако, базовые правила конфигурации фаервола у них
абсолютно идентичны. Есть три основные цепочки (chains) движения сетевых пакетов. Это INPUT, OUTPUT и FORWARD.
Цепочка INPUT - это пакеты, которые предназначены самому роутеру. OUTPUT - это исходящие от роутера пакеты.
А вот FORWARD - это пакеты, гуляющие между подсетями.
Так же, порядок правил в таблице фаервола тоже имеет значение. Ибо когда фаервол получает пакет на обработку,
он его проверяет по правилам сверху вниз. И если находится подходящее для него правило, он его отрабатывает.
А вот если правила нет, то пакет свободно проходит сквозь фаервол. Да, это не циска, где в конце списка всегда стоит неотключаемое правило "блокировать всё". И даже у линуксового IPTABLES можно задать - что делать с неопределенными пакетами. В Mikrotik нужно эти правила задавать самому.
Обычно это правило из разряда "блокировать абсолютно всё", которое размещают в конце списка правил.

У меня стоит запрет на любые проходящие пакеты от VPN и домашней сети к сети датчиков и сервера.
Однако, выше запрета стоят некоторые разрешающие правила:

  1. Пакеты, идущие к серверу на все порты Samba по обоим протоколам (TCP и UDP) - 137,138,139,445 (для доступа к файлопомойке)
  2. Пакеты к серверу по порту 6600 - это для пульта MPD (Music player daemon)
  3. TFTP до сервера по порту 69.
  4. HTTP до сервера по порту 80. Однако, тут стоит лимит на количество одновременных соединений с одного узла.
    Если их больше 50, то IP этого узла залетает в бан на сутки. В дальнейшем хочу написать модуль для MD, который будет получать от роутера
    подобного рода события и слать их в Telegram.

Собственно, это всё самое основное для того, чтобы обезопасить систему на сетевом уровне.

WEB сервер и DNS

WEB сервер Apache умеет работать в качестве множества виртуальных WEB хостов, имеющих разные доменные имена, но один
общий IP на всех. Собственно, так работают хостинг-провайдеры, на серверах которых крутится множество сайтов их клиентов.
При вводе доменного имени сайта в адресную строку браузера, браузер обращается к сетевому стеку системы
в поисках IP адреса для этого доменного имени. Система сначала пороется у себя в кеше имен и не найдя нужного, полезет по файлам hosts. Не найдя и там нужного, система пойдет спрашивать его у DNS сервера, адрес которого задан в настройках сетевого подключения.
DNS копается в своем кеше, потом в статических записях и если не найдет, пойдет выпрашивать у вышестоящего сервера (сервера провайдера). Получив IP адрес, браузер вкладывает доменное имя запрошенного сайта в заголовок HTTP запроса, подключается к WEB серверу по IP, и скармливает ему запрос. Сервер смотрит в этот заголовок, видит там доменное имя, направляет запрос в конкретный виртуальный WEB хост и выдает ответ от него.
DNS сервер есть во всех домашних и не только роутерах, однако, не все домашние роутеры дают его настраивать.
Ввиду того, что WEB сервер мне нужен не только для MajorDoMo, то настраиваться он будет аналогичным образом.
Но о его настройке будет позже, сейчас же нужно настроить то, что от него не зависит. А настроить нужно DNS сервер на роутере.
В Mikrotik DNS сервер простой. Настроек там тоже мало, но он позволяет добавлять статические записи в виде соответствий доменное.имя = ip адрес.
А это значит, что в локальной сети можно назначать доменные имена различным узлам, ни у кого ничего не спрашивая. Однако, работать это будет только в этой локальной сети. Роутеры Mikrotik можно конфигурировать через консоль, но Winbox удобнее. Однако, публиковать настройки все-же удобнее в виде консольных команд.
Добавляем записи для DNS:

/ip dns static
add address=192.168.222.254 name=server.lan
add address=192.168.222.254 name=md.server.lan
add address=192.168.222.254 name=test.server.lan

Как видно из записей, серверу я назначил аж целых три доменных имени. Первое будет использоваться в качестве основного имени,
остальные два - для WEB сервера.
Имя server.lan - имя общего назначения. Его можно вбивать, например, в настройки подключения к серверу на своих датчиках. Удобно это тем, что при развертывании нового сервера и переезде всей ифраструктуры на новый сервер, достаточно будет изменить IP адрес его доменного имени в роутере.
За именем md.server.lan будет закреплен MajorDoMo, за test.server.lan - экспериментальная WEB страница.

Если есть белый IP
На сленге админов-сетевиков, "белым" IP адрес называют адрес, выданный провайдером из глобального пула IP адресов. К узлу с таким адресом можно подключиться из любой точки мира. Но вот есть беда. Белых адресов уже дико не хватает, потому провайдеры практикуют подключение множества своих клиентов через один общий белый IP, выдавая самим клиентам так называемые "серые" IP адреса. Серый IP адрес - это такой же тип адреса, какой выдает домашний роутер устройствам в локальной сети. Снаружи к устройству не подключишься, для этого нужно настраивать проброс портов сквозь роутер. По сути, провайдер просто сажает своих клиентов за свой роутер. А кто даст настраивать роутер провайдера для проброса портов? Верно, никто. Если провайдер раздает белые IP, пусть даже и динамические (которые меняются постоянно, но они все равно белые), то это уже мегакруто. Это позволяет подключаться к дому, не прибегая к сторонним услугам, таким как платные VPN сервисы.

В моем случае провайдер выдает белые IP по DHCP. Он старается выдавать один и тот же IP адрес клиенту, однако не гарантирует, что будет выдаваться один и тот же адрес на постоянной основе. За семь лет, провайдер поменял мне IP более 20 раз. По этому, нужно позаботиться о публичном доменном имени для своего IP адреса. Хороший домен второго уровня (my_domain_2_lvl.com) стоит ежемесячных или ежегодных денег. Однако, есть множество бесплатных сервисов, выдающих домены третьего уровня (my_domain_lvl_3.domain_service.com). Во многих домашних роутерах есть поддержка таких сервисов как no-ip.com, DynDNS.org и прочих. Однако, при бесплатной версии услуги они просили сначала каждые три месяца перерегистрировать домен вручную, но потом сократили до одного месяца. Меня это достало и я стал искать другие сервисы. Я нашел сервис DuckDNS. Это сообщество, которое дает имена в домене .duckdns.org бесплатно и бессрочно, не просит никаких перерегистраций. Им можно задонатить, тогда они позволят пользователю регистрировать больше доменов на постоянной основе. Сервисом пользуюсь уже больше четырех лет и никаких проблем с ними небыло. Рекомендую.

Хорошо, на сайт мы зашли, зарегистрировались и зарегистрировали домен под текущий IP адрес. Но как быть в случае, когда провайдер внезапно поменял IP? Для этого нужно сообщить серверам DuckDNS о смене IP адреса. На сайте у них есть варианты скриптов для различных платформ. Есть там примеры для DD-WRT, OpenWRT, Mikrotik и даже для ESP8266. Но у меня Mikrotik, потому я буду приводить вариант для него. На текущий момент там есть два варианта для Mikrotik. Я использую переработанную версию старого скрипта.

Добавление скрипта:

/system script
add comment="Duck DNS update" dont-require-permissions=yes name=dn_update \
    owner=admin policy=ftp,read,write,policy,test,sensitive source=":global currentIP;\r\
    \n:global dnInterface;\r\
    \n:global dnUpdateCounter;\r\
    \n:global dnHost;\r\
    \n:global dnToken;\r\
    \n:global dnDomain;\r\
    \n:global dnRespPath;\r\
    \n:local newIP [/ip address get [find interface=$dnInterface] address];\r\
    \n:set \$newIP [:pick \$newIP 0 [:find \$newIP \"/\"]];\r\
    \n:if (\$newIP != \$currentIP) do={\r\
    \n    /tool fetch mode=https url=\"https://\$dnHost/update\?domains=\$dnDo\
    main&token=\$dnToken&ip=\$newIP\" dst-path=\$dnRespPath;\r\
    \n    :local result [/file get \$dnRespPath contents];\r\
    \n    :if (\$result = \"OK\") do={\r\
    \n        :log warning \"Duck DNS: IP address \$currentIP changed to \$new\
    IP\";\r\
    \n        :set currentIP \$newIP;\r\
    \n        :log warning \"Duck DNS: Domain update success.\";\r\
    \n        :set \$dnUpdateCounter (\$dnUpdateCounter+1);\r\
    \n    } else={\r\
    \n        :log error \"Duck DNS: Domain update fail!\";\r\
    \n    }\r\
    \n} else={\r\
    \n    :log warning \"Duck DNS: No need to update domain.\";\r\
    \n}"

Он же, при добавлении через Winbox:

:global currentIP;
:global dnInterface;
:global dnUpdateCounter;
:global dnHost;
:global dnToken;
:global dnDomain;
:global dnRespPath;
:local newIP [/ip address get [find interface=$dnInterface] address];
:set $newIP [:pick $newIP 0 [:find $newIP "/"]];
:if ($newIP != $currentIP) do={
    /tool fetch mode=https url="https://$dnHost/update?domains=$dnDomain&token=$dnToken&ip=$newIP" dst-path=$dnRespPath;
    :local result [/file get $dnRespPath contents];
    :if ($result = "OK") do={
        :log warning "Duck DNS: IP address $currentIP changed to $newIP";
        :set currentIP $newIP;
        :log warning "Duck DNS: Domain update success.";
        :set $dnUpdateCounter ($dnUpdateCounter+1);
    } else={
        :log error "Duck DNS: Domain update fail!";
    }
} else={
    :log warning "Duck DNS: No need to update domain.";
}

Этот скрипт использует данные из глобальных переменных для удобства в дальнейшей поддержке.
Все переменные этого скрипта нужно создавать и заполнять данными при каждой загрузке роутера. Но это не беда.
В Mikrotik можно сделать и так:

/system scheduler
add name=startup_init on-event=":global dnUpdateCounter 0\r\
    \n:global dnInterface мой_WAN_интерфейс\r\
    \n:global currentIP \"0.0.0.0\"\r\
    \n:global dnHost www.duckdns.org\r\
    \n:global dnDomain мой_домен_без_суффиксов\r\
    \n:global dnToken мой_токен_с_сайта_duckdns.org\r\
    \n:global dnRespPath duckdns.txt" policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-time=startup

А теперь самое главное. Нужно обновлять IP всякий раз, когда провайдер выдает новый IP.
Для этого в Mikrotik есть возможность писать скрипты, которые будут выполняться при различных событиях.
В разделе IP -> DHCP Client, на вкладке Advanced есть большое окно для скрипта. Там вводим следующее:

:log warning "DHCP client WAN: IP leased. Updating domain...";
:delay 15;
/system script run "dn_update";

Этот скрипт плюнет в лог сообщение о том, что получен IP по DHCP и через 15 сек. запустит скрипт "dn_update", который я приводил выше.
Мало того, я на всякий случай еще сделал так, чтобы скрипт "dn_update" запускался раз в сутки и принудительно
обновлял IP даже если он не менялся. Это чтобы товарищи из Duck DNS не посчитали этот домен мертвым и не удалили его.

/system scheduler
add interval=1d name=duck_dns on-event="log warning \"Shedule duck_dns: Starti\
    ng domain update.\"\r\
    \nset \$currentIP \"0.0.0.0\"\r\
    \n/system script run \"dn_update\";" policy=\
    ftp,read,write,policy,test,sensitive  start-time=00:00:00

Теперь домой можно подключаться по имени, типа "мойдом.duckdns.org"
На этом пока всё. Далее будет о софте и его настройке.

Обсуждение (1) (8)

Смотрите так же:
18.02.2021 Как я развернул домашний сервер с MajorDoMo ч. 1

Вулканешты, Молдова

На форуме: DX168B