
简介这是一款面向开发与运维人员的轻量级内网穿透工具 nps 的完整资源包用于解决无公网 IP 环境下远程访问、端口映射与代理服务搭建等典型问题适合需要快速部署个人穿透服务的初中级用户学习参考。压缩包共 170 个文件约 3.72MB内容涵盖 Go 语言源码、nps 服务端与 npc 客户端可执行文件、Web 管理界面所需的 HTML/CSS/JS 页面以及 conf、yml、json 等运行配置示例同时附带 md 说明文档、png/svg 图标、证书与密钥文件目录结构清晰服务端、客户端、界面资源与文档分区明确便于按模块查阅。目前已有 638 人下载学习。通过该包可以了解服务端与客户端的完整协作方式、配置项含义、内置管理面板及多账号配置的使用思路也能在本地环境直接演练部署过程对需要搭建远程办公、临时演示或测试环境穿透通道的读者是一份可直接落地参考的实用资料。1. nps 是什么为什么我放着 frp 不用选了它做内网穿透我手头有四五台没有公网 IP 的机器——家里的 NAS、临时开发机、客户的测试环境全躲在不同运营商的局域网后面。以前要远程动它们要么临时去路由器上做端口映射要么用远程软件等对方点同意麻烦还不安全。后来我把这些内网服务统一收编到一台公网服务器上用的就是 nps。nps 是一款用 Go 写成的轻量级内网穿透代理服务器服务端一个二进制自带 Web 管理面板和客户端支持 TCP、UDP、HTTP、HTTPS 隧道。对比 ngrok 内网穿透教程和 frp 内网穿透里常见的那套纯文本配置方案nps 最打动我的是管理可视化谁在连、连到哪、流量多大面板上全看得见。适合有公网服务器、想把家里或公司内网服务安全暴露出来、又不想整天改配置文件的人。2. nps 架构与服务端部署先让 Broker 在公网跑起来nps 沿用的是内网穿透代理搭建里最常见的服务端/客户端模型公网机器上跑服务端nps当 Broker内网机器上跑客户端npc当通道工兵。外部流量流向是访问者 → 公网IP:隧道端口 → nps → 已建立的加密通道 → npc → 内网服务。这四段链路里只要中间一段断了现象都是“连不上”所以先把服务端部署这段做扎实后面排查才有据可依。2.1 服务端安装与初始化二进制包与配置文件分工从 zip 包部署 nps 非常直接解压后目录里只有三样东西要关心可执行文件、conf/ 目录和 web/ 目录。web/ 是面板前端静态资源conf/nps.conf 是全部运行时配置这两样都不能删。我一般把整个目录放到 /opt/nps然后用前台模式先跑一次确认路径和配置文件能被正确读取。# 解压并进入安装目录 unzip nps_linux_amd64.zip -d /opt/nps cd /opt/nps # 先不要急着装成服务前台跑一次看有没有报错 ./nps执行后终端会打印监听端口和配置文件加载路径。如果出现 “open conf/nps.conf: no such file or directory”说明工作目录不对用绝对路径执行/opt/nps/nps或者 cd 到 /opt/nps 再跑。确认没问题后 CtrlC 停掉开始编辑核心配置。nps 启动时读取的是 conf/nps.conf不是命令行参数这点和 frp 的 frps.ini 一样改配置后必须重启进程才生效。# 我习惯精简后的 nps.conf 核心段 app_port8080 web_usernameadmin web_password替换成强密码 bridge_port8024 bridge_typetcp http_proxy_port80 https_proxy_port443 auth_crypt_key32位随机字符串 allow_ports2000-3000,8024app_port 是 Web 管理面板的端口默认 8080web_username/web_password 是面板登录凭据。bridge_port 是 nps 与 npc 之间保持长连接的通信端口相当于控制通道后面注册客户端时 -server 参数里填的就是这个端口。bridge_type 推荐 tcp除非你所在网络丢包严重才考虑 kcpkcp 虽然抗丢包但会多占用一点 CPU。http_proxy_port 和 https_proxy_port 是 HTTP/HTTPS 隧道统一入口默认 80/443。auth_crypt_key 是客户端与服务端之间通信加密的密钥长度必须 32 位建议用openssl rand -base64 32生成后手动粘贴进去。allow_ports 可以限制 Web 面板里添加隧道时允许使用的公网端口范围避免有人乱开端口。2.2 桥接端口、Web 管理端口与公网端口规划部署 nps 前先画一张端口规划表免得后面安全组、防火墙、隧道端口三者互相打架。以一台 2C4G 的 ECS 为例我常用下面这套分配方案。用途端口说明Web 管理面板8080建议只对管理员 IP 开放或干脆只走内网访问客户端桥接控制通道8024必须放行npc 靠它连接 npsHTTP 代理入口80公网访问 HTTP 隧道时使用HTTPS 代理入口443公网访问 HTTPS 隧道时使用SSH 隧道示例2222自定义的隧道端口按需放行注意 Web 管理端口和桥接端口的区别前者是给人登录用的后者是给客户端用的。很多人上来把 8080 和 8024 都暴露到公网面板被扫到就是密码爆破的开始。我一般把 app_port 改成 8088 之类的高位端口同时在云安全组里限制来源 IP。隧道端口则要看业务SSH 隧道可以只放行你自己的办公网 IPHTTP 隧道因为要服务公网用户80/443 必须全放。还要注意 allow_ports 配置与云安全组是两套独立机制nps 只控制面板上能不能填这个端口真正挡流量的是云厂商安全组和系统防火墙两者都要放行。2.3 服务端启动与日志验证你该盯哪几行配置改完用 nps 自带的启动命令装成系统服务比手动 nohup 更稳。nps 内置了服务注册能力Linux 下执行安装命令后会自动注册 systemd 单元。# 注册为系统服务并启动 cd /opt/nps ./nps install ./nps start # 查看实时日志 tail -f /opt/nps/log/nps.log初次启动日志里最有价值的三行第一行是监听端口列表确认 8024、80、443 都在第二行是 Web 管理地址形如web service listen on 0.0.0.0:8080第三行是数据库初始化完成提示nps 默认用 sqlite 把隧道和客户端配置存在 nps.db 文件里。看到这三行服务端就算活了。如果日志里出现bind: address already in use说明对应端口被占用用ss -lntp | grep 端口找到占用进程把冲突的应用挪走。服务端稳定后浏览器访问http://公网IP:8080用配置里的账号密码登录看到“客户端”和“隧道”两个空菜单说明服务端部署这一关过了。3. 注册客户端并建立第一条隧道从 web 面板到 nps 客户端服务端只是空壳真正干活的是内网机器上的 npc。这一步要做两件事在面板上注册一个客户端拿到唯一验证密钥然后让 npc 用这个密钥连上来。只要控制通道建立后面加隧道就不用再碰内网机器全部在面板上操作这是 nps 比 frp 舒服的地方。3.1 客户端注册唯一验证密钥与连接配置登录 nps Web 面板进入“客户端”菜单点“新增客户端”。这里有几个字段要说明备注写清楚是“家里NAS”还是“客户测试机”压缩和加密建议勾选尤其是跨运营商传输时加密能防止数据在公网裸奔压缩对内网大文件传输有帮助但会占用一点 CPU最后面板会生成一长串 vkey这就是该客户端唯一的连接凭证。拿到 vkey 后在内网机器上启动 npc。npc 与 nps 在同一目录的 zip 包里把 npc 传到内网机器后执行# 内网机器上建立控制通道 ./npc -server你的公网IP:8024 -vkey面板生成的vkey -typetcp-server 后面必须是公网 IP 加上配置文件里的 bridge_port不是 app_port这里填错是最常见的启动失败原因。-vkey 就是上一步生成的密钥。-typetcp 要和 nps.conf 里 bridge_type 保持一致。启动后终端会显示连接状态同时回到 Web 面板刷新“客户端”列表会看到该客户端状态变为“在线”。如果一直连不上先确认 nps 服务端的 8024 端口是否放行再看内网机器能不能 telnet 通公网IP 8024。npc 支持-loginfo参数把日志打到 stdout排错时建议加上。3.2 添加 TCP 隧道把内网 SSH 暴露到公网端口控制通道建立后隧道配置都在面板上完成。进入“隧道”菜单点“新增”选择 TCP 隧道。以暴露内网 SSH 为例服务端端口填 2222目标地址填内网机器的局域网 IP目标端口填 22。这里有个设计取舍公网端口可以任意选所以同一台内网机器想暴露多个服务时不要全挤在一个端口上而是给每个服务分配不同公网端口比如 2222 给 SSH、3308 给数据库、5900 给 VNC。保存后隧道立即生效npc 不需要重启。如果不想用面板也可以在 npc 的 conf/npc.conf 里写固定配置适合批量部署多台内网机器。[common] server_addr你的公网IP:8024 vkey面板生成的vkey conn_typetcp [ssh] modetcp target_addr192.168.1.10:22 server_port2222用配置文件方式启动时执行./npc -configconf/npc.conf。注意 [ssh] 是隧道名可以随意起server_port 对应面板里的“服务端端口”也就是公网访问入口target_addr 填内网目标 IP 和端口。这里最容易犯的错误是把 target_addr 写成 127.0.0.1这在 nps 的语义里指向的是 npc 本机如果内网服务不在 npc 同一台机器上必然连不通。3.3 验证连通性从公网 IP 到内网服务的完整链路隧道建好后从任何一台外网机器执行ssh -p 2222 user公网IP能登录就说明链路通了。但如果是通的思路要按链路顺序分段排查而不是盲目重启服务。# 第1段公网到 nps 的隧道端口 telnet 公网IP 2222 # 第2段nps 控制通道是否正常看服务端日志 tail -f /opt/nps/log/nps.log # 第3段内网机器上确认目标服务在监听 ss -lntp | grep 22第1段 telnet 不通问题在安全组或系统防火墙第2段日志里如果看到new tunnel但马上断开通常是目标端口不通或目标 IP 错误第3段是很多人的盲区——内网服务可能只监听了 127.0.0.1比如某些 MySQL 实例改成监听 0.0.0.0 或局域网 IP 后才能被 npc 访问到。另外插一句nps 的 Web 面板上每个隧道都显示流量统计如果隧道有连接但流量一直是 0基本可以判定是目标服务本身的问题。4. HTTP/HTTPS 与多域名复用像反向代理一样做内网穿透TCP 隧道是一对一映射80 端口只能给一个服务用这对 Web 业务来说太浪费。nps 真正亮眼的是 HTTP 和 HTTPS 隧道它相当于一台应用层反向代理服务器能在一个公网端口上按域名分发流量到不同的内网 Web 服务。换句话说一台乞丐版云服务器上跑一个 nps就能同时代理十几个不同域名的内网站点。4.1 HTTP 隧道与域名解析80 端口只占一个先在 DNS 服务商把demo.example.com解析到公网 IP。然后在面板“隧道”里新增 HTTP 隧道域名填demo.example.com目标地址填内网 Web 服务的 IP 和端口比如192.168.1.20:8080。保存后访问http://demo.example.com就会直接命中内网服务。原理很简单nps 在 80 端口监听所有 HTTP 请求根据请求头里的 Host 字段决定转发到哪条隧道。这意味着只要域名足够多一个 80 端口可以挂无数条 HTTP 隧道互不干扰。需要注意两点第一域名解析必须生效nps 不做 DNS 解析它只认请求里的 Host第二内网服务如果有跳转逻辑比如后端 302 跳转到http://192.168.1.20:8080/login客户端就会跳转到内网地址导致打不开这种情况要去内网服务配置里把对外域名改成demo.example.com否则只能改用 TCP 隧道。面板里还可以勾选“HTTP 强制跳转 HTTPS”如果服务本身支持 HTTPS建议打开。4.2 HTTPS 证书托管与自动续期HTTPS 隧道是 HTTP 隧道的加强版。在面板里新增或编辑一条 HTTP 隧道勾选“HTTPS”填好域名nps 会自动向 Lets Encrypt 申请证书并续期完全不需要自己在服务器上跑 certbot。这对不熟悉证书操作的人非常友好也是我向团队推荐 nps 的一个重要原因。# 服务端 conf/nps.conf 里和证书相关的默认配置 http_cachefalse https_just_proxytrue https_default_cert_fileconf/server.crt https_default_key_fileconf/server.key如果你有自己的证书可以把 https_just_proxy 设为 false并指定 cert 和 key 文件路径nps 会优先使用你提供的证书而不是自动申请。自动申请的前提是 80 端口可达因为 ACME 协议需要做 HTTP-01 验证。如果你公网入口的 80 端口已经被其他服务占用证书申请会失败这是 HTTPS 隧道最常见的坑。另一个注意点是Lets Encrypt 证书有效期只有 90 天nps 会自动续期但续期时要求隧道在有效期内所以长期不用的隧道会被跳过续期下次访问时证书过期把隧道里的 HTTPS 开关关掉再打开强制重新申请即可。4.3 多隧道复用同一个 nps 端口多域名复用是 nps 在 Web 场景下的核心价值。还是那台只开放了 80/443 的云服务器我同时挂了三条 HTTP 隧道和一个 HTTPS 隧道全部指向不同内网机器。域名目标内网服务类型blog.example.com192.168.1.10:8000HTTPdocs.example.com192.168.1.11:8080HTTPapi.example.com192.168.1.12:9000HTTPSshop.example.com192.168.1.13:8443HTTPS每条隧道独立计流量、独立开压缩互不影响。公网用户只看到 80 和 443 两个端口实际访问的是四个不同内网服务。这个模式下还要注意后端 Web 服务要能正确处理 X-Forwarded-For 头因为 nps 转发时会把真实客户端 IP 放在这个头里后端拿不到源 IP 时要么在 nps 面板打开“HTTP 代理透传真实 IP”要么让 Nginx 配置set_real_ip_from信任 nps 所在机器的 IP。如果内网服务是 Nginx我习惯在 location 里加一行proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;配合使用。5. nps 常见问题排查与避坑连接断、配置失效、端口冲突用 nps 大半年翻车最多的场景集中在四类隧道通但不稳定、端口被拦、重启失效、并发上来后性能下滑。下面每一条都按“现象 → 原因 → 解决”写都是踩过的坑。5.1 客户端在线但隧道连不通先看链路拓扑现象Web 面板里客户端状态是“在线”隧道也显示正常但从公网 telnet 隧道端口就是不通。原因客户端在线只代表控制通道活着不代表数据通道没问题。最常见的是目标地址填了 127.0.0.1而内网服务在另一台机器上其次是 nps 服务端只监听了 IPv4而客户端用 IPv6 访问公网域名解析到了 IPv6 地址还有一种情况是隧道建好后服务端端口刚好和已有端口冲突nps 面板没报错但端口实际没起来。解决先ss -lntp | grep 端口确认隧道端口在公网服务器上真的监听了再确认 target_addr 填的是内网机器能直接访问的 IP不是 127.0.0.1最后在内网机器上手动curl 目标IP:目标端口验证目标服务自身可用。这个链路四段依次打勾基本 10 分钟内定位。5.2 端口被防火墙/安全组拦截排查顺序有讲究现象本地敲 telnet 公网IP 隧道端口一直卡住但 Web 面板里一切正常客户端也在线。原因云厂商安全组、系统 firewalld/iptables 和 nps 自身的 allow_ports 是三层独立的限制漏掉任何一层都连不上。最迷惑的是客户端能在线说明 8024 被放行了但隧道端口可能只被安全组放行而系统防火墙没放行或者反过来。解决按“云安全组 → 系统防火墙 → nps 配置”这个顺序查。先在云控制台确认隧道端口在安全组入方向放行再在服务器上执行firewall-cmd --list-ports或iptables -L -n看本机是否放行最后看 nps.conf 的 allow_ports 是否包含这个端口。如果不想精细控制可以先把系统防火墙关掉排障通了再一条条加回规则别让三层问题叠在一起查。5.3 重启后配置丢失与 systemd 托管现象云服务器重启后Web 面板能打开但所有隧道和客户端都没了像被重置了一样。原因nps 的隧道和客户端配置存在服务端目录下的 nps.db 里。如果你是用./nps前台方式启动的重启后进程自然没了如果用了./nps install注册服务但安装时工作目录不对systemd 服务启动时会跑到其他目录创建一个空白的 nps.db看起来就是配置全丢。解决养成两个习惯。第一用绝对路径执行安装cd /opt/nps ./nps install确保服务的工作目录固定第二定期备份 /opt/nps 下的 nps.db我一般每天 crontab 打包一次到其他磁盘。真要出现配置丢失就用备份恢复没有备份就只能在面板里重新添加客户端和隧道客户端重新连接后隧道会自动同步回来。5.4 带宽瓶颈与并发连接轻量级不代表无上限现象机器配置不低但隧道一多传输大文件时延迟飙升甚至出现连接被重置。原因nps 是单进程处理所有隧道大量并发连接时CPU 和带宽都会成为瓶颈。尤其是开启了压缩但没限制压缩级别高带宽场景下压缩反而消耗大量 CPU。另外隧道默认不限制带宽一条跑满下行的大流量隧道能把其他小流量业务全拖死。解决在面板编辑隧道时找到“带宽限制”字段给重要业务设置合理上限比如普通 Web 服务限 10 Mbps文件同步服务限 50 Mbps。开启压缩前先确认 CPU 有富余低配机器上宁可不开压缩也不要把 CPU 打满。还可以在服务端 nps.conf 里调大connection_read_timeout和connection_write_timeout避免长连接被误杀。真遇到几十个客户端、上百条隧道的规模建议把服务端内存至少提到 4GGo 的 goroutine 虽轻但连接对象本身还是吃内存的。6. 用 systemd 开机自启把 nps 固化成一等公民最后一招把 nps 服务端和 npc 客户端都交给 systemd 管理这样不用每次重启后手动拉起进程也不用担心终端关掉进程就断。虽然 nps 自带 install 命令但它生成的 service 文件比较简陋我更喜欢自己写一个把重启策略和资源限制都控制住。[Unit] Descriptionnps inner tunnel server Afternetwork.target [Service] Typesimple WorkingDirectory/opt/nps ExecStart/opt/nps/nps Restartalways RestartSec5 LimitNOFILE65535 [Install] WantedBymulti-user.target把上面内容保存为 /etc/systemd/system/nps.service执行systemctl daemon-reload systemctl enable --now nps。关键在 Restartalways 和 RestartSec5前者保证进程被 kill 后自动拉起后者控制重启间隔避免频繁崩溃时疯狂刷日志。LimitNOFILE65535 是给高并发场景留的默认 1024 的打开文件数上限在几十条隧道后就会不够用。npc 客户端也可以如法炮制ExecStart 换成带参数的启动命令客户端断线后 systemd 会自动重连比手动 nohup 可靠得多。我自己的一个习惯是给 nps 单独建一个低权限系统用户比如useradd -r -s /sbin/nologin nps然后在 systemd 里加一行Usernps避免用 root 跑代理进程。曾经有一次我在公网服务器上开着 root 跑 nps几天后发现日志里有不认识的管理面板登录尝试从那以后所有暴露在公网的服务都强制降权。还有一个小但实用的验证技巧改完配置或者升级 nps 后不要直接看面板状态而是从公网侧真正发起一次连接测试。用curl -I http://demo.example.com看返回码或者ssh -p 2222 user公网IP走一遍真实链路。面板显示在线只说明管理通道通真正的业务通道才是用户感知的那条路。这个习惯帮我在一次机房迁移后立刻发现了安全组规则没同步的问题否则用户反馈之前我根本不知道服务已经断了。nps 这类轻量级内网穿透代理服务器的价值在于它把最容易出错的端口映射、证书管理、多客户端注册全部收到一个 Web 面板里让内网穿透代理搭建从“配置文件玄学”变成“点几下鼠标”的确定操作。希望这篇文章能帮你把第一台机器的隧道跑通少走我当年绕过的弯路。本文还有配套的精品资源点击获取