noisecat

module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 26, 2026 License: MIT

README ¶

noisecat 😼

The noise swiss army knife

Go Report Card CI

noisecat 😼 is a featured networking utility which reads and writes data across network connections, using the Noise Protocol Framework (and TCP/IP).

Download and build

Requires Go 1.21+. Just git clone it and make it; you'll get noisecat binaries for macOS, Linux, FreeBSD, and Windows under bin/.

Usage

This is how noisecat -h looks like:

Usage: noisecat [options] [address] [port]

Options:
  -e command
    	executes the given command
  -k	accepts multiple connections (-l && (-e || -proxy) required)
  -keygen
    	generates "-proto" appropriate keypair and prints it to stdout
  -l	listens for incoming connections
  -lstatic file
    	loads local keypair from file (use -keygen to generate)
  -negotiation data
    	NoiseSocket negotiation_data (only used with -transport noisesocket)
  -p port
    	uses source port (default "0")
  -prologue prologue
    	application prologue mixed into the handshake hash
  -proto protocol name
    	sets protocol name (default "Noise_NN_25519_AESGCM_SHA256")
  -proxy address:port
    	forwards packets to address:port (-l required)
  -psk pre-shared key
    	uses pre-shared key in handshake
  -rstatic static key
    	defines remote static key (32 bytes, base64)
  -s address
    	uses source address
  -transport transport
    	wire transport: raw (default), noisesocket, or bolt8 (auto-selected for secp256k1) (default "raw")
  -v	prints verbose output
  -validate key
    	validate that the base64 key is well-formed for -proto's DH function, then exit

Protocol name format: Noise_PT_DH_CP_HS

Where:
  PT: Handshake pattern
  DH: Diffie-Hellman handshake function
  CP: Cipher function
  HS: Hash function

  e.g. Noise_NN_25519_AESGCM_SHA256

Available handshake patterns:
  NN, NK, NX, XN, XK,
  XX, KN, KK, KX, IN,
  IK, IX (each combinable with the psk0..psk3 modifier)

Available DH functions:
  25519, secp256k1

Available Cipher functions:
  ChaChaPoly, AESGCM

Available Hash functions:
  BLAKE2s, BLAKE2b, SHA256, SHA512

Available transports:
  raw, noisesocket, bolt8

The flags are similar to the traditional netcat. In short:

  • -l -p 31337 listens on port 31337/tcp
  • -e /bin/sh executes /bin/sh (reverse shell anyone?)

The main difference is the Noise Protocol-related flags:

  • -proto sets the Noise Protocol name that you want to use
  • -psk sets a pre-shared key — base64-encoded 32 bytes (e.g. the output of head -c 32 /dev/urandom | base64). Pair it with a psk-modified protocol name, e.g. -proto Noise_NNpsk0_25519_AESGCM_SHA256 for "PSK before the first message" or -proto Noise_NKpsk2_25519_AESGCM_SHA256 for "PSK after act 2". The psk[0-3] modifier selects which message the PSK token attaches to per the Noise spec §9.2. Passing -psk without a psk modifier (or vice versa) is now rejected.
  • -rstatic specifies the remote peer static (public) key — base64-encoded 32 bytes — used in "K"-type handshakes
  • -lstatic specifies the local file where to load static keys from (recommend chmod 600 on the file)

Other features are:

  • -proxy allows to create a tunnel client -noise-> server -tcp-> final endpoint
  • -k accepts multiple connections (like ncat)
  • -keygen generates a pair of keys that, when saved to a file, can be used with the -lstatic flag
Example

To bind a shell on port 4444/tcp (default protocol) and accept multiple clients:

$ noisecat -k -e /bin/sh -l -p 4444

To connect to that shell:

$ noisecat <ip> 4444

That's it!

Transports

noisecat speaks the Noise Protocol Framework over a pluggable transport layer. The same Noise handshake patterns and DH/cipher/hash combinations work regardless of transport — only the on-the-wire framing differs.

-transport Wire format Notes
raw (default) 2-byte BE length prefix + Noise message noisecat's historical framing; interoperable with itself only.
noisesocket NoiseSocket spec: handshake messages carry negotiation_data, encrypted payloads contain an inner body_len + arbitrary padding, prologue is "NoiseSocketInit1" + neg_data_len + neg_data + app prologue Spec-compliant, interoperable with other NoiseSocket peers. Only the Accept negotiation outcome is supported (no Switch/Retry/Reject).
bolt8 Lightning Network's BOLT-8: Noise_XK_secp256k1_ChaChaPoly_SHA256, fixed-size handshake acts (50/50/66 bytes) with a 1-byte version prefix, encrypted 2-byte length headers + AEAD-tagged payloads, automatic rekey every 1000 messages, prologue defaults to "lightning". Auto-selected when the protocol name contains secp256k1. Interoperable with lnd / cln / eclair (Appendix A test vectors pass byte-for-byte).

Companion flags (work with any transport):

  • -prologue <string> mixes the given byte string into the handshake hash. Both peers must use the same value.
  • -negotiation <string> (NoiseSocket only) is the initiator's first-message negotiation_data.
  • -validate <key> checks that the given base64-encoded value is a well-formed remote static key for the chosen -proto (length + curve-point parse for secp256k1) and exits — useful for sanity-checking an -rstatic value before opening a real connection.

Example NoiseSocket round-trip on localhost:4444:

$ noisecat -transport noisesocket -negotiation 'app=demo' -l -p 4444 &
$ noisecat -transport noisesocket -negotiation 'app=demo' 127.0.0.1 4444
Lightning (BOLT-8)

Generate a secp256k1 static keypair, then connect to a node by its public key:

# 1. Generate (or reuse) a local static keypair
$ noisecat -proto Noise_XK_secp256k1_ChaChaPoly_SHA256 -keygen > node.json
$ chmod 600 node.json

# 2. Connect to a Lightning node (rstatic is the node's compressed pubkey, base64-encoded)
$ noisecat -proto Noise_XK_secp256k1_ChaChaPoly_SHA256 \
    -lstatic node.json \
    -rstatic <base64-encoded-33-byte-compressed-pubkey> \
    <host> <port>

The BOLT-8 transport is auto-selected when the protocol name contains secp256k1; the lightning prologue is supplied automatically. To talk to two noisecats over BOLT-8, both ends need their own node.json and the client needs to know the server's compressed public key (the server prints it with -v).

Proxying

-proxy turns noisecat into a TCP tunnel: the client speaks Noise to noisecat, noisecat forwards the decrypted bytes to the backend over plain TCP, and the backend's response is encrypted on the way back. The proxy uses TCP-style half-close, so a client that sends a request and closes its write side will still receive the backend's full response:

# Terminal 1 — start a plain-TCP backend
$ python3 -m http.server 8000

# Terminal 2 — noise-protected proxy on 19999
$ noisecat -v -k -l -proxy 127.0.0.1:8000 -p 19999 127.0.0.1

# Terminal 3 — client
$ printf 'GET / HTTP/1.0\r\n\r\n' | noisecat 127.0.0.1 19999

Development

make test         # go test -race with coverage
make vet          # go vet ./...
make lint         # golangci-lint (install separately)
make linux darwin windows freebsd   # cross-compile

CI runs build/vet/test on Linux, macOS, and Windows; lint via golangci-lint; and govulncheck for known CVEs on every push and PR. Tagging vX.Y.Z triggers a goreleaser build that publishes signed binaries and checksums to the corresponding GitHub Release.

Directories ¶

Path Synopsis
cmd
noisecat command
pkg
noisenet
Package noisenet is a backwards-compatibility shim that re-exports the "raw" transport (pkg/transport/raw).
Package noisenet is a backwards-compatibility shim that re-exports the "raw" transport (pkg/transport/raw).
transport
Package transport defines the pluggable transport interface noisecat uses to layer different framings on top of the Noise Protocol Framework.
Package transport defines the pluggable transport interface noisecat uses to layer different framings on top of the Noise Protocol Framework.
transport/bolt8
Package bolt8 implements Lightning Network's BOLT-8 transport (https://github.com/lightning/bolts/blob/master/08-transport.md) directly from primitives: secp256k1 ECDH, HKDF-SHA256, ChaCha20-Poly1305.
Package bolt8 implements Lightning Network's BOLT-8 transport (https://github.com/lightning/bolts/blob/master/08-transport.md) directly from primitives: secp256k1 ECDH, HKDF-SHA256, ChaCha20-Poly1305.
transport/noisesocket
Package noisesocket implements the NoiseSocket spec (https://noiseprotocol.org/noisesocket) on top of github.com/flynn/noise.
Package noisesocket implements the NoiseSocket spec (https://noiseprotocol.org/noisesocket) on top of github.com/flynn/noise.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL