Pumpkin-Docs/docs/en/developer/networking/proxy/velocity.md
Alexander Medvedev 102bd0329c update: docs
2026-09-14 21:29:00 +02:00

89 lines
4.7 KiB
Markdown

# Velocity Modern Forwarding
[Velocity](https://papermc.io/software/velocity) is a high-performance proxy created by PaperMC. It uses modern plugin messaging during the `Login` state to securely transmit player data with **HMAC-SHA256** message authentication codes.
Pumpkin implements Velocity modern forwarding in [`crates/pumpkin/src/net/proxy/velocity.rs`](https://github.com/Pumpkin-MC/Pumpkin/blob/master/crates/pumpkin/src/net/proxy/velocity.rs).
---
## How Velocity Forwarding Operates
Unlike BungeeCord, which injects unauthenticated data into the handshake string, Velocity operates during the **Login** state over a dedicated plugin channel:
1. **Handshake & Login**: The player authenticates with Velocity. Velocity initiates a standard TCP connection to Pumpkin and transmits `SHandshake` and `SLoginStart`.
2. **Channel Query**: Recognizing that Velocity modern forwarding is enabled, Pumpkin pauses the login sequence and dispatches a `CLoginPluginRequest` on channel `velocity:player_info`.
3. **Payload Generation**: Velocity bundles the player's remote address, UUID, username, and skin textures. It calculates a 32-byte HMAC-SHA256 signature across this payload using the shared secret.
4. **Signature Verification**: Velocity sends `SLoginPluginResponse`. Pumpkin validates the HMAC-SHA256 digest against its configured secret. If valid, Pumpkin overwrites the connection's network address and GameProfile and transitions to `Config` / `Play`.
---
## Wire Payload Structure
The payload in `SLoginPluginResponse` is structured as follows:
```text
┌─────────────────────────────────────────────────────────────┐
│ 32-byte HMAC-SHA256 Signature │
├─────────────────────────────────────────────────────────────┤
│ Forwarding Protocol Version (VarInt: 1 - 4) │
├─────────────────────────────────────────────────────────────┤
│ Client Remote IP Address (String / IPv4 / IPv6) │
├─────────────────────────────────────────────────────────────┤
│ Player UUID (128-bit / UUID) │
├─────────────────────────────────────────────────────────────┤
│ Player Username (String) │
├─────────────────────────────────────────────────────────────┤
│ Profile Properties Count (VarInt) │
│ ├─ Property Name (String) │
│ ├─ Property Value (String) │
│ └─ Optional Signature (String) │
└─────────────────────────────────────────────────────────────┘
```
---
## Cryptographic Validation in Pumpkin
Inside `crates/pumpkin/src/net/proxy/velocity.rs`:
```rust
use hmac::{Hmac, KeyInit, Mac};
use sha2::Sha256;
type HmacSha256 = Hmac<Sha256>;
// Extract signature and payload
let (signature, data_to_verify) = data.split_at(32);
// Initialize HMAC with secret from pumpkin.toml
let mut mac = HmacSha256::new_from_slice(secret.as_bytes())
.map_err(|_| VelocityError::FailedVerifyIntegrity)?;
mac.update(data_to_verify);
// Constant-time verification prevents timing attacks
mac.verify_slice(signature)
.map_err(|_| VelocityError::FailedVerifyIntegrity)?;
```
If the signature does not match (e.g., if an attacker attempts to connect directly to the backend without knowing the secret), Pumpkin drops the connection immediately.
---
## Configuration in `pumpkin.toml`
1. Open `velocity.toml` on your Velocity proxy and set:
```toml
player-info-forwarding-mode = "modern"
forwarding-secret-file = "forwarding.secret"
```
2. Copy the generated secret string from `forwarding.secret` into `pumpkin.toml`:
```toml
[networking.proxy]
enabled = true
[networking.proxy.velocity]
enabled = true
secret = "YOUR_VELOCITY_FORWARDING_SECRET_HERE"
```