ShitSpeak RS is a Rust implementation of a Mumble compatible voice server. It provides TLS client connections, UDP voice and ping handling, ACL aware channel management, persistent server state, optional WASM authentication, and experimental clustered operation.
The Cargo package name is shitspeak-rs.
Certificate-hash privacy is configured with [privacy].protect_certificate_hashes.
Use false to disable it, true or "irreversible" for a stable one-way
remap, and "reversible" for an AES-based stable remap that can be restored
with the shared secret. Only other users' UserState.hash values are remapped
for non-superuser clients; the viewer's own hash is sent unchanged. Configure
the same [privacy].certificate_hash_secret on every cluster node, or use
SHITSPEAK_PRIVACY_CERTIFICATE_HASH_SECRET.
This project is under active development. The checked in config.toml is suitable for local testing and should be reviewed before public deployment. Some web gateway and MoQ settings are present but disabled by default.
- Mumble client protocol support over TCP with Rustls.
- UDP voice and ping support with Mumble voice crypto.
- Channel, ACL, ban, user state, and text message handling.
- Channel and client state persistence with snapshots and write ahead logs.
- Hot reload for selected runtime settings from
config.toml. - Optional pluggable authentication through Wasmtime modules.
- Server to server transport, overlay routing, and replication components for clustered deployments.
- Browser gateway scaffolding for WebRTC signaling and optional MoQ transport work.
- Criterion benchmarks for ACL and voice path performance.
src/main.rscontains the binary entry point, logging setup, config loading, authenticator setup, config watching, and graceful shutdown.src/server.rscontains the main server accept loops, runtime state, reload handling, web gateway startup, and client orchestration.src/clientcontains client session state, message handlers, voice targets, groups, UDP state, and Mumble voice crypto integration.src/messagescontains protobuf message reading, writing, and helper macros.src/voicecontains UDP voice packet decoding, encoding, ping handling, routing, and datagram batching.src/s2scontains the server to server transport, overlay, replication, status, and test support modules.src/webcontains browser signaling, peer session, protocol, voice, and MoQ gateway code.src/protoscontains the Mumble and internal server to server protobuf definitions.examplescontains certificate generation examples and WASM authenticator examples.deploy/docker-compose-16nodecontains a local Docker Compose 16 node demo generator.web/demoandweb/sdkcontain browser demo and JavaScript SDK assets.benchescontains Criterion benchmark suites.
- Rust stable with Cargo.
- A C toolchain suitable for native Rust dependencies on the target platform.
- PowerShell if you plan to use the included deployment scripts from Windows or PowerShell Core.
- Node.js and npm only if you plan to build the AssemblyScript WASM authenticator example.
- The Rust
wasm32-unknown-unknowntarget only if you plan to build the Rust WASM authenticator example.
The build uses prost-build and protoc-bin-vendored, so a separate system Protobuf compiler is not normally required.
Generate local test certificates:
cargo run --example gen-test-certsCheck and build the server:
cargo check
cargo buildStart the server from the repository root:
cargo runThe default local configuration listens on 0.0.0.0:64738. Connect a Mumble client to localhost on port 64738. The generated test certificate is intended for local development only.
To increase logging during development:
$env:RUST_LOG = "debug"
cargo runTo ship logs directly to Grafana Loki, enable [logging.loki] in config.toml
or set equivalent SHITSPEAK_LOGGING_LOKI_* environment variables:
[logging.loki]
enabled = true
url = "http://localhost:3100"
filter = "shitspeak_rs=debug"
labels = { environment = "dev" }If filter is omitted, Loki shipping defaults to shitspeak_rs=<level>, so
dependency logs are not sent unless you widen the directive explicitly. Failed
pushes are retried from a bounded in-memory cache; tune
retry_cache_capacity, retry_initial_interval_ms, and
retry_max_interval_ms for larger deployments.
The server loads config.toml from the working directory. Values can also be overridden with environment variables using the SHITSPEAK_ prefix and underscores for nested keys.
Important local settings include:
listenis the Mumble client TCP and UDP listener address.cert_pathandkey_pathpoint to the TLS identity used for client connections.max_users,max_bandwidth, and message length settings control client limits.root_channel_namesets the display name for channel0.udp_voice_enabledandudp_ping_enabledcontrol UDP behavior.blob_storage_dircontrols where persistent channel, client, and blob data is stored.authenticator_wasm_pathenables a custom WASM authentication module.s2ssections configure clustered server operation.websections configure the browser gateway.[acl].explicit_enter_deny_overrides_writelets an explicitEnterdeny overrideWrite's impliedEnterpermission.[acl].preserve_write_acl_on_editcontrols whether registered non-superuser ACL editors keep a personalWritefallback.[privacy].protect_certificate_hashesacceptsfalse,true,"irreversible", or"reversible"for other users'UserState.hashvalues in non-superuser views. Configure the same[privacy].certificate_hash_secreton every cluster node, or useSHITSPEAK_PRIVACY_CERTIFICATE_HASH_SECRET.
Selected settings are hot reloaded when config.toml changes. The C2S TLS identity from cert_path and key_path is also hot reloaded for new client handshakes when either file changes. Existing TLS sessions continue using the identity they negotiated. Listener addresses, node identity, storage paths, and other startup resources require a restart.
If authenticator_wasm_path is omitted, the server uses the built in demo authenticator. For real deployments, provide a WASM authenticator that implements the host contract documented in wasm_authenticator.md.
Examples are available in:
examples/wasm-auth-rustexamples/wasm-auth-assemblyscript
Build the Rust example:
rustup target add wasm32-unknown-unknown
cargo build --manifest-path examples/wasm-auth-rust/Cargo.toml --target wasm32-unknown-unknown --releaseBuild the AssemblyScript example:
cd examples/wasm-auth-assemblyscript
npm install
npm run buildWhen a configured WASM file changes, the reload path compiles the new module first. If the new module cannot be loaded, the current authenticator remains active.
The default blob_storage_dir is data. This directory stores channel snapshots, write ahead logs, channel blobs, session blob cache data, and user_channel_cache.json for TTL-bound last/listening channel restoration. For any durable deployment, back up this directory and place it on storage that survives process and host restarts.
The main tunables are:
channel_log_max_entriesclient_log_max_entrieschannel_snapshot_every_opschannel_snapshot_every_secschannel_wal_compaction_expire_count
The server to server subsystem supports multi node operation with transport metrics, overlay routing, state replication, and content addressed channel blob transfer. Configuration is split across [s2s], [s2s.transport], [s2s.overlay], and [s2s.replications].
A clustered deployment must provide unique S2S certificates whose leaf certificate Common Name is the numeric node id, plus listener addresses, advertised addresses, seed peers, and a persistence directory for cluster state. When S2S is disabled or no S2S certificate is configured, the local node id defaults to 0. When s2s.persistence_dir is set, the transport also caches the latest learned adaptive compression dictionary under that directory and renegotiates it with peers after restart. The included Docker Compose demo shows one concrete 16 node layout.
Generate S2S test certificates with:
cargo run --example gen-s2s-certsThe [web] configuration controls the browser gateway. It is disabled by default in config.toml.
The gateway related code includes:
- WebSocket signaling and authentication policy support.
- WebRTC peer and voice bridge modules.
- Optional MoQ and WebTransport support behind the Cargo
moqfeature. - A small browser demo under
web/demo. - JavaScript SDK assets under
web/sdk.
Build with MoQ support when needed:
cargo build --features moqCommon commands:
cargo fmt
cargo check
cargo test
cargo benchThe VS Code workspace includes tasks for certificate generation, cargo check, and cargo build. The default launch profile generates local certificates before starting the debug server.
The examples/docker-compose-16node directory contains a committed 16 node Docker Compose demo. It builds a local cluster layout with one server per node, per node S2S certificates with numeric Common Names, shared client TLS material, generated config, and deterministic host port assignments.
Build the Linux musl binary from the repository root first:
cross build --target=x86_64-unknown-linux-musl --releaseGenerate or refresh the Compose material:
pwsh examples/docker-compose-16node/generate-compose-16node.ps1 -ForceStart the cluster:
docker compose -f examples/docker-compose-16node/compose.yaml up -d --buildUseful follow up commands:
docker compose -f examples/docker-compose-16node/compose.yaml ps
docker compose -f examples/docker-compose-16node/compose.yaml logs -f node-01
docker compose -f examples/docker-compose-16node/compose.yaml down -vThe generator writes compose.yaml, the image bundle, shared certificates, per node config and S2S key material, and manifest.json with host port assignments.
Node N publishes Mumble TCP and UDP on localhost:20000 + N and the S2S status page on localhost:21000 + N. For example, node 1 is reachable at localhost:20001, and its status page is available at http://localhost:21001.
- Do not use generated test certificates for production.
- Protect TLS private keys, S2S keys, authentication modules, and persistent data.
- Configure
allowed_proxiesonly for trusted PROXY protocol senders. - Use a production authenticator instead of the demo authenticator for any exposed service.
- Review public registration settings before enabling server list registration.
No license file is included in this repository.