Михаил Королёв

Зачем мы делаем российский банкомат

И почему это важно

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

Замечу, что рассказывать я буду в основном про софтовую часть, так как это то, чем непосредственно занимается наша команда. Железяки и вопрос их производства оставим тем, кто отвечает за них.

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

Что представляет из себя банкомат?

Почему-то многие люди считают, что банкомат — это какое-то непонятное устройство, которое управляется специальными микроконтроллерами, а те, кто разбирается в разработке еще может заметить, что там какой-то странный интерфейс, в котором, по ощущениям, просто переключаются зашакаленные jpg картинки (на самом деле, в контексте картинок сейчас практически так оно и есть 😄)

На самом же деле все гораздо проще. Практически все банкоматы, которые сейчас существуют (по крайней мере в РФ) — это обычный персональный компьютер на архитектуре Intel x86, на котором запущена всеми любимая (или не очень) винда. Никаких хитрых операционных систем или процессоров, обычный компьютер, на котором вы можете играть в любимые игры.

Вы можете спросить, а как же тогда он принимает деньги, а ещё я там карточку в него вставляю, наверное, с этим есть какие-то хитрости? И да и нет. По сути, это все отдельные и независимые модули, которые подключаются к основному системнику по USB или COM порту. За счет этого, банкомат представляет из себя конструктор, в который можно накидать нужные модули с различными характеристиками или функциональностью, которая необходима заказчику.

Внутрянка банкомата GRG H68VL, на котором наш софт тоже должен был работать.

Хороший XFS

XFS — это протокол, который сформировала Microsoft в партнерстве с производителями банкоматов и остального финансового оборудования. Этот протокол как раз позволял решить большую проблему, которая сильно тормозила развитие рынка устройств самообслуживания. Представим, что вы банк, и используете какое-то управляющее ПО (программное обеспечение), на котором реализованы все нужные вам операции внесения/снятия денег, и которое как-то интегрировано с вашими АБС (автоматизированными банковскими системами).

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

Плохой NDC

NDC — NCR Direct Connect — протокол взаимодействия банкомата (клиента) и хоста (сервера). Он отвечает за управление состоянием банкомата со стороны сервера, через него на клиент приходят команды, какой экран необходимо открыть, какие данные необходимо запросить от клиента, или как необходимо провзаимодействовать с железками.

Долбанные стейты, как же с ними больно...

Этот протокол был разработан одним из крупнейших мировых разработчиков и поставщиков банкоматов и ПО для них — NCR, и по сути стал стандартом для всех.
Сначала разработчикам банковских АБС пришлось его реализовать, чтобы у банков появилась возможность использовать банкоматы NCR, а затем и другим разработчикам ПО для банкоматов пришлось его реализовывать, поскольку банки уже используют этот протокол, и не горят желанием от него отказываться.

На самом деле, сейчас, как правило, он реализован только как часть карточного процессинга, и закрывает только часть функциональности работы с картами и наличными. Работу же с остальными банковскими продуктами реализовывает кто во что горазд.

Но в силу того, что и сама спецификация крайне сложная, сильно устаревшая, да и еще слабо подходящая под современные реалии требований бизнеса, никто (да, даже сами NCR) не работает в полном соответствии с этой спецификацией, и у всех реализована или только часть, или добавлены точки расширения, которые позволяют обойти часть логики.

See table note, в котором ссылка на другой table note, в котором ссылка на другой мануал с другим table note... И еще повезет, если они будут просто дополнять друг-друга, а не противоречить :(

Стейты — наверное, самая сложная и противная часть этого протокола. Их можно представить как «экраны» или «шаги», по которым может ходить банкомат для выполнения различных операций. Есть много типов этих стейтов, которые говорят банкомату, что надо сделать, но из основных можно выделить стейты с экранными данными. Они представляют из себя картинку (да, да, прям ссылку на jpg картинку, которая хранится в файловой системе банкомата), которую необходимо показать, и позиции с текстом, которые надо нарисовать поверх этой картинки.

Чудесные jpg. Джонни, они на деревьях

Некоторые накручивают поверх этого еще html, который может добавить хоть какую-то динамику и анимации к различным действиям, или хоть чуть-чуть расширить возможности банкомата, отвязавшись от 8 кнопочек по бокам экрана банкомата (да, эти 8 кнопочек плотно прибиты внутри спецификации NDC, и даже на сенсорных экранах происходит «эмуляция» нажатия этих физических кнопок)

Чудесные FDK (те самые 8 кнопочек)

Злой Windows

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

XFS — про него я уже упоминал. Поскольку этот протокол является частью винды, и многие производители железа как правило реализовывают только его, то остается или просить производителей сделать драйвера под Linux, или заниматься реверс-инженерингом и пытаться понять, какие байтики уходят в железку, чтобы потом повторить их отправку.

Старый софт. Банкоматы — это очень старый класс устройств, которому уже больше 60 лет, поэтому в этой сфере уже собралось достаточно наследия, от которого не так-то легко отказаться, и в изменение которого банки не готовы вкладываться, ведь оно и так работает. Поэтому на рынке существует множество софта, которому уже больше 20 лет, и который собрал большое число технических решений за эти годы, которые сильно привязали это ПО к винде, и потребуют глобального переписывания, чтобы появилась возможность переноса на Linux.

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

В этот момент можно задать вопрос, а если всех все устраивает — то надо ли вообще отказываться от винды? И ответ тут только один — зависит. Если банк готов платить за лицензии винды, антивирусов (или в контексте текущей ситуации в России — сидеть на ОС без поддержки и патчей безопасности), и при этом работа текущего софта его целиком устраивает — то естественно нет смысла ничего менять (но даже в этом случае стоит об этом задуматься).

И вот мы добрались до основной статьи

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

Поэтому, мы сформировали следующие требования, которым должен был соответствовать наш софт:

  1. Работа на Linux
  2. Возможность работы не только на x86, а так-же на других архитектурах процессоров, например Эльбрус
  3. Возможность общения с хостом как по NDC, так и по любым другим протоколам, в том числе специфичным для конкретного банка
  4. Прямая работа с оборудованием в обход XFS
  5. Большая гибкость решения, чтобы банки могли самостоятельно дорабатывать наше решение
  6. Использование веб технологий для отрисовки UI

Linux

Наверное, это самое большое и важное отличие, которое тянет за собой и плюсы, и минусы.
Из плюсов можно выделить:

  • возможность более глубокого управления безопасностью ОС с помощью встроенных средств;
  • возможность работы на Эльбрусе;
  • возможность покупать поддержку от производителей российских дистрибутивов.

Минусы однако тоже есть:

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

Работа на Эльбрусе

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

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

Работа по NDC и другим протоколам

Поскольку NDC хоть и морально устаревший протокол, но до сих пор является основным стандартом практически для всех банков, поэтому его поддержка (хоть и не полная) является необходимым требованием для внедрения нашего решения в банки.

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

Но мы понимаем, что есть шансы, что некоторые банки примут решение по отказу от него, поэтому учитываем возможность реализации операций и на нашем собственном протоколе, так и на протоколах, разработанных внутри банков.

Отказ от XFS

Хоть XFS и удобен как универсальный протокол, его привязка к винде полностью блокирует его использование с другими ОС.

Сейчас существует инициатива XFS4IoT, которая позволит использовать XFS и на других платформах, и мы в том числе занимаемся его поддержкой, однако она до сих пор мало готова к использованию и почти никто из производителей не реализовал его поддержку.

Так-же один из минусов, про который нельзя не сказать — универсальность добавляет и набор ограничений, которые не всегда удобны, например, через XFS не всегда возможно получить полную информацию о состоянии модуля, из-за чего приходится или собирать внутренние логи железки, или вызывать инженера к банкомату, чтобы он мог с помощью диагностики получить полную телеметрию.

Возможность доработки банками

В современном мире многие банки начинают самостоятельно заниматься разработкой своих решений, как интернет банков, так и внутренних АБС. Поэтому, они привыкают к тому, что они могут быстро проверять и внедрять свои гипотезы или новые продукты в свои решения везде, кроме банкоматов. Из-за привязанности к вендорам, вывод нового продукта обычно занимает месяцы, если не годы, так как надо запустить новые проект, согласовать его с вендором, дождаться своей очереди. В современном мире победившего agile, этот подход не удовлетворяет желаниям банков, поэтому они редко рассматривают банкоматы как еще один канал продаж, а скорее относятся к ним как к просто необходимому наследию.

Использование веб технологий для интерфейса

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

вы , наверное, видели банкоматы Тинькофф, вот там, как раз, чистый веб, ещё и без NDC работают, молодцы.

А так-же это позволит существующим разработчикам в банках не погружаясь в новые технологии и специфику самостоятельно развивать свои банкоматы так, как они развивают и интернет-банки.

Так а важно то это почему?

Надеюсь, с помощью предыдущих пунктов я смог донести, зачем мы это делаем. Осталось пояснить, почему я считаю это важным.
Банкоматы, как и другие устройства самообслуживания очень плотно проникли в нашу жизнь. Мне сложно представить людей, которые бы никогда не пользовались банкоматами.

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

И поэтому нам важно, чтобы в нашей стране, да и вообще в мире, было как можно больше конкуренции и хороших решений, поскольку существующие производители слишком долго сидят на этом рынке без изменений, на устаревших подходах и технологиях, с оборудованием, которому десятки лет. И сейчас мы находимся в ситуации, где хорошее решение, которое удовлетворяет потребностям российского финтеха (а кто бы ни возмущался, в России финтех — один из самых прогрессивных в мире), сможет потом выйти на весь мир и показать, как же надо делать финтех.


Ну и напоследок красивая картиночка.

Если вы хотите получать оповещения о новых заметах, можете подписаться или на RSS, или на телеграмм канал.

Distroless Docker образы для .NET приложений

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

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

Даже в самом «минимальном» базовом образе alpine могут быть уязвимости (Данный пример как раз просто починится с помощью apk -U upgrade, но кого это волнует)

Так что единственным вариантом для решения этой проблемы раз и на всегда была сборка собственного базового docker образа из «scratch».

Пример такого образа вы можете посмотреть тут https://github.com/RoboNET/dotnet-scratch/blob/main/Dockerfile

Прокомментирую только некоторые моменты


RUN adduser \    
    --disabled-password \    
    --gecos "" \    
    --home "/nonexistent" \    
    --shell "/sbin/nologin" \    
    --no-create-home \    
    --uid "${UID}" \    
    "${USER}"


USER $UID:$UID

Раз уж мы делаем базовый образ в целях безопасности, то надо постараться закрыть как можно большее число векторов атаки. По умолчанию, все команды и ENTRYPOINT в докер образе будет запускаться от root пользователя, так что нам необходимо создать и затем указать, что надо использовать другого пользователя.


RUN apk add --no-cache \
    icu-libs \
    icu-data-full \
    tzdata


COPY --from=globalization-builder /usr/share/icu /usr/share/icu
COPY --from=globalization-builder /usr/share/zoneinfo /usr/share/zoneinfo

По умолчанию alpine не содержит в себе информации о локализации и таймзонах, так что если в вашем приложении необходимо с ними работать, то придется вручную поставить нужные пакеты и потом не забыть скопировать их в свой образ.


ENV ASPNETCORE_URLS=http://+:8080 \
    DOTNET_RUNNING_IN_CONTAINER=true \
    DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true \
    TMPDIR=/tmp \
    PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools

Чтобы дотнет понимал, что работает в контейнере, и знал нужные ему пути, необходимо указать ряд важных переменных окружения.


RUN dotnet publish -c Release \
    -r linux-musl-arm64 -p:PublishReadyToRun=true \
    -p:PublishTrimmed=true -p:PublishSingleFile=true \
    -o out

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

А может ли это пригодиться и для других проектов?

На самом деле этот подход имеет как и плюсы, так и минусы.
Из основных плюсов можно выделить:

  • отсутствие лишних библиотек и бинарных файлов, что уменьшает вероятность взлома приложения через уязвимые компоненты
  • повышение безопасности за счет запуска приложения не от root пользователя, что не позволит как-то вмешаться в оставшиеся зависимости, даже если в нашем приложении как-то смогли выполнить зловредный код через уязвимость
  • уменьшение размера приложения, особенно если не добавлять данные о локализации и таймзонах

Из минусов, с которыми приходилось сталкиваться:

  • приходится поддерживать свой собственный базовый образ
  • сложнее происходит удаленная отладка

И как это использовать?

Если хотите начать использовать distroless и rootless образы, то с 8 версии дотнета microsoft собирать рантайм и зависимости в том числе и в distroless образах, например cbl-mariner https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/8.0/cbl-mariner2.0-distroless/amd64/Dockerfile

И так-же он внес некоторые изменения в поведении по умолчанию, чтобы повысить безопасности приложений, например использование rootless подхода https://devblogs.microsoft.com/dotnet/securing-containers-with-rootless/

А если вам надо собрать такие образы под более старые версии, то можете посмотреть примеры использования моих образов, или собрать свои на их основе.

 Нет комментариев    120   3 мес   Docker   DotNet