mirror of
https://github.com/TronoSfera/Law.git
synced 2026-05-18 10:03:45 +03:00
add security test 02
This commit is contained in:
parent
e0bcf72a09
commit
9a403ed32f
4 changed files with 53 additions and 6 deletions
9
Makefile
9
Makefile
|
|
@ -15,6 +15,9 @@ SECOND_DOMAIN ?= ruakb.online
|
||||||
SECOND_WWW_DOMAIN ?= www.ruakb.online
|
SECOND_WWW_DOMAIN ?= www.ruakb.online
|
||||||
LETSENCRYPT_EMAIL ?= admin@ruakb.ru
|
LETSENCRYPT_EMAIL ?= admin@ruakb.ru
|
||||||
AUTO_CERT_INIT ?= 0
|
AUTO_CERT_INIT ?= 0
|
||||||
|
SKIP_LOCAL_SMOKE ?= 0
|
||||||
|
LOCAL_SMOKE_BASE_URL ?= https://127.0.0.1
|
||||||
|
LOCAL_SMOKE_CANDIDATES ?= $(LOCAL_SMOKE_BASE_URL),https://localhost,http://127.0.0.1,http://localhost
|
||||||
CONFIRM_TOKEN ?= ROTATE-PROD-SECRETS
|
CONFIRM_TOKEN ?= ROTATE-PROD-SECRETS
|
||||||
CERTBOT_DOMAINS = -d "$(DOMAIN)" -d "$(WWW_DOMAIN)" $(if $(strip $(SECOND_DOMAIN)),-d "$(SECOND_DOMAIN)") $(if $(strip $(SECOND_WWW_DOMAIN)),-d "$(SECOND_WWW_DOMAIN)")
|
CERTBOT_DOMAINS = -d "$(DOMAIN)" -d "$(WWW_DOMAIN)" $(if $(strip $(SECOND_DOMAIN)),-d "$(SECOND_DOMAIN)") $(if $(strip $(SECOND_WWW_DOMAIN)),-d "$(SECOND_WWW_DOMAIN)")
|
||||||
|
|
||||||
|
|
@ -52,6 +55,9 @@ help:
|
||||||
@echo " SECOND_DOMAIN=$(SECOND_DOMAIN)"
|
@echo " SECOND_DOMAIN=$(SECOND_DOMAIN)"
|
||||||
@echo " SECOND_WWW_DOMAIN=$(SECOND_WWW_DOMAIN)"
|
@echo " SECOND_WWW_DOMAIN=$(SECOND_WWW_DOMAIN)"
|
||||||
@echo " AUTO_CERT_INIT=$(AUTO_CERT_INIT)"
|
@echo " AUTO_CERT_INIT=$(AUTO_CERT_INIT)"
|
||||||
|
@echo " SKIP_LOCAL_SMOKE=$(SKIP_LOCAL_SMOKE)"
|
||||||
|
@echo " LOCAL_SMOKE_BASE_URL=$(LOCAL_SMOKE_BASE_URL)"
|
||||||
|
@echo " LOCAL_SMOKE_CANDIDATES=$(LOCAL_SMOKE_CANDIDATES)"
|
||||||
|
|
||||||
local-up:
|
local-up:
|
||||||
$(LOCAL_COMPOSE) up -d --build
|
$(LOCAL_COMPOSE) up -d --build
|
||||||
|
|
@ -119,6 +125,9 @@ prod-security-audit: check-cert-files
|
||||||
SECOND_WWW_DOMAIN="$(SECOND_WWW_DOMAIN)" \
|
SECOND_WWW_DOMAIN="$(SECOND_WWW_DOMAIN)" \
|
||||||
LETSENCRYPT_EMAIL="$(LETSENCRYPT_EMAIL)" \
|
LETSENCRYPT_EMAIL="$(LETSENCRYPT_EMAIL)" \
|
||||||
AUTO_CERT_INIT="$(AUTO_CERT_INIT)" \
|
AUTO_CERT_INIT="$(AUTO_CERT_INIT)" \
|
||||||
|
SKIP_LOCAL_SMOKE="$(SKIP_LOCAL_SMOKE)" \
|
||||||
|
LOCAL_SMOKE_BASE_URL="$(LOCAL_SMOKE_BASE_URL)" \
|
||||||
|
LOCAL_SMOKE_CANDIDATES="$(LOCAL_SMOKE_CANDIDATES)" \
|
||||||
./scripts/ops/prod_security_audit.sh
|
./scripts/ops/prod_security_audit.sh
|
||||||
|
|
||||||
rotate-encryption-kid:
|
rotate-encryption-kid:
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -355,6 +355,22 @@ Optional: auto-bootstrap Let's Encrypt certs if HTTPS health is failing:
|
||||||
make prod-security-audit AUTO_CERT_INIT=1 DOMAIN=ruakb.ru WWW_DOMAIN=www.ruakb.ru SECOND_DOMAIN=ruakb.online SECOND_WWW_DOMAIN=www.ruakb.online LETSENCRYPT_EMAIL=you@example.com
|
make prod-security-audit AUTO_CERT_INIT=1 DOMAIN=ruakb.ru WWW_DOMAIN=www.ruakb.ru SECOND_DOMAIN=ruakb.online SECOND_WWW_DOMAIN=www.ruakb.online LETSENCRYPT_EMAIL=you@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If localhost loopback probes are not desired on production host:
|
||||||
|
```bash
|
||||||
|
make prod-security-audit SKIP_LOCAL_SMOKE=1 DOMAIN=ruakb.ru WWW_DOMAIN=www.ruakb.ru SECOND_DOMAIN=ruakb.online SECOND_WWW_DOMAIN=www.ruakb.online LETSENCRYPT_EMAIL=you@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
By default local smoke probes now try multiple loopback endpoints:
|
||||||
|
- `https://127.0.0.1`
|
||||||
|
- `https://localhost`
|
||||||
|
- `http://127.0.0.1`
|
||||||
|
- `http://localhost`
|
||||||
|
|
||||||
|
You can override:
|
||||||
|
```bash
|
||||||
|
make prod-security-audit LOCAL_SMOKE_CANDIDATES="https://127.0.0.1,http://127.0.0.1"
|
||||||
|
```
|
||||||
|
|
||||||
## Container health and alerting
|
## Container health and alerting
|
||||||
Docker Compose is configured with:
|
Docker Compose is configured with:
|
||||||
- `restart: unless-stopped` for core services
|
- `restart: unless-stopped` for core services
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ EMAIL_HEALTH_URL="${BASE_URL%/}/email-health"
|
||||||
|
|
||||||
check_http_200() {
|
check_http_200() {
|
||||||
url="$1"
|
url="$1"
|
||||||
code="$(curl -L -sS -o /dev/null -w "%{http_code}" "$url" || true)"
|
code="$(curl -k -L -sS -o /dev/null -w "%{http_code}" "$url" || true)"
|
||||||
[ "$code" = "200" ]
|
[ "$code" = "200" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ SECOND_DOMAIN="${SECOND_DOMAIN:-ruakb.online}"
|
||||||
SECOND_WWW_DOMAIN="${SECOND_WWW_DOMAIN:-www.ruakb.online}"
|
SECOND_WWW_DOMAIN="${SECOND_WWW_DOMAIN:-www.ruakb.online}"
|
||||||
LETSENCRYPT_EMAIL="${LETSENCRYPT_EMAIL:-admin@ruakb.ru}"
|
LETSENCRYPT_EMAIL="${LETSENCRYPT_EMAIL:-admin@ruakb.ru}"
|
||||||
AUTO_CERT_INIT="${AUTO_CERT_INIT:-0}"
|
AUTO_CERT_INIT="${AUTO_CERT_INIT:-0}"
|
||||||
|
SKIP_LOCAL_SMOKE="${SKIP_LOCAL_SMOKE:-0}"
|
||||||
|
LOCAL_SMOKE_BASE_URL="${LOCAL_SMOKE_BASE_URL:-https://127.0.0.1}"
|
||||||
|
LOCAL_SMOKE_CANDIDATES="${LOCAL_SMOKE_CANDIDATES:-${LOCAL_SMOKE_BASE_URL},https://localhost,http://127.0.0.1,http://localhost}"
|
||||||
|
|
||||||
PROD_COMPOSE=(docker compose -f docker-compose.yml -f docker-compose.prod.nginx.yml)
|
PROD_COMPOSE=(docker compose -f docker-compose.yml -f docker-compose.prod.nginx.yml)
|
||||||
CERT_COMPOSE=(docker compose -f docker-compose.yml -f docker-compose.prod.nginx.yml -f docker-compose.prod.cert.yml)
|
CERT_COMPOSE=(docker compose -f docker-compose.yml -f docker-compose.prod.nginx.yml -f docker-compose.prod.cert.yml)
|
||||||
|
|
@ -92,15 +95,34 @@ PY
|
||||||
}
|
}
|
||||||
|
|
||||||
run_local_smoke() {
|
run_local_smoke() {
|
||||||
log "Running local smoke checks via localhost"
|
if [[ "$SKIP_LOCAL_SMOKE" == "1" ]]; then
|
||||||
|
log "Skipping local smoke checks (SKIP_LOCAL_SMOKE=1)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Running local smoke checks (candidates: ${LOCAL_SMOKE_CANDIDATES})"
|
||||||
local max_attempts="${LOCAL_SMOKE_MAX_ATTEMPTS:-24}"
|
local max_attempts="${LOCAL_SMOKE_MAX_ATTEMPTS:-24}"
|
||||||
local sleep_seconds="${LOCAL_SMOKE_SLEEP_SECONDS:-5}"
|
local sleep_seconds="${LOCAL_SMOKE_SLEEP_SECONDS:-5}"
|
||||||
local attempt=1
|
local attempt=1
|
||||||
|
local candidate
|
||||||
|
local ok=0
|
||||||
|
|
||||||
while (( attempt <= max_attempts )); do
|
while (( attempt <= max_attempts )); do
|
||||||
if ./scripts/ops/check_chat_health.sh http://localhost >/dev/null 2>&1 && \
|
ok=0
|
||||||
./scripts/ops/security_smoke.sh http://localhost >/dev/null 2>&1; then
|
IFS=',' read -r -a _urls <<< "$LOCAL_SMOKE_CANDIDATES"
|
||||||
log "Local smoke checks passed (attempt ${attempt}/${max_attempts})"
|
for candidate in "${_urls[@]}"; do
|
||||||
|
candidate="$(echo "$candidate" | xargs)"
|
||||||
|
[[ -z "$candidate" ]] && continue
|
||||||
|
|
||||||
|
if ./scripts/ops/check_chat_health.sh "$candidate" >/dev/null 2>&1 && \
|
||||||
|
./scripts/ops/security_smoke.sh "$candidate" >/dev/null 2>&1; then
|
||||||
|
log "Local smoke checks passed via ${candidate} (attempt ${attempt}/${max_attempts})"
|
||||||
|
ok=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$ok" == "1" ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -109,7 +131,7 @@ run_local_smoke() {
|
||||||
attempt=$((attempt + 1))
|
attempt=$((attempt + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
fail "Local smoke checks failed after ${max_attempts} attempts"
|
fail "Local smoke checks failed after ${max_attempts} attempts (candidates: ${LOCAL_SMOKE_CANDIDATES})"
|
||||||
}
|
}
|
||||||
|
|
||||||
run_domain_quick_health_wait() {
|
run_domain_quick_health_wait() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue