На прошлой неделе «Доктор Веб» выпустил антивирусного бота для Telegram. Я, как непосредственный участник этого проекта, хотел бы от лица всей команды рассказать о том, зачем мы сделали этого бота, как он работает и пора ли уже отказываться от настольного антивируса.
Концепция
Летом прошлого года Telegram представил ботов и Telegram Bot API. Чат-боты существовали давно, но в данном случае платформа предоставила такие широкие возможности для экспериментов по интеграции, что собственных ботов не сделал только ленивый. Есть даже такие экзотичные примеры.
Большинство ботов, которых испытывали мы, были развлекательными (вроде тестов на IQ или оценки стикеров), информационными (например, присылали прогноз погоды, перевод слов или адрес ближайшего банкомата), либо одновременно и теми, и другими — скажем, боты для поиска индийского кино. Пользоваться ими оказалось удобно, и сам формат так увлёк нас, что мы хотели использовать его для собственного информационного стенда — наш бот мог бы давать описание угрозы по запросу: скажем, пользователь спрашивает у бота, что именно делает пойманный антивирусом Linux.Encoder.1, и в ответ получает подробное описание угрозы. Но немного покрутив идею в руках, мы нашли явные недостатки:
- В формате сообщений из мессенджера неудобно читать о вредоносных программах: описание механизма часто очень длинное, с примерами кода и горой скриншотов.
- Искусственной показалась сама ситуация, когда пользователь узнал об угрозе на своём устройстве, открыл Telegram, нашёл бота и задал ему вопрос об этом, а не попросту загуглил.
- Разные антивирусные компании используют разные правила наименования угроз. Пользователь может искать угрозу по другому имени и не найти нужную информацию.
Обдумав всё это, мы решили шагнуть дальше — и создать бота с по-настоящему прикладным функционалом. Экспериментального антивирусного бота.
Задача показалась увлекательной и полезной. За шифрование трафика и безопасный обмен данными отвечает мессенджер, и Telegram отлично себя в этом зарекомендовал. За безопасность устройства, на котором установлен Telegram, отвечает пользователь — и работают все обычные трюки социальной инженерии. Как компьютер, так и смартфон можно заразить троянцем, который в лучшем случае покажет тонны рекламы, а в худшем — превратит устройство в бесчувственный набор пластика и металла.
Мы задумали бота, который мог бы проверять файлы и ссылки на лету и предостерегать пользователя, если обнаружит угрозу. Когда антивирусная защита встраивается, скажем, в электронную почту, антивирус может располагаться либо на стороне почтового
Сразу оговоримся, что такой механизм не является полноценной заменой антивирусу. Бот не в силах помешать пользователю перейти по опасной ссылке или запустить файл, он может лишь предупредить об опасности — в то время как антивирус защитит, даже если беспечная жертва социнженера сразу скачает и запустит троянец. При этом технически подкованную аудиторию Telegram может заинтересовать антивирусный продукт, который никак не ограничивает их действия, но предоставляет информацию по запросу. Мы думаем о боте как об исследовательском проекте, и в первую очередь нас интересует фидбек — поэтому вы и видите здесь нашу статью.
Реализация
Бот реализован с помощью фреймворка Tornado — который, как регулировщица движения на перекрёстке, координирует потоки данных между Telegram Bot API и закрытыми API наших сервисов Dr.Web. Первоначально мы пошли стандартным путём и использовали Django. Однако, особенность фреймворка Django такова, что во время ввода и вывода данных (получение тела запроса, отправление ответа, работа с БД и т.д.) тратится впустую драгоценное время. Мы провели эксперимент с помощью утилиты Siege и поняли, что такая модель оказалась непригодной для эффективной обработки тысяч единовременных запросов.
Поэтому мы стали смотреть в сторону асинхронных моделей работы — и сделали выбор в пользу Tornado (где асинхронность, собственно, и является основной чертой). В настоящий момент весь код бота асинхронный: включая скачивание файлов, проверки ссылок и даже работу с базой данных — при добавлении записи в базу данных бот не ждёт ответа от сервера, а продолжает выполнять задачи.
Когда сообщения, предназначенные боту, приходят из облака Telegram, нам нужно парсить ссылки в полученном тексте. При этом важно избежать расхождений между тем, как сработает наш парсер (то есть какую именно страницу проверит бот), и тем, как работает парсер Telegram (то есть что именно откроется у пользователя по клику в мессенджере), поэтому мы максимально следовали тому, как парсит ссылки Telegram — ориентируясь на открытый код веб-версии. Хотя их механизм, вероятно, этим не ограничивается и периодически вызывал у нас вопросы (так, например, в мобильном приложении для iOS ссылка “test.com:8080” без указания протокола выглядит как “test.com:8080” у отправителя, но как “test.com:8080“ у получателя).
Дальнейшая обработка ссылок и файлов идёт в несколько этапов: распаковка архивов, раскрытие сокращенных ссылок и отслеживание редиректов. Если по ссылке загружаются файлы, мы скачиваем их — благодаря этому бот может проверять не только файлы, отправленные через Telegram, но и файлы по внешним ссылкам.
Чтобы эффективнее распределять нагрузку на серверы, первым делом проверяются кеши файлов и ссылок. После этого бот передает эстафету различным технологиям Dr.Web через наши внутренние API: облачному сервису Dr.Web Cloud, антивирусному движку Scanning Engine, сервису проверки ссылок Link Checker, базам сигнатур вирусов. Обмен данными идёт асинхронно и многопоточно, и при увеличении нагрузки мы можем увеличить мощность, добавив новые серверы и прописав определённые настройки в конфигурационных файлах — возможность масштабирования изначально заложена в архитектуру бота.
Наконец, проверенные материалы возвращаются боту — и тот направляет результаты пользователям, учитывая ограничения на частоту сообщений от ботов, которые устанавливает Telegram Bot API.
Пользователи могут проверять ссылки и файлы как в приватном режиме (отправлять боту подозрительный контент или пересылать ему сообщения, полученные от других пользователей), так и в групповом чате — если добавить бота в участники чата, он будет срабатывать на все файлы и ссылки в чате.
Бот работает в двух режимах: «тихий» и обычный. В обычном режиме бот реагирует на каждый файл или ссылку и отправляет сообщение о том, что ссылка безопасна или же файл не рекомендуется скачивать. Если бот будет вести себя так в групповом чате, то это может мешать людям общаться, поэтому мы сделали «тихий» режим. В этом режиме бот даёт знак только тогда, когда файл или ссылка в чате содержат угрозу, и предостерегает пользователей от необдуманного тэпа или клика. Сообщения об ошибках проверки приходят и в «тихом» режиме — иначе, не дождавшись ответа, пользователь мог бы ошибочно посчитать, что ссылка или файл были успешно проверены и безопасны. Выбрать режим можно с помощью команды /mode.
По мере развития API мы будем внедрять новые возможности, если они окажутся полезными для наших задач. Не так давно Telegram представил использование ботов в inline-режиме без добавления бота в чат — пока что этот механизм не позволяет передать боту файл на проверку, но мы обдумываем его применение. В следующих обновлениях планируем сделать бота быстрее и надёжнее, внимательно следим и за фидбеком пользователей.
Пара слов о локализации (раз уж это не только моя профессия, но и страсть): наш бот умеет общаться на русском, английском или немецком. Особых трудностей не было, мы используем библиотеку gettext, а файлы локализации храним в формате .po.
Как правило, все тексты для наших продуктов написаны в официальном стиле, поэтому любопытным новым опытом стало использование эмодзи в файлах ресурсов — в OS X они поддерживаются «из коробки», в Ubuntu достаточно было добавить шрифт в систему (sudo apt-get install ttf-ancient-fonts), а в Windows потребовались ухищрения, чтобы переводчики могли видеть эмозди в файлах локализации. Мы попробовали вставлять эмодзи в .po-файлы с помощью кодов, но не все операционные системы умеют их считывать (например, пользователи десктопных клиентов для Windows видели вместо них текстовые коды). Видимо, разумных решений два: либо подбирать редактор .po-файлов, который отображает все эмодзи, либо заменять их кодами, но преобразовывать в эмодзи на нашей стороне. Мы думаем в сторону второго варианта — но как бы то ни было, пользователь этих мучений даже не заметит.
Ещё одна особенность, которую мы держим в уме при разработке: одни и те же эмодзи выглядят по-разному на разных устройствах и вообще не везде поддерживаются. С решением этой проблемы помогла Emojipedia — в ней можно посмотреть, есть ли нужные эмодзи на тех или иных платформах, а также скопировать эмодзи или его код и вставить в .po-файл.
И небольшая загвоздка, с которой мы столкнулись: Telegram не позволяет локализовать бота полностью, описание бота и подсказки в поле ввода всегда на каком-то одном языке (в нашем случае на английском). Надеемся, что решение для этого появится в следующих релизах Telegram Bot API.
В целом на разработку, внутреннее тестирование и локализацию у нас ушли 3 месяца с командой в 7 человек. Коллеги занимались разработкой в расслабленном режиме параллельно с основными рабочими задачами, поэтому времени «помедитировать» над логикой работы бота у нас было достаточно. Сложнее всего в таком режиме проводить нагрузочное тестирование — для основного стресс-теста пригласили несколько десятков сотрудников, имеющих аккаунты в Telegram, и по условному сигналу скормили боту коллекции из тысяч файлов. Надеемся, что и наплыв любопытных тестирующих с хабра не выведет нас из строя, но если что — со временем будем подключать дополнительные мощности, не судите строго.
Насколько мы знаем, антивирусных ботов ещё никто не делал, поэтому здесь есть широкое поле для экспериментов. Будем рады, если вы поделитесь мыслями и опытом общения с нашим ботом: @drwebbot
Автор: scalywhale