351 lines
9.7 KiB
Bash
351 lines
9.7 KiB
Bash
#!/bin/bash
|
||
|
||
# MY Network - Защита сервиса (Шаг 2 из 2)
|
||
# Настройка безопасности, nginx, SSL, firewall
|
||
# Запускать после install_service.sh
|
||
|
||
set -e
|
||
|
||
echo "🔒 MY Network - Защита сервиса"
|
||
echo "==============================="
|
||
|
||
# Проверка прав root
|
||
if [[ $EUID -ne 0 ]]; then
|
||
echo "❌ Этот скрипт должен запускаться от root"
|
||
echo "Используйте: sudo bash secure_service.sh"
|
||
exit 1
|
||
fi
|
||
|
||
# Проверка конфигурации
|
||
CONFIG_FILE="/opt/my-network-config.txt"
|
||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||
echo "❌ Конфигурация не найдена!"
|
||
echo "Сначала запустите: sudo bash install_service.sh"
|
||
exit 1
|
||
fi
|
||
|
||
# Извлечение конфигурации
|
||
DOMAIN=$(grep "Домен:" $CONFIG_FILE | cut -d' ' -f2)
|
||
EMAIL=$(grep "Email:" $CONFIG_FILE | cut -d' ' -f2)
|
||
|
||
if [[ -z "$DOMAIN" || -z "$EMAIL" ]]; then
|
||
echo "❌ Не удалось прочитать конфигурацию!"
|
||
exit 1
|
||
fi
|
||
|
||
echo "📋 Настройки безопасности:"
|
||
echo " Домен: $DOMAIN"
|
||
echo " Email: $EMAIL"
|
||
echo " SSL: Let's Encrypt"
|
||
echo " Firewall: UFW"
|
||
echo ""
|
||
|
||
# Установка nginx и certbot
|
||
echo "🌐 Установка nginx и certbot..."
|
||
apt install -y nginx certbot python3-certbot-nginx
|
||
|
||
# Настройка nginx
|
||
echo "⚙️ Настройка nginx..."
|
||
cat > /etc/nginx/sites-available/my-network << EOF
|
||
# MY Network - nginx configuration
|
||
server {
|
||
listen 80;
|
||
server_name $DOMAIN;
|
||
|
||
# Redirect HTTP to HTTPS
|
||
return 301 https://\$server_name\$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name $DOMAIN;
|
||
|
||
# SSL Configuration (will be updated by certbot)
|
||
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
|
||
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
|
||
|
||
# Security headers
|
||
add_header X-Frame-Options DENY;
|
||
add_header X-Content-Type-Options nosniff;
|
||
add_header X-XSS-Protection "1; mode=block";
|
||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
||
|
||
# Hide nginx version
|
||
server_tokens off;
|
||
|
||
# Rate limiting
|
||
limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s;
|
||
limit_req_zone \$binary_remote_addr zone=monitor:10m rate=2r/s;
|
||
|
||
# Main application
|
||
location / {
|
||
limit_req zone=api burst=20 nodelay;
|
||
|
||
proxy_pass http://127.0.0.1:15100;
|
||
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 support
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade \$http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
|
||
# Timeouts
|
||
proxy_connect_timeout 60s;
|
||
proxy_send_timeout 60s;
|
||
proxy_read_timeout 60s;
|
||
}
|
||
|
||
# Monitoring interface (restricted)
|
||
location /api/my/monitor {
|
||
limit_req zone=monitor burst=5 nodelay;
|
||
|
||
# IP whitelist (localhost only by default)
|
||
allow 127.0.0.1;
|
||
allow ::1;
|
||
deny all;
|
||
|
||
proxy_pass http://127.0.0.1:15100;
|
||
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;
|
||
}
|
||
|
||
# Static files
|
||
location /static/ {
|
||
alias /opt/my-network/my-uploader-bot/static/;
|
||
expires 30d;
|
||
add_header Cache-Control "public, immutable";
|
||
}
|
||
|
||
# Block sensitive paths
|
||
location ~ /\.(?!well-known) {
|
||
deny all;
|
||
}
|
||
|
||
location ~ ^/(config|\.env|requirements|docker-compose) {
|
||
deny all;
|
||
}
|
||
}
|
||
EOF
|
||
|
||
# Включение сайта
|
||
ln -sf /etc/nginx/sites-available/my-network /etc/nginx/sites-enabled/
|
||
rm -f /etc/nginx/sites-enabled/default
|
||
|
||
# Проверка конфигурации nginx
|
||
nginx -t
|
||
|
||
# Получение SSL сертификата
|
||
echo "🔐 Получение SSL сертификата..."
|
||
certbot --nginx -d $DOMAIN --email $EMAIL --agree-tos --non-interactive --redirect
|
||
|
||
# Настройка автообновления сертификата
|
||
echo "🔄 Настройка автообновления SSL..."
|
||
(crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab -
|
||
|
||
# Настройка firewall
|
||
echo "🔥 Настройка firewall..."
|
||
ufw --force reset
|
||
ufw default deny incoming
|
||
ufw default allow outgoing
|
||
|
||
# Разрешение SSH (проверяем текущий порт)
|
||
SSH_PORT=$(ss -tlnp | grep sshd | grep -o ':[0-9]*' | head -1 | cut -d: -f2)
|
||
if [[ -n "$SSH_PORT" ]]; then
|
||
echo "🔑 Разрешение SSH на порту $SSH_PORT..."
|
||
ufw allow $SSH_PORT/tcp comment 'SSH'
|
||
fi
|
||
|
||
# Разрешение HTTP/HTTPS
|
||
ufw allow 80/tcp comment 'HTTP'
|
||
ufw allow 443/tcp comment 'HTTPS'
|
||
|
||
# Разрешение внутренних соединений
|
||
ufw allow from 127.0.0.1 to any port 15100 comment 'MY Network internal'
|
||
|
||
# Включение firewall
|
||
ufw --force enable
|
||
|
||
# Дополнительная защита системы
|
||
echo "🛡️ Дополнительная защита..."
|
||
|
||
# Отключение ненужных сервисов
|
||
systemctl disable --now apache2 2>/dev/null || true
|
||
systemctl disable --now nginx 2>/dev/null || true
|
||
|
||
# Запуск nginx
|
||
systemctl enable nginx
|
||
systemctl start nginx
|
||
|
||
# Настройка fail2ban
|
||
echo "🚫 Установка fail2ban..."
|
||
apt install -y fail2ban
|
||
|
||
cat > /etc/fail2ban/jail.local << EOF
|
||
[DEFAULT]
|
||
bantime = 3600
|
||
findtime = 600
|
||
maxretry = 5
|
||
|
||
[sshd]
|
||
enabled = true
|
||
port = $SSH_PORT
|
||
filter = sshd
|
||
logpath = /var/log/auth.log
|
||
|
||
[nginx-http-auth]
|
||
enabled = true
|
||
filter = nginx-http-auth
|
||
logpath = /var/log/nginx/error.log
|
||
|
||
[nginx-limit-req]
|
||
enabled = true
|
||
filter = nginx-limit-req
|
||
logpath = /var/log/nginx/error.log
|
||
maxretry = 3
|
||
EOF
|
||
|
||
systemctl enable fail2ban
|
||
systemctl start fail2ban
|
||
|
||
# Настройка logrotate
|
||
echo "📜 Настройка ротации логов..."
|
||
cat > /etc/logrotate.d/my-network << EOF
|
||
/opt/logs/*.log {
|
||
daily
|
||
missingok
|
||
rotate 30
|
||
compress
|
||
delaycompress
|
||
notifempty
|
||
copytruncate
|
||
}
|
||
EOF
|
||
|
||
# Настройка мониторинга
|
||
echo "📊 Настройка мониторинга..."
|
||
cat > /opt/monitor.sh << 'EOF'
|
||
#!/bin/bash
|
||
# MY Network monitoring script
|
||
|
||
LOG_FILE="/opt/logs/monitor.log"
|
||
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||
|
||
# Check service status
|
||
if systemctl is-active --quiet my-network; then
|
||
SERVICE_STATUS="OK"
|
||
else
|
||
SERVICE_STATUS="FAIL"
|
||
fi
|
||
|
||
# Check nginx status
|
||
if systemctl is-active --quiet nginx; then
|
||
NGINX_STATUS="OK"
|
||
else
|
||
NGINX_STATUS="FAIL"
|
||
fi
|
||
|
||
# Check disk space
|
||
DISK_USAGE=$(df -h /opt | awk 'NR==2 {print $5}' | sed 's/%//')
|
||
if [[ $DISK_USAGE -gt 90 ]]; then
|
||
DISK_STATUS="CRITICAL"
|
||
elif [[ $DISK_USAGE -gt 80 ]]; then
|
||
DISK_STATUS="WARNING"
|
||
else
|
||
DISK_STATUS="OK"
|
||
fi
|
||
|
||
# Check memory
|
||
MEM_USAGE=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100.0}')
|
||
if [[ $MEM_USAGE -gt 90 ]]; then
|
||
MEM_STATUS="CRITICAL"
|
||
elif [[ $MEM_USAGE -gt 80 ]]; then
|
||
MEM_STATUS="WARNING"
|
||
else
|
||
MEM_STATUS="OK"
|
||
fi
|
||
|
||
# Log status
|
||
echo "[$DATE] Service: $SERVICE_STATUS, Nginx: $NGINX_STATUS, Disk: $DISK_STATUS ($DISK_USAGE%), Memory: $MEM_STATUS ($MEM_USAGE%)" >> $LOG_FILE
|
||
|
||
# Alert if critical
|
||
if [[ "$SERVICE_STATUS" == "FAIL" || "$NGINX_STATUS" == "FAIL" || "$DISK_STATUS" == "CRITICAL" || "$MEM_STATUS" == "CRITICAL" ]]; then
|
||
echo "[$DATE] ALERT: Critical status detected!" >> $LOG_FILE
|
||
# Here you can add email notification or webhook
|
||
fi
|
||
EOF
|
||
|
||
chmod +x /opt/monitor.sh
|
||
|
||
# Добавление в cron
|
||
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/monitor.sh") | crontab -
|
||
|
||
# Обновление конфигурации
|
||
echo "💾 Обновление конфигурации..."
|
||
cat >> /opt/my-network-config.txt << EOF
|
||
|
||
Безопасность настроена:
|
||
======================
|
||
SSL: Включен (Let's Encrypt)
|
||
Firewall: Включен (UFW)
|
||
Nginx: Включен с rate limiting
|
||
Fail2ban: Включен
|
||
Мониторинг: /opt/monitor.sh (каждые 5 мин)
|
||
|
||
Проверка безопасности:
|
||
ufw status
|
||
systemctl status nginx
|
||
systemctl status fail2ban
|
||
certbot certificates
|
||
|
||
Логи безопасности:
|
||
/var/log/nginx/access.log
|
||
/var/log/nginx/error.log
|
||
/var/log/fail2ban.log
|
||
/opt/logs/monitor.log
|
||
EOF
|
||
|
||
# Финальная проверка
|
||
echo "🔍 Финальная проверка..."
|
||
sleep 3
|
||
|
||
echo "🌐 Проверка nginx..."
|
||
systemctl status nginx --no-pager -l
|
||
|
||
echo "🔥 Статус firewall..."
|
||
ufw status numbered
|
||
|
||
echo "🔐 SSL сертификаты..."
|
||
certbot certificates
|
||
|
||
echo "📡 Проверка доступности..."
|
||
curl -s -o /dev/null -w "%{http_code}" https://$DOMAIN/api/my/health || echo "Сервис недоступен"
|
||
|
||
echo ""
|
||
echo "✅ MY Network защищен!"
|
||
echo "======================"
|
||
echo "🌐 Домен: https://$DOMAIN"
|
||
echo "🔐 SSL: Включен"
|
||
echo "🔥 Firewall: Включен"
|
||
echo "🚫 Fail2ban: Включен"
|
||
echo "📊 Мониторинг: Включен"
|
||
echo ""
|
||
echo "🔍 Проверка работы:"
|
||
echo " curl https://$DOMAIN/api/my/health"
|
||
echo " systemctl status my-network nginx fail2ban"
|
||
echo ""
|
||
echo "📈 Мониторинг:"
|
||
echo " https://$DOMAIN/api/my/monitor/ (только с localhost)"
|
||
echo " tail -f /opt/logs/monitor.log"
|
||
echo ""
|
||
echo "🛡️ Безопасность:"
|
||
echo " ufw status"
|
||
echo " fail2ban-client status"
|
||
echo " certbot certificates"
|
||
echo ""
|
||
echo "📚 Полная документация: /opt/my-network/my-uploader-bot/DOCS_RU.md" |