gonc: a netcat that finds its peer through NAT
Netcat with automated NAT traversal, secure P2P, and advanced features for shell access, file transfer, and network proxying.
At a glance
- What is it?
- gonc keeps the netcat habit of typing a host and a port, then adds automatic NAT traversal, TLS 1.3, peer-to-peer file sharing and a SOCKS5 proxy over a passphrase you agree on out loud.
- Who is it for?
- gonc fits the admin who already lives in netcat and needs a shell, a file drop or a proxy out of a network it cannot easily expose, and it fits teams that treat a passphrase as a shared secret they can hand over verbally.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
gonc's problem: reaching a peer you cannot address
gonc is a Golang-based netcat tool built for peer-to-peer communication. Used the plain way it behaves like nc, which is a fine way to learn the flags but a poor way to reach someone across two home or mobile networks, since each side sits behind a NAT that hands out a fresh address and port. gonc's answer is automated NAT traversal with zero configuration: both sides agree on a passphrase, the -p2p parameter makes the peers discover each other's network addresses through public STUN and MQTT services, and the connection is established directly between the two machines. That puts gonc in front of admins, support engineers and anyone who wants a remote shell or a file transfer without standing up a VPN or a reverse tunnel. It also inherits netcat's audience, so the commands still read like something you would type into a terminal.
How the -p2p handshake finds the other side
The passphrase does two jobs at once: discovery and authentication. A public STUN service reports each peer's mapped address, and MQTT acts as the rendezvous point where the two ends exchange what they learned. gonc then attempts the hole punch so traffic flows directly rather than through a third-party relay. Roles are negotiated during the handshake: TCP is preferred, UDP is the fallback, and each side takes the TLS client or server role automatically, which is why both ends run the same command. One consequence is a timeout. If the other side is not running yet, gonc exits when it cannot find a peer within roughly half a minute. The documented fix is a waiting mechanism based on MQTT subscription, with -mqtt-wait on one side and -mqtt-hello on the other so the two parties synchronize their start instead of racing. Worth knowing before you blame the network.
TLS 1.3 for TCP, DTLS for UDP, and one shared secret
The passphrase is also the security boundary. The README points at gonc -psk . to generate a high-entropy passphrase, and states that this passphrase is used both for mutual discovery and for certificate derivation, with communication secured by TLS 1.3. Over TCP the transport is TLS, over UDP it is DTLS, and the connection is mutually authenticated, so both ends prove they hold the same secret instead of trusting whoever answers first. That is a better default than an unencrypted nc session, and it costs the user nothing beyond sharing one string. The gap is in the operational details: the README does not document how a passphrase should be distributed or rotated, and while the repository carries an acl/ directory and an acl-example.txt file, the access control mechanism is not explained there. Treat the passphrase as you would treat a private key.
Getting the binary and opening the peer-to-peer path
There is no package manager recipe here. The project points you at its own site for the latest version download and for its documentation, and the repository root carries build scripts for Windows and for local builds if you would rather compile from source. The first thing to try is the netcat behaviour, where a host and a port are all you give it.
gonc www.baidu.com 80
gonc -tls www.baidu.com 443Without the TLS flag the session is a plain connection based on IP and port, which is exactly the limitation the rest of the tool works around. The peer-to-peer mode is where gonc stops being a clone. Both ends run the same command with the same passphrase, and the tool works out which of them is the TLS client and which is the server on its own.
gonc -p2p passphraseThe program attempts TCP or UDP, preferring TCP, negotiates the roles and completes the TLS handshake by itself. A generous passphrase is the better choice, and the README suggests generating one with gonc -psk . and using it in place of the placeholder text.
One binary that serves a shell, a file list or a proxy
The -e parameter sets the application that serves each connection, so -e /bin/sh gives a remote command shell, and gonc also carries built-in virtual commands for SOCKS5 service, HTTP file service and traffic forwarding. File sharing over P2P is a two-sided handshake. The sender exposes the files or directories with gonc -p2p <passphrase> -httpserver c:/RootDir1 c:/RootDir2, where the option accepts several paths and each one can be a single file or a directory.
gonc -p2p <passphrase> -httpserver c:/RootDir1 c:/RootDir2The receiver then picks a mode. The automatic mode downloads the whole tree recursively and, if the process is interrupted, re-running it resumes where it left off.
gonc -p2p <passphrase> -download c:/SavePathThe browse mode starts no download at all: gonc -p2p <passphrase> -httplocal-port 9999 serves the peer's file list at http://127.0.0.1:9999 so you can pick what you want, and gonc -http-download c:/SavePath http://127.0.0.1:9999/subdir pulls down a single subdirectory when browsing feels clumsy.
A proxy on 3080 with the remote address hidden in a hostname
The tunnel mode turns gonc into a way to reach a network you cannot route to. gonc -p2p passphrase -linkagent waits for the tunnel to be established, and the peer side opens a local SOCKS5 or HTTP proxy with the link option, where the link option controls how the local and remote proxy endpoints are created and none means no listening port is opened on that side.
gonc -p2p passphrase -link "3080;none"The addressing trick is the clever part. To reach 10.0.0.1:3389 in the remote network, the Remote Desktop client connects to 10.0.0.1-3389.gonc.cc:3080. That domain resolves into an IP of the form 127.b.c.d, so the client lands on the local SOCKS5 proxy on port 3080, and gonc reverse-parses the 127.b.c.d address to recover 10.0.0.1-3389 and open the right connection. The trade-off is that the scheme depends on DNS for the gonc.cc domain resolving into that loopback-shaped range, and the README does not spell out the DNS arrangement the domain requires.
Check the NAT type before you blame the network
gonc ships a diagnostic for exactly this, which checks your IPv6 and IPv4 TCP and UDP NAT addresses and analyzes port changes after the NAT.
gonc -nat-checkerEach protocol address is tagged with how hard it is to punch through. (easy) marks the highest success rate for hole punching, (hard) a higher success rate than the worst case, and (symm) the most difficult. If no TCP6 or UDP6 addresses are listed, the machine has no IPv6, and the README notes that -4 is used on both ends when both sides have IPv6 but you want to force IPv4 to demonstrate traversal. The honest boundary of the tool is right there in the tagging: a symmetric peer only works when the other end is easy or hard, and the README describes no relay fallback for the case where both are symmetric.
Where gonc is the wrong tool
Three constraints deserve a decision rather than a shrug. First, the discovery step runs on public STUN and MQTT services, so the rendezvous is not under your control and the README does not name which public instances are used by default; for a routine procedure that matters. Second, the shell mode is a genuine remote command surface, and on UNIX-like systems it relies on pseudo-terminal support, with a Windows equivalent in the dependency list, but there is no documented audit trail or session recording, so if your policy requires one, gonc does not provide it here. Third, when the shell needs a real terminal, the listener does not use -keep-open, accepts only one connection and does not authenticate with -psk, and the connecting side needs the -pty flag to get TAB and Ctrl+C behaviour. A listener left open on a reachable port is an unauthenticated command surface, so bind it carefully or put a passphrase on the P2P variant instead. The licence is MIT, so you can embed the binary or the code in commercial tooling without copyleft obligations, and the module path is github.com/threatexpert/gonc/v2 targeting go 1.26.8. The dependency list reads like a map of the design: paho.mqtt.golang for the rendezvous, pion/stun for address discovery, pion/dtls for the UDP transport, yamux and smux for multiplexing, kcp-go for reliable UDP, tun2socks for the SOCKS5 side, x/crypto and blake3 for the cryptographic work, and qrterminal for rendering a QR code in a terminal, which lines up with the passphrase scanning that the companion GUI mentions. Releases v2.6.10 on 2026-09-28, v2.6.9 on 2026-07-28 and v2.6.8 on 2026-07-23 show the line moving, and the last push was on 2026-10-13.
Editorial conclusion
gonc fits the admin who already lives in netcat and needs a shell, a file drop or a proxy out of a network it cannot easily expose, and it fits teams that treat a passphrase as a shared secret they can hand over verbally. It does not fit a setup where both peers sit behind symmetric NAT, because the README states that a symmetric peer needs the other side to be easy or hard for P2P to work at all, and it does not fit anyone who needs the discovery step to stay inside infrastructure they control, since address exchange runs over public STUN and MQTT services. Before you adopt it, run gonc -nat-checker on both ends to see whether the NAT types are compatible, read the -psk . generated passphrase handling and the acl/ directory rather than assuming the shared secret is enough, and confirm that the public STUN and MQTT endpoints behave the way you need before relying on them for a routine procedure.
Frequently asked questions
How does gonc establish a peer-to-peer connection through NAT?
Both peers run gonc -p2p with the same passphrase, and the tool discovers each side's mapped address through public STUN and MQTT services before punching a hole. TCP is attempted first, UDP is the fallback, and the TLS client and server roles are negotiated automatically.
Is the traffic between two gonc peers encrypted?
Yes. The README states the connection is end-to-end encrypted with mutual authentication, using TLS for TCP and DTLS for UDP, and the passphrase serves both for mutual discovery and for certificate derivation under TLS 1.3. You can generate a high-entropy passphrase with gonc -psk .
Which NAT types can gonc punch through?
gonc -nat-checker reports the IPv6 and IPv4 TCP and UDP addresses and labels each one easy, hard or symm. The README states that a symm peer requires the other end to be either easy or hard for P2P to work.
How do I share files with a gonc peer?
The sender runs gonc -p2p <passphrase> -httpserver c:/RootDir1 c:/RootDir2 to expose files or directories, and the receiver runs gonc -p2p <passphrase> -download c:/SavePath to pull everything recursively, or gonc -p2p <passphrase> -httplocal-port 9999 to browse the peer's file list in a browser first.
How is gonc licensed and how often does it ship?
gonc is distributed under the MIT licence, so it carries no copyleft obligation. The repository publishes tagged releases, with v2.6.10 on 2026-09-28, v2.6.9 on 2026-07-28 and v2.6.8 on 2026-07-23, and the last push was on 2026-10-13.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/threatexpert-gonc)Was this useful?