Megalodon: manage ARK servers over RCON from a web dashboard
Watches any number of ARK:SE servers (RCON for players and chat, the query port for map, version and player cap), records joins, leaves, chat and an audit trail, and keeps a player database across servers. Control: save, broadcast, chat, whisper, kick, time of day, MOTD, wild dino wipe, a raw console with history and macros, restarts with timed warnings and a world save, optional start command and auto-start. Bans are kept by Megalodon: timed, cluster-wide and re-enforced when the player returns. Automation: schedules (every N or at times of day), Discord/ntfy/webhook notifications, welcome message, chat word filter. Access: viewer, moderator and admin roles, API tokens, Prometheus metrics. cmd/fakeark simulates a server for trying it out. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
0d2cb31abf
32 files changed
+6280
No files matched your search
@@ -0,0 +1,166 @@
|
||||
# Megalodon
|
||||
|
||||
Remote management for ARK: Survival Evolved servers over RCON. One small binary (no database, no
|
||||
dependencies) that watches your servers, gives you a web dashboard to run them from, and does the
|
||||
boring parts on a schedule.
|
||||
|
||||
It talks to the server the way the game's own admin console does, so it works with any ARK:SE
|
||||
server that has RCON switched on, whether it runs in Docker, on TrueNAS, or on a plain machine.
|
||||
|
||||
## What it does
|
||||
|
||||
**Watch**
|
||||
- Live status of every server: online or not, players, map, version, RCON latency, uptime, and a
|
||||
24-hour player-count graph. No RCON password needed for the map/version/player cap: it also asks
|
||||
the game's query port, like the Steam server browser does.
|
||||
- Join/leave events, chat log, and an audit trail of everything anyone does from the dashboard.
|
||||
- A player database across all servers: first and last seen, total play time, number of visits, notes.
|
||||
- A watch list: get an event the moment a particular player joins.
|
||||
- Prometheus metrics at `/metrics`.
|
||||
|
||||
**Control**
|
||||
- Save the world, broadcast, chat as SERVER, whisper to one player, kick, set the time of day, set
|
||||
the message of the day, wipe wild creatures.
|
||||
- **Bans that behave**: with a reason, optionally for a set time, applied to every server in a
|
||||
cluster at once, and enforced again whenever the player turns up (even on a server that was
|
||||
offline when you banned them). Expired bans lift themselves.
|
||||
- **Restarts that warn people**: a countdown with announcements at 30, 15, 10, 5, 2 and 1 minute and
|
||||
30 and 10 seconds, a world save first, cancellable at any time. Optionally Megalodon starts the
|
||||
server again itself (see `start_command`), and can start it automatically if it stays down.
|
||||
- A raw console with history and suggestions, plus saved **macros** (named lists of commands).
|
||||
- Cluster actions: broadcast or save on every server in one click.
|
||||
|
||||
**Automate**
|
||||
- **Schedules**: a save every 30 minutes, a daily restart at 04:30 on weekdays, a broadcast every
|
||||
hour, any console command on a timer.
|
||||
- **Notifications** to Discord, ntfy or any webhook for the events you choose.
|
||||
- **Welcome message** whispered to each player who joins.
|
||||
- **Chat filter**: warn, then kick or temporarily ban, for words you list.
|
||||
|
||||
**Share it safely**
|
||||
- Three roles: *viewer* (look), *moderator* (talk to players, kick, ban, save), *admin* (everything,
|
||||
including the raw console, restarts, schedules and settings).
|
||||
- API tokens with the same roles, for scripts and monitoring.
|
||||
|
||||
## Setting up the server side
|
||||
|
||||
RCON is off by default. In `GameUserSettings.ini` under `[ServerSettings]`:
|
||||
|
||||
```ini
|
||||
RCONEnabled=True
|
||||
RCONPort=27020
|
||||
ServerAdminPassword=choose-something-long
|
||||
```
|
||||
|
||||
(or add `?RCONEnabled=True?RCONPort=27020?ServerAdminPassword=...` to the launch command). The
|
||||
password you set there is the RCON password.
|
||||
|
||||
**Do not expose the RCON port to the internet.** RCON is unencrypted and its password is the whole
|
||||
admin password. Keep it on your LAN or a VPN; only Megalodon needs to reach it. If Megalodon and
|
||||
the server are on the same machine or Docker network, nothing needs to be opened at all.
|
||||
|
||||
## Running it
|
||||
|
||||
```sh
|
||||
# download a release, or: go build ./cmd/megalodon
|
||||
./megalodon serve
|
||||
```
|
||||
|
||||
On first run it writes `megalodon.json`, creates a user called `admin` and prints its password
|
||||
**once** in the log. Open http://127.0.0.1:8480, sign in, and use **Add server**. Or copy
|
||||
[`megalodon.example.json`](megalodon.example.json) and edit it.
|
||||
|
||||
By default the dashboard only listens on `127.0.0.1`. To reach it from elsewhere, put it behind an
|
||||
HTTPS reverse proxy, or expose it through [Hammerhead](https://git.veillax.com/Veillax/hammerhead),
|
||||
and set `"cookie_secure": true` and `"trust_proxy": true`. Don't put the dashboard on the open
|
||||
internet over plain HTTP.
|
||||
|
||||
Docker: see [`Dockerfile`](Dockerfile) and [`deploy/docker-compose.yml`](deploy/docker-compose.yml).
|
||||
Set `TZ` so scheduled times use your clock.
|
||||
|
||||
### Commands
|
||||
|
||||
```
|
||||
megalodon serve [-config megalodon.json] [-listen addr]
|
||||
megalodon user NAME [ROLE] add a user, or change a password (reads MEGALODON_PASSWORD or stdin)
|
||||
megalodon token NAME [ROLE] create an API token (printed once)
|
||||
megalodon rcon -addr host:27020 -password PW [COMMAND...]
|
||||
one-off console command, or an interactive prompt without a command
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Everything is in one JSON file, and everything except `listen`, `data_dir`, `poll_seconds`,
|
||||
`chat_seconds`, `trust_proxy` and `cookie_secure` can be edited from the dashboard (changes are
|
||||
written back to the file). See [`megalodon.example.json`](megalodon.example.json).
|
||||
|
||||
| Setting | Meaning |
|
||||
|---|---|
|
||||
| `servers[].host`, `rcon_port`, `password` | where to reach the console |
|
||||
| `servers[].query_port` | game query port (UDP, usually 27015); `0` turns it off |
|
||||
| `servers[].start_command` | shell command that starts the server (`docker start ark-island`, `systemctl start ark`, a script). Runs on the machine Megalodon is on; it must return promptly |
|
||||
| `servers[].auto_start` | run `start_command` when the server has been down for `auto_start_after` seconds (default 120), at most every 5 minutes. A server you **Stop** from the dashboard stays stopped |
|
||||
| `jobs[]` | `action` is `save`, `broadcast`, `restart`, `command`, `destroy_wild_dinos` or `motd`; use `every` (`"30m"`) **or** `at` (`["04:30"]`, optionally with `days`) |
|
||||
| `notify[]` | `kind` is `discord`, `ntfy` or `json`. No `events` list means joins, leaves, up/down, restarts, bans and errors |
|
||||
| `poll_seconds` | how often each server is asked who is online (default 10) |
|
||||
|
||||
Files in `data_dir`: `events.jsonl` (event log, rotated at 20 MB), `players.json`, `bans.json`,
|
||||
`samples-<server>.jsonl` (the graph).
|
||||
|
||||
## API
|
||||
|
||||
Everything the dashboard does goes through a JSON API. Sign in with `POST /api/login`, or send an
|
||||
API token as `Authorization: Bearer mgl_…`.
|
||||
|
||||
```sh
|
||||
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8480/api/servers
|
||||
curl -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||||
-d '{"action":"broadcast","message":"Restart in 10 minutes"}' \
|
||||
http://127.0.0.1:8480/api/servers/island/action
|
||||
```
|
||||
|
||||
`action` is one of `save`, `broadcast`, `say`, `whisper`, `kick`, `ban`, `unban`, `allow`,
|
||||
`disallow`, `destroy_wild_dinos`, `set_time`, `motd`, `exec`, `restart`, `stop`, `cancel_restart`
|
||||
and `start`. `POST /api/actions` does the same on several (or all) servers. `GET /api/events`,
|
||||
`GET /api/players`, `GET /api/stream` (live events, server-sent) and `GET /metrics` round it out.
|
||||
|
||||
Prometheus: `megalodon_server_up`, `megalodon_players`, `megalodon_players_max`,
|
||||
`megalodon_rcon_rtt_ms`, `megalodon_uptime_seconds`, `megalodon_restart_pending`, all labelled by
|
||||
`server`.
|
||||
|
||||
## Security notes
|
||||
|
||||
- Passwords are stored as PBKDF2-SHA256 hashes; API tokens as SHA-256 hashes. RCON passwords sit in
|
||||
`megalodon.json` in plain text (they have to), so the file is written `0600`: keep it that way.
|
||||
- Sessions are `HttpOnly`, `SameSite=Strict` cookies, and every change needs a custom header a
|
||||
web page on another site can't send. Failed sign-ins are rate-limited per address.
|
||||
- The dashboard has a strict Content-Security-Policy and never renders game text as HTML.
|
||||
- Values that go into console commands (Steam IDs, messages) are validated and stripped of quotes
|
||||
and line breaks, so a player name or message can't inject a second command. The raw console is
|
||||
admin-only and recorded in the event log.
|
||||
- Moderators can see audit entries; viewers cannot.
|
||||
|
||||
## Honest limits
|
||||
|
||||
- It has been tested against a simulated ARK server and unit tests, **not yet against a real
|
||||
ARK:SE server**. The console's reply formats (`ListPlayers`, `GetChat`) are parsed leniently, but
|
||||
if one differs on your version, [open an issue](https://git.veillax.com/Veillax/megalodon/issues)
|
||||
with the raw reply (`megalodon rcon … ListPlayers`).
|
||||
- RCON can't read or write `GameUserSettings.ini`, install mods or update the game; restarting
|
||||
and updating are left to whatever runs the server (Docker, systemd, SteamCMD).
|
||||
- Commands that take an in-game *player ID* rather than a Steam ID (`GiveItemToPlayer`,
|
||||
`GiveExpToPlayer`) are available from the console but have no buttons, because RCON doesn't
|
||||
report that ID.
|
||||
- ARK:SE only (it is untested on ASA, which uses the same protocol but may differ in detail).
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go run ./cmd/fakeark & # a pretend server on :27020 (password "secret") with players and chat
|
||||
go run ./cmd/megalodon serve
|
||||
```
|
||||
|
||||
Releases are built by the Gitea workflow when a `v*` tag is pushed.
|
||||
|
||||
Licensed under the AGPL-3.0 (see [LICENSE](LICENSE)).
|
||||
Reference in new issue
Block a user