161 lines
11 KiB
Markdown
161 lines
11 KiB
Markdown
# SecretText — Сервис безопасной передачи одноразовых секретов
|
||
|
||
**SecretText** — это self-hosted веб-приложение на Flask, предназначенное для конфиденциальной передачи одноразовых паролей, ключей шифрования и защищенных текстовых заметок. Сервис работает по принципу «прочитано — удалено», минимизируя цифровой след.
|
||
|
||
## 🚀 Основные возможности
|
||
|
||
- **Одноразовые секреты**: Ссылка на секрет автоматически уничтожается в Redis сразу после первого просмотра получателем.
|
||
- **Двусторонний обмен (Запросы секретов)**: Возможность создать защищенную ссылку-запрос с уникальным токеном, перейдя по которой, сторонний пользователь может безопасно отправить секрет вам в личный кабинет.
|
||
- **Симметричное шифрование**: Все секреты шифруются «на лету» с помощью библиотеки `cryptography` (алгоритм Fernet/AES) перед отправкой в оперативную память.
|
||
- **Встроенная защита от атак**:
|
||
- Защита от перебора ссылок (Anti-Bruteforce) с прогрессивной блокировкой IP-адресов в Redis.
|
||
- Ограничение частоты запросов (Rate Limiting) для предотвращения DoS-атак и спама.
|
||
- Строгая санитизация входных данных (`bleach`) и защита от CSRF-атак.
|
||
- **Панель администратора**: Встроенный аудит событий безопасности, просмотр системных логов, управление пользователями (активация/деактивация) и просмотр статистики.
|
||
- **Мультиязычные шаблоны**: Готовые двуязычные блоки (RU/EN) с кнопками автоматического копирования в один клик.
|
||
- **Автономность**: Проект не использует внешние CDN. Все библиотеки (Bootstrap 5, Bootstrap Icons) упакованы локально в папке `static`.
|
||
|
||
---
|
||
|
||
## 🛠️ Подготовка к первому запуску
|
||
|
||
### 1. Системные требования
|
||
Для работы приложения необходимы:
|
||
- **Python 3.10** или выше
|
||
- **Redis Server** (для хранения зашифрованных секретов и сессий)
|
||
- **MariaDB / MySQL** (для хранения учетных записей пользователей и логов безопасности)
|
||
|
||
### 2. Клонирование репозитория и окружение
|
||
```bash
|
||
git clone https://git.palchikov.name/PalchikovAleksandr/secrettext.git
|
||
cd secrettext
|
||
|
||
# Создание и активация виртуального окружения
|
||
python -m venv .venv
|
||
source .venv/bin/activate # Для Linux/macOS
|
||
# .venv\Scripts\activate # Для Windows
|
||
|
||
# Установка зависимостей
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 3. Настройка конфигурации (`.env`)
|
||
Создайте файл `.env` в корневом каталоге проекта и заполните его учетными данными:
|
||
```env
|
||
# Flask конфигурация
|
||
FLASK_ENV=production
|
||
DEBUG=False
|
||
SECRET_KEY=укажите_случайный_длинный_хеш
|
||
ENCRYPTION_PASSWORD=укажите_стойкий_пароль_для_шифрования_секретов
|
||
SALT=укажите_случайный_соленый_хеш
|
||
|
||
# Настройки MariaDB / MySQL
|
||
DB_HOST=localhost
|
||
DB_PORT=3306
|
||
DB_USER=secretuser
|
||
DB_NAME=secrettext
|
||
DB_PASSWORD=ваш_пароль_от_базы_данных
|
||
|
||
# Настройки Redis
|
||
REDIS_HOST=localhost
|
||
REDIS_PORT=6379
|
||
REDIS_DB=0
|
||
REDIS_PASSWORD=пароль_redis_если_есть
|
||
|
||
# Безопасность админки
|
||
ADMIN_USERNAME=admin
|
||
ADMIN_PASSWORD=придумайте_сложный_пароль_админа
|
||
ADMIN_ALLOWED_IPS=127.0.0.1,::1
|
||
ADMIN_ALLOW_ALL=False
|
||
```
|
||
⚠️ *Внимание: Обязательно добавьте `.env` в ваш `.gitignore`, чтобы случайно не опубликовать пароли в репозитории.*
|
||
|
||
---
|
||
|
||
## 🏁 Запуск приложения
|
||
|
||
### Шаг 1. Инициализация базы данных
|
||
Перед самым первым запуском раскомментируйте блок инициализации в `main.py` (примерно 121-123 строки):
|
||
```python
|
||
with app.app_context():
|
||
database.init_db()
|
||
create_admin()
|
||
```
|
||
Запустите приложение один раз, чтобы создались таблицы в MariaDB и сгенерировалась учетная запись администратора, указанная в `.env`. После успешного создания **закомментируйте этот блок обратно**, чтобы сервер не выполнял избыточные проверки при каждом перезапуске.
|
||
Или ещё проще, запустить Python в интерактивном режиме и выполнить инициализацию вручную, чтобы точно не забыть закомментировать код.
|
||
|
||
Сразу после установки сменить пароль администратора через интерфейс, даже если он задан в .env. Это защитит от случайной утечки, если файл с настройками попадёт в чужие руки.
|
||
### Шаг 2. Запуск в режиме разработки
|
||
```bash
|
||
python main.py
|
||
```
|
||
Приложение станет доступно по адресу `http://localhost:5000`.
|
||
|
||
---
|
||
|
||
## 🔒 Рекомендации по настройке в продакшене (Production)
|
||
|
||
Запуск напрямую через `python main.py` предназначен **только для разработки**. При развертывании в реальной сети строго следуйте правилам ниже:
|
||
|
||
### 1. Использование боевого WSGI-сервера
|
||
Для стабильной и многопоточной работы Flask-приложения в продакшене рекомендуется использовать чистый Python WSGI-сервер, например **Waitress**. Это исключает проблемы с потоками встроенного сервера разработки:
|
||
|
||
```bash
|
||
# Установка сервера
|
||
pip install waitress
|
||
|
||
# Запуск приложения через WSGI-интерфейс
|
||
waitress-serve --host=127.0.0.1 --port=5000 main:app
|
||
```
|
||
|
||
### 2. При использование HTTPS (Apache)
|
||
Поскольку сервис обрабатывает пароли, передача данных по незащищенному протоколу HTTP категорически запрещена. Настройте **Apache** в качестве Reverse Proxy (используя модули `mod_proxy` и `mod_proxy_http`) и установите SSL-сертификат (например, бесплатный от Let's Encrypt через `certbot`).
|
||
|
||
Пример конфигурации виртуального хоста (VirtualHost) в Apache:
|
||
|
||
```apache
|
||
<VirtualHost *:443>
|
||
ServerName yourdomain.com
|
||
|
||
SSLEngine on
|
||
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
|
||
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
|
||
|
||
# Запрет доступа к скрытым файлам и папкам в корне (включая .env)
|
||
<FilesMatch "^\.">
|
||
Require all denied
|
||
</FilesMatch>
|
||
|
||
# Настройка Reverse Proxy на локальный боевой WSGI-сервер (Waitress)
|
||
ProxyRequests Off
|
||
ProxyPreserveHost On
|
||
|
||
# Проксирование всех запросов на приложение, запущенное на порту 5000
|
||
ProxyPass / http://127.0.0.1:5000/
|
||
ProxyPassReverse / http://127.0.0.1:5000/
|
||
|
||
# Дополнительные заголовки безопасности для прокси
|
||
ProxySetHeader X-Forwarded-Proto https
|
||
ProxySetHeader X-Forwarded-Host %{HTTP_HOST}s
|
||
ProxySetHeader X-Real-IP %{REMOTE_ADDR}s
|
||
|
||
# Логирование
|
||
ErrorLog ${APACHE_LOG_DIR}/secrettext_error.log
|
||
CustomLog ${APACHE_LOG_DIR}/secrettext_access.log combined
|
||
</VirtualHost>
|
||
```
|
||
|
||
|
||
### 3. Настройка заголовков за прокси-сервером
|
||
При работе за Nginx Proxy обязательно убедитесь, что в `main.py` корректно обрабатывается заголовок `X-Forwarded-For`. Это необходимо, чтобы встроенная система rate-limiting и блокировки брутфорса видела **реальные IP-адреса злоумышленников**, а не локальный адрес самого Nginx (`127.0.0.1`).
|
||
|
||
### 4. Ротация логов и очистка Redis
|
||
В файле `database.py` предусмотрена функция `cleanup_old_data()`. Рекомендуется настроить системный планировщик **Cron** для ежедневного вызова скрипта очистки старых логов безопасности и просроченных записей:
|
||
```bash
|
||
0 3 * * * /home/shurik/pass_toket/.venv/bin/python -c "import database; database.cleanup_old_data()"
|
||
```
|
||
|
||
---
|
||
## 📄 Лицензия
|
||
Этот проект является полностью свободным программным обеспечением и передан в общественное достояние. Вы можете копировать, изменять, публиковать, использовать, компилировать, продавать или распространять этот код как в исходном, так и в скомпилированном виде, в любых целях, коммерческих или некоммерческих, любыми способами.
|