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

PortProtokółPrzeznaczenie
8089TCP/TLSStrumień CoT — połączenia klientów ATAK i WinTAK
8443HTTPSInterfejs webowy, REST API, kanały WebSocket
8446HTTPSKanały danych TAK i dystrybucja pakietów misji
9000TCP/TLSFederacja 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_DN i LDAP_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=true i podaj CA_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).