some fixes
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-11-08 18:45:20 +09:00
parent 20014d3a81
commit fb74a4a25d
9 changed files with 538 additions and 2 deletions

View File

@@ -59,6 +59,10 @@ DJANGO_EMAIL_PORT=587
DJANGO_EMAIL_HOST_USER=
DJANGO_EMAIL_HOST_PASSWORD=
DJANGO_EMAIL_USE_TLS=True
DJANGO_EMAIL_USE_SSL=False
DJANGO_EMAIL_TIMEOUT=30
DJANGO_DEFAULT_FROM_EMAIL=
DJANGO_SERVER_EMAIL=
# SSL настройки (для Let's Encrypt)
DOMAIN=

View File

@@ -452,6 +452,26 @@ reset: ## Сброс к заводским настройкам
# === Security Commands ===
diagnose: ## Диагностика проблем на сервере
@echo "🔍 Запуск диагностики сервера..."
@./scripts/diagnose-server.sh
check-db: ## Проверка подключения к базе данных
@echo "🔗 Проверка подключения к БД..."
@./scripts/check-db-connection.sh
check-api: ## Проверка всех API эндпоинтов
@echo "🌐 Проверка API эндпоинтов..."
@./scripts/check-api-endpoints.sh
check-users: ## Показать данные пользователей
@echo "👥 Данные пользователей:"
@$(DOCKER_COMPOSE) exec db psql -U links_user -d links_db -c "SELECT id, username, email, first_name, last_name, is_active, is_staff, is_superuser, date_joined FROM users_user ORDER BY date_joined DESC;"
fix-admin: ## Исправить маршрут /admin в nginx
@echo "🔧 Исправление маршрута /admin..."
@./scripts/fix-nginx-admin.sh
security-audit: ## Аудит безопасности PostgreSQL
@echo "🔍 Запуск аудита безопасности PostgreSQL..."
@./scripts/audit-db-security.sh

View File

@@ -190,4 +190,18 @@ SECURE_HSTS_INCLUDE_SUBDOMAINS = os.getenv('DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAIN
SECURE_HSTS_PRELOAD = os.getenv('DJANGO_SECURE_HSTS_PRELOAD', 'False') == 'True'
SECURE_CONTENT_TYPE_NOSNIFF = os.getenv('DJANGO_SECURE_CONTENT_TYPE_NOSNIFF', 'True') == 'True'
SECURE_BROWSER_XSS_FILTER = os.getenv('DJANGO_SECURE_BROWSER_XSS_FILTER', 'True') == 'True'
X_FRAME_OPTIONS = os.getenv('DJANGO_X_FRAME_OPTIONS', 'DENY')
X_FRAME_OPTIONS = os.getenv('DJANGO_X_FRAME_OPTIONS', 'DENY')
# Email настройки из переменных окружения
EMAIL_BACKEND = os.getenv('DJANGO_EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend')
EMAIL_HOST = os.getenv('DJANGO_EMAIL_HOST', '')
EMAIL_PORT = int(os.getenv('DJANGO_EMAIL_PORT', '587'))
EMAIL_HOST_USER = os.getenv('DJANGO_EMAIL_HOST_USER', '')
EMAIL_HOST_PASSWORD = os.getenv('DJANGO_EMAIL_HOST_PASSWORD', '')
EMAIL_USE_TLS = os.getenv('DJANGO_EMAIL_USE_TLS', 'True') == 'True'
EMAIL_USE_SSL = os.getenv('DJANGO_EMAIL_USE_SSL', 'False') == 'True'
EMAIL_TIMEOUT = int(os.getenv('DJANGO_EMAIL_TIMEOUT', '30'))
# Адреса отправителей по умолчанию
DEFAULT_FROM_EMAIL = os.getenv('DJANGO_DEFAULT_FROM_EMAIL', EMAIL_HOST_USER)
SERVER_EMAIL = os.getenv('DJANGO_SERVER_EMAIL', EMAIL_HOST_USER)

View File

@@ -1,4 +1,4 @@
version: '3.8'
services:
web:
build: ./backend

114
docs/EMAIL_SETUP.md Normal file
View File

@@ -0,0 +1,114 @@
# Email Configuration Guide
## Настройка email для различных провайдеров
### 📧 Mail.ru
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
DJANGO_EMAIL_HOST=smtp.mail.ru
DJANGO_EMAIL_PORT=587
DJANGO_EMAIL_HOST_USER=your-email@mail.ru
DJANGO_EMAIL_HOST_PASSWORD=your-app-password
DJANGO_EMAIL_USE_TLS=True
DJANGO_EMAIL_USE_SSL=False
DJANGO_DEFAULT_FROM_EMAIL=your-email@mail.ru
DJANGO_SERVER_EMAIL=your-email@mail.ru
```
### 📧 Gmail
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
DJANGO_EMAIL_HOST=smtp.gmail.com
DJANGO_EMAIL_PORT=587
DJANGO_EMAIL_HOST_USER=your-email@gmail.com
DJANGO_EMAIL_HOST_PASSWORD=your-app-password
DJANGO_EMAIL_USE_TLS=True
DJANGO_EMAIL_USE_SSL=False
DJANGO_DEFAULT_FROM_EMAIL=your-email@gmail.com
DJANGO_SERVER_EMAIL=your-email@gmail.com
```
### 📧 Yandex
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
DJANGO_EMAIL_HOST=smtp.yandex.ru
DJANGO_EMAIL_PORT=587
DJANGO_EMAIL_HOST_USER=your-email@yandex.ru
DJANGO_EMAIL_HOST_PASSWORD=your-app-password
DJANGO_EMAIL_USE_TLS=True
DJANGO_EMAIL_USE_SSL=False
DJANGO_DEFAULT_FROM_EMAIL=your-email@yandex.ru
DJANGO_SERVER_EMAIL=your-email@yandex.ru
```
### 📧 Rambler
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
DJANGO_EMAIL_HOST=smtp.rambler.ru
DJANGO_EMAIL_PORT=587
DJANGO_EMAIL_HOST_USER=your-email@rambler.ru
DJANGO_EMAIL_HOST_PASSWORD=your-password
DJANGO_EMAIL_USE_TLS=True
DJANGO_EMAIL_USE_SSL=False
DJANGO_DEFAULT_FROM_EMAIL=your-email@rambler.ru
DJANGO_SERVER_EMAIL=your-email@rambler.ru
```
## 🔐 Важные моменты безопасности
### Mail.ru
1. Перейдите в настройки почты
2. Включите "Пароль для внешних приложений"
3. Создайте специальный пароль приложения
4. Используйте этот пароль в `DJANGO_EMAIL_HOST_PASSWORD`
### Gmail
1. Включите двухфакторную аутентификацию
2. Создайте "Пароль приложения" в настройках Google Account
3. Используйте этот пароль в `DJANGO_EMAIL_HOST_PASSWORD`
### Yandex
1. Перейдите в настройки безопасности
2. Создайте "Пароль приложения"
3. Используйте этот пароль в `DJANGO_EMAIL_HOST_PASSWORD`
## 🧪 Тестирование email
Создайте файл для тестирования email в Django shell:
```python
# В Django shell: python manage.py shell
from django.core.mail import send_mail
send_mail(
'Тестовое письмо',
'Это тестовое сообщение для проверки email настроек.',
'from@example.com', # будет заменено на DEFAULT_FROM_EMAIL
['to@example.com'],
fail_silently=False,
)
```
## 🔧 Режим разработки
Для разработки используйте консольный backend:
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
```
Письма будут выводиться в консоль вместо отправки.
## 📁 Сохранение в файл
Для сохранения писем в файл:
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.filebased.EmailBackend
DJANGO_EMAIL_FILE_PATH=/app/sent_emails
```
## 🚫 Отключение email
Для полного отключения email:
```env
DJANGO_EMAIL_BACKEND=django.core.mail.backends.dummy.EmailBackend
```

95
scripts/check-api-endpoints.sh Executable file
View File

@@ -0,0 +1,95 @@
#!/bin/bash
# scripts/check-api-endpoints.sh - Проверка всех API эндпоинтов
set -e
echo "🌐 Проверка API эндпоинтов..."
echo "============================="
# Функция для тестирования эндпоинта
test_endpoint() {
local url="$1"
local expected_codes="$2"
local description="$3"
echo -n "🔗 $description: "
local response_code
response_code=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000")
if echo "$expected_codes" | grep -q "$response_code"; then
echo "✅ ($response_code)"
return 0
else
echo "❌ ($response_code)"
return 1
fi
}
echo ""
echo "📡 1. Прямые подключения к контейнерам:"
# Backend endpoints
test_endpoint "http://localhost:8000/admin/" "200 302" "Django Admin"
test_endpoint "http://localhost:8000/api/" "200 404" "Django API Root"
test_endpoint "http://localhost:8000/api/auth/register/" "405" "Register API"
test_endpoint "http://localhost:8000/static/" "404" "Static Files"
# Frontend endpoint
test_endpoint "http://localhost:3000/" "200" "Frontend Home"
echo ""
echo "📡 2. Через nginx (внешние подключения):"
# Through nginx
test_endpoint "http://localhost/admin/" "200 302" "Admin через nginx"
test_endpoint "http://localhost/api/" "200 404" "API через nginx"
test_endpoint "http://localhost/" "200" "Frontend через nginx"
echo ""
echo "📡 3. HTTPS эндпоинты (если SSL настроен):"
# HTTPS endpoints
test_endpoint "https://localhost/admin/" "200 302" "Admin HTTPS" || true
test_endpoint "https://localhost/api/" "200 404" "API HTTPS" || true
test_endpoint "https://localhost/" "200" "Frontend HTTPS" || true
# С доменным именем
test_endpoint "https://links.shareon.kr/admin/" "200 302" "Admin на домене" || true
test_endpoint "https://links.shareon.kr/api/" "200 404" "API на домене" || true
test_endpoint "https://links.shareon.kr/" "200" "Frontend на домене" || true
echo ""
echo "📡 4. Детальная проверка API:"
echo -n "🔗 API Schema (Swagger): "
swagger_code=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:8000/api/schema/" 2>/dev/null || echo "000")
if [ "$swagger_code" = "200" ]; then
echo "✅ ($swagger_code)"
else
echo "❌ ($swagger_code)"
fi
echo -n "🔗 API Documentation: "
docs_code=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:8000/api/docs/" 2>/dev/null || echo "000")
if [ "$docs_code" = "200" ]; then
echo "✅ ($docs_code)"
else
echo "❌ ($docs_code)"
fi
echo ""
echo "📡 5. Проверка специфических API эндпоинтов:"
# Проверяем конкретные API endpoints
echo -n "🔗 Auth endpoints: "
if curl -s -X POST -H "Content-Type: application/json" \
-d '{"username":"test","password":"test","email":"test@test.com"}' \
http://localhost:8000/api/auth/register/ 2>/dev/null | grep -q -E "(error|success|created|username|email)" 2>/dev/null; then
echo "✅ (отвечает)"
else
echo "❌ (не отвечает)"
fi
echo ""
echo "🏁 Проверка эндпоинтов завершена!"

78
scripts/check-db-connection.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
# scripts/check-db-connection.sh - Быстрая проверка подключения к БД
set -e
echo "🔗 Проверка подключения к базе данных..."
# Проверка из контейнера web
echo "📡 Тест 1: Django ORM подключение..."
if docker-compose exec -T web python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
django.setup()
from django.db import connection
from django.contrib.auth import get_user_model
try:
# Тест подключения
with connection.cursor() as cursor:
cursor.execute('SELECT 1')
print('✅ База данных отвечает')
# Тест ORM
User = get_user_model()
user_count = User.objects.count()
print(f'✅ Пользователей в системе: {user_count}')
# Тест миграций
from django.core.management import call_command
from io import StringIO
out = StringIO()
call_command('showmigrations', '--plan', stdout=out)
migrations_output = out.getvalue()
if '[X]' in migrations_output:
print('✅ Миграции применены')
else:
print('⚠️ Есть неприменённые миграции')
except Exception as e:
print(f'❌ Ошибка Django: {e}')
exit(1)
" 2>/dev/null; then
echo "✅ Django успешно подключается к БД"
else
echo "❌ Ошибка подключения Django к БД"
exit 1
fi
# Прямая проверка PostgreSQL
echo ""
echo "📡 Тест 2: Прямое подключение к PostgreSQL..."
if docker-compose exec -T db pg_isready -U links_user -d links_db; then
echo "✅ PostgreSQL готов к подключениям"
else
echo "❌ PostgreSQL не готов"
exit 1
fi
# Проверка таблиц
echo ""
echo "📡 Тест 3: Проверка структуры БД..."
if docker-compose exec -T db psql -U links_user -d links_db -c "
SELECT
schemaname,
tablename
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename;
" 2>/dev/null; then
echo "✅ Таблицы базы данных доступны"
else
echo "❌ Не удается получить список таблиц"
exit 1
fi
echo ""
echo "✅ Все проверки подключения к БД пройдены успешно!"

136
scripts/diagnose-server.sh Executable file
View File

@@ -0,0 +1,136 @@
#!/bin/bash
# scripts/diagnose-server.sh - Диагностика проблем на сервере
set -e
echo "🔍 Диагностика сервера CatLink..."
echo "================================="
echo ""
echo "📊 1. Статус Docker контейнеров:"
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo ""
echo "🔗 2. Статус сетей Docker:"
docker network ls
echo ""
echo "📡 3. Проверка подключения к базе данных:"
echo " Тестируем подключение из контейнера web к базе данных..."
if docker-compose exec -T web python -c "
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
django.setup()
from django.db import connection
try:
with connection.cursor() as cursor:
cursor.execute('SELECT 1')
print('✅ Подключение к базе данных успешно')
except Exception as e:
print(f'❌ Ошибка подключения к БД: {e}')
" 2>/dev/null; then
echo "✅ База данных доступна"
else
echo "❌ База данных недоступна"
fi
echo ""
echo "👥 4. Данные пользователей в базе:"
if docker-compose exec -T db psql -U links_user -d links_db -c "SELECT COUNT(*) as user_count FROM users_user;" 2>/dev/null; then
echo "✅ Таблица пользователей доступна"
docker-compose exec -T db psql -U links_user -d links_db -c "SELECT id, username, email, is_active, is_staff, is_superuser FROM users_user ORDER BY date_joined DESC LIMIT 5;"
else
echo "❌ Не удается получить данные пользователей"
fi
echo ""
echo "🌐 5. Проверка nginx конфигурации:"
if sudo nginx -t 2>/dev/null; then
echo "✅ Конфигурация nginx корректна"
else
echo "❌ Ошибка в конфигурации nginx"
fi
echo ""
echo "🔧 6. Статус nginx сервиса:"
sudo systemctl status nginx --no-pager -l
echo ""
echo "🚪 7. Проверка портов:"
echo " Порты, которые слушает система:"
sudo netstat -tlnp | grep -E ":(80|443|3000|8000|5432)" || echo "Нет активных портов"
echo ""
echo "📋 8. Логи nginx (последние 10 строк):"
sudo tail -10 /var/log/nginx/error.log 2>/dev/null || echo "Логи nginx недоступны"
echo ""
echo "📋 9. Логи Docker контейнеров:"
echo " --- Web контейнер (последние 5 строк) ---"
docker-compose logs --tail=5 web 2>/dev/null || echo "Логи web недоступны"
echo ""
echo " --- Frontend контейнер (последние 5 строк) ---"
docker-compose logs --tail=5 frontend 2>/dev/null || echo "Логи frontend недоступны"
echo ""
echo "🔗 10. Тест API эндпоинтов локально:"
echo " Тестируем доступность API..."
if curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/admin/ | grep -q "200\|302"; then
echo "✅ Django admin доступен по http://localhost:8000/admin/"
else
echo "❌ Django admin недоступен по http://localhost:8000/admin/"
fi
if curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/api/ | grep -q "200\|404"; then
echo "✅ Django API доступен по http://localhost:8000/api/"
else
echo "❌ Django API недоступен по http://localhost:8000/api/"
fi
if curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/ | grep -q "200"; then
echo "✅ Frontend доступен по http://localhost:3000/"
else
echo "❌ Frontend недоступен по http://localhost:3000/"
fi
echo ""
echo "🌍 11. Тест внешних эндпоинтов:"
echo " Тестируем доступность через nginx..."
if curl -s -o /dev/null -w "%{http_code}" http://localhost/admin/ | grep -q "200\|302"; then
echo "✅ Admin доступен через nginx: http://localhost/admin/"
else
echo "❌ Admin недоступен через nginx: http://localhost/admin/"
fi
if curl -s -o /dev/null -w "%{http_code}" http://localhost/api/ | grep -q "200\|404"; then
echo "✅ API доступен через nginx: http://localhost/api/"
else
echo "❌ API недоступен через nginx: http://localhost/api/"
fi
echo ""
echo "🔐 12. SSL сертификаты:"
if [ -d "/etc/letsencrypt/live" ]; then
echo "✅ Директория SSL сертификатов существует:"
sudo ls -la /etc/letsencrypt/live/ 2>/dev/null || echo "Не удается прочитать директорию сертификатов"
else
echo "❌ SSL сертификаты не найдены"
fi
echo ""
echo "📄 13. Переменные окружения (.env):"
echo " Проверяем ключевые переменные..."
if [ -f ".env" ]; then
echo "✅ Файл .env существует"
echo " DJANGO_DEBUG: $(grep '^DJANGO_DEBUG=' .env | cut -d= -f2)"
echo " NEXT_PUBLIC_API_URL: $(grep '^NEXT_PUBLIC_API_URL=' .env | cut -d= -f2)"
echo " DATABASE_HOST: $(grep '^DATABASE_HOST=' .env | cut -d= -f2)"
else
echo "❌ Файл .env не найден"
fi
echo ""
echo "🏁 Диагностика завершена!"
echo "================================="

75
scripts/fix-nginx-admin.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/bash
# scripts/fix-nginx-admin.sh - Исправление маршрута admin в nginx
set -e
echo "🔧 Исправление маршрута /admin в nginx..."
# Проверяем, существует ли файл конфигурации
if [ ! -f "/etc/nginx/sites-available/links" ]; then
echo "❌ Конфигурация nginx не найдена. Создаем новую..."
sudo ./scripts/setup-nginx.sh
exit 0
fi
echo "📄 Текущая конфигурация nginx:"
sudo cat /etc/nginx/sites-available/links | grep -A 5 -B 2 "location /admin"
echo ""
echo "🔍 Проверяем текущую конфигурацию..."
# Проверим, есть ли маршрут admin
if sudo grep -q "location /admin/" /etc/nginx/sites-available/links; then
echo "✅ Маршрут /admin/ найден в конфигурации"
else
echo "❌ Маршрут /admin/ не найден. Добавляем..."
# Создаем backup
sudo cp /etc/nginx/sites-available/links "/etc/nginx/sites-available/links.backup.$(date +%Y%m%d_%H%M%S)"
# Добавляем маршрут admin после API
sudo sed -i '/location \/api\// a\\n # Proxy admin requests to backend (Django)\n location /admin/ {\n proxy_pass http://localhost:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n }' /etc/nginx/sites-available/links
fi
echo ""
echo "🧪 Проверяем конфигурацию nginx..."
if sudo nginx -t; then
echo "✅ Конфигурация nginx корректна"
else
echo "❌ Ошибка в конфигурации nginx"
exit 1
fi
echo ""
echo "🔄 Перезагружаем nginx..."
sudo systemctl reload nginx
echo ""
echo "🧪 Тестируем маршрут /admin..."
sleep 2
if curl -s -o /dev/null -w "%{http_code}" http://localhost/admin/ | grep -q "200\|302"; then
echo "✅ Маршрут /admin/ работает через nginx"
else
echo "❌ Маршрут /admin/ не работает"
echo ""
echo "🔍 Дополнительная диагностика:"
echo " - Проверяем статус контейнеров:"
docker-compose ps
echo ""
echo " - Проверяем прямое подключение к Django:"
if curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/admin/ | grep -q "200\|302"; then
echo " ✅ Django admin доступен напрямую"
echo " ❌ Проблема в конфигурации nginx"
else
echo " ❌ Django admin недоступен напрямую"
echo " ❌ Проблема в Django контейнере"
fi
fi
echo ""
echo "📋 Полная конфигурация nginx:"
sudo cat /etc/nginx/sites-available/links
echo ""
echo "✅ Исправление завершено!"