Skip to content

dmitrymodder/minewire-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Minewire CLI

A lightweight local proxy client for Minewire - it exposes a SOCKS5 or HTTP CONNECT proxy on your machine and tunnels traffic to a Minewire server disguised as Minecraft protocol traffic.

This is the core/CLI counterpart to the Minewire server. If you're looking for the old Flutter/Android client, that's a separate, partly outdated project - better not to use it for now.

Features

  • SOCKS5 or HTTP CONNECT local proxy - point your browser, curl, or system proxy settings at it
  • AES-GCM Encryption - matches the server, keyed from your shared password
  • Minecraft Camouflage - performs a real handshake/login/settings sequence before tunneling
  • Stream Multiplexing - multiple simultaneous connections over one tunnel (yamux)
  • Auto-Reconnect - maintains the tunnel session in the background with bounded backoff, and shuts down cleanly on Ctrl+C / SIGTERM
  • Fast / Realistic modes - optionally throttle upload to match a server running in realistic mode
  • Leveled logging - error / warn / info / debug
  • Daemon mode - run as a background process controlled via line-delimited JSON over stdin/stdout, for a desktop UI to drive
  • gomobile-ready core - the tunnel engine is a plain Go library (src/core) with a thin Android facade (src/mobile) for building an .aar

Requirements

  • Go 1.22+ (only if building from source)
  • A running Minewire server and a password that's whitelisted on it

Installation

From a release

Download the binary for your platform from Releases, place it next to client.yaml, edit the config, and run it.

From source

git clone https://github.com/dmitrymodder/minewire-cli.git
cd minewire-cli
go mod tidy
go build -o minewire-cli ./src
./minewire-cli

Configuration

Edit client.yaml:

local_port: ":1080"
server_address: "IP_HERE:25565"
password: "PASSWORD_HERE"
proxy_type: "http"   # "socks5" or "http"

mode: "fast"         # "fast" or "realistic" - should match your server's mode
realistic_bandwidth_kb: 128
realistic_burst_kb: 512
  • proxy_type: "socks5" gives you a plain SOCKS5 proxy on local_port (no auth).
  • proxy_type: "http" gives you an HTTP proxy that supports CONNECT (works for HTTPS and most system-wide "HTTP proxy" settings; plain unencrypted HTTP-only requests aren't proxied in this MVP).
  • mode only matters if the server you're connecting to is also running in realistic mode - throttling only one direction of the tunnel doesn't accomplish anything.

Usage

Plain CLI mode

./minewire-cli
# or explicitly:
./minewire-cli -config client.yaml -log-level info

Then point your browser / OS / app at 127.0.0.1:1080 using the proxy type you configured. Ctrl+C (or SIGTERM) now triggers a graceful shutdown instead of killing the tunnel mid-stream.

Flags:

Flag Default Meaning
-config client.yaml path to the config file (ignored in -daemon mode)
-log-level info error, warn, info, or debug
-daemon off run in background/JSON mode instead of reading client.yaml
-v / -version - print version and exit

Daemon mode (for the desktop UI)

Run with -daemon and the process no longer touches client.yaml - instead it reads newline-delimited JSON commands from stdin and writes newline-delimited JSON events to stdout. This is meant to be spawned as a child process by the UI and driven over its stdio pipes (no local socket/port to manage, no permission prompts).

Commands the UI sends (stdin), one JSON object per line:

{"cmd":"start","config":{"local_port":":1080","server_address":"1.2.3.4:25565","password":"...","proxy_type":"http","mode":"fast","realistic_bandwidth_kb":128,"realistic_burst_kb":512}}
{"cmd":"stop"}      // stop the tunnel + local proxy, process stays alive
{"cmd":"status"}    // ask for an immediate status snapshot
{"cmd":"shutdown"}  // stop everything and exit the process

Sending start again (e.g. after editing settings) swaps in a fresh engine after cleanly stopping the previous one - no need to stop first.

Events the daemon emits (stdout), one JSON object per line:

{"event":"status","data":{"running":true,"connected":true,"mode":"fast","proxy_type":"http","local_addr":":1080","server_address":"1.2.3.4:25565"}}
{"event":"log","level":"INFO","message":"connected and logged in"}
{"event":"error","message":"start failed: ..."}
{"event":"shutdown"}

A status event is emitted automatically after start/stop, and can also be requested any time with {"cmd":"status"}. All log lines are mirrored as log events, so the UI doesn't need a separate channel to show what's happening. If the UI process dies and stdin just closes, the daemon stops the tunnel on its own rather than leaking a background connection.

Quick manual test:

echo '{"cmd":"start","config":{"local_port":":1080","server_address":"1.2.3.4:25565","password":"secret","proxy_type":"http","mode":"fast"}}' | ./minewire-cli -daemon

Android (.aar)

The core engine has no CLI/daemon-specific code in it, so it binds cleanly with gomobile:

go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
gomobile bind -o libminewire.aar -target=android ./src/mobile

This produces libminewire.aar exposing a mobile.Client with Start(...), Stop(), IsConnected(), LastError(), and a LogCallback interface to receive log lines in Kotlin/Java. See src/mobile/mobile.go for the exact signatures.

Building all three outputs

# Windows
GOOS=windows GOARCH=amd64 go build -o minewire-cli.exe ./src

# Linux
GOOS=linux GOARCH=amd64 go build -o minewire-cli-linux ./src

# Android AAR (needs gomobile + Android SDK/NDK set up)
gomobile bind -o libminewire.aar -target=android ./src/mobile

Architecture

The protocol itself (packet IDs, handshake sequence, encryption, camouflage timing) is unchanged - only the code around it was restructured so the same core can run as a CLI, a background daemon, or an Android library.

minewire-cli/
├── client.yaml
├── go.mod
├── src/
│   ├── main.go       # package main - thin entrypoint: flags, CLI mode vs daemon mode, signal handling
│   ├── core/         # package core - the actual engine, importable as a library
│   │   ├── engine.go    # Engine type: Start/Stop/Status/Wait, replaces the old global session/cfg vars
│   │   ├── tunnel.go    # Minecraft handshake, encrypted yamux tunnel, background camouflage traffic
│   │   ├── proxy.go     # SOCKS5 and HTTP CONNECT handlers (now Engine methods)
│   │   ├── protocol.go  # Minecraft protocol primitives (VarInt, String, etc.) - kept in sync with the server's
│   │   ├── throttle.go  # token-bucket rate limiter used for realistic-mode upload throttling
│   │   ├── config.go    # Config struct (shared by client.yaml and the JSON daemon protocol) + defaults
│   │   ├── logger.go    # leveled logger (error/warn/info/debug) with an optional sink for log forwarding
│   │   └── daemon.go    # JSON IPC control protocol (Commands in, Events out) over any io.Reader/io.Writer
│   └── mobile/       # package mobile - the ONLY nested subpackage, required by gomobile bind
│       └── mobile.go    # flat, primitive-typed facade over core.Engine for Kotlin/Java consumers

License

MIT

About

A lightweight local proxy client for Minewire protocol

Resources

License

Stars

4 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages