natpass 内网穿透工具 - 基于tls链接,protobuf进行数据传输

natpass

natpass Go Report Card go-mod license platform QQ群711086098

内网穿透工具

实现原理

基于tls链接,protobuf进行数据传输,下面举例在办公网络穿透到家庭网络, 并通过rdp进行连接家庭网络下的某台windows设备

rdp

server端配置(10.0.1.1):

listen: 6154       # 监听端口号
secret: 0123456789 # 预共享密钥
log:
  dir: /opt/natpass/logs # 路径
  size: 50M   # 单个文件大小
  rotate: 7   # 保留数量
tls:
  key: /dir/to/tls/key/file # tls密钥
  crt: /dir/to/tls/crt/file # tls证书

家庭网络client配置(192.168.1.100):

id: home              # 客户端ID
server: 10.0.1.1:6154 # 服务器地址
secret: 0123456789    # 预共享密钥,必须与server端相同,否则握手失败
log:
  dir: /opt/natpass/logs # 路径
  size: 50M   # 单个文件大小
  rotate: 7   # 保留数量

办公网络client配置(172.16.1.100):

id: work              # 客户端ID
server: 10.0.1.1:6154 # 服务器地址
secret: 0123456789    # 预共享密钥,必须与server端相同,否则握手失败
log:
  dir: /opt/natpass/logs # 路径
  size: 50M   # 单个文件大小
  rotate: 7   # 保留数量
tunnel:                         # 远端tunnel列表可为空
  - name: rdp                   # 链路名称
    target: home                # 目标客户端ID
    type: tcp                   # 连接类型tcp或udp
    local_addr: 0.0.0.0         # 本地监听地址
    local_port: 3389            # 本地监听端口号
    remote_addr: 192.168.1.101  # 目标客户端连接地址
    remote_port: 3389           # 目标客户端连接端口号

工作流程如下:

  1. 办公网络与家庭网络中的np-cli创建tls连接到np-svr
  2. np-cli服务发送握手包,并将配置文件中的secret字段进行md5哈希
  3. np-svr等待握手报文,若等待超时则为非法链接,直接断开
  4. 办公网络客户机创建新连接到172.16.1.100的3389端口
  5. 172.16.1.100上的np-cli接收到新请求后创建新的link并生成链接id
  6. 172.16.1.100上的np-cli发送connect_request消息,告知连接类型和链接目标地址和端口
  7. np-svr转发connect_request消息至192.168.1.100上的np-cli
  8. 192.168.1.100上的np-cli接收到connect_request消息,根据请求信息创建链接到目标地址和端口
  9. 192.168.1.100上的np-cli根据链接创建结果返回connect_response消息
  10. np-svr转发connect_response消息至172.16.1.100上的np-cli
  11. 172.168.1.100上的np-cli接收到connect_response消息后根据是否成功来决定是否需要断开rdp客户端链接
  12. 链路打通,两端各自发送data消息到对应链路

编译

./build

linux部署

  1. 将init.d/np-cli和init.d/np-svr拷贝至/etc/init.d目录

  2. 创建/opt/natpass和对应目录

     sudo mkdir -p /opt/natpass/bin /opt/natpass/conf
    
  3. 将编译出的二进制文件拷贝至/opt/natpass/bin目录

  4. 将配置文件拷贝至/opt/natpass/conf目录,并修改对应参数

  5. 设置开机启动项

     sudo systemctl enable np-svr
     或
     sudo systemctl enable np-cli
    
  6. 启动对应服务

     sudo /etc/init.d/np-svr start
     或
     sudo /etc/init.d/np-cli start
    

iperf3压测对比

使用相同参数,iperf3压测1分钟

# natpass
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  69.6 MBytes  9.73 Mbits/sec   38             sender
[  5]   0.00-63.74  sec  62.1 MBytes  8.17 Mbits/sec                  receiver

# frp单路复用stcp,tls
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  67.5 MBytes  9.44 Mbits/sec   42             sender
[  5]   0.00-60.22  sec  58.7 MBytes  8.17 Mbits/sec                  receiver
Comments
  • 编译出错

    编译出错

    执行 build_all ,在编译 linux amd64 时出错,详细日志如下: 代码分支 v0.8.3

    `natpass git:(heads/v0.8.3) ✗ ./build_all [+] Building 3.3s (7/7) FINISHED
    => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 37B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/debian:stable-slim 3.2s => [1/3] FROM docker.io/library/debian:stable-slim@sha256:091320245c2637337fc612baf22430ec1735fd395e2c97e2c90136137d156f63 0.0s => CACHED [2/3] WORKDIR /build 0.0s => CACHED [3/3] RUN sed -i "s|deb.debian.org|mirrors.ustc.edu.cn|g" /etc/apt/sources.list && sed -i "s|security.debian.org|mirrors.ustc.edu.cn|g" /etc/apt/sources.list && 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:02faaa823400e4098f801bf50b212737f81314da3cbe5348d46615083e9cd7de 0.0s => => naming to docker.io/library/natpass 0.0s

    Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them 2022/03/07 08:44:13 [INFO]go env... GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/root/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/root/go" GOPRIVATE="" GOPROXY="https://goproxy.cn,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.17.7" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/build/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3024449258=/tmp/go-build -gno-record-gcc-switches" 2022/03/07 08:44:35 [INFO]build target linux/amd64... 2022/03/07 08:44:36 [INFO]build server... 2022/03/07 08:44:41 [INFO]build client... # github.com/lwch/rdesktop/keycode /usr/bin/ld: skipping incompatible /usr/lib/i386-linux-gnu/libX11.so when searching for -lX11 /usr/bin/ld: skipping incompatible /usr/lib/i386-linux-gnu/libX11.a when searching for -lX11 /usr/bin/ld: cannot find -lX11 /usr/bin/ld: skipping incompatible /usr/lib/i386-linux-gnu/libX11.so when searching for -lX11 collect2: error: ld returned 1 exit status panic: exit status 2

    goroutine 1 [running]: github.com/lwch/runtime.Assert(...) /root/go/pkg/mod/github.com/lwch/[email protected]/assert.go:6 main.build({{0x4f09db, 0x5}, {0x4f0972, 0x5}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, ...}) /build/contrib/build/build_all.go:207 +0x132f main.main() /build/contrib/build/build_all.go:114 +0x305 exit status 2`

  • 三端启动报错

    三端启动报错

    hi. 我在测试中遇到一些问题,所有配置文件仅修改了端口和服务器IP,local 可以跑起来看到设备列表,但是无法vnc 和shell, 有如下错误信息。 ser:

     + (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
      + (/build/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle
    2022/07/11 11:46:59 [ERROR]invalid handshake from 
      + (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
      + (/build/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle
    panic: runtime error: index out of range [0] with length 0
    
    goroutine 56 [running]:
    github.com/lwch/logging.(*rotateSizeLogger).rotate(0xc000190000)
    	/root/go/pkg/mod/github.com/lwch/[email protected]/rotate_size.go:99 +0x951
    github.com/lwch/logging.(*Logger).Error(0xb9d900, {0x88a118, 0x27}, {0xc0001010e0, 0x3, 0x3})
    	/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:90 +0x9b
    github.com/lwch/logging.Error(...)
    	/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30
    github.com/lwch/natpass/code/server/handler.(*Handler).Handle(0xc0001940c0, {0x929ec0?, 0xc00000e248?})
    	/build/code/server/handler/handler.go:67 +0xdc
    created by main.run
    	/build/code/server/main.go:141 +0x165
    

    cli local:

      + (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
      + (/build/code/client/conn/conn.go:114) github.com/lwch/natpass/code/client/conn.(*Conn).loopRead
    2022/07/11 11:46:59 [INFO]x.x.x.x:8976 connected
    2022/07/11 11:46:59 [ERROR]read message: EOF
      + (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
      + (/build/code/client/conn/conn.go:114) github.com/lwch/natpass/code/client/conn.(*Conn).loopRead
    

    cli remote(win 10)

    panic: runtime error: index out of range [0] with length 0
    
    goroutine 35 [running]:
    github.com/lwch/logging.(*rotateSizeLogger).rotate(0xc000094000)
            /root/go/pkg/mod/github.com/lwch/[email protected]/rotate_size.go:99 +0x951
    github.com/lwch/logging.(*Logger).Error(0x14268c0, {0x15169df, 0xe}, {0xc000210170, 0x1, 0x1})
            /root/go/pkg/mod/github.com/lwch/[email protected]/log.go:90 +0x9b
    github.com/lwch/logging.Error(...)
            /root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30
    github.com/lwch/natpass/code/network.(*Conn).loopWrite(0xc000222040)
            /build/code/network/network.go:127 +0x248
    created by github.com/lwch/natpass/code/network.NewConn
            /build/code/network/network.go:42 +0x137
    
  • 小建议

    小建议

    • 代码目录结构:可否参照下相关golang开源项目或者规范靠一下呢,暂可忽略
    • windows支持:既然当前只支持windows vnc,不知是否有调测,配置文件是否单独抽出windows支持的配置路径格式,或者程序处理转义路径形式。windows报错,启动panic,尴尬
    • panic: 直接使用panic处理所有错误,太硬了,出问题哪里抛出的都不一定能直接找到,估摸的一层一层去找了,生产环境定然不能直接这样,推荐log信息埋点加时间event关键词是否会更友好点
    • 直接上tls: 个人感觉有必要,也有点硬,门槛拉高了,只是想使用下,或者放置个默认试用证书? 或者配置tls开启、关闭 客服考虑下
    • 开发者文档:暂可忽略

    目前看想试用下跑起来有点费劲。测试各种panic 泪崩

  • 2022/11/27 15:53:22 [ERROR]invalid handshake from 172.16.17.136:50278   + (/github/home/go/pkg/mod/github.com/lwch/logging@v0.0.0-20221013035348-e250895ebb72/log.go:30) github.com/lwch/logging.Error   + (/github/workspace/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle

    2022/11/27 15:53:22 [ERROR]invalid handshake from 172.16.17.136:50278 + (/github/home/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error + (/github/workspace/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle

    2022/11/27 15:53:22 [ERROR]invalid handshake from 172.16.17.136:50278

    • (/github/home/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/github/workspace/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle
  • [ERROR]invalid handshake from X.X.X.X:XXXXX   + (/github/home/go/pkg/mod/github.com/lwch/logging@v0.0.0-20221013035348-e250895ebb72/log.go:30) github.com/lwch/logging.Error   + (/github/workspace/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle

    [ERROR]invalid handshake from X.X.X.X:XXXXX + (/github/home/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error + (/github/workspace/code/server/handler/handler.go:64) github.com/lwch/natpass/code/server/handler.(*Handler).Handle

    控制端出现上述的报错内容,控制端和服务端的时间一致,common.yaml配置文件的secret的值也一致 报错内容 image

    控制端的时间 image 服务端的时间 image 服务端的common.yaml image 控制端的common.yaml image

    Originally posted by @SkewwG in https://github.com/lwch/natpass/issues/59#issuecomment-1367751979

  • 按照文档运行没有任何日志,运行失败

    按照文档运行没有任何日志,运行失败

    在同一台机器上运行了服务端和控制端 [root@VM-8-5-centos natpass-server]# sudo systemctl start np-svr [root@VM-8-5-centos natpass-server]# sudo systemctl start np-cli 启动后没有任何提示,也没有日志输出,打开对应端口也是失败的

  • Got some error stright after deployment

    Got some error stright after deployment

    ~/natpass_0.9.0 
    ❯ bat server.yaml
    ────────────── 1 │ listen: 6154 # 监听端口号 2 │ #include common.yaml 3 │ #tls: 4 │ # key: /dir/to/tls/key/file # tls密钥 5 │ # crt: /dir/to/tls/crt/file # tls证书

    Below log of errors which was occurred after I tried to open -> http://vpsip:6541 if i do http://vpsip:8080 - I cant connect ether

    ubuntuvnc 19:36   ~/natpass_0.9.0 
    ❯ ./np-svr -conf server.yaml 2022/07/11 20:09:38 [ERROR]read handshake from 45.15.16.60:51496 1 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51496: i/o timeout

    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:38 [ERROR]read handshake from 45.15.16.60:51492 1 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51492: i/o timeout
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 2 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 3 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 4 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 5 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 6 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 7 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 8 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 9 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:39 [ERROR]read handshake from 45.15.16.60:51496 10 times, err=EOF
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:43 [ERROR]read handshake from 45.15.16.60:51492 2 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51492: i/o timeout
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:48 [ERROR]read handshake from 45.15.16.60:51492 3 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51492: i/o timeout
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:53 [ERROR]read handshake from 45.15.16.60:51492 4 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51492: i/o timeout
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:09:58 [ERROR]read handshake from 45.15.16.60:51492 5 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51492: i/o timeout
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle 2022/07/11 20:10:03 [ERROR]read handshake from 45.15.16.60:51492 6 times, err=read tcp 185.102.170.197:6154->45.15.16.60:51492: i/o timeout
    • (/root/go/pkg/mod/github.com/lwch/[email protected]/log.go:30) github.com/lwch/logging.Error
    • (/build/code/server/handler/handler.go:67) github.com/lwch/natpass/code/server/handler.(*Handler).Handle

    Server environments : Linux version 5.4.0-29-generic (buildd@lgw01-amd64-035) (gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #33-Ubuntu SMP Wed Apr 29 14:32:27 UTC 2020

  • 编译报错

    编译报错

    编译报错如下,应该是缺少了assets.go文件

    # github.com/lwch/natpass/code/client/rule/shell
    rule\shell\h_render.go:16:15: undefined: Asset
    rule\shell\h_render.go:26:12: undefined: Asset
    # github.com/lwch/natpass/code/client/rule/code
    rule\code\h_render.go:18:15: undefined: Asset
    rule\code\h_render.go:28:12: undefined: Asset
    # github.com/lwch/natpass/code/client/dashboard
    dashboard\h_render.go:21:15: undefined: Asset
    dashboard\h_render.go:35:15: undefined: Asset
    dashboard\h_render.go:45:15: undefined: Asset
    dashboard\h_render.go:46:14: undefined: Asset
    dashboard\h_render.go:47:15: undefined: Asset
    # github.com/lwch/natpass/code/client/rule/vnc
    rule\vnc\h_render.go:16:15: undefined: Asset
    rule\vnc\h_render.go:26:12: undefined: Asset
    
Related tags