nps 是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持 tcp、udp 流量转发,可支持任何 tcp、udp 上层协议(访问内网网站、本地支付接口调试、ssh 访问、远程桌面,内网 dns 解析等等……),此外还支持内网 http 代理、内网 socks5 代理、p2p 等,并带有功能强大的 web 管理端。

实现结构图

  +---------------+  +---------------------------------------+     +--------------------------------------------+
  |               |  |                                       |     |                                            |
  |    traffic    |  |   Server  x.x.x.x                     |     |                                            |
  |               |  |                                       |     |                                            |
  |               |  |                          nps web      |     |                                            |
  |               |  |  +---------+        +--------------+  |     |                intranet                    |
  | nps.test.com -----> | Traefik |  +-->  |127.0.0.1:8081|  |     |                                            |
  |               |  |  +---------+        +--------------+  |     |                                            |
  |               |  |                                       |     |                                            |
  |               |  |                                       |     |     nps Client                             |
  |               |  |  +---------+                  x.x.x.x:8024  |   +-------------+  :5900  +-------------+  |
  | x.x.x.x:8001 -----> |   nps   |  <------------------------------>  | 10.1.50.100 | +-----> | 10.1.50.101 |  |
  |               |  |  +---------+                          |     |   +-------------+         +-------------+  |
  |               |  |                                       |     |                                            |
  +---------------+  +---------------------------------------+     +--------------------------------------------+

服务端:CentOS 7.9 客户端:MacOS 10.15

traefik

traefik 之前有过介绍,不再多说。仅作为 nps web 管理的前置路由,解包 https 转发给本地的 nps http 服务。虽然 nps 也是支持 https 的,但是我使用 traefik 作为统一流量入口管理更方便。

首先解析域名举例 nps.test.com 至服务端主机。 修改 file provider 配置新增 nps 服务和路由。转发 https://nps.test.com/ 请求至 http://127.0.0.1:8081/

[http.routers.my-nps]
  rule = "Host(`nps.test.com`)"
  service = "nps-server"
  [http.routers.my-nps.tls]
    certResolver = "sample"
    [[http.routers.my-nps.tls.domains]]
      main = "nps.test.com"

[http.services.nps-server]
  [http.services.nps-server.loadBalancer]
    [[http.services.nps-server.loadBalancer.servers]]
      url = "http://127.0.0.1:8081/"

如果你 traefik 配置和我之前的一样修改完成就已经生效了不用重启。

服务端 nps

这里下载 nps 服务端,客户端也是从这下。

修改 conf/nps.conf 配置文件。

appname = nps
runmode = dev
# 服务端客户端通信的 协议、端口、ip
bridge_type=tcp
bridge_port=8024
bridge_ip=0.0.0.0
public_vkey=
# log level LevelEmergency->0  LevelAlert->1 LevelCritical->2 LevelError->3 LevelWarning->4 LevelNotice->5 LevelInformational->6 LevelDebug->7
log_level=7
log_path=/var/log/nps.log
# web 管理的 用户名、密码、监听端口、ip
web_username=admin
web_password=ow@ner
web_port=8081
web_ip=127.0.0.1
disconnect_timeout=60

执行安装命令,启动服务端。

$ sudo ./nps install
$ sudo nps start

install 之后,可执行文件和配置文件会复制到 /etc/nps/ 下,同时会安装为系统服务。 启动之后 tail 日志看有无报错,netstat 看端口监听是否正常。 打开 nps.test.com 进入 web 管理后台,新增一个客户端,唯一密钥建议留空自动生成即可。

客户端(内网) nps

同样下载 nps 客户端,修改客户端配置 conf/npc.conf

[common]
# 服务端ip 自行修改
server_addr=0.0.0.0:8024
# 唯一密钥
vkey=0000000
# 是否自动重连
auto_reconnection=true
conn_type=tcp
# 是否加密
crypt=false
# 是否压缩
compress=false
disconnect_timeout=60

手动执行测试看配置链接是否正常

$ ./npc -config=/path/conf/npc.conf

链接正常同样安装为服务

$ sudo ./npc install

install 之后可执行文件会复制到 /usr/local/bin/ 下。同时会创建一个 launchctl 配置文件 /Library/LaunchDaemons/Npc.plist 这是 mac 下的定时任务、守护进程管理利器。

修改下 Npc.plist 加个配置文件参数。

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version='1.0'>
<dict>
<key>Label</key><string>Npc</string>
<key>ProgramArguments</key>
<array>
        <string>/path/npc</string>
        <string>-config=/path/conf/npc.conf</string>
        <string>-debug=false</string>
</array>
<key>SessionCreate</key><false/>
<key>KeepAlive</key><true/>
<key>RunAtLoad</key><false/>
<key>Disabled</key><false/>
</dict>
</plist>

启动客户端

$ sudo npc start

创建 tcp 隧道

tcp 隧道可以实现 ssh、远程桌面等 tcp 连接

举例实现 mac vnc 远程桌面,在刚才创建的客户端隧道管理中添加一条 tcp 隧道,填写监听的端口8001、内网目标ip和目标端口10.1.50.101:5900 保存(vnc 默认端口5900)。 vnc 客户端链接服务端 1.1.1.1:8001 即可,相当于访问内网ip10.1.50.101:5900

更多隧道代理模式自行摸索吧!