MCPcopy Index your code
hub / github.com/Gegam/redpill

github.com/Gegam/redpill @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
393 symbols 838 edges 39 files 157 documented · 40%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

English | Русский | فارسی | العربية | 中文

RedpillVPN

Fast, censorship-resistant VPN built on QUIC. Written in Rust.

Status: MVP / early alpha. Core tunneling works and is tested on macOS/Linux, but expect rough edges, breaking changes, and missing features. See Roadmap for what's planned.

Tunnels raw IP packets over QUIC DATAGRAM frames (RFC 9221) on UDP:443, TLS 1.3. The outer QUIC uses a no-op congestion controller (fixed 16 MB window) since inner TCP already handles CC. Supports multiple transport modes for different network conditions.

Features

Transport

  • QUIC DATAGRAM frames (RFC 9221) over UDP:443
  • TLS 1.3 via quinn/rustls, self-signed certificates (auto-generated on first run)
  • No-op congestion control (16 MB constant window) - inner TCP handles CC
  • Datagram batching for small packets (<300 B: DNS queries, TCP ACKs)
  • Dynamic MTU - server monitors PMTU and pushes updates to the client in real time

Security

  • PSK authentication (HMAC-SHA256, constant-time verification)
  • Multi-user support - each user gets their own PSK (add-user / remove-user CLI)
  • Source IP anti-spoofing validation
  • Kill-switch on macOS (pf), Windows (Windows Firewall) - prevents leaks on disconnect
  • HTTP/3 decoy server (fake nginx page for active probe resistance)

Anti-Censorship

  • 5 transport modes - direct QUIC, QUIC + camouflage, TCP Reality, WebSocket CDN, auto
  • SNI camouflage with round-robin domain rotation
  • Browser TLS fingerprint mimicry - Chrome, Firefox, Safari profiles (JA3/JA4 resistance)
  • Packet size normalization to standard HTTP/3 sizes (128 / 256 / 512 / 1024 / 1200 / 1400)
  • Idle traffic padding (dummy packets during inactivity)
  • TCP Reality - non-VPN TLS connections are transparently proxied to a real website
  • WebSocket CDN - tunnel through CDN reverse proxies (Cloudflare, etc.)

Server

  • Multi-client with per-client priority queues and IP allocation (10.0.1.2-254, up to 253 clients)
  • Traffic prioritization - realtime (small UDP, DNS, DSCP EF) dequeued before bulk
  • Server-side backpressure to prevent loss amplification
  • Adaptive RTT-based traffic shaping + per-client bandwidth cap
  • XDP conntrack bypass for high packet-rate performance (Linux, optional)
  • Prometheus metrics endpoint (/metrics)
  • SIGHUP hot-reload (PSK, users, max_connections, decoy page, log level)
  • NAT masquerade + MSS clamping (automatic)

Client

  • Auto-reconnect with exponential backoff (1s-30s) and jitter
  • Health monitoring with automatic transport fallback and upgrade
  • Daemon mode (Linux/macOS) - up / down / status commands with IPC
  • Stale state cleanup on startup (routes, DNS, firewall rules from crashed sessions)

Supported Platforms

Role OS Arch
Server Linux x86_64, arm64
Client macOS, Linux, Windows arm64, x86_64

Note: The Windows client compiles and includes full wintun/routing/firewall support, but has not been tested on real hardware yet. macOS and Linux clients are fully tested.


Quick Start

1. Build

git clone https://github.com/redpill-vpn/redpill.git
cd redpill
cargo build --release

Binaries appear in target/release/: - redpill-server - VPN server - redpill-client - VPN client

Optional build features:

cargo build --release --features xdp    # XDP conntrack bypass (Linux server only)
cargo build --release --features acme   # ACME/Let's Encrypt stub

2. Generate a PSK

openssl rand -hex 32
# Example output: a3f7b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0

Save this 64-character hex string - you will need it for both server and client.

3. Server Setup

# Create config directory
sudo mkdir -p /etc/redpill

# Copy example config
sudo cp config/server.example.toml /etc/redpill/server.toml

# Save the PSK
echo "YOUR_64_CHAR_HEX_PSK" | sudo tee /etc/redpill/psk

# Install binary
sudo cp target/release/redpill-server /usr/local/bin/

# Start the server
sudo redpill-server -c /etc/redpill/server.toml

Important: Edit /etc/redpill/server.toml and set nat.interface to your server's WAN interface (e.g. ens1, eth0). Find it with ip route show default.

On first run the server auto-generates a self-signed TLS certificate at the paths specified in the config (cert_file / key_file). Copy the certificate file to the client machine.

4. Client Setup

Simple (CLI flags)

sudo redpill-client \
  --server YOUR_SERVER_IP:443 \
  --cert path/to/cert.pem \
  --psk YOUR_64_CHAR_HEX_PSK

With config file (recommended)

sudo cp config/client.example.toml ~/client.toml
# Edit ~/client.toml - set server address, cert path, and PSK
sudo redpill-client --config ~/client.toml

Test mode (no routes, keeps your existing connection)

sudo redpill-client --server YOUR_SERVER_IP --cert cert.pem --psk <hex> --test-mode

In test mode the tunnel is established but no system routes or DNS are changed. Useful for iperf3 benchmarks or debugging.

5. Verify

# Should show your server's IP
curl -s https://api.ipify.org

# Ping through the tunnel
ping 10.0.1.1

Multi-User Management

Instead of a single shared PSK, you can give each user their own key.

Enable multi-user mode

Add users_dir to the server config:

users_dir = "/etc/redpill/users"

Add a user

# Generate a random PSK for the user
openssl rand -hex 32 | sudo tee /etc/redpill/users/alice.key

Give alice her PSK and the server certificate. She connects with:

sudo redpill-client --server YOUR_SERVER_IP --cert cert.pem --psk $(cat alice.key)

Remove a user

sudo rm /etc/redpill/users/alice.key
sudo kill -HUP $(pidof redpill-server)   # Reload without restart

List users

ls /etc/redpill/users/
# alice.key  bob.key  charlie.key

Each .key file is a 64-character hex PSK. The filename (without .key) is the username shown in logs and metrics.

Backward compatibility: If psk_file is also set, its key is accepted as a fallback (shown as user legacy in logs). To migrate: copy the old PSK into users_dir/legacy.key and remove psk_file.


Transport Modes

RedpillVPN supports 5 transport modes. Choose the one that fits your network:

Mode Protocol When to use
quic Direct QUIC DATAGRAM over UDP:443 Default. Best performance on unrestricted networks
quic-camouflaged QUIC + SNI rotation + padding + browser fingerprint Networks with light DPI (SNI-based filtering)
tcp-reality TLS-over-TCP with active probe deflection QUIC is blocked, TCP+TLS still works
websocket WebSocket binary frames through a CDN Only CDN-fronted access works
auto Probes all transports, picks the best one Recommended for censored or unknown networks

Configuring transports

Transport selection is done in the client config file ([transport] section):

Direct QUIC (default)

[server]
address = "1.2.3.4:443"
cert = "cert.pem"
psk = "your-psk-hex"

[transport]
mode = "quic"

QUIC Camouflaged

Makes your QUIC traffic look like regular browser HTTPS:

[transport]
mode = "quic-camouflaged"

[camouflage]
# Domains to rotate through (SNI field in ClientHello)
sni_pool = ["dl.google.com", "www.google.com", "fonts.gstatic.com", "www.youtube.com"]
# Pad packets to standard HTTP/3 sizes
padding = true
# Mimic a real browser's TLS fingerprint
chrome_fingerprint = true
# Browser to mimic: "chrome", "firefox", "safari", or "random"
browser_profile = "chrome"

TCP Reality

When QUIC/UDP is completely blocked. The server accepts TCP+TLS on a separate port and deflects non-VPN probes to a real website:

Server config:

[reality]
enabled = true
listen = "0.0.0.0:8443"
target = "www.google.com:443"   # Probes see this real website

Client config:

[transport]
mode = "tcp-reality"

[reality]
target = "www.google.com:443"
address = "1.2.3.4:8443"       # Server's Reality port

WebSocket CDN

Route traffic through a CDN (e.g. Cloudflare) to hide the server IP:

Server config:

[websocket]
enabled = true
listen = "127.0.0.1:8080"      # Behind CDN reverse proxy

Client config:

[transport]
mode = "websocket"

[websocket]
url = "wss://cdn.example.com/ws"
host = "cdn.example.com"

Auto Mode (recommended for censored networks)

Probes transports in priority order and picks the first one that works:

[transport]
mode = "auto"

[camouflage]
sni_pool = ["dl.google.com", "www.google.com"]
padding = true
browser_profile = "chrome"

[reality]
target = "www.google.com:443"
address = "1.2.3.4:8443"

The client tries: QUIC → QUIC Camouflaged → TCP Reality → WebSocket. If the active transport degrades, the health monitor triggers a switch.


Daemon Mode (Linux / macOS)

Run the client as a background service:

# Start VPN in background
sudo redpill-client --config client.toml up

# Check status
redpill-client status
# Output:
# Redpill VPN Client
#   Status:    connected
#   Server:    1.2.3.4:443
#   Transport: QuicRaw
#   Client IP: 10.0.1.2
#   Uptime:    3600s
#   TX: 150.3 MB (125000 pkts)
#   RX: 1200.5 MB (1000000 pkts)

# Stop VPN
sudo redpill-client down

Logs are written to /tmp/redpill-client.log. The PID file is at /tmp/redpill-client.pid.

Note: Daemon mode is not available on Windows. Use redpill-client connect (foreground) instead.


Server Deployment

systemd Service

Create /etc/systemd/system/redpill-quic.service:

[Unit]
Description=RedpillVPN Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/redpill-server -c /etc/redpill/server.toml
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable redpill-quic
sudo systemctl start redpill-quic

# View logs
journalctl -u redpill-quic -f

SIGHUP Reload

Reload configuration without restarting:

sudo kill -HUP $(pidof redpill-server)

Reloadable: PSK, user keys, max_connections, decoy page, log level. Not reloadable (requires restart): listen address, TUN config, certificates, NAT interface.

Prometheus Metrics

curl http://127.0.0.1:9093/metrics

Available metrics:

Metric Type Description
redpill_active_sessions gauge Currently connected clients
redpill_sessions_by_user{user} gauge Sessions per user
redpill_bytes_in / _out counter Total bytes received / sent
redpill_datagrams_in / _out counter Total datagrams received / sent
redpill_handshakes_total counter Total handshake attempts
redpill_handshakes_failed counter Failed handshakes (bad PSK)
redpill_drops_backpressure counter Packets dropped by backpressure
redpill_drops_rate_limit counter Packets dropped by rate limiter
redpill_drops_stale counter Stale realtime packets dropped
redpill_rtt_ms histogram Round-trip time distribution

XDP Performance (Linux)

Build with the xdp feature for conntrack bypass on high-throughput servers:

cargo build --release --features xdp

This adds iptables -t raw -j NOTRACK rules for UDP:443, skipping connection tracking in the kernel. The rules are automatically cleaned up on graceful shutdown.

XDP also tunes socket buffers (8 MB) and disables UDP GRO for consistent latency.


Configuration Reference

Server Config

Full example: config/server.example.toml

Key Default Description
listen 0.0.0.0:443 Listen address (UDP)
tun_name redpill1 TUN device name
tun_address 10.0.1.1 Server tunnel IP
tun_prefix_len 24 Subnet prefix length
mtu 1200 Initial TUN MTU (auto-updated via PMTU)
max_connections 64 Max simultaneous clients
max_bandwidth_mbps 0 Per-client bandwidth cap (0 = unlimited)
metrics_listen 127.0.0.1:9093 Prometheus metrics address
psk_file - Path to shared PSK file (single-user mode)
users_dir - Directory with per-user .key files (multi-user mode)
cert_file cert.pem TLS certificate path
key_file key.pem TLS private key path
dns 1.1.1.1 DNS server pushed to clients
log_level info Log level (trace, debug, info, warn, error)
nat.enabled true Enable NAT masquerade
nat.interface ens1 WAN interface for NAT
decoy.enabled true Enable HTTP/3 decoy for probe resistance
decoy.page - Path to HTML file served as decoy
reality.enabled false Enable TCP Reality listener
reality.listen 0.0.0.0:8443 TCP Reality listen address
reality.target www.google.com:443 Real website for probe deflection
websocket.enabled false Enable WebSocket listener
websocket.listen 127.0.0.1:8080 WebSocket listen address

Client Config

Full example: config/client.example.toml

Section Key Default Description
[server] address - Server IP:port
cert - Path to server certificate
psk - 64-char hex PSK
domain - Domain for WebPKI verification (instead of cert pinning)
[transport] mode auto Transport mode (see above)
[camouflage] sni_pool Google domains SNI domains to rotate
padding true Pad packets to standard size

Extension points exported contracts — how you extend this code

Authenticator (Interface)
Trait for authentication verification. Returns username on success. [2 implementers]
crates/redpill-quic/src/auth.rs
Transport (Interface)
(no doc) [4 implementers]
crates/redpill-quic/src/transport/mod.rs
TransportConnector (Interface)
(no doc) [4 implementers]
crates/redpill-quic/src/transport/manager.rs

Core symbols most depended-on inside this repo

len
called by 60
crates/redpill-quic/src/users.rs
run_cmd
called by 57
crates/redpill-tun/src/route.rs
load
called by 41
crates/redpill-quic/src/users.rs
register
called by 21
crates/redpill-quic/src/demux.rs
push
called by 16
crates/redpill-quic/src/priority.rs
encode
called by 15
crates/redpill-quic/src/control.rs
is_empty
called by 14
crates/redpill-quic/src/users.rs
compute_mac
called by 11
crates/redpill-quic/src/auth.rs

Shape

Function 165
Method 147
Class 65
Enum 13
Interface 3

Languages

Rust100%

Modules by API surface

crates/redpill-quic/src/config.rs38 symbols
crates/redpill-quic/tests/integration.rs37 symbols
crates/redpill-quic/src/server.rs23 symbols
crates/redpill-tun/src/route.rs20 symbols
crates/redpill-quic/src/transport/manager.rs14 symbols
crates/redpill-tun/src/device.rs13 symbols
crates/redpill-quic/src/users.rs13 symbols
crates/redpill-quic/src/stats.rs12 symbols
crates/redpill-quic/src/shaper.rs12 symbols
crates/redpill-quic/src/padding.rs12 symbols
crates/redpill-quic/src/transport/tcp_reality.rs11 symbols
crates/redpill-quic/src/transport/quic_camouflaged.rs11 symbols

For agents

$ claude mcp add redpill \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact