CloudTAK to natywny webowo następca przestarzałego serwera TAK opartego na Javie — aplikacja Node.js, która udostępnia ekosystem ATAK i WinTAK w każdej przeglądarce bez konieczności instalowania Javy po stronie klienta ani złożonego zarządzania keystorem. Podczas gdy przestarzały TAK Server był ciężką aplikacją Java EE zbudowaną dla garnizonowych centrów danych, CloudTAK stawia na konteneryzację, natywne REST API i można go wdrożyć na pojedynczej chmurowej maszynie wirtualnej w niecałą godzinę. Ten przewodnik obejmuje pełną ścieżkę od czystego serwera do zabezpieczonej, gotowej do użycia produkcyjnego infrastruktury TAK — z uwzględnieniem integracji z kopiotem AI TAKpilot firmy Corvus Intelligence.
Czym jest CloudTAK i jak różni się od przestarzałego serwera TAK
Przestarzały TAK Server (dystrybuowany też jako FreeTAKServer w ekosystemie społecznościowym) był zbudowany jako aplikacja Java EE, która udostępniała federację CoT przez TCP/TLS i ograniczone REST API dodane następczo. Obsługa wymaga Javy 11 lub nowszej, keystora Java (.jks) do zarządzania certyfikatami oraz kontenera Tomcat lub samodzielnego JAR. Samo przygotowanie certyfikatów — wygenerowanie CA, certyfikatu serwera i certyfikatów per-klient, a następnie import każdego do właściwego keystora — zazwyczaj zajmuje nowemu operatorowi kilka godzin i jest częstą przyczyną niepowodzeń wdrożeń.
CloudTAK obrał inną ścieżkę architektoniczną. Serwer jest napisany w TypeScript/Node.js, przechowuje dane w PostgreSQL z rozszerzeniem przestrzennym PostGIS i udostępnia każdą funkcję poprzez REST API z dokumentacją OpenAPI. Interfejs webowy jest w pełni funkcjonalnym klientem TAK — operatorzy bez urządzeń Android obsługujących ATAK mogą przeglądać obraz taktyczny i z nim wchodzić w interakcję z dowolnej przeglądarki. Zarządzanie certyfikatami TLS używa standardowych plików PEM zamiast keystorów Java, co zapewnia zgodność z Let's Encrypt i standardowymi narzędziami PKI.
- Natywny webowo klient TAK — operatorzy na laptopach, wysuniętych posterunkach dowodzenia i stacjach roboczych SOC uzyskują dostęp do obrazu bez instalowania ATAK lub WinTAK.
- REST API jako priorytet — przyjmowanie CoT, zarządzanie pakietami danych, administracja użytkownikami i konfiguracja federacji są realizowane przez API, co umożliwia automatyzację i integrację z zewnętrznymi systemami.
- Wdrożenie oparte na kontenerach — jeden plik Docker Compose uruchamia kompletny stos; bez środowiska uruchomieniowego Java, bez Tomcata, bez konfiguracji keystora.
- Pełna zgodność z ATAK/WinTAK — istniejący klienci ATAK i WinTAK łączą się z CloudTAK identycznie jak z przestarzałym TAK Server na porcie 8089 TCP/TLS. Nie są wymagane żadne zmiany po stronie klienta.
Wymagania wstępne: infrastruktura, domeny i porty
Przed wdrożeniem CloudTAK upewnij się, że spełnione są poniższe wymagania wstępne.
Wymagania dotyczące serwera
Minimalne wdrożenie obsługujące do 100 jednoczesnych klientów ATAK wymaga:
- 2 vCPU, 4 GB RAM, 20 GB SSD (system operacyjny + kontenery + baza danych)
- Ubuntu 22.04 LTS lub RHEL 9 (przetestowane dystrybucje)
- Docker Engine 24+ i Docker Compose v2
- Statyczny publiczny adres IP lub rekord DNS A wskazujący na serwer
Dla 500+ jednoczesnych klientów lub środowisk z intensywnym ruchem CoT (kanały UAV, roje dronów raportujące z częstotliwością 1 Hz) zwiększ do 4–8 vCPU i 8–16 GB RAM. I/O PostgreSQL staje się wąskim gardłem przy skali — użyj dysku NVMe SSD lub zarządzanej usługi bazy danych zamiast współdzielonego storage'u.
Wymagania dotyczące portów
| Port | Protokół | Przeznaczenie |
|---|---|---|
8089 | TCP/TLS | Strumień CoT — połączenia klientów ATAK i WinTAK |
8443 | HTTPS | Interfejs webowy, REST API, kanały WebSocket |
8446 | HTTPS | Kanały danych TAK i dystrybucja pakietów misji |
9000 | TCP/TLS | Federacja z innymi instancjami serwera TAK (jeśli używana) |
Certyfikat TLS
Uzyskaj certyfikat TLS dla nazwy hosta, z którą będą się łączyć klienci ATAK. Umieść fullchain.pem i privkey.pem w /opt/cloudtak/ssl/ przed kontynuowaniem.
Krok po kroku: wdrożenie Docker Compose
Utwórz strukturę katalogów:
mkdir -p /opt/cloudtak/{ssl,data,logs}
cd /opt/cloudtak
cp /etc/letsencrypt/live/tak.yourdomain.com/fullchain.pem ssl/
cp /etc/letsencrypt/live/tak.yourdomain.com/privkey.pem ssl/
Utwórz /opt/cloudtak/.env:
CLOUDTAK_DOMAIN=tak.yourdomain.com
CLOUDTAK_VERSION=latest
POSTGRES_DB=cloudtak
POSTGRES_USER=cloudtak
POSTGRES_PASSWORD=change_this_strong_password_32chars
SSL_CERT_PATH=/ssl/fullchain.pem
SSL_KEY_PATH=/ssl/privkey.pem
CLOUDTAK_ADMIN_PASSWORD=change_this_admin_password
CLOUDTAK_JWT_SECRET=generate_64_char_random_string_here
CLOUDTAK_MTLS=false
CLOUDTAK_AUDIT_LOG=true
DB_POOL_MAX=20
CLOUDTAK_COT_RATE_LIMIT=100
COT_RETENTION_HOURS=72
Utwórz /opt/cloudtak/docker-compose.yml:
version: '3.9'
services:
postgres:
image: postgis/postgis:15-3.3
container_name: cloudtak-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- cloudtak-internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
cloudtak:
image: ghcr.io/tak-ps/cloudtak:${CLOUDTAK_VERSION}
container_name: cloudtak
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "8089:8089"
- "8443:8443"
- "8446:8446"
environment:
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
DOMAIN: ${CLOUDTAK_DOMAIN}
SSL_CERT: ${SSL_CERT_PATH}
SSL_KEY: ${SSL_KEY_PATH}
ADMIN_PASSWORD: ${CLOUDTAK_ADMIN_PASSWORD}
JWT_SECRET: ${CLOUDTAK_JWT_SECRET}
MTLS: ${CLOUDTAK_MTLS}
AUDIT_LOG: ${CLOUDTAK_AUDIT_LOG}
DB_POOL_MAX: ${DB_POOL_MAX}
COT_RATE_LIMIT: ${CLOUDTAK_COT_RATE_LIMIT}
COT_RETENTION_HOURS: ${COT_RETENTION_HOURS}
volumes:
- ./ssl:/ssl:ro
- ./data/cloudtak:/data
- ./logs:/var/log/cloudtak
networks:
- cloudtak-internal
- cloudtak-external
networks:
cloudtak-internal:
driver: bridge
internal: true
cloudtak-external:
driver: bridge
Uruchom stos:
cd /opt/cloudtak
docker compose up -d
docker compose logs -f cloudtak
Po pomyślnym uruchomieniu w logach powinna pojawić się informacja CloudTAK listening on :8089 (CoT), :8443 (HTTPS), :8446 (feeds). Przejdź do https://tak.yourdomain.com:8443/admin i zaloguj się hasłem administratora z pliku .env.
Konfiguracja: pakiety danych, użytkownicy i federacja
Generowanie pakietów danych dla klientów
Generuj pakiety przez panel administratora: Admin → Połączenia → Generuj pakiet lub przez REST API:
curl -s -X POST https://tak.yourdomain.com:8443/api/package/generate \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"operator01","callsign":"ALPHA-1","team":"Red","role":"Team Member"}' \
-o operator01-connection.zip
Załaduj plik .zip na urządzenie ATAK (przez USB, importer pakietów ATAK lub MDM). ATAK przetworzy pakiet i automatycznie nawiąże połączenie TCP/TLS z portem 8089.
Zarządzanie użytkownikami
CloudTAK obsługuje trzy tryby uwierzytelniania, które można konfigurować niezależnie:
- Konta lokalne — zarządzane przez API administratora. Odpowiednie dla małych wdrożeń lub izolowanych sieci bez istniejącej usługi katalogowej.
- LDAP / Active Directory — konfigurowane przez zmienne środowiskowe
LDAP_URL,LDAP_BIND_DNiLDAP_BASE_DN. Użytkownicy uwierzytelniają się przy użyciu istniejących poświadczeń domenowych. - Oparte na certyfikatach (mTLS) — każde urządzenie klienckie posiada unikalny certyfikat klienta podpisany przez CA wdrożenia. Ustaw
CLOUDTAK_MTLS=truei podajCA_CERT_PATH. To preferowany tryb w środowiskach operacyjnych.
Łącza federacyjne
curl -s -X POST https://tak.yourdomain.com:8443/api/federation \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"HQ-TAK-Server","address":"tak.hq.example.mil","port":9000,"protocol":"tls","ca_cert":"/ssl/hq-ca.pem","bidirectional":true}'
Zdarzenia federacyjne przepływają w obu kierunkach: jednostki na zdalnym serwerze pojawiają się na mapie CloudTAK i odwrotnie. Federacja używa wzajemnego TLS — przed konfiguracją łącza wymień certyfikaty CA z administratorem zdalnego serwera.
Zabezpieczanie: przypinanie TLS, zapora, uwierzytelnianie i logowanie audytu
Uwaga dotycząca bezpieczeństwa operacyjnego: Instancja CloudTAK z domyślnymi poświadczeniami, certyfikatem z podpisem własnym i otwartymi portami stanowi poważne zagrożenie wywiadowcze. Każde wdrożenie CloudTAK obsługujące jednostki operacyjne musi przejść poniższe kroki zabezpieczania przed podłączeniem urządzeń polowych.
Przypinanie certyfikatu TLS
Przypinanie certyfikatu ogranicza klientów do akceptowania tylko certyfikatów od określonego CA. W generatorze pakietów danych ustaw "pin_ca": true — spowoduje to osadzenie odcisku CA w profilu połączenia ATAK.
Reguły zapory
iptables -A INPUT -p tcp --dport 8089 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8089 -j DROP
iptables -A INPUT -p tcp --dport 8443 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8443 -j DROP
iptables -A INPUT -p tcp --dport 8446 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8446 -j DROP
iptables-save > /etc/iptables/rules.v4
Logowanie audytu
Przy CLOUDTAK_AUDIT_LOG=true CloudTAK zapisuje ustrukturyzowane zdarzenia audytu JSON do /var/log/cloudtak/audit.log. Przesyłaj te logi do systemu SIEM za pomocą Filebeat lub Fluentd — błędy uwierzytelniania i nieoczekiwane źródła połączeń powinny generować alerty.
Integracja kopilota AI TAKpilot
TAKpilot to kopilot AI firmy Corvus Intelligence dla operacji taktycznych opartych na TAK. Działa jako mikroserwis Node.js obok CloudTAK, subskrybuje strumień zdarzeń CoT przez WebSocket API CloudTAK i publikuje wyniki oparte na AI z powrotem jako zdarzenia CoT widoczne na wszystkich podłączonych klientach ATAK/WinTAK.
Dodawanie TAKpilot do stosu Docker Compose
takpilot:
image: ghcr.io/corvus-intelligence/takpilot:latest
container_name: takpilot
restart: unless-stopped
depends_on:
- cloudtak
environment:
CLOUDTAK_API_URL: https://cloudtak:8443
CLOUDTAK_WS_URL: wss://cloudtak:8443/api/events
CLOUDTAK_API_TOKEN: ${TAKPILOT_CLOUDTAK_TOKEN}
TAKPILOT_API_KEY: ${TAKPILOT_API_KEY}
TAKPILOT_THREAT_DETECTION: "true"
TAKPILOT_PATTERN_OF_LIFE: "true"
TAKPILOT_ROUTE_OPTIMIZATION: "true"
TAKPILOT_COT_OUTPUT: "true"
TAKPILOT_COT_CALLSIGN_PREFIX: "AI-"
networks:
- cloudtak-internal
Dodaj do pliku .env dwie nowe zmienne:
# TAKpilot (uzyskaj klucz API na https://corvusintell.com/takpilot/)
TAKPILOT_API_KEY=your_takpilot_api_key_here
TAKPILOT_CLOUDTAK_TOKEN=generate_via_cloudtak_admin_api
Wygeneruj TAKPILOT_CLOUDTAK_TOKEN przez API administratora CloudTAK:
curl -s -X POST https://tak.yourdomain.com:8443/api/token \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "takpilot-service",
"scopes": ["cot:read", "cot:write", "events:subscribe"]
}' | jq -r '.token'
Uruchom ponownie stos poleceniem docker compose up -d. TAKpilot połączy się z kanałem WebSocket CloudTAK i w ciągu sekund zacznie publikować zdarzenia CoT generowane przez AI. Wyniki AI pojawiają się na mapie ATAK z prefiksem znaku wywoławczego AI-, odróżniając je od śladów raportowanych z terenu.
Strojenie wydajności: połączenia, retencja śladów i ograniczanie przepustowości
Ustaw DB_POOL_MAX na 20–30% oczekiwanej liczby jednoczesnych klientów. Zwiększ max_connections PostgreSQL odpowiednio. CLOUDTAK_COT_RATE_LIMIT domyślnie wynosi 100 zdarzeń/s — zwiększ do 500–1000 dla integracji UAV. COT_RETENTION_HOURS domyślnie 72; zwiększ dla wymagań odtwarzania danych historycznych.
Typowe problemy i rozwiązywanie błędów
Klient ATAK natychmiast wyświetla „Connection Failed". Sprawdź, czy port 8089 jest otwarty: nc -zv tak.yourdomain.com 8089.
Certyfikat TLS odrzucony przez ATAK. Zweryfikuj SAN poleceniem: openssl x509 -in ssl/fullchain.pem -text | grep -A1 "Subject Alternative".
Wyczerpanie puli połączeń z bazą danych. Zwiększ DB_POOL_MAX i max_connections w postgresql.conf.
Zdarzenia CoT widoczne na serwerze, ale nie u klientów ATAK. Prawie zawsze problem rozbieżności zegarów — upewnij się, że NTP jest skonfigurowany: timedatectl status.
TAKpilot nie publikuje zdarzeń AI. Sprawdź logi: docker compose logs takpilot. Zweryfikuj klucz API i uprawnienia tokena (wymagane cot:write).