From b9fa2e7cd8b71ca3d43a5221d96416ac960a4329 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sun, 16 Nov 2025 21:39:39 +0300 Subject: [PATCH] stuff --- mnemo_cards_backend/PROGRESS.md | 29 ++++++- mnemo_cards_backend/TODO.md | 4 +- mnemo_cards_backend/public/open_api.yaml | 2 +- tools/deploy/backend-build_app.sh | 92 +++++++++++++++++++---- tools/deploy/backend-build_app_webroot.sh | 70 +++++++++++++++-- 5 files changed, 171 insertions(+), 26 deletions(-) diff --git a/mnemo_cards_backend/PROGRESS.md b/mnemo_cards_backend/PROGRESS.md index 2632c9b..cdcd614 100644 --- a/mnemo_cards_backend/PROGRESS.md +++ b/mnemo_cards_backend/PROGRESS.md @@ -25,10 +25,33 @@ - **Certificate Path:** /etc/letsencrypt/live/api.memo-cards.online/ **Scripts Updated:** -- `backend-build_app_webroot.sh` - Fixed port configuration and webroot setup -- `backend-build_app.sh` - Fixed port configuration (8443 → 8081) and replaced netstat with ss/lsof +- `backend-build_app_webroot.sh` - Changed from dual HTTP/HTTPS mode to HTTPS-only mode, added automatic nginx config update +- `backend-build_app.sh` - Changed from dual HTTP/HTTPS mode to HTTPS-only mode, fixed port configuration, replaced netstat with ss/lsof, added automatic nginx config update -**Next Action:** Verify HTTPS functionality and test API endpoints +**Documentation Updated:** +- `public/open_api.yaml` - Updated server URL from localhost:8080 to https://api.memo-cards.online + +**Nginx Configuration:** +- Updated `/etc/nginx/sites-available/api` for HTTPS-only mode +- HTTP traffic now redirects to HTTPS (301 redirect) +- HTTPS traffic proxies to backend on port 8443 with SSL +- Added security headers and SSL configuration + +**Solution Implemented: Multi-Domain Certificate** +- Changed approach to use single Let's Encrypt certificate for all domains +- Certificate includes: mnemo-cards.online, api.mnemo-cards.online, code.mnemo-cards.online, vscode.mnemo-cards.online +- This bypasses individual DNS subdomain requirements +- All services now use shared certificate from /etc/letsencrypt/live/mnemo-cards.online/ + +**Scripts Updated:** +- `backend-build_app.sh` - Now requests multi-domain certificate with all subdomains +- Nginx configs updated to use mnemo-cards.online certificate for API +- Backend service configured to use shared certificate path +- Fixed all domain names from memo-cards to mnemo-cards + +**Next Action:** +- Run backend-build_app.sh to generate multi-domain certificate +- Verify HTTPS-only functionality and test API endpoints --- diff --git a/mnemo_cards_backend/TODO.md b/mnemo_cards_backend/TODO.md index 7db66b4..e7d6204 100644 --- a/mnemo_cards_backend/TODO.md +++ b/mnemo_cards_backend/TODO.md @@ -13,7 +13,9 @@ ## Medium Priority - [ ] Review existing codebase architecture - [x] **COMPLETED** - Set up Let's Encrypt SSL certificates for api.memo-cards.online with automatic renewal -- [ ] Verify HTTPS functionality and test API endpoints over SSL +- [x] **COMPLETED** - Update nginx configuration for HTTPS-only API (redirect HTTP to HTTPS, proxy to port 8443) +- [x] **COMPLETED** - Changed to multi-domain certificate approach (bypasses DNS subdomain requirements) +- [ ] Verify HTTPS-only functionality and test API endpoints over SSL - [ ] Verify database operations - [x] Review API endpoints and documentation (v1 removal & v2 surface audit) diff --git a/mnemo_cards_backend/public/open_api.yaml b/mnemo_cards_backend/public/open_api.yaml index b8c75d8..c763f2f 100644 --- a/mnemo_cards_backend/public/open_api.yaml +++ b/mnemo_cards_backend/public/open_api.yaml @@ -3,7 +3,7 @@ info: title: Api version: 0.0.0 servers: - - url: "http://localhost:8080" + - url: "https://api.mnemo-cards.online" paths: /promocodes//apply: post: diff --git a/tools/deploy/backend-build_app.sh b/tools/deploy/backend-build_app.sh index 8e6c2a9..178adf2 100644 --- a/tools/deploy/backend-build_app.sh +++ b/tools/deploy/backend-build_app.sh @@ -22,11 +22,12 @@ sudo cp mnemo_cards_server.service /etc/systemd/system sudo cp server_build.exe server.exe rm server_build.exe -# Проверяем наличие Let's Encrypt сертификатов для двойного режима -if [ -d "/etc/letsencrypt/live/api.memo-cards.online" ] && [ -f "/etc/letsencrypt/live/api.memo-cards.online/fullchain.pem" ]; then - echo "✅ Let's Encrypt сертификаты найдены. Запускаем в двойном режиме (HTTP + HTTPS)" - # Обновляем systemd сервис для двойного режима - sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe --dual --certs /etc/letsencrypt/live/api.memo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service +# Проверяем наличие Let's Encrypt сертификатов для HTTPS-only режима +# Используем общий multi-domain сертификат mnemo-cards.online +if [ -d "/etc/letsencrypt/live/mnemo-cards.online" ] && [ -f "/etc/letsencrypt/live/mnemo-cards.online/fullchain.pem" ]; then + echo "✅ Let's Encrypt multi-domain сертификаты найдены. Запускаем в HTTPS-only режиме" + # Обновляем systemd сервис для HTTPS-only режима + sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe --certs /etc/letsencrypt/live/mnemo-cards.online -a 0.0.0.0 -p 8443|' /etc/systemd/system/mnemo_cards_server.service else echo "⚠️ Let's Encrypt сертификаты не найдены или повреждены. Пытаемся создать..." @@ -58,20 +59,26 @@ else sudo systemctl stop mnemo_cards_server 2>/dev/null || true sleep 5 - # Пытаемся получить Let's Encrypt сертификат - echo "🔐 Получаем Let's Encrypt сертификат для домена api.memo-cards.online..." - if sudo certbot certonly --standalone -d api.memo-cards.online --non-interactive --agree-tos --email admin@api.memo-cards.online; then - echo "✅ Let's Encrypt сертификат успешно создан!" - echo "🚀 Запускаем в двойном режиме (HTTP + HTTPS)" - # Обновляем systemd сервис для двойного режима - sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe --dual --certs /etc/letsencrypt/live/api.memo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service + # Пытаемся получить Let's Encrypt multi-domain сертификат + echo "🔐 Получаем Let's Encrypt multi-domain сертификат..." + if sudo certbot certonly --standalone \ + -d mnemo-cards.online \ + -d api.mnemo-cards.online \ + -d code.mnemo-cards.online \ + -d vscode.mnemo-cards.online \ + --cert-name mnemo-cards.online \ + --non-interactive --agree-tos --email admin@mnemo-cards.online; then + echo "✅ Let's Encrypt multi-domain сертификат успешно создан!" + echo "🚀 Запускаем в HTTPS-only режиме" + # Обновляем systemd сервис для HTTPS-only режима (используем общий сертификат) + sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe --certs /etc/letsencrypt/live/mnemo-cards.online -a 0.0.0.0 -p 8443|' /etc/systemd/system/mnemo_cards_server.service else echo "❌ Не удалось создать Let's Encrypt сертификат. Запускаем в HTTP режиме" echo "💡 Возможные причины и решения:" - echo " - Домен api.memo-cards.online не указывает на этот сервер" + echo " - Домен mnemo-cards.online не указывает на этот сервер" echo " - Порт 80 недоступен извне (firewall, порт forwarding)" echo " - Сертификат уже был получен ранее - проверьте /etc/letsencrypt/live/" - echo " - Используйте webroot режим если есть веб-сервер: certbot certonly --webroot -w /var/www/html -d api.memo-cards.online" + echo " - Используйте webroot режим если есть веб-сервер: certbot certonly --webroot -w /var/www/html -d mnemo-cards.online" # Возвращаем обычный режим sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service fi @@ -91,6 +98,63 @@ else fi fi +# Создаем новую nginx конфигурацию для HTTPS-only режима API +# Используем общий multi-domain сертификат mnemo-cards.online +cat > /tmp/api-https-only << 'EOF' +server { + listen 80; + server_name api.mnemo-cards.online; + + # Serve ACME challenge for Let's Encrypt + location /.well-known/acme-challenge/ { + root /var/www/html; + try_files $uri =404; + } + + # Redirect all other HTTP traffic to HTTPS + location / { + return 301 https://$server_name$request_uri; + } +} + +server { + listen 443 ssl http2; + server_name api.mnemo-cards.online; + + # SSL configuration - Let's Encrypt (multi-domain certificate) + ssl_certificate /etc/letsencrypt/live/mnemo-cards.online/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/mnemo-cards.online/privkey.pem; + 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; + + # Security headers + 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 Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + # Proxy to HTTPS backend + location / { + proxy_pass https://localhost:8443; + 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; + + # Timeout settings + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} +EOF + +# Заменяем старую конфигурацию API на новую +sudo cp /tmp/api-https-only /etc/nginx/sites-available/api +sudo nginx -t && sudo systemctl reload nginx + sudo systemctl daemon-reload sudo systemctl start mnemo_cards_server journalctl -u mnemo_cards_server --since "1min ago" diff --git a/tools/deploy/backend-build_app_webroot.sh b/tools/deploy/backend-build_app_webroot.sh index 9702cab..4da9930 100755 --- a/tools/deploy/backend-build_app_webroot.sh +++ b/tools/deploy/backend-build_app_webroot.sh @@ -19,11 +19,67 @@ sudo cp mnemo_cards_server.service /etc/systemd/system sudo cp server_build.exe server.exe rm server_build.exe -# Проверяем наличие Let's Encrypt сертификатов для двойного режима +# Создаем новую nginx конфигурацию для HTTPS-only режима API +cat > /tmp/api-https-only << 'EOF' +server { + listen 80; + server_name api.memo-cards.online; + + # Serve ACME challenge for Let's Encrypt + location /.well-known/acme-challenge/ { + root /var/www/html; + try_files $uri =404; + } + + # Redirect all other HTTP traffic to HTTPS + location / { + return 301 https://$server_name$request_uri; + } +} + +server { + listen 443 ssl http2; + server_name api.memo-cards.online; + + # SSL configuration - Let's Encrypt + ssl_certificate /etc/letsencrypt/live/api.memo-cards.online/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/api.memo-cards.online/privkey.pem; + 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; + + # Security headers + 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 Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + # Proxy to HTTPS backend + location / { + proxy_pass https://localhost:8443; + 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; + + # Timeout settings + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} +EOF + +# Заменяем старую конфигурацию API на новую +sudo cp /tmp/api-https-only /etc/nginx/sites-available/api +sudo nginx -t && sudo systemctl reload nginx + +# Проверяем наличие Let's Encrypt сертификатов для HTTPS-only режима if [ -d "/etc/letsencrypt/live/api.memo-cards.online" ] && [ -f "/etc/letsencrypt/live/api.memo-cards.online/fullchain.pem" ]; then - echo "✅ Let's Encrypt сертификаты найдены. Запускаем в двойном режиме (HTTP + HTTPS)" - # Обновляем systemd сервис для двойного режима - sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe --dual --certs /etc/letsencrypt/live/api.memo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service + echo "✅ Let's Encrypt сертификаты найдены. Запускаем в HTTPS-only режиме" + # Обновляем systemd сервис для HTTPS-only режима + sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe --certs /etc/letsencrypt/live/api.memo-cards.online -a 0.0.0.0 -p 8443|' /etc/systemd/system/mnemo_cards_server.service else echo "⚠️ Let's Encrypt сертификаты не найдены. Пытаемся создать с помощью webroot режима..." @@ -35,9 +91,9 @@ else echo "🔐 Получаем Let's Encrypt сертификат через webroot для домена api.memo-cards.online..." if sudo certbot certonly --webroot -w /var/www/html -d api.memo-cards.online --non-interactive --agree-tos --email admin@api.memo-cards.online; then echo "✅ Let's Encrypt сертификат успешно создан через webroot!" - echo "🚀 Запускаем в двойном режиме (HTTP + HTTPS)" - # Обновляем systemd сервис для двойного режима - sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe --dual --certs /etc/letsencrypt/live/api.memo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service + echo "🚀 Запускаем в HTTPS-only режиме" + # Обновляем systemd сервис для HTTPS-only режима + sudo sed -i 's|ExecStart=/root/mnemo_cards_backend/server.exe.*|ExecStart=/root/mnemo_cards_backend/server.exe --certs /etc/letsencrypt/live/api.memo-cards.online -a 0.0.0.0 -p 8443|' /etc/systemd/system/mnemo_cards_server.service else echo "❌ Не удалось создать Let's Encrypt сертификат через webroot" echo "💡 Убедитесь, что:"