Why a clipboard
The design target: a browser on one machine, redirected through a local SOCKS proxy, ultimately reaching a web server running on an isolated VM that exposes nothing except its shared clipboard.
Zero direct connection
Front and Back never open a socket to each other. Every frame travels as text through the shared clipboard.
Compressed by default
Streaming zstd on both directions, primed with an HTTP dictionary, so repeated headers shrink fast.
Authenticated encryption
XChaCha20-Poly1305 per frame with --encrypt, plus CRC32 integrity checks on every frame.
File transport too
Swap the clipboard for a shared file — handy for testing, or headless environments with no clipboard at all.
Usage
Back runs where the network access lives. Front runs on the client and exposes a local proxy. Pick a transport — clipboard or a shared file.
./cliptun back
./cliptun front --listen 127.0.0.1:1080
curl --socks5-hostname 127.0.0.1:1080 http://example.test/
No destination filter on Back means only loopback (localhost, 127.0.0.1, ::1) is reachable by default. Open it up with --allow, or pin every connection with --connect-to.
./cliptun back --backend file --file /tmp/cliptun
./cliptun front --backend file --file /tmp/cliptun
Same protocol, same framing — only the transport changes. Useful for local testing or any environment without clipboard support. Omit --file and cliptun falls back to cliptun.clip in the system temp directory.
Encryption
Off by default. Turn it on with --encrypt on both sides, backed by a shared key generated once.
./cliptun keygen --out cliptun.key
./cliptun back --encrypt --key-file cliptun.key --connect-to 127.0.0.1:8080 ./cliptun front --encrypt --key-file cliptun.key
| Aspect | Choice |
|---|---|
| Cipher | XChaCha20-Poly1305 (AEAD) |
| Key | 256-bit, shared, from the OS CSPRNG |
| Nonce | 192-bit, random per frame |
| Overhead | 40 bytes per non-empty frame |
| Downgrade | plain frames refused in encrypted mode |
No forward secrecy — the key is a static shared secret. Replay protection resets if Back restarts. See the README for the full threat model.
How a frame looks
Every exchange is a half-duplex, stop-and-wait cycle: Front writes a frame, Back answers with the same sequence number, Front dispatches the result and moves on.
plain CT3|<direction>|<gen>|<peer>|<sequence>|<base64(wire)>|<crc32> encrypted CT4|<direction>|<gen>|<peer>|<sequence>|<base64(wire)>|<crc32>
Front always initiates. While no stream is open, Front never touches the clipboard at all.
Security & usage disclaimer
- Proof of concept, not production software. cliptun has not been security-audited. Treat it as experimental and review the source before relying on it for anything sensitive.
- Front has no authentication. Keep it bound to
127.0.0.1— anything that can reach the listener can use the tunnel. - No forward secrecy. The encryption key is a static shared secret; anyone who later obtains it can decrypt traffic captured earlier.
- The clipboard is shared, not private. Any process able to read or write the clipboard on either machine can observe metadata (frame sizes, timing, direction) or disrupt the tunnel, encrypted or not.
- Use only on systems and networks you're authorized to test or operate. Tunneling traffic to or from a destination without permission may violate laws, terms of service, or organizational policy.
- No warranty. Provided as-is, with no guarantee of fitness for any particular purpose. You are responsible for how you deploy and use it.