Hopper - Fast, configurable, lightweight Reverse Proxy for Minecraft

Overview

Hopper License

Hopper is a lightweight reverse proxy for minecraft. It allows you to connect multiple servers under the same IP and port, with additional functionalities, just like Nginx. It is built with Rust 🦀 to ensure maximum performance and efficiency.

Hopper works starting from version 1.7 up to the latest version of Minecraft.

NOTE: this proxy is still heavily under development, and a lot of new features are coming really soon!

FEATURES:

Index

Configuration

To quickly get started checkout this example configuration:

Example Config.toml:
# the address hopper will listen on
listen = "0.0.0.0:25565"

# metrics configuration
# [metrics]
# type = "influx"
# ...
#
# follow the section below for more information about
# gathering metrics with hopper

# general routing configuration
[routing]
default = { ip = "127.0.0.1:12345" } # optional
# default = { ip = ["127.0.0.1:12001", "127.0.0.1:12002"] } # load balanced

# list of servers fronted by hopper
[routing.routes]
# simple reverse proxy
"mc.gaming.tk" = { ip = "docker_hostname:25008" } # hostnames are supported too!

# bungeecord's ip forwarding feature enabled
"mc.server.com" = { ip-forwarding = "bungeecord", ip = "127.0.0.1:25123" }

# RealIP ip forwarding feature enabled
"mc.withrealip.com" = { ip-forwarding = "realip", ip = "127.0.0.1:26161" }

# this will load balance between the two servers
"other.gaming.tk" = { ip = ["127.0.0.1:25009", "10.1.0.1:25123"] }

Load balancing

Hopper's load balancer is a hash distributor based on the player's source IP and port.

You can load balance players between two backend servers by specifying a list of ip addresses instead of a single address.

[routing]
default = { ip = ["1.1.1.1:25565", "2.2.2.2:25577"] } # works on non-default routes too

IP Forwarding

Without IP Forwarding, when servers receive connections from this reverse proxy they won't see the original client's ip address. This may lead to problems with sessions with plugins such as AuthMe. Hopper implements both the legacy BungeeCord protocol and the more versatile RealIP one.

Bungeecord

You must enable bungeecord ip-forwarding inside of spigot.yml just like you would using bungeecord. Click here to learn more.

You can enable ip forwarding per-server on hopper with the "ip-forwarding" directive:

# You can either do it this way
[routing.routes]
"your.hostname.com" = { ip-forwarding = "bungeecord", ip = "<your server ip>" }

# or this way
[routing.routes."your.hostname.com"]
ip-forwarding = "bungeecord" # available options are: bungeecord, none. Defaults to none
ip = "<your server ip>"

RealIP

Hopper supports up to RealIP v2.4 (private/public key authentication has been implemented for versions after that, which only works with TCPShield).

⚠️ Note: RealIP v2.4 was built using older dependencies, hence support for newer minecraft versions may be lacking.

You must whitelist Hopper's ip address (or network) by adding a line inside of plugins/TCPShield/ip-whitelist/tcpshield-ips.list.

Finally, you must enable RealIP support in your Config.toml:

[routing.routes]
"your.hostname.com" = { ip-forwarding = "realip", ip = "<your server ip>" }

PROXY Protocol a.k.a HAProxy V2

Support for PROXY Protocol is available by setting ip-forwarding to proxy_protocol. Only the 2nd version of the protocol (the one supported by Bungeecord out of the box) is implemented in Hopper.

Example configuration:

[routing.routes]
"my.bungee.hostname.com" = { ip-forwarding = "proxy_protocol", ip = "<your server ip>" }

Logging metrics with InfluxDB

Hopper supports cheap (resource-wise), easily configurable data gathering through the help of an external database like InfluxDB (although other databases will be supported in the future, I still recommend InfluxDB whose query language is very easy and versatile).

You must first configure an InfluxDB instance and get a token with writing privilege before moving along with this section.

Add and modify this configuration section in Config.toml according to your setup:

[metrics] # top-level section
type = "influxdb"
# hostname = "my-hostname" # OPTIONAL, defaults to system hostname
url = "<http/https>://<influxdb-host-or-ip>:<port>/"
organization = "<Your organization>"
bucket = "<Your data bucket>"
token = "<Your access token>"

Hopper will start logging every 5 seconds according to this data format:

Measurement "traffic":

Field Type Description
host Tag system (or custom if specified) hostname generating this metric
destination_hostname Tag the hostname clients connected corresponding to these metrics
clientbound_traffic Value (int) the traffic this host generated server=>client
serverbound_traffic Value (int) same as above, but client=>server
open_connections Value(int) connections opened in the moment of the measurement
total_game Value(int) people who attemped or succeded joining this server
total_ping Value(int) people who pinged this server

NOTE: Since counters reset through restarts, data manipulation using the influx query language allows you to aggregate rows and get persistent results.

How to run

There are two ways to run hopper:

Docker GitHub Workflow Status

  • Pull the latest image from the GitHub registry:
docker pull ghcr.io/bra1l0r/hopper-rs
  • Create a Config.toml (NOTE: the port you will specify must match the exposed port below)
  • Run it using docker:
docker run -d -p 25565:25565 -v /home/user/path-to/Config.toml:/Config.toml ghcr.io/bra1l0r/hopper-rs

Using docker-compose (recommended):

# new versions of compose don't require this anymore
version: "3"

services:
  hopper:
    image: ghcr.io/bra1l0r/hopper-rs
    ports:
      - 25565:25565
    volumes:
      - ./Config.toml:/Config.toml

Binary GitHub Workflow Status

You can either download the latest release (recommended) or follow the steps below to build your own binary:

  • Download and install the latest version of the rustc toolchain
  • Clone and build the repo:
# Clone the repo into hopper-rs and enter the directory
git clone https://github.com/BRA1L0R/hopper-rs
cd hopper-rs/

# Build the project with the release profile
cargo build --release
  • The runnable binary will now be available at target/release/hopper

Systemd configuration

Assuming both the hopper binary and Config.toml configuration file are located inside /opt/hopper, you can extend this systemd configuration that supports both the stop and reload commands.

It is strongly advised not to use the root user as a best practice, however this configuration does use it and is to be intended as a template.

[Unit]
Description=Hopper reverse proxy
After=network.target

[Service]
Type=simple
ExecStart=/opt/hopper/hopper
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -SIGINT $MAINPID
WorkingDirectory=/opt/hopper

[Install]
WantedBy=multi-user.target

Changing the verbosity level

If you think something is off with your instance and want to enable debug logging, or you just want to reduce the default talkativeness of hopper you must choose your desired level of verbosity through the RUST_LOG environment variable.

Level Description
off No console output at all
error Only output important errors such as an unreachable backend server
info Informative data such as incoming connections and the current listening address
debug More descriptive errors (includes failed handshakes and bad packet data)

Default: info

Example:

RUST_LOG="debug" ./hopper

Hot reload

Hot reloading of Config.toml is supported only on linux as it provides the best way to signal the process to perform a hot reload.

If you think you know how something similar might be implemented in Windows please open an issue explaining your idea.

Hopper supports hot reloading through the SIGHUP process signal. Just like nginx. A rudimentary example of doing this would be through the kill command:

kill -s sighup <process PID>

If the new configuration contains the reload is aborted and the server continues running with the previous configuration.

You can automate this with systemd, allowing for the handy systemctl reload <service> shortcut, as you can see explained here.

Comments
  • CPU max usage

    CPU max usage

    Hello, I have set up hopper to proxy a basic spigot server. even when no one uses the proxy, hopper tends to spike the cpu at 100% for like 10 minutes. unknown (3) unknown (4)

    opened by InfiniteCod3 15
  • RealIP support

    RealIP support

    Hi! I installed the hopper and everything is fine, except for one thing. When I turn on "ip-forwarding", the players pings jump twice. I'm sure it's because of the bungeecord protocol as I had similar problems when I had the server linked via bungeecord. I suggest adding support for "realIP" from TCPShield. I know it's complicated but add at least 2.4 support which doesn't seem to require public and private keys. (If possible, add support for the latest version at once, please!) Thanks in advance!

    enhancement 
    opened by JaredHuh 8
  • Ping seems quite volatile

    Ping seems quite volatile

    Hey,

    I replaced HAProxy with Hopper as a proxy and noted the following: With HAProxy, my ping appears to be stable at around ~20: image

    With Hopper, it likes to jump around quite a lot and is way higher than it was: image

    (This behavior is also seen by different users from different parts of the country with different ISPs)

    Both Revers Proxies connect to the same Minecraft Proxy and are hosted by the same Hoster. And both Revers Proxies are using the Proxy Protocol. I can give you both Revers Proxies IPs in case you are interested and want to investigate that.

    opened by Alex1607 7
  • Add routing reload option

    Add routing reload option

    Hey

    I tried my best to implement my feature from #16. However, since I haven't worked a lot in rust, yet it may be not up to the standard needed. So feel free to change it as needed or just reject it. Wherever you reject or accept the PR, I would appreciate some feedback 😄

    opened by Alex1607 6
  • Suggestion: Reload config for High Availability

    Suggestion: Reload config for High Availability

    Maybe it would be possible to add a reload mechanism into hopper to allow for easy changes without having to disconnect all users. Like for example, if I want to add a new route, hopper would kick all users because I have to restart it. Furthermore, this is something which might be important for me but not for others. But I would love the ability to change the IP of the backend server, reload hopper, and then have only new users connect to this new IP while users that are currently connected keep their current connection.

    enhancement 
    opened by Alex1607 4
  • Luckperms

    Luckperms "module"

    I don't think I need to state just how popular and useful Luckperms is as a permission manager.

    One of the things that I can do with Luckperms on both Bungee and Server is to allow/deny usergroups connecting to a a host amongst other options.

    enhancement wontfix 
    opened by spannerman79 3
  • Compatibility issue with Nyx plugin

    Compatibility issue with Nyx plugin

    https://builtbybit.com/threads/%E2%9C%85-nyx-ultimate-1-8-1-18-%E2%9C%85-manage-players-online-mode-alts-ips-and-even-passwords.629772/

    Nyx, a plugin for online mode authentication, does not seem to be compatible with hopper. This issue has been reported by a hopper-rs user using 1.8.2 testing both with and without RealIP ip forwarding.

    opened by BRA1L0R 2
  • Broken docker image dependencies

    Broken docker image dependencies

    Hello! I did all steps mentioned under "How to run" title, and it don't start. I tried to run it using docker: docker run -d -p 25565:25565 -v /etc/hopper/Config.toml:/Config.toml ghcr.io/bra1l0r/hopper-rs

    Logs: Error relocating /hopper: __res_init: symbol not found

    Any tutorial with fixing it? Thank you in advance!

    bug 
    opened by JaredHuh 2
  • Bedrock support

    Bedrock support

    Hi! Could you look into making this compatible with Bedrock/Geyser? It could be a very interesting alternative for Bedrock proxies as Nginx does not quite work well with Geyser and there is not much else out there.

    enhancement wontfix 
    opened by mbenitog 1
  • Hopper macros | Refactor  + Derive(Serialize) + minor version bump

    Hopper macros | Refactor + Derive(Serialize) + minor version bump

    Codebase refactor of the hopper_macro crate with a good amount of detailed docstrings introduced. Added Derive(Serialize) procedural macro to public API. Minor version bump from 0.1.0 to 0.2.0.

    Changes have not yet been tested nor have they been implemented to the hopper codebase.

    Testing is needed.

    opened by DumbMahreeo 1
  • Adding hopper_macros package for Derive(Deserialize)

    Adding hopper_macros package for Derive(Deserialize)

    No changes have been done to the codebase. The hopper_macros crate has been added in /src with a reference to it in the Cargo.toml file.

    The macro has yet to be tested on the actual codebase.

    opened by DumbMahreeo 1
  • Protocol Routing

    Protocol Routing

    Hello there, don't know if this is in the scope of the software but would be neat to have the option to route players to different proxy using different protocol versions

    enhancement 
    opened by MastoryMd5 5
Releases(v0.6.0)
Owner
Pietro
@stack_smash on telegram.
Pietro
A lightweight Rust reverse proxy.

Brachyura A reverse proxy, which I am primarily using as a Rust / Hyper learning project. I utilize Nginx as part of my home lab providing reverse pro

William Howard 8 Jan 8, 2023
Lightweight proxy that allows redirect HTTP(S) traffic through a proxy.

Proxyswarm Proxyswarm is a lightweight proxy that allows redirect HTTP(S) traffic through a proxy. WARNING: This app isn't recomended for download lar

Jorge Alejandro Jimenez Luna 4 Apr 16, 2022
A fast and stable reverse proxy for NAT traversal, written in Rust

rathole A fast and stable reverse proxy for NAT traversal, written in Rust rathole, like frp, can help to expose the service on the device behind the

Yujia Qiao 4.6k Dec 30, 2022
Web3-proxy: a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers.

web3-proxy Web3-proxy is a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers. Signed transactions (eth_sendRawTrans

null 55 Jan 8, 2023
A high performence Socks5 proxy server with bind/reverse support implementation by Rust.

rsocx A high performence Socks5 proxy server with bind/reverse support implementation by Rust Features Async-std No unsafe code Single executable Linu

b23r0 259 Jan 6, 2023
A firewall reverse proxy for preventing Log4J (Log4Shell aka CVE-2021-44228) attacks.

log4jail ??️ A fast firewall reverse proxy with TLS (HTTPS) and swarm support for preventing Log4J (Log4Shell aka CVE-2021-44228) attacks. ?? Table of

Mufeed VH 22 Dec 27, 2022
Reverse proxy for HTTP microservices and STDIO. Openfass watchdog which can run webassembly with wasmer-gpu written in rust.

The of-watchdog implements an HTTP server listening on port 8080, and acts as a reverse proxy for running functions and microservices. It can be used independently, or as the entrypoint for a container with OpenFaaS.

yanghaku 7 Sep 15, 2022
A minimal ngrok liked reverse proxy implemented in Rust.

rok A minimal ngrok implementation in Rust, for educational purpose. This work is largely based on rathole, especially the very first commit. Other ho

Kai 3 Jun 21, 2022
A multi-connection TCP reverse proxy server and client.

tprox A multi-connection TCP reverse proxy. The tprox server is able to proxy multiple incoming connections to the tprox client over a single TCP conn

Mohammed Ajmal Siddiqui 4 Sep 21, 2022
A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption

A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption

editso 1.3k Dec 30, 2022
RCProxy - a lightweight, fast but powerful Redis Cluster Proxy written in Rust

RCProxy - a lightweight, fast but powerful Redis Cluster Proxy written in Rust

Cris Liao 16 Dec 4, 2022
Minecraft proxy

mc-proxy This is a fully functional proxy for online and offline-mode Minecraft servers. It is based on an optimized, custom-made packet parser for Mi

null 21 Oct 7, 2022
The true next-gen L7 minecraft proxy and load balancer. Built in Rust.

Lure The true next-gen L7 minecraft proxy and load balancer. Built in Rust, Tokio and Valence. Why? Rust is a powerful programming language and a grea

Sammwy 67 Apr 16, 2023
Proxy sentry request to a sentry server using a tunnel/proxy endpoint

Sentry Tunnel This is a proxy that forwards tunneled sentry requests to the real sentry server. The implementation is based on the explanation provide

Paul FLORENCE 14 Dec 20, 2022
UDP proxy with Proxy Protocol and mmproxy support

udppp UDP proxy with Proxy Protocol and mmproxy support. Features Async Support Proxy Protocol V2 SOCKET preserve client IP addresses in L7 proxies(mm

b23r0 10 Dec 18, 2022
A fast, offline reverse geocoder in Python

Reverse Geocoder A Python library for offline reverse geocoding. It improves on an existing library called reverse_geocode developed by Richard Penman

Ajay Thampi 1.8k Dec 26, 2022
Rust crate for configurable parallel web crawling, designed to crawl for content

url-crawler A configurable parallel web crawler, designed to crawl a website for content. Changelog Docs.rs Example extern crate url_crawler; use std:

Pop!_OS 56 Aug 22, 2021
Simple and fast layer 4 proxy in Rust

Fourth 这一波在第四层。 English Fourth是一个Rust实现的Layer 4代理,用于监听指定端口TCP流量,并根据规则转发到指定目标。 功能 监听指定端口代理到本地或远端指定端口 监听指定端口,通过TLS ClientHello消息中的SNI进行分流 安装方法 为了确保获得您架构

Rui Li 17 Nov 8, 2022
Utility for working with reverse DNS

RDNS RDNS is a small Rust CLI utility for performing single and bulk reverse DNS (PTR) lookups. Usage RDNS 0.1.0 Joe Banks <[email protected]> Utilities for

Joe Banks 2 Sep 22, 2021