Настройка Nginx для ботов
В этой статье мы рассмотрим настройку Nginx как reverse proxy для ботов, включая SSL сертификаты, балансировку нагрузки, кэширование и безопасность.Содержание
- Установка и базовая настройка
- Reverse Proxy для ботов
- SSL сертификаты
- Балансировка нагрузки
- Кэширование
- Безопасность
- Мониторинг и логирование
Установка и базовая настройка
Установка Nginx
#!/bin/bash
# install-nginx.sh
# Обновление системы
apt update && apt upgrade -y
# Установка Nginx
apt install -y nginx
# Запуск и включение автозапуска
systemctl start nginx
systemctl enable nginx
# Проверка статуса
systemctl status nginx
# Проверка конфигурации
nginx -t
echo "Nginx установлен и запущен!"Базовая конфигурация
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Основные настройки
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# MIME типы
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Логирование
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
# Gzip сжатие
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Безопасность
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Включение конфигураций сайтов
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}Reverse Proxy для ботов
Конфигурация для Telegram бота
# /etc/nginx/sites-available/telegram-bot
server {
listen 80;
server_name bot.yourdomain.com;
# Логирование
access_log /var/log/nginx/telegram-bot.access.log;
error_log /var/log/nginx/telegram-bot.error.log;
# Основной прокси
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Таймауты
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# Буферизация
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# Webhook для Telegram
location /webhook {
proxy_pass http://127.0.0.1:8000/webhook;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Специальные настройки для webhook
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# Статические файлы
location /static/ {
alias /home/botuser/telegram-bot/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Медиа файлы
location /media/ {
alias /home/botuser/telegram-bot/media/;
expires 1M;
add_header Cache-Control "public";
}
# Health check
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}Конфигурация для Discord бота
# /etc/nginx/sites-available/discord-bot
server {
listen 80;
server_name discord-bot.yourdomain.com;
# Логирование
access_log /var/log/nginx/discord-bot.access.log;
error_log /var/log/nginx/discord-bot.error.log;
# Основной прокси
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket поддержка
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# API endpoints
location /api/ {
proxy_pass http://127.0.0.1:8001/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Ограничение размера запроса
client_max_body_size 10M;
}
# Dashboard
location /dashboard {
proxy_pass http://127.0.0.1:8001/dashboard;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Аутентификация
auth_basic "Discord Bot Dashboard";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}Конфигурация для VK бота
# /etc/nginx/sites-available/vk-bot
server {
listen 80;
server_name vk-bot.yourdomain.com;
# Логирование
access_log /var/log/nginx/vk-bot.access.log;
error_log /var/log/nginx/vk-bot.error.log;
# Callback API для VK
location /callback {
proxy_pass http://127.0.0.1:8002/callback;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Специальные настройки для VK Callback
proxy_read_timeout 30s;
proxy_send_timeout 30s;
# Ограничение размера запроса
client_max_body_size 1M;
}
# Основной прокси
location / {
proxy_pass http://127.0.0.1:8002;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Статические файлы
location /static/ {
alias /home/botuser/vk-bot/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}SSL сертификаты
Let's Encrypt с Certbot
#!/bin/bash
# setup-ssl.sh
# Установка Certbot
apt install -y certbot python3-certbot-nginx
# Получение SSL сертификата
certbot --nginx -d bot.yourdomain.com -d discord-bot.yourdomain.com -d vk-bot.yourdomain.com
# Автоматическое обновление
echo "0 12 * /usr/bin/certbot renew --quiet" | crontab -
# Проверка обновления
certbot renew --dry-run
echo "SSL сертификаты настроены!"Конфигурация с SSL
# /etc/nginx/sites-available/telegram-bot-ssl
server {
listen 80;
server_name bot.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name bot.yourdomain.com;
# SSL сертификаты
ssl_certificate /etc/letsencrypt/live/bot.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bot.yourdomain.com/privkey.pem;
# SSL настройки
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Основной прокси
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Webhook для Telegram
location /webhook {
proxy_pass http://127.0.0.1:8000/webhook;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Балансировка нагрузки
Load Balancer конфигурация
# /etc/nginx/conf.d/load-balancer.conf
upstream telegram_bot_backend {
least_conn;
server 127.0.0.1:8000 weight=3 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8001 weight=2 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8002 weight=1 max_fails=3 fail_timeout=30s;
# Health check
keepalive 32;
}
upstream discord_bot_backend {
ip_hash;
server 127.0.0.1:9000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:9001 max_fails=3 fail_timeout=30s;
keepalive 32;
}
upstream vk_bot_backend {
round_robin;
server 127.0.0.1:7000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:7001 max_fails=3 fail_timeout=30s;
keepalive 32;
}Конфигурация с балансировкой
# /etc/nginx/sites-available/load-balanced-bots
server {
listen 443 ssl http2;
server_name bots.yourdomain.com;
# SSL настройки
ssl_certificate /etc/letsencrypt/live/bots.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bots.yourdomain.com/privkey.pem;
# Telegram бот
location /telegram/ {
proxy_pass http://telegram_bot_backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Health check
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
# Discord бот
location /discord/ {
proxy_pass http://discord_bot_backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket поддержка
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# VK бот
location /vk/ {
proxy_pass http://vk_bot_backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Статус балансировщика
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}Кэширование
Кэширование статических файлов
# /etc/nginx/conf.d/caching.conf
# Кэширование статических файлов
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
# Gzip сжатие
gzip_static on;
}
# Кэширование API ответов
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Кэширование
proxy_cache api_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
# Заголовки кэша
add_header X-Cache-Status $upstream_cache_status;
}
# Кэш зона
proxy_cache_path /var/cache/nginx/api levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m use_temp_path=off;Redis кэширование
# /etc/nginx/conf.d/redis-cache.conf
upstream redis_backend {
server 127.0.0.1:6379;
}
# Кэширование через Redis
location /cache/ {
# Проверка кэша в Redis
access_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
return
end
local key = ngx.var.request_uri
local res, err = red:get(key)
if res and res ~= ngx.null then
ngx.say(res)
ngx.exit(200)
end
}
# Если нет в кэше, проксируем запрос
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Сохранение в кэш
header_filter_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if ok then
local key = ngx.var.request_uri
local value = ngx.arg[1]
red:setex(key, 300, value) -- Кэш на 5 минут
end
}
}Безопасность
Ограничение доступа
# /etc/nginx/conf.d/security.conf
# Ограничение по IP
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=webhook:10m rate=5r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /webhook {
limit_req zone=webhook burst=10 nodelay;
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Блокировка вредоносных запросов
location / {
# Блокировка SQL инъекций
if ($args ~ "union.select.*\(") {
return 403;
}
# Блокировка XSS
if ($args ~ "<script.>") {
return 403;
}
# Блокировка попыток доступа к системным файлам
if ($uri ~* "\.(htaccess|htpasswd|ini|log|sh|sql|conf)$") {
return 403;
}
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}ModSecurity интеграция
#!/bin/bash
# install-modsecurity.sh
# Установка ModSecurity
apt install -y libmodsecurity3 modsecurity-crs
# Копирование правил
cp /usr/share/modsecurity-crs/crs-setup.conf.example /etc/nginx/modsec/crs-setup.conf
cp /usr/share/modsecurity-crs/rules/*.conf /etc/nginx/modsec/
# Настройка ModSecurity
cat > /etc/nginx/modsec/modsecurity.conf << EOF
SecRuleEngine On
SecRule REQUEST_HEADERS:Content-Type "text/xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "application/xml" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "application/soap+xml" \
"id:'200002',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
EOF
echo "ModSecurity установлен!"# /etc/nginx/sites-available/modsecurity-bot
server {
listen 443 ssl http2;
server_name secure-bot.yourdomain.com;
# ModSecurity
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
modsecurity_rules_file /etc/nginx/modsec/crs-setup.conf;
modsecurity_rules_file /etc/nginx/modsec/rules/*.conf;
# SSL настройки
ssl_certificate /etc/letsencrypt/live/secure-bot.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/secure-bot.yourdomain.com/privkey.pem;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Мониторинг и логирование
Расширенное логирование
# /etc/nginx/conf.d/logging.conf
# Расширенный формат логов
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'$upstream_cache_status';
# Логирование по сайтам
access_log /var/log/nginx/telegram-bot.access.log detailed;
access_log /var/log/nginx/discord-bot.access.log detailed;
access_log /var/log/nginx/vk-bot.access.log detailed;
# Логирование ошибок
error_log /var/log/nginx/telegram-bot.error.log warn;
error_log /var/log/nginx/discord-bot.error.log warn;
error_log /var/log/nginx/vk-bot.error.log warn;Мониторинг производительности
# nginx_monitor.py
import subprocess
import json
import time
import logging
from datetime import datetime
class NginxMonitor:
def __init__(self):
self.logger = logging.getLogger(__name__)
def get_nginx_status(self):
"""Получение статуса Nginx"""
try:
result = subprocess.run(
['curl', '-s', 'http://localhost/nginx_status'],
capture_output=True,
text=True
)
if result.returncode == 0:
lines = result.stdout.strip().split('\n')
status = {}
for line in lines:
if ':' in line:
key, value = line.split(':', 1)
status[key.strip()] = value.strip()
return status
except Exception as e:
self.logger.error(f"Error getting nginx status: {e}")
return None
def get_connection_stats(self):
"""Получение статистики соединений"""
try:
result = subprocess.run(
['ss', '-tuln'],
capture_output=True,
text=True
)
if result.returncode == 0:
connections = 0
for line in result.stdout.split('\n'):
if ':80 ' in line or ':443 ' in line:
connections += 1
return connections
except Exception as e:
self.logger.error(f"Error getting connection stats: {e}")
return 0
def monitor_performance(self):
"""Мониторинг производительности"""
while True:
try:
status = self.get_nginx_status()
connections = self.get_connection_stats()
if status:
self.logger.info(f"Nginx Status: {status}")
self.logger.info(f"Active Connections: {connections}")
time.sleep(60) # Проверка каждую минуту
except Exception as e:
self.logger.error(f"Error in monitoring: {e}")
time.sleep(60)
# Использование
monitor = NginxMonitor()
monitor.monitor_performance()Алерты и уведомления
#!/bin/bash
# nginx-alerts.sh
# Проверка статуса Nginx
check_nginx_status() {
if ! systemctl is-active --quiet nginx; then
echo "ALERT: Nginx is not running!"
# Отправка уведомления
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Nginx is down on server!"}' \
https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
fi
}
# Проверка использования памяти
check_memory_usage() {
memory_usage=$(free | grep Mem | awk '{printf "%.2f", $3/$2 * 100.0}')
if (( $(echo "$memory_usage > 90" | bc -l) )); then
echo "ALERT: High memory usage: ${memory_usage}%"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"High memory usage: ${memory_usage}%\"}" \
https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
fi
}
# Проверка размера логов
check_log_size() {
log_size=$(du -m /var/log/nginx/access.log | cut -f1)
if [ $log_size -gt 1000 ]; then
echo "ALERT: Log file is too large: ${log_size}MB"
# Ротация логов
logrotate -f /etc/logrotate.d/nginx
fi
}
# Запуск проверок
check_nginx_status
check_memory_usage
check_log_sizeЗаключение
В этой статье мы рассмотрели настройку Nginx для ботов:- ✅ Установка и базовая настройка
- ✅ Reverse Proxy для различных типов ботов
- ✅ SSL сертификаты и безопасность
- ✅ Балансировка нагрузки
- ✅ Кэширование и оптимизация
- ✅ Безопасность и защита
- ✅ Мониторинг и логирование
Полезные ссылки
1246 просмотров
8 лайков
1 комментариев
Комментарии (1)