Skip to content

Repository files navigation

KOMMS – Self-Hosted Communications & MDM Platform

License: AGPL v3 Latest Release Last Commit Issues Stars

A fully self-hosted, secure communications platform with mobile device management for Android and Windows.
One installation gives your team encrypted chat, voice, file sharing, VPN, TAK situational awareness, and MDM — all behind a single SSO.

Operator guide (step-by-step): WORKFLOW.md
Deutsche Dokumentation: WORKFLOW.de.md


A note from the maintainer

Hey — this is a hobby project I built for my own deployment and decided to publish in case it helps others running similar setups. It works for me, but I'm one person: expect bugs, rough edges, and undocumented assumptions baked into the code.

If you run into problems or have ideas, please open an issue — I read all of them and I'm genuinely happy to get feedback, both bug reports and suggestions.

I'll try to respond within a few days. Bigger changes (new services, refactors) might take longer depending on how much free-time work they need, but they're not off the table.

Want to try before you install? If you'd like to poke at a running test deployment before standing one up yourself, open an issue and I can arrange read-only access to a live test environment.


What's Included

Service Role VPN required
Authelia SSO portal — log in once for all services No
LLDAP Lightweight LDAP — single user directory
Nextcloud File sharing, onboarding, CalDAV/CardDAV No
Collabora Online In-browser document editing (Nextcloud integration) No
Matrix / Synapse Encrypted team messaging Yes
Element Web Matrix web client Yes
OpenVPN VPN — required for all internal services
Headwind MDM Android MDM — app + config management Yes
TAKServer Situational awareness (ATAK / WinTAK) No*
Jitsi Meet Encrypted video conferencing Yes
Mumble Low-latency encrypted voice Yes
nginx Reverse proxy — TLS termination, Authelia gate, VPN enforcement
PostgreSQL Shared database for Headwind, Synapse, Authelia, Nextcloud

Scale: Designed for small teams (< 50 devices).
ARM64 / Raspberry Pi: TAKServer is x86-only and is automatically skipped on ARM; all other services run on RPi 4/5 (64-bit OS).

* TAKServer WebTAK / Marti (browser) is reachable without VPN via nginx:443 — Authelia (lldap_admin group) is the only gate. ATAK clients connect directly on :8089 (CoT/SA) and :8443 (OTA updates), both publicly exposed.


Architecture

Internet
    │
    ▼
┌──────────────────────────────────────────────────────────────┐
│  nginx :443                                                  │
│                                                              │
│  auth.domain       → Authelia SSO portal  [no VPN]          │
│  cloud.domain      → Nextcloud            [no VPN, Authelia] │
│  collabora.domain  → Collabora Online     [no VPN, WOPI]     │
│  tak.domain        → TAKServer WebTAK     [no VPN, Authelia*]│
│  meet.domain       → Jitsi Meet           [VPN + Authelia]   │
│  element.domain    → Element Web          [VPN + Authelia]   │
│  matrix.domain     → Matrix / Synapse     [VPN only]         │
│  mdm.domain        → Headwind MDM         [VPN + Authelia*]  │
│  ldap.domain       → LLDAP Web UI         [VPN + Authelia*]  │
│                                                              │
│  OpenVPN :1194/UDP  Mumble :64738  TAKServer :8089/8443       │
│  Jitsi JVB :10000/UDP (WebRTC media — public)                │
└──────────────────────────────────────────────────────────────┘
         ▲                                ▲
         │ HTTPS (no VPN needed)          │ HTTPS (VPN tunnel 10.8.0.0/24)
    ─────┴──────────────────             ──────┴──────
   auth / cloud / collabora              element / matrix
   tak (WebTAK/Marti, Authelia)          mdm / ldap

* lldap_admin group membership required

VPN enforcement is handled by nginx (geo $vpn_ip) — VPN-required services return 403 for non-VPN IPs regardless of Authelia session state.


Quick Start

Prerequisites

  1. Fresh Ubuntu 22.04/24.04, Debian 12, or Raspberry Pi OS 64-bit
  2. Root SSH access — minimum 4 GB RAM (8 GB if using TAKServer)
  3. DNS A-records pointing to your server (*.domain.com + domain.com) — VPS only
  4. Optional: TAKServer Docker ZIP from tak.gov

One-command install

# Public repository:
curl -fsSL https://raw.githubusercontent.com/GUMMIIII/TAKSERVER_MDM/main/install.sh | bash

# Private repository (GitHub PAT required):
curl -H "Authorization: token $GITHUB_PAT" \
     -fsSL https://raw.githubusercontent.com/GUMMIIII/TAKSERVER_MDM/main/install.sh \
  | GITHUB_PAT=$GITHUB_PAT bash

The installer prompts for all settings interactively, then runs fully automatically (~15–25 min).
At the end it prints an SCP command to download your operator .ovpn.

For a full walkthrough see WORKFLOW.md.

TAKServer (optional)

TAKServer requires a free registration at tak.gov.

Note: TAKServer setup via install.sh is not yet fully automated. The installer detects the ZIP and reports it, but setup_tak.sh must be run manually after the main install completes. See roadmap for details.

# 1. Place the ZIP on the server before or after install.sh:
scp TAKSERVER-DOCKER-*.zip root@your.server:/opt/komms-data/tak-release/

# 2. After install.sh finishes, run setup manually:
sudo bash /opt/komms/server/setup_tak.sh

setup_tak.sh takes 5–10 minutes — most of this is waiting for TAKServer's internal grid to initialize before the admin certificate can be registered. This is expected; do not interrupt the script.

Companion: ATAK OTA Updates

If you want your ATAK clients to receive over-the-air APK + plugin updates from your own TAKServer instead of pulling from external sources, see the companion repo GUMMIIII/takserver_ota.

It sets up a self-hosted OTA channel served from this same TAKServer instance — ATAK clients check in, pull the latest APK and plugin set, and stay up to date without anyone touching a device manually. Useful for keeping a fleet of field devices in sync after a TAK version bump or plugin change.

Where to drop the generated files:

/opt/komms-data/tak/webcontent/update/
  ├── product.inf
  ├── product.infz
  ├── *.apk
  └── *.png

This bind-mounts to /opt/tak/webcontent/update/ inside the container.

ATAK Update-Server URL to configure on each client:

https://tak.<your-domain>:8443/update

⚠️ Important — use port :8443, not :443. ATAK 5.x has its own internal trust-store that only contains the KOMMSca CA (the TAKServer self-signed CA, also present in user.p12 / truststore-tak.p12). The nginx reverse proxy on port 443 serves a Let's Encrypt certificate that ATAK does not trust — connections to https://tak.<domain>/update will fail with "socket is closed" during the TLS handshake. Port 8443 connects directly to TAKServer with its KOMMSca-signed cert, which ATAK trusts out of the box.

For convenience, the /update/ path is also reachable through nginx on https://tak.<domain>/update (Authelia-bypassed, useful for curl / browser verification), but ATAK itself must use the :8443 URL.


User Management

# Add a regular user (Nextcloud + Element + VPN + TAK cert)
sudo bash /opt/komms/server/add_user.sh <username> "Display Name"

# Add an admin/operator user (+ MDM, LLDAP, TAKServer WebTAK access)
sudo bash /opt/komms/server/add_user.sh --admin <username> "Display Name"

# Remove a user from all systems
sudo bash /opt/komms/server/delete_user.sh <username>

Each add_user.sh run creates:

/opt/komms-data/users/<username>/
├── <username>.ovpn         ← OpenVPN profile
├── <username>-tak.p12      ← TAK client certificate
├── <username>-tak.zip      ← TAK data package (recommended)
├── qr-credentials.png      ← QR code with LLDAP login credentials
└── credentials.txt         ← Plain-text summary (delete after handover!)

Files are automatically uploaded to Nextcloud (KOMMS-Users/<username>/) and shared with the user.

Onboarding in 4 steps

  1. User opens https://cloud.domain.com — no VPN needed
  2. Logs in via Authelia SSO with the LLDAP credentials from qr-credentials.png (Nextcloud redirects automatically — no password form on Nextcloud itself)
  3. Downloads .ovpn → imports into OpenVPN app → connects
  4. All other services are now accessible

Updates

Platform update (code + Docker images)

sudo bash /opt/komms/server/update.sh            # latest release tag (recommended)
sudo bash /opt/komms/server/update.sh main       # current main branch
sudo bash /opt/komms/server/update.sh v0.0.5     # specific tag
  • Backs up /opt/komms-data/.env before touching anything
  • Never modifies data in /opt/komms-data/
  • Warns if new .env variables are missing from your config
  • Stops stack → updates code → pulls images → restarts

Nextcloud major version upgrade

Nextcloud only supports single-step major upgrades. Run once per major version:

sudo bash /opt/komms/server/update_nextcloud.sh        # auto: current + 1
sudo bash /opt/komms/server/update_nextcloud.sh 34     # explicit target

Then commit the updated image tag to keep the repo in sync:

git add server/docker-compose.yml
git commit -m "chore: update Nextcloud 33 to 34"
git push

File Structure

TAKSERVER_MDM/
├── install.sh                        ← One-shot installer (entry point)
│
├── server/
│   ├── docker-compose.yml            ← All services
│   ├── .env.example                  ← Configuration template
│   ├── setup_server.sh               ← Server configuration (called by install.sh)
│   ├── setup_tak.sh                  ← TAKServer setup (optional)
│   ├── add_user.sh                   ← User provisioning
│   ├── delete_user.sh                ← User removal
│   ├── update.sh                     ← Platform update
│   ├── update_nextcloud.sh           ← Nextcloud major version upgrade
│   ├── migrate-data-dir.sh           ← Migration helper for existing installs
│   ├── authelia/
│   │   └── configuration.yml.template← Authelia SSO + access_control rules
│   ├── nginx/
│   │   └── nginx.conf.vps.template   ← Reverse proxy config template (envsubst)
│   ├── matrix/
│   │   └── homeserver.yaml           ← Synapse configuration
│   ├── mumble/
│   │   └── murmur.ini                ← Mumble configuration
│   └── takserver/
│       └── CoreConfig.xml            ← TAKServer configuration template
│
├── android/
│   ├── provisioner.sh                ← MDM post-enrollment provisioner
│   └── debloat.sh                    ← Android debloat script
│
├── windows/
│   └── setup.ps1                     ← Windows device provisioner
│
├── README.md                         ← This file (English)
├── WORKFLOW.md                       ← Full operator guide (English)
└── WORKFLOW.de.md                    ← Vollständige Betriebsanleitung (Deutsch)

Data separation

Path Purpose Touched by git?
/opt/komms/ Code, scripts, Docker Compose Yes — git pull updates this
/opt/komms-data/ Live configs, secrets, certificates, user files Never

git pull can never overwrite your .env, certificates, or user credentials.


Security Notes

  • Change all passwords in .env before going live — see .env.example for all variables
  • TAKServer cert passphrase (TAK_CERT_PASS) defaults to atakatak — change it
  • Matrix federation is disabled by default (closed deployment)
  • Let's Encrypt renewal runs automatically via Certbot cron job (VPS only)
  • Firewall: setup_server.sh opens 22/tcp, 80/tcp, 443/tcp, 1194/udp (VPN), 8089/tcp (ATAK/WinTAK TLS), 8443/tcp (TAKServer direct — ATAK OTA uses the TAKServer-internal KOMMSca cert, not the Let's Encrypt cert on :443), 8444/tcp (TAK cert enrollment), 64738/tcp+udp (Mumble), 10000/udp (Jitsi JVB WebRTC media — public; web UI and signaling remain VPN+Authelia-gated). TAKServer WebTAK / Marti is reachable without VPN via nginx on :443 (Authelia lldap_admin gate).
  • VPN enforcement cannot be bypassed via Authelia — it is enforced at the nginx IP layer
  • All secrets and configs live in /opt/komms-data/ which is outside the git repository

License

AGPL-3.0

About

Self-hosted communications + MDM platform — TAKServer, OpenVPN, Matrix, Nextcloud, Mumble, Headwind MDM, behind a single SSO (Authelia + LLDAP).

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages