Grasshopper is a UDP packet forwarder that listens for incoming packets and forwards them to a configured destination. It optionally supports encryption for both incoming and outgoing packets, using different keys and cryptographic methods.
Grasshopper functions as a chained relay system. For example, consider a chained DNS query:
┌────────────┐ ┌───────────────┐
│ ENCRYPTED │ │ RE-ENCRYPTION │
└─────┬──────┘ │ AES ───► 3DES │
│ └──────┬────────┘
│ │
│ │
│ │
│ │
┌─────────┐ │ ┌────────────┐ │ ┌─────────┐
<HOP0> │ │ <HOP1> │ │ <HOP2> HOPS(FINAL)
┌─────────┐ └ │ ▼ └ │ │ │ ┌─┴──┐ ┌────────────┐
│ dig xxx ├─► CLEAR TEXT ┼────(AES)──────► │ ▼ └ DNS │DNS1├─► 8.8.8.8:53 │
│ @hop0 │ ┌ │ ┌ ├─────(3DES)────────► QUERY │DNS2│ └────────────┘
└─────────┘ │ ▲ │ │ ▲ │ ┌ └─┬──┘
│ │ │ │ │ │ │ │
└──┼──────┘ └─────┼──────┘ └─────────┘
│ │
│ │
│ │
│ │
┌──┼────────┐ │
│ │ │
│ OPTIONAL ├──────────────────┘
│ PACKET │
│ PROCESSOR │
│ │
└───────────┘
To install the latest version of Grasshopper, use the following command:
go install github.com/xtaci/grasshopper/cmd/grasshopper@latest Grasshopper supports the following command-line parameters:
Grasshopper is a UDP packet forwarder that listens for incoming packets and forwards them to a configured destination. It optionally supports cryptography for both incoming and outgoing packets, using different keys and methods. Optionally, the listener can be configured to apply cryptogrraphy on both the incoming and outgoing packets, with different keys and methods.
Usage:
grasshopper [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
start Start a listener for UDP packet forwarding
Flags:
--ci string Cryptography method for incoming data. Available options: aes, aes-128, aes-192, qpp, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, sm4, none (default "qpp")
--co string Cryptography method for outgoing data. Available options: aes, aes-128, aes-192, qpp, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, sm4, none (default "qpp")
-c, --config string config file name
-h, --help help for grasshopper
--ki string Secret key to encrypt and decrypt for the last hop(client-side) (default "it's a secret")
--ko string Secret key to encrypt and decrypt for the next hops (default "it's a secret")
-l, --listen string Listener address, eg: "IP:1234" (default ":1234")
-n, --nexthops strings Servers to randomly forward to (default [127.0.0.1:3000])
--sockbuf int Socket buffer size for the listener (default 1048576)
--timeout duration Idle timeout duration for a UDP connection (default 1m0s)
-t, --toggle Help message for toggle
-v, --version version for grasshopper
Use "grasshopper [command] --help" for more information about a command.
- SM4 (国密)
- AES (Advanced Encryption Standard), 128, 192, 256-bit
- QPP (Quantum Permutation Pad)
- Salsa20 (https://en.wikipedia.org/wiki/Salsa20)
- Blowfish (https://en.wikipedia.org/wiki/Blowfish_(cipher))
- Twofish (https://en.wikipedia.org/wiki/Twofish)
- Cast5 (https://en.wikipedia.org/wiki/CAST-128)
- 3DES (https://en.wikipedia.org/wiki/Triple_DES)
- Tea (Tiny Encryption Algorithm)
- XTea (https://en.wikipedia.org/wiki/XTEA)
Flow at a glance:
Client (ncat @127.0.0.1:4000)
│ plaintext
▼
Level-1 relay (ci=none, co=aes) ── AES cipher ──► Level-2 relay (ci=aes, co=none) ──► UDP echo @127.0.0.1:5000
What this means: your terminal only talks to 127.0.0.1:4000; everything beyond that hop is encrypted on the way out and decrypted before it hits the echo server.
Use ncat to start a UDP echo server on port 5000:
ncat -e /bin/cat -k -u -l 5000Run the following command to start a relay:
./grasshopper start --ci aes --co none -l "127.0.0.1:4001" -n "127.0.0.1:5000"--ci aes: Applies encryption to incoming packets.--co none: Forwards plaintext to thencatecho server.
Run the following command to start another relay:
./grasshopper start --ci none --co aes -l "127.0.0.1:4000" -n "127.0.0.1:4001"--ci none: No encryption is applied to incoming packets.--co aes: Encrypts packets and forwards them to the next hop.
Use ncat to send UDP packets and interact with the relay chain:
ncat -u 127.0.0.1 4000Flow at a glance (two relays, random upstream resolver):
Laptop dig ──► Level-1 (ci=none, co=aes) ── AES cipher over WAN ──► Level-2 (ci=aes, co=none) ──► DNS pool {8.8.8.8, 1.1.1.1}
The laptop only sees 127.0.0.1:4000; the WAN hop stays encrypted, and Level-2 randomly picks a resolver from the pool for each request.
┌──────────── YOUR─LAPTOP ──────────────┐ ┌────────── CLOUD─SERVER ───────────┐
│ │ │ │
│ │ │ │
│ ┌───────────────────┐ ┌──────────┐ │ │ ┌──────────┐ ┌───────────────┐ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ dig google.com ├───► Level-1 │ │ │ │ Level-2 ├───► Google DNS:53 │ │
│ │ @127.0.0.1 -p 4000│ │ Relayer ┼──┼ ENCRYPTED ┼─► Relayer │ │ CloudFlare:53 │ │
│ │ │ │ │ │ UDP │ │ │ │ │ │
│ └───────────────────┘ └──────────┘ │ │ └──────────┘ └───────────────┘ │
│ │ │ │
│ │ │ │
└───────────────────────────────────────┘ └───────────────────────────────────┘
./grasshopper start --ci aes --co none -l "CLOUD_PUBLIC_IP:4000" -n "8.8.8.8:53,1.1.1.1:53"--ci aes: Decrypts incoming packets from the Level-1 relay. (cistands for cipher-in)--co none: Forwards decrypted plaintext DNS query packets to the DNS server. (costands for cipher-out)
./grasshopper start --ci none --co aes -l "127.0.0.1:4000" -n "CLOUD_PUBLIC_IP:4000"--ci none: Since thedigcommand sends queries in plaintext, no decryption is needed for incoming packets.--co aes: Encrypts and forwards packets to the Level-2 relay.
dig google.com @127.0.0.1 -p 4000