Безопасное хранение средств пользователей с использованием мультисиг кошельков
Концепция
Данный вариант интеграции является оптимальным для достижения следующих целей:
- высокая безопасность решения с приемлемой сложностью реализации
- максимальная простота для пользователей, им не придется заботиться о сид-фразах, они могут даже не знать, что внутри используется блокчейн
Мы будем хранить средства пользователей на мультисиг-кошельках. У каждого мультисиг-кошелька будет 3 кошелька-владельца (3 подписанта), для прохождения транзакции необходимо будет две подписи из трёх.
- Горячий кошелёк-владелец будет уникальным для каждого мультисига, храниться будет на отдельном сервере в БД
- Так называемый прохладный кошелёк-владелец, общий для всех пользователей, одновременно хранится и на сервере и "на бумажке"
- Холодный кошелёк-владелец хранится только "на бумажке"
Горячий и прохладный кошельки будут использоваться для подписи транзакций во время штатной работы сервиса.
Прохладный и холодный кошельки будут использоваться при компрометации безопасности для вывода средств в безопасное место. Для этого также нужно будет реализовать систему мониторинга за логами серверов и за активностью средств на кошельках, чтобы можно было отследить момент взлома. А так же написать скрипт для автоматического или полуавтоматического вывода средств в безопасное место.
Структура
В целом, система будет состоять из следующих сервисов:
- App - бэкэнд с бизнес логикой, отвечающий за то, когда и сколько монет переводить от юзера к юзеру
- MQ - брокер сообщений между остальными сервисами
- Keeper - сервис хранящий сид-фразы от горячих кошельков
- Cooler - сервис хранящий прохладный кошелёк
App
- хранит информацию о юзерах
- при создании нового пользователя отправляет запрос “-> MQ -> Keeper” на создание горячего кошелька, с полученным адресом создаёт мультисиг-адрес и сохраняет мультисиг-адрес у себя
- инициирует отправку транзакции: формирует транзакцию и отправляет запрос в MQ на подписание сформированной транзакции
- ждёт две подписи и используя их отправляет транзакцию в блокчейн
MQ
Хороший выбор - NATS, т.к. умеет подписывать сообщения
- отвечает за общение между сервисами
- открыто смотрит наружу в вебе, достоверность сообщений обеспечивается подписью https://docs.nats.io/nats-server/configuration/securing_nats/auth_intro/nkey_auth
Keeper
- хранит сиды пользователей
- по запросу от App может создавать сид для нового пользователя
- по запросу от App подписывает транзакцию приватником пользователя
Cooler
- хранит один наш прохладный кошелёк
- по запросу от App подписывает транзакцию
Особенности
Хранение кошельков на отдельных серверах защищает от утечек БД с сидами.
Общение через MQ с авторизацией по подписи приводит к тому, что App и MQ не знают, где физически находятся Keeper и Cooler, соответственно осложняется их идентификация и взлом.
Самым уязвимым местом становится App, если злоумышленник получит полный доступ к этому серверу, то сможет отправлять транзакции на перевод средств
Что стоит учесть:
- сиды в БД кипера и кулера стоит дополнительно зашифровать, например, с помощью Vault
- располагать Keeper и Cooler стоит каждый в отдельном дата-центре, чтобы исключить одновременный физический доступ к обоим серверам
- предусмотреть мониторинг системы и автоматический/полуавтоматический вывод средств в безопасное место в случае опасности предусмотреть бэкапы БД App, чтобы не потерять связи между id пользователей и их средствами в блокчейне
- обеспечить надёжное хранение прохладного и холодного кошелька
Альтернативы:
- (нормальная, усложнение) можно различными способами усложнять систему, это повысит безопасность, т.к. злоумышленнику будет сложнее разобраться, но также повысит сложность и стоимость поддержки сервиса
- (нормальная, упрощение) шифровать сиды в БД можно не Vault’ом, а паролем пользователя из App или отдельным uuid хранящимся в App в качестве ключа шифрования, тогда при каждом запросе на подпись, надо будет передавать этот ключ шифрования в кипер
- (нормальная, упрощение) можно горячие кошельки перенести из кипера в апп, шифровать их там паролем, на отдельном сервере оставить только прохладный кошелёк (плохая, упрощение) средства можно хранить не на мультисиг-кошельках, а на обычных, но тогда слива БД будет достаточно для кражи средств
- (плохая, упрощение) можно не хранить средства, а раздать юзерам сид-фразы, это будет самое безопасное решение, но очень сложное для пользователей