傻瓜式-Web面板的轻量级、高性能内网穿透工具_nps使用教程

什么是nps

我的上一篇文章是:内网穿透工具frp,然后有网友评论提到了nps,我花了一段时间研究研究了nps,nps是一款轻量级、高性能、功能强大的内网穿透代理服务器,几乎支持所有协议,支持内网http代理、内网socks5代理、p2p等,简洁但功能强大的WEB管理界面,支持服务端、客户端同时控制,扩展功能强大,全平台兼容,一键注册为服务。

官网地址:#/,可以看到GitHub关注度也挺高的,但是frp是nps的好几倍star,由此可见,各有各的好。后文我将按照我自己的学习过程比较这两款内网穿透工具的不同。

安装nps

nps也是用go语言开发的,因此也可以做到无依赖的二进制可执行程序安装。不过nps没有将web相关文件嵌入可执行程序,因此解压的时候不像frp那样是单文件。同样的类似frps、frpc这样的服务器客户端可执行程序。nps也分nps、npc这两个可执行程序。

下载地址:,下图是我在VMware的黑苹果里面安装MAC版服务端。

相比服务端携带的web文件,客户端则只有可执行程序和配置文件,我下载的是windows_amd64_client.tar.gz,在我的window宿主机上加压npc,如下图所示。

配置nps

下面配置实际就是conf/nps.conf抄下来的,加了一些注释,具体含义可以去官网查看:#/server_config。执行nps -config conf/nps.conf启动服务。

# 服务端示例: #/server_config appname = nps #Boot mode(dev|pro) runmode = dev #HTTP(S) proxy port, no startup if empty # 域名代理Ip地址 http_proxy_ip=0.0.0.0 # 域名代理http代理监听端口 http_proxy_port=80 # 域名代理https代理监听端口 https_proxy_port=443 https_just_proxy=true #default https certificate setting https_default_cert_file=conf/server.pem https_default_key_file=conf/server.key ##bridge # 客户端与服务端连接方式kcp或tcp bridge_type=tcp # 服务端客户端通信端口 bridge_port=8024 bridge_ip=0.0.0.0 # Public password, which clients can use to connect to the server # After the connection, the server will be able to open relevant ports and parse related domain names according to its own configuration file. # 客户端以配置文件模式启动时的密钥,设置为空表示关闭客户端配置文件连接模式 public_vkey=123 #Traffic data persistence interval(minute) #Ignorance means no persistence # 服务端流量数据持久化间隔,单位分钟,忽略表示不持久化 #flow_store_interval=1 # log level LevelEmergency->0LevelAlert->1 LevelCritical->2 LevelError->3 LevelWarning->4 LevelNotice->5 LevelInformational->6 LevelDebug->7 # 日志输出级别 log_level=7 #log_path=nps.log #Whether to restrict IP access, true or false or ignore # 是否限制ip访问,true或false或忽略 #ip_limit=true #p2p # 服务端Ip,使用p2p模式必填 #p2p_ip=127.0.0.1 # p2p模式开启的udp端口 #p2p_port=6000 #web # web界面域名,一般都用ip web_host=a.o.com # web界面管理账号 web_username=admin # web界面管理密码 web_password=123 # web管理端口 web_port = 8080 # web管理绑定Ip web_ip=0.0.0.0 # web管理主路径,用于将web管理置于代理子路径后面 web_base_url= web_open_ssl=false web_cert_file=conf/server.pem web_key_file=conf/server.key # if web under proxy use sub path. likeneed this. #web_base_url=/nps #Web API unauthenticated IP address(the len of auth_crypt_key must be 16) #Remove comments if needed # web api密钥 #auth_key=test # 获取服务端authKey时的aes加密密钥,16位 auth_crypt_key =45678 #allow_ports=9001-9009,10001,11000-12000 #Web management multi-user login allow_user_login=false allow_user_register=false allow_user_change_username=false #extension allow_flow_limit=false allow_rate_limit=false allow_tunnel_num_limit=false allow_local_proxy=false allow_connection_num_limit=false allow_multi_ip=false system_info_display=false #cache http_cache=false http_cache_length=100 #get origin ip http_add_origin_header=false #pprof debug options #pprof_ip=0.0.0.0 #pprof_port=9999 #client disconnect timeout # 客户端连接超时,单位 5s,默认值 60,即 300s = 5mins disconnect_timeout=60

配置npc

如下所示,对conf/nps.conf稍作修改,示例可以参考:#/use?id=%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6%e6%a8%a1%e5%bc%8f。我的客户端配置主要启用了一个web的内网穿透,以及一个tcp的内网穿透。实际frp也是支持下面这种配置的,我在写frp教程的时候没有加,大家可以去frp官网找到相应配置。执行npc -config conf/nps.conf启动服务。

# 官方示例: #/use?id=%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6%e6%a8%a1%e5%bc%8f [common] # 服务端ip/域名:port server_addr=10.252.250.237:8024 # 与服务端通信模式(tcp或kcp) conn_type=tcp # 服务端配置文件中的密钥(public_vkey) vkey=123 # 自动重连 auto_reconnection=true # 最大连接数,可忽略 max_conn=1000 # 流量限制,可忽略 flow_limit=1000 # 速度限制,可忽略 rate_limit=1000 # 是否加密传输(true或false或忽略) crypt=true # 是否压缩传输(true或false或忽略) compress=true # debug pprof ip:port,搜一下go语言的pprof用法 #pprof_addr=0.0.0.0:9999 # 断开超时时间 disconnect_timeout=60 # 名字随意,有含义就行 [web1] # 域名 host=www.janbar.com # 内网目标,负载均衡时多个目标,逗号隔开 target_addr=127.0.0.1:8083,127.0.0.1:8082 host_change=www.janbar_change.com # 请求header修改或添加,header_proxy表示添加header proxy:nps header_set_proxy=nps # 名字随意,有含义就行 [tcp] # 指定类型为tcp mode=tcp # 在服务端的代理端口 target_addr=127.0.0.1:8080 # 内网目标 server_port=10000

访问nps的web服务

访问::8080/,输入admin/123的用户名和密码登录。然后就可以看到客户端列表,注意客户端ID,在其他页面是需要用到的。

内网穿透web的界面,表示转发www.janbar.com域名到内网127.0.0.1:8083 127.0.0.1:8082这两台设备上。经过验证传说中的负载均衡就是,轮询配置里面的地址,但是nps有一个健康检查,如果配置了健康检查,估计会有更高级的负载均衡吧。

测试内网穿透http的web服务

由于配置了域名,要访问nps服务,那就得有相应的dns或者修改host文件达到目的。我这里先简单地用host文件做域名解析吧。

编写了一段内网服务器的测试代码,执行go run web.go -h 127.0.0.1:8082,go run web.go -h 127.0.0.1:8083,开启内网两个web服务。

package main import ( "flag" "fmt" "net/http" ) func main() { addr := flag.String("h", "127.0.0.1:8082", "") flag.Parse() http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "RemoteAddr:%s\n", r.RemoteAddr) fmt.Fprintf(w, "Listen:%s\n", *addr) fmt.Fprintf(w, "header:%v\n", r.Header) fmt.Fprintf(w, "data:%s\n", r.FormValue("data")) }) http.ListenAndServe(*addr, nil) }

如下图所示,当执行如下命令,时会得到当前内网访问的服务器地址,实际就是在8082和8083这两个端口轮询去请求。并且http的header也按照npc.conf里面的内容设置好了。并且npc客户端收到的host是:www.janbar_change.com,说明上述配置都按照要求实现了。

curl "?data=890" RemoteAddr:127.0.0.1:53084 Listen:127.0.0.1:8082 header:map[Accept:[*/*] Set_proxy:[nps] User-Agent:[curl/7.64.1]] data:890

测试内网穿透tcp服务

根据如下配置可知访问nps服务的10000端口就相当于访问内网127.0.0.1:8080,这一点和frp完全一样。因此我启动服务go run web.go -h 127.0.0.1:8080。

# 名字随意,有含义就行 [tcp] # 指定类型为tcp mode=tcp # 在服务端的代理端口 target_addr=127.0.0.1:8080 # 内网目标 server_port=10000

然后再通过命令:curl ":10000/test?data=890",访问nps服务,成功穿透到内网的8080端口tcp的服务。

curl ":10000/test?data=890" RemoteAddr:127.0.0.1:61586 Listen:127.0.0.1:8080 header:map[Accept:[*/*] User-Agent:[curl/7.64.1]] data:890

nps特色功能

个人感觉nps能通过服务端的web页面添加代理,这一点比frp的配置文件要方便很多,frp的web页面只能查看服务运行状态,功能相对简陋了一些。毕竟很多人对配置文件里面的参数要填什么不是很清楚,而通过web页面,也是中文的,所以理解起来很方便。

还记得上面说过的客户端ID么,在web页面新增内网穿透服务时需要指定是哪个客户端来完成内网穿透代理。通过这些web页面可以非常方便地增删内网穿透配置,以及查看这些代理的运行情况。

总结

nps和frp都是优秀的内网穿透工具,都是go语言开发,但是从GitHub的关注度来说frp要远超nps,但nps支持中文web页面,这一点比frp要更易用点。估计太多国外的人只关注到frp导致GitHub上frp比nps好吧。而且nps支持web页面配置反向代理服务,比frp单纯的改配置文件要舒服太多了。不过有一点不太好,就是nps服务端的web文件没有嵌入可执行程序,导致部署nps服务端会有一堆web文件。总体上来说nps要比frp更方便,但是我的需求很简单,有没有web配置都不影响。所以我还是喜欢更简单点的frp,毕竟GitHub的star还是有点优势的。