Как разработать Telegram-бота на Python, который будет генерировать сложные пароли прямо в мессенджере?

Чтобы придумать надежный и запоминающийся пароль, можно объединить несколько слов в последовательность, напоминающую сюжет. А после — разбавить специальными символами. Алгоритм простой, но его можно автоматизировать — написать Telegram-бота для генерации паролей. В тексте рассказываем, как это сделать.

Используйте навигацию, если нет времени читать текст целиком:

Требования к работе бота

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

  • Длина пароля должна быть от 2 до 8 слов. Так мы усложним задачу злоумышленнику: подобрать связку слов намного сложнее, чем одно слово.
  • Между словами могут быть разделители в виде цифр и спецсимволов. Это увеличит энтропию и затруднит подбор пароля. Пароль с разделителями может выглядеть так: unmovable8ENCRUST=macho.
  • Дополнительно в пароле могут использоваться спецсимволы в начале (префиксы) и в конце (суффиксы) слова, которые также помогут увеличить сложность подбора.
  • Количество слов, разделителей, префиксов и суффиксов должен настраивать пользователь. Для этого ему нужен интерфейс в виде сообщения с кнопками настроек.
  • Пользовательские настройки должны сохраняться даже после перезагрузки сервера с ботом. В качестве базы данных подойдет Redis.

Что понадобится для разработки бота

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

  • Python — от версии 3.9 и выше,
  • aiogram — асинхронный фреймворк для работы с Telegram Bot API,
  • Redis — быстрое key-value хранилище,
  • redis-py — клиент для работы с Redis,
  • XKCD-password-generator — библиотека для генерации паролей,
  • pydantic — библиотека для валидации данных и формирования настроек приложения.

Самое главное — репозиторий на GitHub. Его нужно импортировать в свое рабочее окружение и настроить.

Как настроить бота

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

Если используете среду разработки PyCharm, запустить бота будет максимально просто. После клонирования репозитория переключитесь на ветку article-tweaks (git checkout article-tweaks) и создайте новую конфигурацию запуска (Run Configuration). А затем установите параметры:

  • BOT_TOKEN — укажите токен бота, его можно получить у @BotFather.
  • STORAGE_MODE — выберите memory.
  • WORDS__WORDFILE — укажите путь к файлу с набором слов. Он входит в состав репозитория, поэтому отдельно скачивать его не нужно.

Должно получится, как на скриншоте:

Как разработать Telegram-бота на Python, который будет генерировать сложные пароли прямо в мессенджере?

После этого запустите созданную конфигурацию. Вы увидите в консоли следующий текст:

INFO:aiogram.dispatcher.dispatcher:Start polling

Если используете не PyCharm, то процесс запуска несколько отличается. Создайте виртуальное окружение bot (python3 -m venv bot) и установите зависимости (pip install -r requirements.txt), а после — запустите бота следующей командой:

BOT_TOKEN=ключ от BotFather STORAGE_MODE=memory WORDS__WORDFILE=/path/to/words.txt python -m bot

Теперь попробуйте отправить в личные сообщения с ботом команду /start. Если в ответ получили текстовое приветствие, бот работает.

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

  • /generate_weak –— два случайных слова без каких-либо дополнительных символов.
  • /generate_normal — три случайных слова, каждое из которых случайным образом может состоять из всех прописных или всех строчных букв, в качестве разделителей используются числа.
  • /generate_strong — то же, что и в предыдущем случае, но слов четыре, а в качестве разделителей, помимо цифр, возможны спецсимволы.
При нажатии на команду бот сразу отправляет сгенерированный пароль.
При нажатии на команду бот сразу отправляет сгенерированный пароль.

Также есть команда /settings — она выводит сообщение с настройками, и /generate — отправляет сгенерированный пароль с учетом новой конфигурации:

Как разработать Telegram-бота на Python, который будет генерировать сложные пароли прямо в мессенджере?

Деплой бота на сервер

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

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

Для начала зарегистрируемся в панели управления и создадим новый сервер в разделе Облачная платформа. Затем — настроим его.

<p>Боту подойдет ОС Ubuntu 22.04 LTS, 2 виртуальных ядра с минимальной границей в 10% процессорного времени, 2 ГБ оперативной памяти, а также 10 ГБ на сетевом диске (базовый HDD).</p>

Боту подойдет ОС Ubuntu 22.04 LTS, 2 виртуальных ядра с минимальной границей в 10% процессорного времени, 2 ГБ оперативной памяти, а также 10 ГБ на сетевом диске (базовый HDD).

С учетом выделенного IP-адреса такая конфигурация выйдет примерно в 28 ₽/день. При желании можно обойтись без маршрутизируемого IP, поскольку Telegram-бот может принимать события методом опроса (поллинга), даже находясь за NAT.

После подключения к серверу по SSH, бота необходимо перенести. Для этого выполните следующие шаги:

1. Откройте консоль сервера и обновите систему с помощью команды:

apt update && apt upgrade -y

2. Создайте отдельного пользователя для нашего бота и добавьте его в группу sudoers:

Дальнейшие действия выполняйте от лица созданного пользователя.
Дальнейшие действия выполняйте от лица созданного пользователя.

3. Установите Redis и присоедините его к systemd, воспользовавшись удобной инструкцией от DigitalOcean. Шаги 4 и 5 можно пропустить.

4. Клонируйте репозиторий и переключитесь на нужную ветку:

Как разработать Telegram-бота на Python, который будет генерировать сложные пароли прямо в мессенджере?

5. Настройте виртуальное окружение:

python3 -m venv venv && source /venv/bin/activate && pip install -r requirements.txt

6. Создайте файл systemd-службы по пути /etc/systemd/system/passgenbot.service со следующим содержимым:

[Unit] Description=Telegram Password Generator Bot Requires=redis.service After=network.target redis.service [Service] Type=simple WorkingDirectory=/home/bot/passgenbot ExecStart=/home/bot/passgenbot/venv/bin/python -m bot User=bot Group=bot EnvironmentFile=/home/bot/passgenbot/.env KillMode=process Restart=always RestartSec=10 [Install] WantedBy=multi-user.target

7. Обратите внимание на директиву EnvironmentFile. Создайте этот файл и поместите туда необходимые переменные окружения:

Как разработать Telegram-бота на Python, который будет генерировать сложные пароли прямо в мессенджере?

8. Убедитесь, что Redis запущен (systemctl status redis) и включите бота с добавлением в автозапуск:

sudo systemctl enable passgenbot --now

Готово!

Программируем кастомные пресеты

Возможности бота можно в любой момент персонализировать под себя. Если пресетов станет недостаточно — добавить новые или изменить существующие. Это сделать достаточно просто.

За генерацию паролей по заданным пресетам отвечает класс XKCD. Под капотом наш бот выглядит так:

# bot/pwdgen.py from random import choice from xkcdpass import xkcd_password class XKCD: # Весь список разделителей, отдельно цифры, отдельно – спецсимволы delimiters_numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] delimiters_full = ["!", "$", "%", "^", "&", "*", "-", "_", "+", "=", ":", "|", "~", "?", "/", ".", ";"] + delimiters_numbers def __init__(self, filename: str): # Загрузка словаря в память self.wordlist = xkcd_password.generate_wordlist( wordfile=filename, valid_chars="[a-z]", min_length=4, max_length=10, ) def weak(self): # Слабый пароль: 2 слова без раздетилей return xkcd_password.generate_xkcdpassword( self.wordlist, numwords=2, delimiter="", ) def normal(self): # Средний пароль: 3 слова, разделитель # в виде случайной цифры return xkcd_password.generate_xkcdpassword( self.wordlist, numwords=3, case="random", random_delimiters=True, valid_delimiters=self.delimiters_numbers ) def strong(self): # Сильный пароль: 4 слова и большой выбор разделителей return xkcd_password.generate_xkcdpassword( self.wordlist, numwords=4, case="random", random_delimiters=True, valid_delimiters=self.delimiters_full ) def custom(self, count: int, separators: bool, prefixes: bool): # Произвольный пароль: # сложность зависит от настроек пользователя pwd = xkcd_password.generate_xkcdpassword( self.wordlist, numwords=count, case="random", delimiter="", random_delimiters=separators, valid_delimiters=self.delimiters_full ) if prefixes == separators: return pwd elif separators and not prefixes: return pwd[1:-1] elif prefixes and not separators: return f"{choice(self.delimiters_full)}{pwd}{choice(self.delimiters_full)}"

Для добавлении нового пресета достаточно скопировать существующий, изменить его название и настроить параметры метода generate_xkcdpassword под себя.

И последним этапом — добавить в обработчик commands функцию для вызова своего пресета. Это можно сделать по аналогии с существующими пресетами.

# bot/handlers/commands.py from aiogram import types, Dispatcher from aiogram.utils.markdown import hcode from bot.pwdgen import XKCD async def cmd_generate_weak(message: types.Message): # вызов пресета weak pwd: XKCD = message.bot.get("pwd") await message.answer(hcode(pwd.weak())) async def cmd_generate_normal(message: types.Message): # вызов пресета normal pwd: XKCD = message.bot.get("pwd") await message.answer(hcode(pwd.normal())) async def cmd_generate_strong(message: types.Message): # вызов пресета strong pwd: XKCD = message.bot.get("pwd") await message.answer(hcode(pwd.strong())) # вот здесь можно добавить свою функцию для вызова пресета # регистрация команд def register_commands(dp: Dispatcher): # обработчик вызывает пресет weak по команде generate_weak dp.register_message_handler(cmd_generate_weak, commands="generate_weak") # обработчик вызывает пресет normal по команде generate_normal dp.register_message_handler(cmd_generate_normal, commands="generate_normal") # обработчик вызывает пресет strong по команде generate_strong dp.register_message_handler(cmd_generate_strong, commands="generate_strong") # вот здесь можно добавить свою команду

Что можно добавить

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

Напишите в комментариях, какого еще Telegram-бота можно разработать на Python. И подпишитесь на блог Selectel, чтобы не пропустить обзоры, новости, кейсы и полезные гайды из мира IT.

Читайте также:

2121
8 комментариев

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

10
Ответить

Зачем это нахер нужно

4
Ответить

Провел рукой справа налево или слева направо по клавиатуре вот тебе и сложный пароль, а все остальное создано чтобы красть пароли

4
Ответить

А нафига? Я бы понял, если бы вы написали инструкцию по установке и защите Bitwarden, но телеграм бот, который просто генерирует пароли, на сервере. Ээ.

2
Ответить

Рад за автора, что он попрактиковался в кодинге. Но для всех людей есть — "qwerty1234", для тех, кто решил, что для всех сервисов нужен больше, чем один пароль — 1password, для тех, кто не доверяет компаниям и сможет запустить свой сервер — bitwarden (да, можно сохранять все и на сервера bitwarden) / pass

1
Ответить

Никогда бы подобному не доверился. Зачем просить сгенерить тебе сложный пароль, который уже вбит в базу? Проще придумать самим, записать где-то и всё.

1
Ответить

все равно все пароли как обычно забываются

1
Ответить