Added multi server support

This commit is contained in:
2026-06-23 18:15:37 -04:00
parent 640d4f45f2
commit 4414dce4e4
32 changed files with 543 additions and 207 deletions
+234 -118
View File
@@ -1,75 +1,95 @@
# DirtSimpleP2P
DirtSimpleP2P lets a public Bungee/Waterfall proxy reach a Paper/Spigot server that is running at home behind NAT.
DirtSimpleP2P is a Minecraft networking plugin that lets a public BungeeCord or Waterfall proxy reach backend Paper/Spigot servers that are behind NAT.
You do not need to open the Minecraft port on your home router. The backend server connects outbound to your public proxy/VPS, then Minecraft traffic is carried through that tunnel.
It is designed for server owners who want to host a backend Minecraft server at home or on a private network without opening the backend Minecraft port on their router.
## What You Get
The backend server connects outbound to the public proxy. Bungee/Waterfall then connects to a local port on the proxy machine, and DirtSimpleP2P carries the Minecraft TCP connection through the tunnel.
- One jar file for both servers
- No home router port forwarding
- Works with a public Bungee/Waterfall proxy
- Works with a backend Paper/Spigot server
## Features
- One jar for both the proxy and backend server
- No home router port forwarding for backend Minecraft servers
- NAT-safe outbound tunnel from backend to proxy
- Multiple simultaneous Minecraft player connections
- Multiplexed framed TCP protocol
- Secret-token authentication
- Automatic secret-token generation
- Optional TLS encryption with generated self-signed certificates
- Multiple Minecraft player connections over one tunnel
- Fast reconnect with heartbeat-based latency tolerance
- Automatic token generation
- Optional TLS encryption
- Self-signed TLS certificate generation
- TLS certificate pinning on backend servers
- Fast reconnect with heartbeat checks
- Multiple public proxies can connect to one backend
- One proxy can expose multiple named backend servers
- `/dsp2p status` and `/dsp2p doctor` commands
- Simple properties config files
- Simple `config.properties` setup
## Current Status
## Requirements
This is still a development build, not a paid release build yet.
- Java 21
- Maven 3.8+
- BungeeCord or Waterfall for the public proxy side
- Paper or Spigot for the backend server side
The tunnel core exists and the plugin jar builds. TLS can now generate a self-signed certificate when enabled, but before paid release it should get more real-world testing on actual Bungee and Paper servers.
## How It Works
## Build The Jar
Normal Minecraft proxy setup expects Bungee/Waterfall to connect directly to a backend server.
From this project folder, run:
That does not work well when the backend server is at home behind NAT, unless you forward ports on the home router.
DirtSimpleP2P avoids that:
1. The proxy server runs DirtSimpleP2P in `frontend` mode.
2. The backend server runs DirtSimpleP2P in `backend` mode.
3. The backend opens an outbound tunnel to the public proxy.
4. The proxy exposes a local port such as `127.0.0.1:25566`.
5. Bungee/Waterfall sends players to that local port.
6. DirtSimpleP2P carries the TCP traffic through the tunnel to the backend server.
The public proxy needs an open tunnel port. The home/backend router does not need a Minecraft port forward.
## Build
From the project folder:
```bash
mvn clean package
```
The plugin jar will be here:
The plugin jar is created at:
```bash
plugin/target/DirtSimpleP2P-0.1.0-SNAPSHOT.jar
```
Use this same jar on both servers.
Use this same jar on both the proxy and backend server.
## Basic Setup
You need two Minecraft-side servers:
You need:
- Public proxy server: BungeeCord, Waterfall, or another Bungee-compatible proxy
- Backend server: Paper or Spigot
- A public BungeeCord/Waterfall proxy, usually on a VPS
- A backend Paper/Spigot server, which can be at home or on a private network
The public proxy is usually on a VPS. The backend server can be at home.
### 1. Install On The Proxy
## Step 1: Install On Bungee
Put the jar in your BungeeCord/Waterfall `plugins` folder:
Put this jar in your Bungee/Waterfall `plugins` folder:
```bash
```text
DirtSimpleP2P-0.1.0-SNAPSHOT.jar
```
Start the proxy once, then stop it.
DirtSimpleP2P will create:
DirtSimpleP2P creates:
```bash
```text
plugins/DirtSimpleP2P/config.properties
```
Open that file.
### 2. Configure The Proxy
## Step 2: Configure Bungee
On the Bungee/proxy server, use:
Use this on the BungeeCord/Waterfall side:
```properties
role=frontend
@@ -96,70 +116,57 @@ tunnel.tls.requireClientAuth=false
routes=minecraft
route.minecraft.frontendBindHost=127.0.0.1
route.minecraft.frontendBindPort=25566
route.minecraft.backendNode=paper-backend
```
Change:
Notes:
- `tunnel.listenPort` only if port `24445` is already used
- `tunnel.listenPort` is the public tunnel port that the backend connects to.
- `tunnel.authToken` is generated automatically on first start.
- Copy the generated token to the backend config.
- `route.minecraft.frontendBindPort` is the local port Bungee/Waterfall should use for this backend.
- `route.minecraft.backendNode` must match the backend server's `node.name`.
The plugin automatically generates `tunnel.authToken` on first start.
### 3. Point Bungee/Waterfall At The Local Tunnel
Copy the generated Bungee token into the backend server config. The token must match on both sides.
To enable TLS on Bungee, change:
```properties
tunnel.tls.enabled=true
tunnel.tls.allowInsecure=false
```
When Bungee starts, DirtSimpleP2P will generate:
```text
plugins/DirtSimpleP2P/certs/frontend.p12
```
It will also fill in `tunnel.tls.keyStorePassword` if that value is blank.
## Step 3: Point Bungee At The Local Tunnel
In your Bungee server config, set the backend server address to:
In your BungeeCord/Waterfall server config, set the backend address to:
```text
127.0.0.1:25566
```
That is not your home server IP. DirtSimpleP2P listens there locally on the proxy server.
Do not put your home server IP in the Bungee/Waterfall config. Bungee connects locally, and DirtSimpleP2P carries the traffic through the tunnel.
## Step 4: Install On Paper Or Spigot
### 4. Install On The Backend
Put the same jar in your backend Minecraft server `plugins` folder:
Put the same jar in your Paper/Spigot `plugins` folder:
```bash
```text
DirtSimpleP2P-0.1.0-SNAPSHOT.jar
```
Start the backend server once, then stop it.
DirtSimpleP2P will create:
DirtSimpleP2P creates:
```bash
```text
plugins/DirtSimpleP2P/config.properties
```
Open that file.
### 5. Configure The Backend
## Step 5: Configure Paper Or Spigot
On the backend server, use:
Use this on the Paper/Spigot side:
```properties
role=backend
node.name=paper-backend
tunnel.connectHost=YOUR_BUNGEE_OR_VPS_IP
tunnel.connectPort=24445
tunnel.authToken=PASTE_THE_BUNGEE_TOKEN_HERE
frontends=proxy1
frontend.proxy1.connectHost=YOUR_PROXY_IP_OR_DOMAIN
frontend.proxy1.connectPort=24445
frontend.proxy1.tls.pinnedCertificateSha256=
tunnel.authToken=PASTE_THE_PROXY_TOKEN_HERE
tunnel.connectTimeoutMillis=5000
tunnel.heartbeatIntervalMillis=2000
@@ -171,7 +178,6 @@ tunnel.reconnectMaxMillis=10000
tunnel.tls.enabled=false
tunnel.tls.allowInsecure=true
tunnel.tls.trustOnFirstUse=true
tunnel.tls.pinnedCertificateSha256=
routes=minecraft
route.minecraft.backendTargetHost=127.0.0.1
@@ -180,58 +186,167 @@ route.minecraft.backendTargetPort=25565
Change:
- `tunnel.connectHost` to your public proxy/VPS IP or domain name
- `tunnel.authToken` to the same secret used on Bungee
- `route.minecraft.backendTargetPort` if your backend Minecraft server is not on `25565`
- `frontend.proxy1.connectHost` to your public proxy IP or domain
- `frontend.proxy1.connectPort` to the proxy `tunnel.listenPort`
- `tunnel.authToken` to the token from the proxy config
- `route.minecraft.backendTargetPort` if your Paper/Spigot server is not listening on `25565`
Do not put your home IP in the Bungee config. The backend connects out to the proxy.
### 6. Start Everything
To enable TLS on Paper/Spigot, change:
Start the public proxy first.
Then start the backend Paper/Spigot server.
If the tunnel connects, the proxy log should show that a backend authenticated. Players connect to your normal public proxy address.
## TLS
TLS is optional, but recommended for real deployments.
On the proxy:
```properties
tunnel.tls.enabled=true
tunnel.tls.allowInsecure=false
tunnel.tls.autoGenerate=true
```
Leave this enabled for the easiest setup:
When TLS is enabled, the proxy can generate:
```text
plugins/DirtSimpleP2P/certs/frontend.p12
```
On the backend:
```properties
tunnel.tls.enabled=true
tunnel.tls.allowInsecure=false
tunnel.tls.trustOnFirstUse=true
```
On the first successful TLS connection, the backend saves the Bungee certificate fingerprint here:
On the first successful TLS connection, the backend saves the proxy certificate fingerprint:
```properties
tunnel.tls.pinnedCertificateSha256=
frontend.proxy1.tls.pinnedCertificateSha256=
```
After that, the backend will only trust that same Bungee certificate.
After that, the backend only trusts that same certificate.
## Step 6: Start Everything
For stricter security, copy the certificate fingerprint from the proxy log and paste it into the backend config before the first connection.
Start the public Bungee/Waterfall proxy first.
## Multi-Server Setups
Then start the backend Paper/Spigot server.
### Two Public Proxies, One Backend
If it works, the Bungee logs should show that a backend tunnel authenticated.
Use this when two public BungeeCord/Waterfall proxies should both reach the same backend server.
Players should connect to your normal public proxy address. Bungee sends them to `127.0.0.1:25566`, and DirtSimpleP2P carries the connection to the backend server.
Backend config:
```properties
role=backend
node.name=survival-backend
frontends=proxy1,proxy2
frontend.proxy1.connectHost=proxy1.example.com
frontend.proxy1.connectPort=24445
frontend.proxy1.tls.pinnedCertificateSha256=
frontend.proxy2.connectHost=proxy2.example.com
frontend.proxy2.connectPort=24445
frontend.proxy2.tls.pinnedCertificateSha256=
routes=minecraft
route.minecraft.backendTargetHost=127.0.0.1
route.minecraft.backendTargetPort=25565
```
Each proxy config:
```properties
role=frontend
node.name=proxy1
routes=minecraft
route.minecraft.frontendBindHost=127.0.0.1
route.minecraft.frontendBindPort=25566
route.minecraft.backendNode=survival-backend
```
Each proxy listens for tunnel connections. The backend connects outbound to both proxies.
### One Proxy, Multiple Backends
Use this when one proxy should expose more than one backend server.
Proxy config:
```properties
role=frontend
node.name=main-proxy
routes=survival,lobby
route.survival.frontendBindHost=127.0.0.1
route.survival.frontendBindPort=25566
route.survival.backendNode=survival-backend
route.lobby.frontendBindHost=127.0.0.1
route.lobby.frontendBindPort=25567
route.lobby.backendNode=lobby-backend
```
Bungee/Waterfall server entries:
```text
survival -> 127.0.0.1:25566
lobby -> 127.0.0.1:25567
```
Survival backend config:
```properties
role=backend
node.name=survival-backend
frontends=main
frontend.main.connectHost=YOUR_PROXY_IP
frontend.main.connectPort=24445
routes=survival
route.survival.backendTargetHost=127.0.0.1
route.survival.backendTargetPort=25565
```
Lobby backend config:
```properties
role=backend
node.name=lobby-backend
frontends=main
frontend.main.connectHost=YOUR_PROXY_IP
frontend.main.connectPort=24445
routes=lobby
route.lobby.backendTargetHost=127.0.0.1
route.lobby.backendTargetPort=25565
```
All nodes in the same private tunnel group must use the same `tunnel.authToken`.
## Commands
Run these commands in game or from the server console:
Run from the server console or in game:
```text
/dsp2p status
```
Shows whether the agent is running, whether the tunnel is connected, active streams, TLS state, and the last important event.
Shows role, node name, whether the tunnel is connected, connected tunnel count, active streams, TLS state, and the latest event.
```text
/dsp2p doctor
```
Checks the config and prints useful setup/security hints.
Checks the config and prints setup/security hints.
Permission:
@@ -239,35 +354,35 @@ Permission:
dirtsimplep2p.command
```
On Paper/Spigot it defaults to server operators. On Bungee, give that permission to staff who should see tunnel diagnostics.
On Paper/Spigot, the permission defaults to server operators. On BungeeCord/Waterfall, give this permission to staff who should see tunnel diagnostics.
## Firewall Notes
On the public proxy/VPS, allow:
On the public proxy/VPS, allow the tunnel port:
```text
24445/tcp
```
On the home router, you do not need to forward:
On the home router, you do not need to forward the backend Minecraft port:
```text
25565/tcp
```
Your backend server must be allowed to make outbound connections to the proxy/VPS.
The backend server must be allowed to make outbound TCP connections to the proxy.
## Reconnect Behavior
DirtSimpleP2P is tuned to notice real drops quickly while still tolerating short latency spikes.
DirtSimpleP2P is tuned to detect real drops quickly while still tolerating short latency spikes.
Default behavior:
- Heartbeat every `2` seconds
- Warns in status if heartbeats are delayed
- Disconnects after about `8` seconds of no tunnel traffic
- Status warning if heartbeats are delayed
- Disconnect after about `8` seconds without tunnel traffic
- First reconnect retry after about `250ms`
- Backoff grows up to `10` seconds if the proxy/VPS is still unreachable
- Exponential backoff up to `10` seconds while the proxy is unreachable
Useful config values:
@@ -279,39 +394,43 @@ tunnel.reconnectInitialMillis=250
tunnel.reconnectMaxMillis=10000
```
If your users are very far from the VPS or your home internet has frequent latency spikes, increase `tunnel.heartbeatMissesBeforeDisconnect` to `5` or `6`.
If your network has frequent latency spikes, increase:
## Common Problems
```properties
tunnel.heartbeatMissesBeforeDisconnect=5
```
### Plugin says the token is still the default
## Troubleshooting
Restart once on each side so DirtSimpleP2P can generate a token.
### Token Problems
Then copy the generated Bungee token into the backend config. The token must be the same on both sides.
The token must match on both sides.
### Backend says connection refused
If the plugin generated a token on the proxy, copy that generated value into the backend config.
### Backend Says Connection Refused
Check that:
- Bungee/proxy server is running
- DirtSimpleP2P started on Bungee
- `tunnel.connectHost` points to the proxy/VPS
- `tunnel.connectPort` matches the Bungee `tunnel.listenPort`
- The VPS firewall allows that TCP port
- The proxy server is running
- DirtSimpleP2P started on the proxy
- `frontend.proxy1.connectHost` points to the proxy IP or domain
- `frontend.proxy1.connectPort` matches the proxy `tunnel.listenPort`
- The proxy firewall allows the tunnel port
### Bungee cannot connect to backend server
### Bungee Cannot Reach The Backend
Make sure your Bungee backend server entry points to:
Make sure the Bungee/Waterfall backend server entry points to the local tunnel port:
```text
127.0.0.1:25566
```
Also make sure the backend Paper/Spigot server is running and connected to the tunnel.
Also check that the backend Paper/Spigot server is running and the tunnel is connected.
### Players disconnect or freeze
### Players Disconnect Or Freeze
Check both server logs. Look for:
Check both server logs for:
- reconnect messages
- heartbeat timeout messages
@@ -320,23 +439,20 @@ Check both server logs. Look for:
## Security Notes
The secret token is important. Do not share it.
Keep `tunnel.authToken` private. Anyone with the token can attempt to authenticate to the tunnel.
Local-test configs use:
For local testing, insecure mode is available:
```properties
tunnel.tls.enabled=false
tunnel.tls.allowInsecure=true
```
For a better setup, enable TLS on both sides:
For real deployments, enable TLS:
```properties
tunnel.tls.enabled=true
tunnel.tls.allowInsecure=false
```
The Bungee side generates a self-signed certificate. The Paper/Spigot side pins that certificate after the first successful connection.
Trust-on-first-use is convenient, but the very first TLS connection is still the sensitive moment. For a stricter setup, copy the fingerprint from the Bungee log and paste it into the backend config before the first connection.
Trust-on-first-use is convenient, but the first TLS connection is the sensitive moment. For the strictest setup, manually copy the proxy certificate fingerprint into the backend config before the first connection.