Должно ли мое устройство IoT опрашивать по HTTP или прослушивать по TCP?

Я создаю систему IoT Device + Server, используя .NET Micro Framework и ASP.NET WebAPI (вероятно, в Azure).

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

Я беспокоюсь о наилучшем балансе между безопасностью устройства и нагрузкой на сервер. Кроме того, должна быть относительно небольшая задержка между сервером, которому необходимо выдать команду, и устройством, выполняющим ее; порядка нескольких секунд.

Как я вижу, мои варианты:

  • При подключении к Интернету устройство устанавливает постоянное TCP-соединение с сервером, которое затем используется как для опроса, так и для получения команд.

  • Устройство прослушивает порт (например, HttpListener) для входящих команд, одновременно обновляя сервер с помощью частых HTTP-запросов.

  • Устройство всегда опрашивает сервер только с HTTP-запросами. Сервер использует ответ для передачи команд устройству.

Второй вариант кажется наименее безопасным, поскольку на устройстве будут открыты входящие порты. Первый вариант кажется наиболее сложным для надежной реализации, так как он требует низкоуровневого программирования сокетов. Третий вариант кажется простым и безопасным, но из-за требований к задержке устройству нужно будет опрашивать каждые несколько секунд. Это влияет на масштабируемость системы.

Итак, с какой частотой опрос HTTP создает больше накладных расходов, чем просто постоянное поддержание TCP-соединения открытым? 5 с? 3 секунды? 1с? Или я преувеличиваю накладные расходы на поддержание открытого TCP-соединения в ASP.NET? Или есть совершенно другой способ, которым это может быть реализовано?

Спасибо.


person mistakenot    schedule 05.07.2015    source источник
comment
Открытый входящий порт сам по себе не более и не менее безопасен, чем когда он сам по себе закрыт.   -  person PeeHaa    schedule 05.07.2015
comment
Я не эксперт по безопасности встроенных устройств, но я помню, как читал статью, в которой говорилось, что наличие открытых входящих портов увеличивает вашу уязвимость, давая злоумышленникам еще один вектор для доступа к устройству, особенно если устройство использует устаревшие / неподдерживаемые сетевые драйверы. .   -  person mistakenot    schedule 05.07.2015
comment
Я никогда не говорил, что это не может быть проблемой. Я только что сказал, что открытие порта не будет волшебным образом небезопасным само по себе. Даже если это будет небезопасно, это не потому, что порт открыт, а потому, что какой-то сервис прослушивает порт. Открытый порт сам по себе ничего сделать не может. В тот момент, когда вы осознаете этот факт, вы на полпути к выяснению того, является ли он менее безопасным для вашей ситуации.   -  person PeeHaa    schedule 05.07.2015
comment
Я понимаю, что фактическая служба, прослушивающая порт, будет иметь большее влияние, чем тот факт, что сам порт открыт. Я собираюсь использовать сертификаты X509/SSL и т. д. для обеспечения подлинности. Меня беспокоит только необнаруженная ошибка где-то в сетевом стеке устройства, которая может его скомпрометировать. Предположительно, подобные уязвимости было бы легче использовать удаленно, если бы на устройстве были прослушиваемые порты.   -  person mistakenot    schedule 05.07.2015


Ответы (3)


Итак, с какой частотой опрос HTTP создает больше накладных расходов, чем просто постоянное поддержание TCP-соединения открытым? 5 с? 3 секунды? 1с?

Ничего не нужно делать, чтобы оставить TCP-соединение открытым. Единственное, что вам может понадобиться, это использовать TCP keep-alive (который не имеет ничего общего с HTTP keep-alive!), если вы хотите, чтобы соединение оставалось бездействующим (т. е. без отправки данных) в течение длительного времени.

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

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

WebSockets — это нечто среднее: вы делаете HTTP-запрос, а затем обновляете HTTP до WebSocket. Таким образом, начальные накладные расходы такие же большие, как и для HTTP, но для следующих сообщений накладные расходы не намного выше, чем для TCP. И вы также можете использовать WebSockets с HTTPS (т.е. wss:// вместо ws://). Он проходит через большинство простых брандмауэров и прокси-серверов, но у брандмауэров с более глубокими проверками могут возникнуть проблемы с ним.

Настройка прослушивателя TCP будет проблемой, если ваше устройство IoT находится за каким-либо маршрутизатором NAT, то есть обычная настройка внутри частных сетей или сетей SoHo. Чтобы получить доступ к устройству, необходимо открыть туннель на маршрутизаторе извне в сеть либо путем администрирования маршрутизатора вручную, либо с помощью UPnP (который часто отключается из соображений безопасности). Таким образом, вы создадите слишком много проблем для обычного пользователя.

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

Что касается ресурсов на стороне сервера: каждый HTTP-запрос на опрос может использовать новое TCP-соединение, но вы также можете повторно использовать существующее. В этом случае вы можете выбирать между большими накладными расходами и задержкой на стороне клиента (новое TCP-соединение для каждого запроса), для которой требуется мало ресурсов на стороне сервера, и меньшими накладными расходами и задержкой на стороне клиента, для которой требуется больше ресурсов на стороне сервера (несколько HTTP-запросы на TCP-соединение). С WebSockets и простым TCP-соединением вам всегда нужно больше ресурсов на стороне сервера, если только ваш клиент не будет автоматически восстанавливать соединение при потере соединения.

person Steffen Ullrich    schedule 05.07.2015
comment
Я не осознавал проблем, которые может вызвать прослушиватель TCP с брандмауэрами, сетями и т. д. Спасибо, что исключили этот вариант. Я думаю, что запрос на поддержку активности или SignalR может быть решением. - person mistakenot; 06.07.2015

В наши дни вы должны использовать специальный протокол связи IOT через TLS 2.0 для безопасных легких соединений. Например, AWS использует MQTT http://mqtt.org/, а Azure использует AMQP https://www.amqp.org/

Идея состоит в том, что вы получаете брокера, к которому можно безопасно подключиться, а затем используете протокол обмена сообщениями с темой для маршрутизации сообщений на соответствующие устройства. Кроме того, IBM уже давно использует MQTT, и теперь маршрутизаторы обычно поставляются с открытым портом 8883, который представляет собой MQTT через TLS.

Удачи!

person Chris Lucian    schedule 01.05.2017

Просто используйте SignalR для подключения клиента и сервера. Это обеспечивает минимальную задержку без опроса. API очень прост в использовании.

Физически это работает через веб-сокеты, которые масштабируются до большого количества одновременных подключений. Если вам не нужно более 100 КБ на сервер Windows, это не будет проблемой.

person usr    schedule 05.07.2015
comment
SignalR был бы хорошим решением, я поищу работающий клиент .NET MF. - person mistakenot; 06.07.2015