From 34a1670ea92923e41984a5bdb68578e7e22d6a30 Mon Sep 17 00:00:00 2001 From: PTah Date: Sat, 20 Jun 2026 17:12:31 +1000 Subject: [PATCH] fix: nginx proxy timeout for long SSH/WinRM agent actions (0.20.3) Raise proxy_read_timeout to 960s for agent-update and related API paths so bootstrap git clone does not hit 504 from nginx. --- backend/app/version.py | 2 +- deploy/nginx/sac.conf.example | 13 +++++++ deploy/nginx/sac.conf.tls.example | 13 +++++++ tools/patch-nginx-sac-long-timeout.sh | 53 +++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tools/patch-nginx-sac-long-timeout.sh diff --git a/backend/app/version.py b/backend/app/version.py index eeb9dd6..05b91fc 100644 --- a/backend/app/version.py +++ b/backend/app/version.py @@ -1,5 +1,5 @@ """Единый источник версии SAC (API, health, логи, OpenAPI).""" APP_NAME = "Security Alert Center" -APP_VERSION = "0.20.2" +APP_VERSION = "0.20.3" APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}" diff --git a/deploy/nginx/sac.conf.example b/deploy/nginx/sac.conf.example index b32e1dd..7e60ce1 100644 --- a/deploy/nginx/sac.conf.example +++ b/deploy/nginx/sac.conf.example @@ -31,6 +31,19 @@ server { client_max_body_size 2m; + # SSH/WinRM и git-probe: backend ждёт до 900s + location ~ ^/api/v1/(hosts/[0-9]+/actions/(agent-update|agent-update-fallback|ssh-test|winrm-test)|settings/agent-updates/test-git) { + proxy_pass http://sac_api; + proxy_http_version 1.1; + 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 960s; + proxy_read_timeout 960s; + } + location / { proxy_pass http://sac_api; proxy_http_version 1.1; diff --git a/deploy/nginx/sac.conf.tls.example b/deploy/nginx/sac.conf.tls.example index 6f3f015..01906b8 100644 --- a/deploy/nginx/sac.conf.tls.example +++ b/deploy/nginx/sac.conf.tls.example @@ -56,6 +56,19 @@ server { client_max_body_size 2m; + # SSH/WinRM и git-probe: backend ждёт до 900s + location ~ ^/api/v1/(hosts/[0-9]+/actions/(agent-update|agent-update-fallback|ssh-test|winrm-test)|settings/agent-updates/test-git) { + proxy_pass http://sac_api; + proxy_http_version 1.1; + 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 960s; + proxy_read_timeout 960s; + } + location / { proxy_pass http://sac_api; proxy_http_version 1.1; diff --git a/tools/patch-nginx-sac-long-timeout.sh b/tools/patch-nginx-sac-long-timeout.sh new file mode 100644 index 0000000..e60d989 --- /dev/null +++ b/tools/patch-nginx-sac-long-timeout.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# Одноразовый hotfix: увеличить proxy_read_timeout для долгих SSH/WinRM API. +# Запуск на SAC-сервере: sudo bash patch-nginx-sac-long-timeout.sh +set -euo pipefail + +CFG="${SAC_NGINX_SITE:-/etc/nginx/sites-available/sac}" + +if [[ "$(id -u)" -ne 0 ]]; then + echo "Run as root: sudo bash $0" >&2 + exit 1 +fi + +if [[ ! -f "$CFG" ]]; then + echo "Config not found: $CFG" >&2 + exit 1 +fi + +if grep -q 'agent-update-fallback' "$CFG"; then + echo "Already patched: $CFG" +else + cp "$CFG" "${CFG}.bak-$(date +%Y%m%d%H%M%S)" + python3 - "$CFG" <<'PY' +import sys +from pathlib import Path + +path = Path(sys.argv[1]) +text = path.read_text(encoding="utf-8") +block = """ + # SSH/WinRM и git-probe: backend ждёт до 900s + location ~ ^/api/v1/(hosts/[0-9]+/actions/(agent-update|agent-update-fallback|ssh-test|winrm-test)|settings/agent-updates/test-git) { + proxy_pass http://sac_api; + proxy_http_version 1.1; + 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 960s; + proxy_read_timeout 960s; + } + +""" +needle = " location / {" +if needle not in text: + raise SystemExit(f"needle not found in {path}") +path.write_text(text.replace(needle, block + needle, 1), encoding="utf-8") +print(f"Patched {path}") +PY +fi + +nginx -t +systemctl reload nginx +echo "nginx reloaded OK"