Привет GT! Всех с наступившим и прошедшими!
Продолжаю рассказ о том, как я подключал дверной замок к Интернету. Начало тут.
Большое спасибо всем за комментарии. Готовые решения действительно есть, но так же есть ряд нюансов, не позволивших мне ими воспользоваться. Квартира это все-таки не отель, так что специализированные гостиничные замки мы отметаем сразу. Клавиатуры кодовых замков, антенны для NFC, дабы не пугать соседей, тоже не рассматриваем. Никакой карты, токена или иного физического носителя использовать тоже не получится, подразумевается, что нет возможности их передать гостю до того, как он откроет дверь.
Kevo, August или Lockitron использовать не получилось, т.к. они основаны на американском типе замка (deadbolt), что не очень удачно устанавливается на стальную дверь толщиной 65-70 мм. Наш выбор это электромеханический CISA для бронированных дверей, ценой около 500 евро (пока не купил, ибо дорого).
И самое главное, хочется что-то такое сделать своими руками, не корысти ради токма увлечения для.


Напомню, что контроллер замка находится глубоко за NAT в локальной домашней сети, а следовательно поднимать web-сервер на Ардуине нет смысла, из Интернета до него не достучаться. Сервер написан на Python с использованием фреймворка Twisted, работает под Linux в другом месте, где есть настоящий IP адрес, а контроллер подключается к нему и ждет команд.

Сейчас я хочу рассказать о логике работы и о криптографии.
Что-то надежно шифрующее трафик для Ардуины я не нашел, потому коммуникации замка и сервера будут идти по открытым каналам нешифрованным трафиком.
В первом прототипе я ипользовал MD5, теперь сменил его на SHA-1, вот на этой библиотеке Cryptosuite. Памяти она потребляет поменьше, и уже есть готовая функция HMAC.
Ключ — это пароль до 30 ASCII символов, храниться в EEPROM памяти контроллера
В первом прототипе этот же пароль хранился в явном виде и на сервере, что конечно же не секьюрно. Для второго прототипа потребовалось два пароля. Первый для аутентификации замка при подключении к серверу, этим паролем открыть замок нельзя, он нужен для того, что бы только правильные замки могли подключаться к серверу.
Замок подключается к серверу и первым делом сообщает ему свой идентификатор. Сервер проверяет в базе данных, есть ли такой замок, и если есть, высылает в ответ случайным образом сгенерированную ASCII последовательность. Замок «подписывает» ее паролем и отправляет хеш обратно. Сервер сравнивает полученный хеш с тем, что он рассчитал самостоятельно, и если они совпали, авторизирует подключившийся контроллер как «замок».
В противном случае соединение сбрасывается.
Второй пароль, это уже цифровой ключ, на сервере он не храниться.
Работает следующим образом: пользовательское приложение вызывает через SOAP функцию на сервере, указывает ID замка и команду, которую он хочет ему отправить. Результатом функция возвращает ID запроса. Сервер переправляет эту команду на контроллер, контроллер в ответ отправляет случайным образом сгенерированную ASCII последовательность, и ждет «правильный» ответ пару секунд. Далее пользовательскому приложению нужно получить ее от сервера, через тот же SOAP по ID запроса, подписать ее цифровым ключом и отправить обратно.
Контроллер сравнивает полученный хеш с рассчитанным самостоятельно и если они совпадают, выполняет ранее полученную команду, о чем отчитывается серверу.
Время на подтверждение команды ограничено 2-я секундами, если в течение этого времени ответа не придет, контроллер игнорирует ранее полученную команду. Если хеши не совпадут, команда так же игнорируется.
Таким образом я пытаюсь защититься от атаки «человек посередине», которую на проводах моего провайдера устроить очень просто. Соединение там простое, никаких паролей и сертификатов, достаточно обрезать витую пару в щитке, обжать с обоих сторон, со стороны квартиры воткнуть в сеть с подмененным IP-адресом командного сервера, на другом конце эмулировать замок (скрипт эмулятора я на питоне тоже написал для отладки), устроив такой «межсетевой экран» с прослушкой.
В этом плане, на мой взгляд, замок получился достаточно защищенный.
Даже взлом командного сервера и кража его базы с паролями для авторизации замком особой беды не наделают, ибо открыть ими замок не получится.
Осталось только разобраться с гостями. Это требования №№6-8 из первой статьи.
Клавиатуры, прокси-карты, RFID и NFC не вариант, выше написал почему. Но почти у каждого есть смартфон и во всех смартфонах есть Bluetooth, выбор очевиден!

В первом прототипе гость был ассоциирован с одним единственным кодом доступа. В базе сервера для этого кода хранились ID замка, дата-время начала и конца действия гостевого доступа, ну и текстовое поле для человеко-читаемого наименования гостя.
Гость подходит к замку, запускает мобильное приложение на своем смартфоне, оно передает через Bluetooth на контроллер код доступа, от контроллера на сервер приходит сообщение о том, что к нему подошел гость с таким-то кодом доступа. Сервер проверяет его по базе данных, и если правильный гость пришел в правильное время в правильное место, отправляет замку команду на открытие. На самом деле вместо кода доступа в открытом виде гость будет отправлять его HMAC-хеш, подписанный «временным штампом» (строковое представление юниксового времени, деленное на 30 с отброшенной дробной частью). Сервер для проверки делает запрос к базе с селектом всех действительных в текущий момент для данного замка кодов доступа, затем последовательно перебирает и вычисляет для них аналогичный HMAC, если находит совпадение, отправляет команду на открытие, если перебор кодов доступа заканчивается до того, как удается найти совпадение, замку отправляется отрицательный ответ на попытку открытия.
Проблема в том, что цифровой ключ для такой авторизации надо было хранить на сервере.
Пришлось для второго прототипа усложнить «гостевую» авторизацию. Гостевой код доступа теперь состоит из двух ключей, назовем их «серверный» и «приватный». Серверный нужен для заведения учетной записи гостя на сервере, а приватный собственно для открытия замка. Серверный в явном виде будет храниться на сервере, а от приватного будет только хеш, но не простой, а HMAC с цифровым ключом замка.
Теперь сессия авторизации гостя выглядит так:
1. Гостевое приложение передает на контроллер «серверный» ключ (так же как и в первом прототипе его хеш) и
2. Сервер точно так же его проверяет, но вместо команды открытия отправляет хеш приватного ключа
3. Контроллер сравнивает хеш приватного ключа, полученный от сервера с рассчитанным самостоятельно и если оно совпало, замок открывается.
Таким образом на сервере не храниться ничего, что могло бы открыть замок. Сгенерировать нужный хеш, не зная цифрового ключа, не получится.
Тот же Bluetooth используется и для «хозяйского» доступа без Интернета. Контроллер принимает через него команды, отвечает одноразовым кодом, который нужно подписать правильным цифровым ключом в течение 2-х секунд.
Через него же хочу сделать настройку основных параметров контроллера. Хозяин нажимает на специальную кнопку контроллера, после чего он начинает принимать расширенный набор команд, такие как установка ID замка, секретных ключей, адреса-порта сервера, параметры сети и т.п. Но в Адруине кончилась память и скетч не влезает.
В завершении короткая демонстрация работы.

Комментарии (21)


  1. AotD
    13.01.2016 14:11

    В качестве альтернативы Cisa'овскому замку я рассматривал PERCo серию LB
    https://www.perco.ru/products/zamki/lb72.1/


    1. kuld
      13.01.2016 14:21

      Слабоват он для наших дверей-монстров.

      для запирания легких и средних дверей толщиной от 38 мм до 50 мм.

      В квартиры у нас устанавливают в основном тяжелые бронированные двери, от 55 до 70 мм.
      Понятно, что с цилиндровым замком проще, цилиндр и накладки приобретаются отдельно, но все таки, 1 ригель, нет вертикальных тяг. Годится как замок дополнительный, типа того, что у меня в прототипе.


      1. AotD
        13.01.2016 14:39
        +1

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


    1. stigory
      15.01.2016 06:56

      Еще одна альтернатива: http://www.techlaboratory.ru/product/soca-sl-500/
      Не помню модель своего замка (давно дело было), но выбирал что-то похожее. Вскрыть дверь, физически сломав замок, невозможно. Устанавливается в штатные размеры. Один, но большой недостаток — требует бесперебойного питания. Иначе по правилам пожарной безопасности, сами понимаете, замком он быть перестает.
      Управляет замком простейший контроллер Z-5R от IronLogic'a. Считыватель бесконтактный антивандальный от PERCo. А вот к контроллеру замка цеплял уже ПЛК и веселился.
      Лет семь на эту систему нареканий не было. Потом квартиру продал.


  1. kuld
    13.01.2016 14:49

    Это да. Плюс, если я правильно понял, PERCo — это отечественное производство, что тоже хорошо.
    Я все это с сервером, контроллером и клиентом начал городить именно для того, что бы не привязываться к какой-то конкретной модели замка. Например, для установки вне помещения потребуется морозоустойчивое и влагозащищенное исполнение и т.д. Нет возможности протянуть провод, можно вместо ethetnet-а собрать контроллер с wifi или gsm.
    За универсализм!


  1. alexpp
    13.01.2016 15:47

    Расскажите, а как работает система в случае пропадания элетричества?
    Если используете синезуб — то почему бы не сделать автоматическое подключение, как это сделано например в системах громкой связи в авто? Подошли к двери, дверь открылась. Спустя некоторое время — закрылась сама, ждет второй «ключ» — например жены.


    1. kuld
      13.01.2016 16:13

      Есть два типа электромеханических замков: нормально открытые (NO) и нормально закрытые (NC)
      На фотографиях NO, при отключении питания ригель прячется, дверь открыта. Есть точно такой же замок типа NC, при отключении питания ригель остается выдвинутым, дверь закрыта.
      Самый оптимальный вариант, это NC замок с цилиндром под ключ, типа такого
      image
      Ну или CISA за 500 евро, которую я хотел купить. При выключении питания дверь будет оставаться закрытой, а открыть ее можно обычным ключом.

      Bluetooth у меня сейчас в зачаточном состоянии, собран на HC-06. Сомневаюсь, что на нем такое можно сделать. Планирую дальше развивать в сторону BLE, с ним вроде можно кое-чего поинтересней сотворить.


      1. gorbln
        13.01.2016 21:55

        Если честно — то ацкая многофакторная авторизация с кучей ключей и защитой от кражи сервера (??? это как вообще) и цилиндрический цилиндровый механизм, вскрываемый профессионалом за одну минуту, а если повезёт — то бамп-ключом за 5-15 секунд(!) — не особо вяжутся.


        1. kuld
          13.01.2016 22:13
          +2

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


          1. foxmuldercp
            16.01.2016 11:51

            Фаервол на сервере или простейший фейл2бан Вам в помощь


            1. kuld
              16.01.2016 12:53

              В сервере (в смысле приложения) есть специальный контроль наиболее «активных» IP, Фиксируются бестолковые подключения и попытки угадать пароль. Как их банить пока не понятно. Допустим кто-то устроит имитацию атаки с IP адреса какого-нибудь сотового оператора. Если его автоматически забанить, вся сеть оператора лишится доступа. Надо что-то поинтеллектуальный делать, пока только черный/белый список приходит на ум.
              Кстати, сервер (в смысле оборудования) сейчас выглядит так:


              1. foxmuldercp
                17.01.2016 13:54
                -1

                Почитайте уже что такое fail2ban и не городите огород, всё давно придумано до нас


      1. BOOMik
        14.01.2016 20:23

        Получается в момент поиска жильца квартира закрыта только на данный, нормально открытый замок? Выключили электричество в доме, или в квартире (во многих же домах счетчики электрические с пробками стоят в подъезде) и дверь открыта? Подозрительное решение.
        Отлично бы подошел нормально закрытый замок, который изнутри просто ручкой открывается, даже если закрыт, тогда в случае пожара выйти можно без проблем, но вот конечно тогда не зайти в помещение, если нет электричества.
        Хотя можно же резервное питание сделать для обоих сценариев.
        Но свободно открытая дверь при отсутствии электричества — большая уязвимость системы.


        1. kuld
          14.01.2016 23:31
          +1

          Этот лежит у меня на столе, как демонстрационный экземпляр. Установлен NC и с цилиндровым механизмом.


  1. CRImier
    13.01.2016 16:04

    Я правильно понимаю, что Вы используете HC-05/6, который не будет работать с iдевайсами?


    1. kuld
      13.01.2016 16:14

      Сейчас да. Буду переделывать на другой чип BLE.


  1. gleb_l
    13.01.2016 17:26

    я экспериментировал вот с таким изделием — это полноценный ригельный замок с ходом ригелей 30 мм, контроллером с резервным питанием от аккумулятора и (опционально) GSM-модулем, через который можно настраивать и открывать-закрывать замок. По нынешнему курсу — 250 евро за все


    1. kuld
      13.01.2016 18:01

      На тему открытия по GSM каналу тоже думал. Но:
      1. Нужна сим-ка
      2. За СМС-ки надо платить
      3. Требования №7 и 8 из первой статьи не удовлетворяет

      «7. Гостевой ключ» срабатывает только в непосредственной близости от замка;
      «8. Гостевой ключ» ограничен по времени действия.


      1. gleb_l
        13.01.2016 23:04

        В данном разрезе у Меттэма интересна в первую очередь даже не электронная часть, а механическая. Это полноценный дверной замок, на который не страшно запереть входную дверь квартиры на беспокойном пространстве ex-USSR, в то время как замок на Вашей картинке — скорее офисного или внутриквартирного назначения.

        Можно взять только железо (в истинном, не электронном смысле) — там внутри стоит автомобильный активатор — соответственно, открывать-закрывать его мостом на реле или полевиках (в их оригинальном электронном блоке — полевики).

        Если же взять замок + электронный блок (а к нему придается корпус с аккумулятором автономной работы внутри плюс три keeloq-брелка), то со стороны Вашей системы можно управлять открытием замка через вход для кнопки открывания. Закрытие можно сделать ручное (с внутренней стороны замок имеет поворотную ручку), либо автоматическое через датчик закрытой двери, активировав соответствующий режим джампером.

        Вообще, это довольно интересная платформа — и сам замок и схемотехника/реализация спроектированы и сделаны качественно.

        Я разбирал механику и исследовал электронику + общался с разработчиком аппаратно-программной части насчет схемотехники отдельных узлов и нюансов алгоритма работы — везде очень профессионально. Потом поставил :)


  1. vvzvlad
    13.01.2016 20:23

    Так я и не понял, что это за замок.


  1. serafims
    14.01.2016 11:03

    Ваше решение весьма неплохо для гостиниц типа Omena Hotelli, где минимум персонала и нет приемной в обычном виде.