gonc 是一个基于 Golang 的 netcat 工具,旨在更方便地建立点对点通信。其主要特点包括:
🔁 自动化内网穿透:零配置,双方仅需约定一个口令,使用参数-p2p既可自动发现彼此网络地址和穿透内网建立点对点连接,使用公共 STUN 和 MQTT 服务交换地址信息。
🔒 端到端双向认证的加密:支持 TCP 的 TLS 和 UDP 的 DTLS 加密传输,可基于口令双向身份认证。
🧩 灵活的服务配置:通过参数 -e 可灵活的设置为每个连接提供服务的应用程序,例如-e /bin/sh可提供远程cmdshell,还可以使用内置的虚拟命令便捷的使用socks5服务、http文件服务和流量转发功能。
gonc 的桌面(Windows)和 Android 应用:提供便捷的跨设备、跨网络点对点直连与安全文件传输。只需分享口令(或扫码),无需命令行。可像 nc 一样使用:
gonc www.baidu.com 80
gonc -tls www.baidu.com 443
gonc -l 4444 #监听模式
nc只能根据IP和端口建立点对点的连接
现在,还可以基于约定口令,建立点对点连接了,还能自动化内网穿透。
下图是gonc在家庭宽带(困难型NAT)环境和对端为手机移动网络(对称型NAT)之间建立P2P连接的过程。由于两边都有IPv6,因此两边都使用了-4强制使用IPv4来演示NAT打洞。

双方约定一个相同的口令,然后发送文件的一端,执行下面命令启动 HTTP 文件服务器,-httpserver参数后支持多个参数描述要发送的文件路径,可以是文件或目录:
gonc -p2p <口令> -httpserver c:/RootDir1 c:/RootDir2
要下载文件的另一端有2种方式:
1、自动下载完整目录,执行下面命令后,会递归下载所有文件到本地,中断重新执行会自动断点续传:
gonc -p2p <口令> -download c:/SavePath
2、这种不会自动开始下载,需手动打开浏览器访问 http://127.0.0.1:9999 浏览对端的文件列表和针对性下载文件
gonc -p2p <口令> -httplocal-port 9999
这时如果需要下载某个子目录,浏览器就不方便了,但可以这样再运行一个gonc命令:
gonc -http-download c:/SavePath http://127.0.0.1:9999/subdir
双方约定一个相同的口令,然后双方都执行下面命令:
gonc -p2p <口令>
双方就能基于口令发现彼此的网络地址,内网穿透 NAT ,双向认证和加密通讯。双方都用口令派生证书,基于 TLS 1.3 保证安全通信。(口令相当于证书私钥,建议使用 gonc -psk . 随机生成高强度的口令)
注意这条命令在两端的运行时差不能太久(30秒以内),否则错过NAT打洞时机会失败退出。因此还支持基于MQTT消息订阅的等待机制,使用-mqtt-wait和-mqtt-hello来同步双方开始P2P的时机。例如,下面用了-mqtt-wait可以持续等待,
gonc -p2p <口令> -mqtt-wait
另一端使用:
gonc -p2p <口令> -mqtt-hello
以上这样建立的裸连接,也只是可以互相打字发消息哦。如果你是懂nc的,现在要p2p传输数据的话,例如发送文件的命令应该类似是这样:
cat 文件路径 | gonc -p2p 口令 -mqtt-wait #linux风格
或
gonc -p2p 口令 -mqtt-wait -send 文件路径 #用-send参数,兼容linux和windows
另一端使用:
gonc -p2p 口令 -mqtt-hello > 保存文件名
检查你的NAT类型
gonc -nat-checker
这会检查你的ipv6和ipv4的tcp和udp的NAT地址,并且研判端口经过NAT后的变化,如果没有列出tcp6或udp6的地址说明你没有ipv6。每行协议地址最后如果是(easy),则表示该协议打洞成功率最高,(hard)则表示较为困难,(symm)类型是最难的,symm必须依赖对端是easy或hard才有可能P2P。
-keep-open,仅接受一次连接;未使用 -psk,无身份认证):
gonc -tls -exec ":sh /bin/bash" -l 1234
gonc -tls -pty x.x.x.x 1234
<口令> 用于身份认证,基于 TLS 1.3 实现安全通信):
gonc -exec ":sh /bin/bash" -p2p <口令>
gonc -pty -p2p <口令>
/dev/zero 和 /dev/urandom):
gonc.exe -send /dev/zero -P x.x.x.x 1234
IN: 76.8 MiB (80543744 bytes), 3.3 MiB/s | OUT: 0.0 B (0 bytes), 0.0 B/s | 00:00:23
gonc -P -l 1234 > NUL
等待建立隧道:
gonc -p2p <口令> -linkagent
另一端将在本机监听端口3080提供socks5/HTTP代理服务访问远程:
# link可开启远程代理反向访问,none则表示远程不监听端口
gonc -p2p <口令> -link "3080;none"
使用透明代理特性:接下来例如你想连接远程网络的10.0.0.1:3389,你可以直接在本地远程桌面客户端填要连接的地址为:
10.0.0.1-3389.gonc.cc:3080
该域名会被解析为类似127.b.c.d的IP,因此远程桌面客户端会连入本地的socks5代理端口3080,然后gonc根据连接一端的127.b.c.d地址去反解析出域名中的10.0.0.1-3389这个信息。
link的配置格式
# 这表示基于建立的隧道,在本地和远程都监听1080代理端口,支持HTTP或SOCKS5协议互相访问,且端口支持透明代理特性
gonc -p2p <口令> -link "1080;1080"
# 下面是URL格式的配置方式,-link的参数值要引号包起来,否则解析容易出问题
# 左边 x://0.0.0.0:1080?tproxy=1 和仅写1080等效,右边写法表示远程也要开启1080端口,但没启用透明代理特性
gonc -p2p <口令> -link "x://0.0.0.0:1080?tproxy=1;x://127.0.0.1:1080"
# 左边的 f://127.0.0.1:1080?to=1.2.3.4:80 表示本地监听1080端口,并转发到远程去访问1.2.3.4:80;右边none表示远程不开端口
gonc -p2p <口令> -link "f://127.0.0.1:1080?to=1.2.3.4:80;none"
# 右边的 f://0.0.0.0:80?to=127.0.0.1:80 的描述方式表示远程监听80端口,转发到本地去访问127.0.0.1:80
gonc -p2p <口令> -link "none;f://0.0.0.0:80?to=127.0.0.1:80"
# 左边是代理协议+tls加密,可配置证书,右边通过outbound_bind指定出口IP(适用多IP环境)
gonc -p2p <口令> -link "x+tls://user:[email protected]:1080?cert=ca.pem&key=key.pem;none?outbound_bind=10.0.0.5"
gonc -keep-open -exec "gonc -tls www.baidu.com 443" -l 8000
gonc -keep-open -exec ":nc -tls www.baidu.com 443" -l 8000
配置客户端模式:
gonc -x s.s.s.s:port x.x.x.x 1234
内置 Socks5 服务端,使用-e :s5s提供socks5标准服务,支持-auth设置一个socks5的账号密码,用-keep-open可提供持续接受客户端连入socks5服务器,受益于golang的协程,可以获得不错的多客户端并发性能:
gonc -e ":s5s -auth user:passwd" -keep-open -l 1080
使用高安全性 Socks5 over TLS,由于标准socks5是不加密的,我们可使用-e :s5s,结合-tls和-psk定制高安全性的socks5 over tls通讯,使用-P统计连接传输信息,还可以使用-acl对接入和代理目的地实现访问控制。acl.txt文件格式详见acl-example.txt。
gonc.exe -tls -psk randomString -e :s5s -keep-open -acl acl.txt -P -l 1080
另一端使用:s5c把socks5 over tls转为标准socks5,在本地127.0.0.1:3080提供本地客户端接入
gonc.exe -e ":s5c -tls -psk randomString x.x.x.x 1080" -keep-open -l -local 127.0.0.1:3080
参考SSH的22端口,既可提供shell也提供sftp和端口转发功能,gonc使用 -e ":service" 也可监听在一个服务端口,基于tls+psk安全认证提供shell、socks5(支持CONNECNT+BIND)和文件服务。(请务必使用gonc -psk .生成高熵PSK替换randomString)
gonc -k -l -local :2222 -tls -psk randomString -e ":service" -:sh "/bin/bash" -:s5s "-c -b" -:mux "httpserver /"
另一端使用获得shell
gonc -tls -psk randomString -remote <server-ip>:2222 -call :sh -pty
另一端把socks5 over tls转为本地标准socks5端口1080
gonc -e ":s5c -tls -psk randomString -call :s5s <server-ip> 2222" -k -P -l -local 127.0.0.1:1080
另一端把文件服务为本地标准HTTP端口8000
gonc -tls -psk randomString -remote <server-ip>:2222 -call :mux -httplocal-port 8000
帮WireGuard打洞组VPN
在被动等待连接的PC-S运行下面的参数(直接拿节点公钥来当口令,接口的监听端口51820):
gonc -p2p PS-S的公钥 -mqtt-wait -u -k -e ":nc -u 127.0.0.1 51820"
其他发起主动连接的PC-C,设置WireGuard节点PS-S公钥的Endpoint = 127.0.0.1:51821,接口的监听端口51820,gonc运行下面的参数,-k可以让gonc在网络异常后自动重新建立连接。
gonc -p2p PS-S的公钥 -mqtt-hello -u -k -e ":nc -u -local 127.0.0.1:51821 127.0.0.1 51820"
一个公网IP上支持UDP ASSOCIATE的Socks5服务器就可以,也可以用自己的VPS,运行gonc本身的socks5代理服务器便可让其成为中转服务器。
下面命令启动了仅支持UDP转发功能的socks5代理,-psk和-tls开启了加密和PSK口令认证。注意防火墙不能只开放1080,因为每次提供转发的UDP端口是随机。
gonc -e ":s5s -u -c=0" -psk 口令 -tls -k -l 1080
P2P遇到困难的时候,只需要有一端的gonc使用-x参数再进行P2P就可以。你也可以把-x换为-x2,这样就是先P2P,失败了再尝试用中转
gonc -p2p randomString -x "-psk 口令 -tls <socks5server-ip>:1080"
下面例子是使用标准的socks5代理服务器(需服务器支持UDP)。
gonc -p2p randomString -x "<socks5server-ip>:1080" -auth "user:password"
例如原本两端都是对称型NAT,无法P2P,现在一端使用了socks5代理(UDP模式),就相当于转为容易型的NAT了,于是就能很容易和其他建立连接,数据加密仍然是端到端的。
"tcp://turn.cloudflare.com:80",
"udp://turn.cloudflare.com:53",
"udp://stun.l.google.com:19302",
"stun.gonc.cc:3478",
"global.turn.twilio.com:3478",
"stun.nextcloud.com:443",
"tcp://broker.hivemq.com:1883",
"tcp://broker.emqx.io:1883",
"tcp://test.mosquitto.org:1883",
"tcp://mqtt.gonc.cc:1883"
gonc将NAT类型分为3种:
当固定一个内网端口去访问多个STUN服务器,根据多个STUN服务器反馈的地址研判:
针对这些类型,gonc采用了如下一些NAT穿透策略: