Skip to content

Releases: posch-dev/minecraft-wake-on-demand

Release list

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 00:13

The watcher is written in Go and ships as a single binary. Your config.yml
keeps working unchanged.

You need to know

  • Docker users: the known_hosts mount changed from a file to a directory.
    Replace the ./known_hosts:/root/.ssh/known_hosts line with
    ./state:/state and add SERVER_SSH_KNOWN_HOSTS: /state/known_hosts to the
    environment. The updated watcher/docker-compose.yml has it. The touch known_hosts step is gone for good.
  • Everyone else: re-run sudo ./watcher/install.sh, or download the new
    .exe on Windows. Python and PyYAML are no longer needed anywhere.
  • SSH keys with a passphrase are now refused with an explanation instead of
    failing later. An unattended service cannot type one, so use a key without.

Added

  • mc-wol-proxy init asks for your settings and writes config.yml. It finds
    the server's MAC address itself by pinging the IP and reading the ARP cache,
    and derives the broadcast address from the same IP.
  • mc-wol-proxy setup-ssh creates the key and installs it in authorized_keys
    over a one time password login, restricted to docker start by default. It
    shows the host key fingerprint and asks before trusting it.
  • mc-wol-proxy check tests the whole setup and names the step that is broken.
  • Release binaries for linux amd64, arm64, armv7 and armv6 and for windows
    amd64, published with a checksums.txt and build provenance attestation.
    install.sh downloads the right one and refuses to install it unverified.

Fixed

  • The readiness probe could hang forever. write_varint shifted a signed
    integer right, which in Python keeps the sign, so encoding the protocol
    version -1 never terminated and grew a buffer until memory ran out. The
    container was started before that probe ran, so the symptom was a stuck
    thread and a boot lock that was never released rather than an obvious
    failure.
  • Custom MOTDs and the server icon were ignored on Windows. The batch file
    pointed the config path at the repository root, and assets were looked for
    next to it instead of in watcher/assets.
  • The accepted SSH host key was thrown away on every container recreate unless
    known_hosts had been created by hand first, because Docker puts a directory
    in place of a bind mounted file that does not exist.
  • Shutdown waits for connections in flight instead of tearing them down, so a
    restart no longer cuts a player off mid session.

Changed

  • SSH runs through golang.org/x/crypto/ssh and ICMP through
    golang.org/x/net/icmp. Neither openssh-client nor iputils-ping is
    needed, which takes the container image from roughly 150 MB to about 8 MB on
    a scratch base.
  • A changed SSH host key is now a hard failure in both accept-new and yes,
    with an error naming the two things it can mean.
  • The config is validated at startup, with messages saying what to put in a
    field rather than what is wrong with it.
  • The systemd unit gained CAP_NET_RAW as an ambient capability plus
    NoNewPrivileges, ProtectSystem=strict and a read only home.
  • server.container_name is checked against what Docker accepts, since it is
    the one config value that reaches the remote command string.

Removed

  • watcher/mc_wol_proxy.py and the Python and PyYAML requirement.

Full Changelog: v1.0.0...v2.0.0

v1.0.0

Choose a tag to compare

@posch-dev posch-dev released this 10 Aug 18:41

Minecraft Wake-on-Demand v1.0.0

First release. Your Minecraft server sleeps when nobody plays and wakes up by
itself when someone connects. Players need no extra software, they click Join
and wait a few seconds.

How it works

An always-on watcher, a Raspberry Pi is plenty, listens on the Minecraft port.
While the server sleeps it answers the server list with its own MOTD. On a
login attempt it sends a Wake-on-LAN packet, waits for the PC, starts the
container over SSH and hands the player through.

Features

  • Wake-on-LAN with broadcast or unicast mode
  • Custom MOTD and server icon while the server sleeps
  • Full proxy mode, or transfer mode which redirects players straight to the
    server after waking it
  • Local players are transferred to the server's LAN address, so no router
    loopback is needed
  • DuckDNS updater built in
  • Automatic world backups through itzg/mc-backup
  • Runs on Linux via Docker or systemd, and on Windows

Security

The watcher sits on a port anyone can reach and can power on a PC, so this
release ships the results of a security audit:

  • Reachability probes never block the event loop, a burst of connections can no
    longer stall the proxy
  • The wake sequence is rate limited, with an exponential backoff for attempts
    that fail
  • SSH host key checking is on, defaulting to trust on first use
  • The real config and the RCON password stay out of the repository
  • The watcher container drops all capabilities but NET_RAW, runs with
    no-new-privileges and a read-only root filesystem
  • Image tags and the Minecraft version are pinned
  • Usernames from unauthenticated clients are validated and sanitized

SECURITY.md documents the threat model and what you can tighten
further.

Known limitations

This should work on real hardware. The wake path was verified against a
stand-in server rather than a sleeping PC, and there is no automated test suite
yet, so if something does not come up for you, commit
b6f14a2d87cfbadb0d19e08d80e3df4956d36c1c is a state that ran in practice. It
does not contain the security audit or any of the hardening in this release.

Getting started

See the README. It takes you from BIOS settings to joining the
server.