# Raport Incydentu - nordabiznes.pl ERR_TOO_MANY_REDIRECTS

**Data incydentu:** 2026-01-02
**Czas wykrycia:** ~18:00 CET
**Czas rozwiązania:** ~18:30 CET
**Czas trwania:** ~30 minut
**Severity:** CRITICAL (portal niedostępny z zewnątrz)
**Status:** ROZWIĄZANY

---

## 1. OPIS PROBLEMU

### Objawy
- Portal https://nordabiznes.pl całkowicie niedostępny z zewnątrz
- Błąd w przeglądarce: `ERR_TOO_MANY_REDIRECTS` (zbyt wiele przekierowań)
- Dotyczyło WSZYSTKICH zewnętrznych użytkowników
- Dostęp z sieci wewnętrznej INPI działał poprawnie

### Zgłoszenie
Użytkownik zgłosił problem:
> "krytyczne!!! z zewnatrz nie dziala !!!"
> "To nie działa na nowym komputerze nowy test pierwszy raz i od razu jest taki błąd także to nie jest jakiś cash"

---

## 2. PRZYCZYNA GŁÓWNA (ROOT CAUSE)

### Błędna konfiguracja Nginx Proxy Manager (NPM)

**Proxy Host ID:** 27
**Domena:** nordabiznes.pl, www.nordabiznes.pl

**Problem:** NPM był skonfigurowany do przekazywania ruchu na **port 80** zamiast **port 5000**

```
BŁĘDNA KONFIGURACJA:
NPM (10.22.68.250) → Backend (10.22.68.249:80) ← ŹRÓDŁO PROBLEMU

PRAWIDŁOWA KONFIGURACJA:
NPM (10.22.68.250) → Backend (10.22.68.249:5000) ✓
```

### Dlaczego to powodowało pętlę przekierowań?

1. Na serwerze backend (10.22.68.249) działają DWA serwisy:
   - **Port 80:** Nginx (system) - przekierowuje na HTTPS
   - **Port 5000:** Flask/Gunicorn (aplikacja NordaBiznes)

2. Przepływ ruchu z błędną konfiguracją:
   ```
   Użytkownik → https://nordabiznes.pl
   ↓
   NPM (SSL termination) → http://10.22.68.249:80
   ↓
   Nginx (port 80) → 301 redirect → https://nordabiznes.pl
   ↓
   NPM (SSL termination) → http://10.22.68.249:80
   ↓
   ... PĘTLA NIESKOŃCZONA ...
   ```

3. Po 20 przekierowaniach przeglądarka przerywa z błędem `ERR_TOO_MANY_REDIRECTS`

---

## 3. DIAGNOZA

### Kroki diagnostyczne

1. **Sprawdzenie logów NPM:**
   ```bash
   ssh maciejpi@10.22.68.250 "docker logs nginx-proxy-manager_app_1 --tail 50"
   # Wynik: Wszystkie requesty zwracały 301 redirect
   ```

2. **Test bezpośredni na backend:**
   ```bash
   # Test portu 80 (nginx systemowy)
   curl -I http://10.22.68.249:80/
   # Wynik: HTTP 301 → https://nordabiznes.pl/ ← PROBLEM!

   # Test portu 5000 (Flask/Gunicorn)
   curl -I http://10.22.68.249:5000/
   # Wynik: HTTP 200 OK ← DZIAŁA!
   ```

3. **Sprawdzenie konfiguracji NPM:**
   ```bash
   docker exec nginx-proxy-manager_app_1 sqlite3 /data/database.sqlite \
     "SELECT forward_port FROM proxy_host WHERE id = 27;"
   # Wynik: 80 ← BŁĘDNY PORT!
   ```

---

## 4. ROZWIĄZANIE

### Zmiana portu w NPM z 80 na 5000

**Metoda:** NPM API (PUT request)

```python
import requests

NPM_URL = "http://10.22.68.250:81/api"
# ... autentykacja ...

data = {
    "domain_names": ["nordabiznes.pl", "www.nordabiznes.pl"],
    "forward_scheme": "http",
    "forward_host": "10.22.68.249",
    "forward_port": 5000,  # ZMIANA: 80 → 5000
    "certificate_id": 27,
    "ssl_forced": True,
    "http2_support": True,
    "block_exploits": True,
    "allow_websocket_upgrade": True,
    "hsts_enabled": True,
    "hsts_subdomains": True
}

resp = requests.put(f"{NPM_URL}/nginx/proxy-hosts/27", headers=headers, json=data)
```

### Weryfikacja po naprawie

```bash
curl -I https://nordabiznes.pl/
# HTTP/2 200 ✓
# server: nginx/1.24.0 (Ubuntu)
# strict-transport-security: max-age=31536000; includeSubDomains
```

---

## 5. KIEDY I JAK POWSTAŁ PROBLEM?

### Analiza historii

1. **Pierwotna konfiguracja (2025-11-23):** Proxy utworzony z portem 5000 - POPRAWNIE
2. **Okres działania:** 2025-11-23 do ~2026-01-02 - portal działał poprawnie
3. **Zmiana konfiguracji:** Podczas dodawania maintenance mode lub innej modyfikacji NPM, port mógł zostać zmieniony na 80 (domyślny)

### Możliwe przyczyny zmiany portu:

1. **Edycja w NPM UI** - ktoś edytował proxy host i nie zwrócił uwagi na port
2. **Automatyczna zmiana** - NPM mógł zresetować do domyślnego portu 80 przy aktualizacji
3. **Maintenance mode** - konfiguracja maintenance mode mogła zmodyfikować inne ustawienia

### Lekcja na przyszłość:
> Port 5000 to niestandardowy port dla aplikacji Flask. Przy KAŻDEJ modyfikacji proxy hosta należy sprawdzić czy port jest poprawny!

---

## 6. ŚRODKI ZAPOBIEGAWCZE

### Natychmiastowe (wdrożone)

1. **Dokumentacja konfiguracji NPM:**
   - Proxy Host 27: nordabiznes.pl → 10.22.68.249:**5000**
   - Zapisane w tym raporcie incydentu

2. **Procedura weryfikacji po zmianach NPM:**
   ```bash
   # Po KAŻDEJ zmianie w NPM sprawdź:
   curl -I https://nordabiznes.pl/health
   # Oczekiwany wynik: HTTP 200
   ```

### Długoterminowe (do wdrożenia)

1. **Monitoring zewnętrzny:**
   - Dodać monitoring https://nordabiznes.pl do Zabbix
   - Alert gdy HTTP != 200
   - Sprawdzanie co 5 minut

2. **Backup konfiguracji NPM:**
   ```bash
   # Regularny backup (raz dziennie)
   docker cp nginx-proxy-manager_app_1:/data/database.sqlite /backup/npm/
   ```

3. **Checklist przy zmianach NPM:**
   - [ ] Sprawdź forward_port (musi być 5000 dla nordabiznes.pl)
   - [ ] Testuj z zewnętrznej sieci (telefon bez WiFi)
   - [ ] Sprawdź health endpoint: /health

4. **Usunięcie zbędnego nginx na porcie 80:**
   - Na serwerze 10.22.68.249 działa nginx na porcie 80 który tylko przekierowuje
   - Rozważyć wyłączenie (NPM obsługuje SSL termination)

---

## 7. KLUCZOWE DANE TECHNICZNE

### Architektura

```
Internet
    │
    ▼
[Fortigate 85.237.177.83] (NAT/Firewall)
    │
    ▼ Port 443
[NPM R11-REVPROXY-01 10.22.68.250] (SSL Termination, Reverse Proxy)
    │
    ▼ Port 5000 (HTTP)
[NORDABIZ-01 10.22.68.249] (Flask/Gunicorn Application)
    │
    ▼
[PostgreSQL localhost:5432] (Database)
```

### Konfiguracja NPM (PRAWIDŁOWA)

| Parametr | Wartość |
|----------|---------|
| Proxy Host ID | 27 |
| Domeny | nordabiznes.pl, www.nordabiznes.pl |
| Backend IP | 10.22.68.249 |
| **Backend Port** | **5000** (NIE 80!) |
| SSL Certificate ID | 27 |
| SSL Forced | Yes |
| HTTP/2 | Yes |
| HSTS | Yes |

### Porty na backend server (10.22.68.249)

| Port | Serwis | Status |
|------|--------|--------|
| 22 | SSH | Aktywny |
| 80 | Nginx (redirect) | Aktywny (NIE UŻYWAĆ!) |
| 443 | Nginx (redirect) | Aktywny (NIE UŻYWAĆ!) |
| **5000** | **Gunicorn (Flask App)** | **WŁAŚCIWY PORT** |
| 5432 | PostgreSQL | Aktywny (tylko localhost) |

---

## 8. PODSUMOWANIE

| Aspekt | Wartość |
|--------|---------|
| Czas niedostępności | ~30 minut |
| Wpływ na użytkowników | 100% użytkowników zewnętrznych |
| Przyczyna główna | Błędny port w NPM (80 zamiast 5000) |
| Rozwiązanie | Zmiana portu na 5000 via NPM API |
| Status | ROZWIĄZANY |
| Ponowne wystąpienie | Mało prawdopodobne (monitoring do wdrożenia) |

---

## 9. ZAŁĄCZNIKI

### Polecenia diagnostyczne (do użycia w przyszłości)

```bash
# 1. Sprawdź status aplikacji
curl -I https://nordabiznes.pl/health
# Oczekiwany: HTTP 200

# 2. Sprawdź konfigurację NPM
ssh maciejpi@10.22.68.250 "docker exec nginx-proxy-manager_app_1 \
  sqlite3 /data/database.sqlite \
  \"SELECT id, domain_names, forward_host, forward_port FROM proxy_host WHERE id = 27;\""
# Oczekiwany: 27|["nordabiznes.pl","www.nordabiznes.pl"]|10.22.68.249|5000

# 3. Test bezpośredni na backend (z sieci INPI)
curl -I http://10.22.68.249:5000/health
# Oczekiwany: HTTP 200

# 4. Sprawdź logi NPM
ssh maciejpi@10.22.68.250 "docker logs nginx-proxy-manager_app_1 --tail 20"

# 5. Sprawdź status usługi
ssh maciejpi@10.22.68.249 "sudo systemctl status nordabiznes"
```

---

**Autor raportu:** Claude Code
**Data utworzenia:** 2026-01-02
**Wersja:** 1.0
