Провайдер в норме видит только мой публичный трафик после NAT. Можно допустить, что там тоже можно статистически нарыть немало интересного — но чувствительной информации без шифрования в интернет уходить не должно (по крайней мере, by-design). Информация, гуляющая между локальными интерфейсами маршрутизатора защищена гораздо хуже, а приватных данных содержит гораздо больше. Увы…
Давайте честно признаемся, что при существующем положении дел в государстве РФ — законом и договором с провайдером безопасность не (!) обеспечивается.
Ситуация была бы немного лучше, если бы роутер имел аппаратную кнопку «Удаленный сервис», после нажатия на которую в течение разумного промежутка времени (например, час) были бы доступны функции удаленного управления. По крайней мере, в таком случае бэкдор доступен не постоянно, и пользователь осознает, что дает доступ к своей внутренней сети неизвестному ему лично внешнему агенту.
С другой стороны, понятно что «аппаратная» кнопка на самом деле будет присоединена к ноге GPIO встроенной системы, и никаких гарантий что прошивка соблюдает протокол доступа только с разрешения пользователя — на самом деле нет. Если TP-Link свою прошивку сделает именно так (и даже сертифицирует у независимой третьей стороны) — как только пользователь даст доступ к своему оборудованию «специалисту провайдера» — те могут прошить внутрь устройства все что угодно, в том числе и отключить протокол «аппаратной» кнопки.
С третьей стороны, огромное количество пользователей не разбираются в ИТ, не думают о безопасности, и готовы дать любой доступ кому угодно — лишь бы на планшет загрузились картинки котиков.
У меня нет хорошего решения для этой задачи. :-( Но наличие бэкдора в устройствах «прямо с конвейера» — все-равно, печалит…
То есть, поставив себе оборудование в аренду от провайдера — мы получаем не стоковый роутер, а черный ящик с недокументированными функциями и возможностью удаленного управления не-пойми кем ?! Аргумент, что это только поддержка провайдера — не канает: кто сидит в поддержке провайдеров, как их туда набирают, и за какие копейки они сольют любому желающему инфу и пароли доступа — все более-менее догадываются. :-(
В любом случае, спасибо за предупреждение!
Я подозревал что-то в таком духе, когда купил у провайдера приставку для IP-TV, и она при первом включении полезла (tcpdump!) за каким-то обновлениями на провайдерский сервер. После этого, приставка была выселена в отдельный порт на роутере, и средствами iptables напрочь лишена возможности общаться с внутренней домашней сетью. Потому что, мне вот только устройств с аппаратным бэкдором в домашней сети не хватало для полного счастья!..
P.S. Не являются ли такие функции предметом статьи УК РФ о вредоносном программном обеспечении? Особенно, если клиент роутер не взял в аренду а выкупил — а об «особенностях» прошивки роутера ему провайдер рассказать заб(ы|и)л?
Я на C++ кодил еще когда Java толком никому и известна-то не была. :-) Но вот реально так получается, что большие проекты мы делаем на Java, а прошивки для ICP-DAS на C++ (кстати, Borland C++ 3.1 в DosBox — раритет!). А вычислительную часть для задачи оптимизации — на C++v11. Где-то потихоньку на более новые стандарты C++ переползаем. Где-то на Java — все-таки разработчиков в стране дефицит, иметь возможность ввести человека в проект без стреляния себе в ногу разными способами — для бизнеса тоже ценность…
В больших проектах мы часто пишем Collection вместо указания конкретного типа (Java, конечно — но смысл будет тот же). И, поскольку в этой точке уже нет понимания что именно подадут на вход — уже надо или итератор или range-for. А потом уже как карты лягут: из тестов туда пойдет ArrayList. В продакшене какая-то backed-by-database коллекция. Потом еще что-то. Но опять, дело-то в том, что мы пишем нечто сейчас, стараясь не делать предположений о том, как его захочется использовать через пять лет. Но хотим чтобы работало — поэтому и извращаемся с абстрактными типами данных и прочей мощью ООП. В разработке для МК нет смысла это делать: задача известна сейчас, и при минимальном везении через пять лет будет ровно той же! И если динамическое распределение памяти запрещено (а часто это так!) — то вопрос в объявлении массива, или std::array как тонкой обертки над ним становится вопросом вкуса и привычек. Мне кажется (я могу ошибаться!) что большАя часть доработок C++ последних лет сделана в попытке «закопать» адресную арифметику и аллокацию/деаллокацию ресурсов, чтобы можно было (придерживаясь определенных правил) жить как в Java: завел себе объект (даже new писать не надо), потом бросил (или кому-то передал) не думая. В Java GC за тебя мусор убирает — тут умные указатели. Но в специфике МК — ни то ни другое не нужно, IMHO.
Вот из-за таких примерно комментариев в научных журналах избегают публиковать отрицательные результаты. Которые для прогресса тоже важны. Вообще, начались рассуждения о виновности — конструктивного решения уже можно, как правило, и не ждать… :-(
:-) Ну или еще бывает, что привыкший к «большой» системе разработчик искренне считает, что если через Serial сообщение о достижении контрольной точки не пришло — значит ошибка где-то до этого места. И без заглядывания в черный ящик UART попробуй объясни, почему это не так! На большой-то системе абстракция не течет: что в лог записал, то потом в файле (даже в случае крэша — библиотека и ОС же заботятся...) и увидел!
+1 за невозможность программировать МК без понимания железа. Или этого программиста нужно абстракциями так обложить, что он вздохнуть не сможет (не то что полезную работу делать). Или он без задней мысли так использует достаточно мощные абстракции, что вызовет глюки или зависание софта. И без шансов понять, что именно он такое сделал и как это можно было бы починить! :-)
В больших (не МК) проектах смысл есть. Если алгоритм обработки является первоклассным объектом (той же лямбдой), и спускается откуда-то из-за пределов собственно функции, которая обрабатывает данные, то:
— До некоторой степени облегчается построение сложных обработок, т.к. используется комбинация лямбд, а не постоянные изменения кода внутри цикла.
— По мере жизненного цикла проекта проще прикрутить кеширование результатов расчетов (буде таковое потребуется), или, например, ограничить одновременно выполняющееся количество «тяжелых» вычислений.
— Но самое главное — на энтерпрайзе всегда есть шанс что придется систему горизонтально масштабировать. Сегодня тебе на вход подают 10к данных, а через пять лет — 1Тб. При небольшом везении, код с лямбдами путем применения хитрой библиотеки сам распараллелит обработку на несколько ядер/GPU/кластеров, раздав куски данных и копии лямбды каждому worker-у.
А вот внутри МК таких задач не наблюдается. Там обычно задача очень конкретная — и один раз хорошо написанная прошивка может годами работать без всякого развития и изменения. С третьей стороны — бывают и большие проекты под МК (а-ля управление 3Д-принтерами). Но даже там сейчас народ немного переосмысливает ситуацию: на МК оставляют только низкоуровневое дрыгание ногами, а на микрокомпьютер с Linux — высокоуровневые расчеты и логику. Это проект Klipper — я за ним последнее время все больше наблюдаю.
Пожалуй, очень важная (и одновременно — редко встречающаяся) категория статей — рассказывающая о том, что не заработало. Обычно всем больше нравится рисовать истории успеха — и не только в программировании, к сожалению. Думаю, что стоит плюсовать автора!
Поддержу еще несколько технических моментов:
— Активное использование шаблонов и boost в малых микроконтроллерных проектах, скорее всего, не очень оправдано. По ощущениям — высоко-уровневые абстракции (вместо цикла по массиву делаем коллекцию и обрабатываем ее модными лямбдами) не уменьшают сложность разработки. И про простыни сообщений об ошибках где что не так с шаблоном — автор написал совершенно верно! В скобках замечаю: в больших проектах на Java, наоборот, без объектных фишек жить было бы тяжко. Значит где-то проходит водораздел, и должны быть признаки, по которым можно определять, где ООП дает потенциальные выгоды — а где не дает.
— Чем ближе к аппаратуре работаешь — тем сложнее сделать эффективные абстракции, которые бы при этом не текли. Очень многое в ООП заложено на то, что у объекта есть некое состояние, которое может изменяться не иначе, как вызовом методов этого объекта. В случае с МК — это не всегда (и это мягко сказано) так. Поскольку большая часть объектов отражает свойства реального узла контроллера — вдруг оказывается, что либо состояние объекта меняется без вызова его методов, либо состояние программного объекта не адекватно состоянию реальной кучки транзисторов внутри микросхемы.
— Вместе с тем, оказывается очень (!) продуктивным отлаживать высокоуровневые алгоритмы не внутри микроконтроллера — а на хост-системе (например на Linux), имитируя поступление данных из заранее подготовленных файлов. Поэтому некоторый (тонкий!) слой абстракции в средние-большие проекты на МК вводить все-таки стоит. По крайней мере, становится гораздо легче разбираться — то ли проблема с аппаратной частью МК (или — что чаще: нашим неправильным пониманием, как она ждет чтобы мы с ней работали), то ли проблема уровнем выше в алгоритмах опроса/управления.
Еще добавлю в режиме «managerial hat on»: SCRUM/AGILE — не самая удобная или комфортная методология для менеджера. Потому что где-то там во внешнем мире существует понятие сделки. То есть другие люди хотят от вас понимания: какой результат будет достигнут, в какие сроки, и за какие ресурсы?
Хотя бы просто для того, чтобы оценить альтернативы.
И вы, как менеджер, обязаны эту оценку дать, и за нее (плюс-минус) нести ответственность. А протранслировать эту ответственность на разработчиков (пусть подпишутся под графиком, да и дело с концом!) вы в рамках Agile не можете. И это неприятно. Но два момента:
Во-первых (и об этом неоднократно упомянуто в статье) — в условиях неопределенности жесткие методологии работают еще хуже. Упрощается только процесс поиска виновных — но легче от этого обычно не становится. И поверьте: если проект израсходовал первоначальный бюджет, но выдал в продакшн 80% функционала (и его не закрыли на итерациях раньше) — значит уже есть реальная выгода от внедрения и можно договориться о выделении дополнительных ресурсов. Такие переговоры — малоприятное занятие, но жить можно. Когда тебя ведут расстреливать за расходование бюджета проекта БЕЗ осязаемых результатов — это куда более печальная история. :-)
Во-вторых — повышенная зарплата менеджерам платится не просто так. Если ответственность, прилагаемая к менеджерской шапке не нравится — правильнее от должности отказаться и развивать карьеру в другом направлении. Все люди разные, и кому-то это может подойти больше, чем условному вам.
Сам по себе микросервис не решает проблему сложности. Потому что — ну в самом деле, что такое микросервис: ну вытащили мы некий код в отдельное адресное пространство. Ну перестали передавать этому куску кода параметры через стек и регистры, а стали сериализовать и толкать через REST API, например. Тут сложность скорее увеличилась, а не наоборот.
Но если сервис выделен правильно, и архитектура системы изначально такая, что это (правильное!) выделение возможно — тогда вдруг происходит чудо: пользователи сервиса видят красивое и прозрачное API, и сложность выделенного сервиса перестает влиять на сложность остального приложения.
Приведу пример: при взаимодействии с промышленным оборудованием, оно обычно подключается через последовательный порт. И там все более-менее просто. Но в какой-то момент мы начинаем подключать его через TCP/IP — и (почему-то!) не замечаем, что теперь у нас задействовался TCP, congestion control, весь стек сетевых драйверов, NAT и прочие прелести ядра Linux. Поскольку это все там изолировано, и оттуда торчит только fd (file descriptor), единый как для сокета, так и для последовательного порта — сложность нашего куска системы практически не изменилась.
Мне кажется, что предупреждения в фейсбуке связаны с тем, что иногда встречается без(д)умное деление системы на микросервисы. При этом они не оказываются логически законченными и изолированными — и мы получаем тот же кошмар масштаба, что и в монолитном приложении, но приправленный еще и чисто специфическими возможными проблемами в контейнеризации, service-discovery, мониторинге и т.п.
И это еще мы не упоминаем о том, что в модели COCOMO оценка стоимости программного обеспечения является экспоненциальной (что гарантированно хуже любого полинома!). К счастью, с относительно небольшим коэффициентом в показателе экспоненты. Но общий принцип остается тем же: если можно разработать три продукта по 100k строк вместо монолита за 300k строк — это немедленно следует ровно так и делать. А вот уж как обеспечить возможность деления продукта, чтобы команды могли разрабатывать, тестировать и деплоить свои компоненты независимо — это и есть главная головная боль менеджера проектов и архитектора. Микросервисы, ООП, interface-based programming, плагины, embedded scripting и прочее в помощь…
Нет, ну можно и без ORM жить… Но (говорю за Hibernate), когда ORM за тебя следит за изменением объектов текущей сессии и генерирует апдейты в базу — это удобно. Когда оно для тебя само делает Optimistic Locking — тоже хорошо. Когда Lazy Fetch можно аннотациями прописать — это тоже время экономит. Конечно, хотелось бы еще лучше (в пределе — одна волшебная кнопка «Сделать хорошо» — и все). Но это ж не повод отказываться от того неидеально хорошего, что есть!..
Тут есть тонкая разница между «проектом» и «проектом». Есть проекты, целью которых является нечто имеющее отношение к программированию: новый продукт, новые фичи, пилот новой технологии, и т.д. И руководя этим проектом, ПМ-у будет очень трудно без знания специфики отрасли. Тут нужен «программистский ПМ».
Есть проекты уровнем выше, когда задачи ставятся уже на уровне целого бизнеса. Этот ПМ будет руководить людьми, которые будут руководить людьми, которые будут решать (в том числе) задачи связанные с программированием. Ему уже можно и без особых знаний специфики отрасли жить.
Вообще, многие авторы отмечают, что чем ниже по управленческой лестнице, тем более важны прикладные навыки и особенности отрасли. Чем выше — тем более важно уметь управлять проектами, временем и «ресурсами вообще», и тем больше там управления людьми, чем отраслевых особенностей.
Я не думаю, что это злой умысел со стороны 1С. Вон тут была статья, как они на новый стандарт C++ ядро переводили…
С другой стороны, конечно, конфигурация 1С стала сама по себе отдельной системой. И нестабильность процесса ее разработки и отсутствие хороших и стабильных guidelines как ее писать — доставляет. Но 1С, кажется, больше заинтересована в растягивании своего продукта на максимальное число ниш, чем в стабильном качестве или разделении монолитной конфы на более-менее стабильные модули.
Скажу крамольную, быть может, мысль — но нужно брать пример с летчиков-испытателей. Каковые, после окончания своей профессиональной школы (ШЛИ), обязаны после 15-минутного инструктажа уметь взлететь, отработать программу и благополучно приземлиться на любом (в разумных пределах) летательном аппарате. Если не брать декларативные (a-la Prolog) и функциональные языки, то все остальное в ИТ — плюс-минус одно и то же. У меня не возникает внутреннего отторжения, когда для микроконтроллера я пишу на C со вставками на Asm, для статистических расчетов использую R, модуль WMS дописываю на Java, а расчет НДС смотрю в конфигураторе эски. С одной стороны — каждой задаче свой инструмент, а с другой — заложишься на одну технологию, а она возьми да загнись лет через пять… Лучше быть разным. :-)
Очень доходчиво объяснено, что 1С — это хорошая система для задач автоматизации учета (и особенно, посмертного, завязанного на документы учета). Со своей терминологией, стандартными объектами и экосистемой. И что ее программирование является своей отдельной отраслью знаний. Так же как embedded programming, или kernel programming, или web, или что угодно еще.
Ситуация была бы немного лучше, если бы роутер имел аппаратную кнопку «Удаленный сервис», после нажатия на которую в течение разумного промежутка времени (например, час) были бы доступны функции удаленного управления. По крайней мере, в таком случае бэкдор доступен не постоянно, и пользователь осознает, что дает доступ к своей внутренней сети неизвестному ему лично внешнему агенту.
С другой стороны, понятно что «аппаратная» кнопка на самом деле будет присоединена к ноге GPIO встроенной системы, и никаких гарантий что прошивка соблюдает протокол доступа только с разрешения пользователя — на самом деле нет. Если TP-Link свою прошивку сделает именно так (и даже сертифицирует у независимой третьей стороны) — как только пользователь даст доступ к своему оборудованию «специалисту провайдера» — те могут прошить внутрь устройства все что угодно, в том числе и отключить протокол «аппаратной» кнопки.
С третьей стороны, огромное количество пользователей не разбираются в ИТ, не думают о безопасности, и готовы дать любой доступ кому угодно — лишь бы на планшет загрузились картинки котиков.
У меня нет хорошего решения для этой задачи. :-( Но наличие бэкдора в устройствах «прямо с конвейера» — все-равно, печалит…
В любом случае, спасибо за предупреждение!
Я подозревал что-то в таком духе, когда купил у провайдера приставку для IP-TV, и она при первом включении полезла (tcpdump!) за каким-то обновлениями на провайдерский сервер. После этого, приставка была выселена в отдельный порт на роутере, и средствами iptables напрочь лишена возможности общаться с внутренней домашней сетью. Потому что, мне вот только устройств с аппаратным бэкдором в домашней сети не хватало для полного счастья!..
P.S. Не являются ли такие функции предметом статьи УК РФ о вредоносном программном обеспечении? Особенно, если клиент роутер не взял в аренду а выкупил — а об «особенностях» прошивки роутера ему провайдер рассказать заб(ы|и)л?
Но в целом, идея понятна. Разные языки, разные подходы, разные области применения.
— До некоторой степени облегчается построение сложных обработок, т.к. используется комбинация лямбд, а не постоянные изменения кода внутри цикла.
— По мере жизненного цикла проекта проще прикрутить кеширование результатов расчетов (буде таковое потребуется), или, например, ограничить одновременно выполняющееся количество «тяжелых» вычислений.
— Но самое главное — на энтерпрайзе всегда есть шанс что придется систему горизонтально масштабировать. Сегодня тебе на вход подают 10к данных, а через пять лет — 1Тб. При небольшом везении, код с лямбдами путем применения хитрой библиотеки сам распараллелит обработку на несколько ядер/GPU/кластеров, раздав куски данных и копии лямбды каждому worker-у.
А вот внутри МК таких задач не наблюдается. Там обычно задача очень конкретная — и один раз хорошо написанная прошивка может годами работать без всякого развития и изменения. С третьей стороны — бывают и большие проекты под МК (а-ля управление 3Д-принтерами). Но даже там сейчас народ немного переосмысливает ситуацию: на МК оставляют только низкоуровневое дрыгание ногами, а на микрокомпьютер с Linux — высокоуровневые расчеты и логику. Это проект Klipper — я за ним последнее время все больше наблюдаю.
Поддержу еще несколько технических моментов:
— Активное использование шаблонов и boost в малых микроконтроллерных проектах, скорее всего, не очень оправдано. По ощущениям — высоко-уровневые абстракции (вместо цикла по массиву делаем коллекцию и обрабатываем ее модными лямбдами) не уменьшают сложность разработки. И про простыни сообщений об ошибках где что не так с шаблоном — автор написал совершенно верно! В скобках замечаю: в больших проектах на Java, наоборот, без объектных фишек жить было бы тяжко. Значит где-то проходит водораздел, и должны быть признаки, по которым можно определять, где ООП дает потенциальные выгоды — а где не дает.
— Чем ближе к аппаратуре работаешь — тем сложнее сделать эффективные абстракции, которые бы при этом не текли. Очень многое в ООП заложено на то, что у объекта есть некое состояние, которое может изменяться не иначе, как вызовом методов этого объекта. В случае с МК — это не всегда (и это мягко сказано) так. Поскольку большая часть объектов отражает свойства реального узла контроллера — вдруг оказывается, что либо состояние объекта меняется без вызова его методов, либо состояние программного объекта не адекватно состоянию реальной кучки транзисторов внутри микросхемы.
— Вместе с тем, оказывается очень (!) продуктивным отлаживать высокоуровневые алгоритмы не внутри микроконтроллера — а на хост-системе (например на Linux), имитируя поступление данных из заранее подготовленных файлов. Поэтому некоторый (тонкий!) слой абстракции в средние-большие проекты на МК вводить все-таки стоит. По крайней мере, становится гораздо легче разбираться — то ли проблема с аппаратной частью МК (или — что чаще: нашим неправильным пониманием, как она ждет чтобы мы с ней работали), то ли проблема уровнем выше в алгоритмах опроса/управления.
Хотя бы просто для того, чтобы оценить альтернативы.
И вы, как менеджер, обязаны эту оценку дать, и за нее (плюс-минус) нести ответственность. А протранслировать эту ответственность на разработчиков (пусть подпишутся под графиком, да и дело с концом!) вы в рамках Agile не можете. И это неприятно. Но два момента:
Во-первых (и об этом неоднократно упомянуто в статье) — в условиях неопределенности жесткие методологии работают еще хуже. Упрощается только процесс поиска виновных — но легче от этого обычно не становится. И поверьте: если проект израсходовал первоначальный бюджет, но выдал в продакшн 80% функционала (и его не закрыли на итерациях раньше) — значит уже есть реальная выгода от внедрения и можно договориться о выделении дополнительных ресурсов. Такие переговоры — малоприятное занятие, но жить можно. Когда тебя ведут расстреливать за расходование бюджета проекта БЕЗ осязаемых результатов — это куда более печальная история. :-)
Во-вторых — повышенная зарплата менеджерам платится не просто так. Если ответственность, прилагаемая к менеджерской шапке не нравится — правильнее от должности отказаться и развивать карьеру в другом направлении. Все люди разные, и кому-то это может подойти больше, чем условному вам.
Сам по себе микросервис не решает проблему сложности. Потому что — ну в самом деле, что такое микросервис: ну вытащили мы некий код в отдельное адресное пространство. Ну перестали передавать этому куску кода параметры через стек и регистры, а стали сериализовать и толкать через REST API, например. Тут сложность скорее увеличилась, а не наоборот.
Но если сервис выделен правильно, и архитектура системы изначально такая, что это (правильное!) выделение возможно — тогда вдруг происходит чудо: пользователи сервиса видят красивое и прозрачное API, и сложность выделенного сервиса перестает влиять на сложность остального приложения.
Приведу пример: при взаимодействии с промышленным оборудованием, оно обычно подключается через последовательный порт. И там все более-менее просто. Но в какой-то момент мы начинаем подключать его через TCP/IP — и (почему-то!) не замечаем, что теперь у нас задействовался TCP, congestion control, весь стек сетевых драйверов, NAT и прочие прелести ядра Linux. Поскольку это все там изолировано, и оттуда торчит только fd (file descriptor), единый как для сокета, так и для последовательного порта — сложность нашего куска системы практически не изменилась.
Мне кажется, что предупреждения в фейсбуке связаны с тем, что иногда встречается без(д)умное деление системы на микросервисы. При этом они не оказываются логически законченными и изолированными — и мы получаем тот же кошмар масштаба, что и в монолитном приложении, но приправленный еще и чисто специфическими возможными проблемами в контейнеризации, service-discovery, мониторинге и т.п.
Есть проекты уровнем выше, когда задачи ставятся уже на уровне целого бизнеса. Этот ПМ будет руководить людьми, которые будут руководить людьми, которые будут решать (в том числе) задачи связанные с программированием. Ему уже можно и без особых знаний специфики отрасли жить.
Вообще, многие авторы отмечают, что чем ниже по управленческой лестнице, тем более важны прикладные навыки и особенности отрасли. Чем выше — тем более важно уметь управлять проектами, временем и «ресурсами вообще», и тем больше там управления людьми, чем отраслевых особенностей.
С другой стороны, конечно, конфигурация 1С стала сама по себе отдельной системой. И нестабильность процесса ее разработки и отсутствие хороших и стабильных guidelines как ее писать — доставляет. Но 1С, кажется, больше заинтересована в растягивании своего продукта на максимальное число ниш, чем в стабильном качестве или разделении монолитной конфы на более-менее стабильные модули.