NPS Enhanced: a fork of ehang-io/nps that keeps the Web UI and adds a node control plane
NPS Enhanced — Lightweight intranet tunneling and reverse proxy with Web UI | NPS 内网穿透 反向代理 增强版 全修 新版 二开
At a glance
- What is it?
- NPS Enhanced is a GPL-3.0 Go reverse proxy and NAT traversal system with a Web UI, forked from the original nps and maintained by djylb. It is aimed at operators who want a self-hosted tunnel server with a browser panel, but the v0.35.0 management API and the fork's divergence from upstream are the parts worth checking before adoption.
- Who is it for?
- Adopt NPS Enhanced if you need a self-hosted tunnel server with a browser panel and you are comfortable running a GPL-3.0 fork whose release cadence is set by one maintainer. Do not adopt it if you need a formal support contract, if you cannot accept the GPL-3.0 obligations on redistribution, or if your threat model requires an audited codebase; this is a community fork, not a vendor product.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 97 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap NPS Enhanced fills: reaching services that sit behind NAT, without hand-writing proxy config
The problem is mundane and persistent. A service runs on a machine with no public address, behind a firewall or a carrier NAT, and you want it reachable from outside. You can forward a port on the router, which fails when you do not control the router, or you can run a tunnel. NPS Enhanced is the server side plus a client, npc, that dials out from the private network to a machine you do control. The server then exposes the tunnelled service on a public port or hostname.
The README frames the project as a fork: it is based on the original ehang-io/nps and describes itself as an actively maintained and extensively improved edition with continuous refactoring. That lineage matters for who this is for. The audience is the operator who wants a single binary on a small VPS, a browser panel to add tunnels, and a client that installs as a system service on Linux or Windows. It is not aimed at teams that need a managed control plane with an SLA. The README links an Android client (djylb/npsclient) and an OpenWrt package (djylb/nps-openwrt), which tells you the maintainer expects edge devices as clients, not just servers.
The protocol list is broad: TCP and UDP forwarding, HTTP and HTTPS reverse proxy, HTTP and SOCKS5 proxy, P2P mode, Proxy Protocol, and HTTP/3. Breadth here is a menu, not a promise. The README does not state which of these are exercised in CI, so treat the list as the surface you must test yourself for whichever mode you pick.
How the pieces fit: a server, an npc client, and a Web UI that owns the configuration
The architecture visible in the material is a two-part system. The server (nps) listens for client connections and for inbound traffic on the public side. The client (npc) runs inside the private network and opens a connection outward. The README states the client can connect using TCP, KCP, TLS, QUIC, WS, or WSS, so the transport between npc and the server is selectable rather than fixed.
Configuration is split in two places. The server keeps a file, nps.conf, which the Docker instructions tell you to edit before starting the service, citing listening ports and Web admin credentials as the examples. Everything else lives in the Web UI: the README says the client page in the UI is where you read the -server, -vkey, and -type values that npc needs, and it explicitly recommends taking them from there to avoid manual input mistakes. That is the data flow to keep in mind. The UI is not a read-only dashboard; it is the source of truth for tunnel definitions, and the client's command line is derived from it.
The v0.35.0 release notes describe a third surface: a public /api/* management interface for external platforms, with snapshots, batch requests, config export and import, and scoped actor access. The same notes mention reverse WebSocket channels, callback delivery, retry queues, replay, signing, and change-window based resynchronization. In other words, the project is growing a node control plane on top of the tunnel server. If you only want tunnels, this is weight you carry without using.
Getting it running: the exact commands the README gives
Docker is the shortest path. The README pulls duan2001/nps and runs it with host networking and a mounted conf directory:
docker pull duan2001/nps docker run -d --restart=always --name nps --net=host -v $(pwd)/conf:/conf -v /etc/localtime:/etc/localtime:ro duan2001/nps
The accompanying tip is to edit nps.conf (listening ports and Web admin credentials) before starting the service. Note --net=host: the container shares the host network namespace, so the ports in nps.conf are the host's ports. There is no port mapping to fall back on.
The client container is similarly direct:
docker pull duan2001/npc docker run -d --restart=always --name npc --net=host duan2001/npc -server=xxx:123,yyy:456 -vkey=key1,key2 -type=tls,tcp -log=off
The README notes that -server, -vkey, and -type should be copied from the client page in the Web UI. The example itself shows comma-separated lists for -server, -vkey, and -type, which implies one npc process can point at multiple servers or use multiple transports.
On a Linux host the README uses install.sh with an argument that selects which component to install:
wget -qO- https://raw.githubusercontent.com/djylb/nps/refs/heads/master/install.sh | sudo sh -s nps nps install nps start|stop|restart|uninstall
Updating is nps update && nps restart. The default configuration path is /etc/nps/ and the binary path is /usr/bin/. The README advises editing /etc/nps/nps.conf and verifying it before the first nps start. Windows has a parallel path through install.ps1 and nps.exe, with a separate nps-update.exe for updates, and the README points Windows 7, 8, and 8.1 users at release assets whose names end in old.
Where it stops being the right tool
The README does not describe a formal security audit, a threat model, or a hardening guide, and the project carries a GPL-3.0 licence with a single-maintainer release history. That combination is fine for a homelab or an internal tool. It is not fine if you need to hand an auditor a vendor's security whitepaper.
The Web UI is the second constraint. Because the UI is where tunnels and client credentials are defined, it is also the highest-value target in the deployment. The README lists encrypted transmission, traffic limiting, access expiration controls, and certificate management as built-in features, but it does not state where admin credentials are stored or how sessions are protected. If you expose the panel, that is the surface you must reason about yourself.
The third constraint is scope creep. v0.35.0's headline item is a public /api/* management surface for external platforms, with batch requests and config import and export. If all you want is a TCP forward, this is extra code, extra endpoints, and extra configuration you now have to keep disabled or scoped. The README describes scoped actor access, which suggests permissions exist, but does not document the default posture. Check it rather than assume it.
Finally, the Docker path uses --net=host on both server and client. That is simple, and it means container isolation is not buying you network separation. If your environment requires per-container network namespaces, the documented command is not the one you want.
What to compare it against, and what actually differs
frp is the obvious alternative, and it appears in this repository's own topic list. The difference is not protocol support, since both do TCP, UDP, HTTP, and HTTPS tunnelling. The difference is where configuration lives. frp is configured through TOML files on both ends, with frps.ini or frps.toml on the server and frpc.toml on the client, and there is a dashboard but the files remain the primary interface. NPS Enhanced inverts that: the Web UI is where tunnels are defined, and the client invocation is derived from what the UI shows you. If you want tunnels defined in version-controlled files that a config management system can render, frp's model fits better. If you want a person to click through a panel and copy a client command, NPS Enhanced's model fits better.
The second comparison is against the original ehang-io/nps. NPS Enhanced is a fork of it, and the README positions the fork as the actively maintained line. Anyone already running upstream nps should treat a migration as a fork migration, not a version bump: the v0.35.0 notes describe a management workflow refactor around users, clients, tunnels, hosts, and node-facing operations, which implies the UI and API shape have moved. The README does not provide an upgrade path from upstream, so plan on exporting configuration and re-creating it.
For pure HTTP reverse proxying without a client agent, a conventional reverse proxy such as nginx or Caddy is a different category entirely: it terminates traffic on a host that already has a public address and does not solve the NAT problem. NPS Enhanced exists precisely because the service is not reachable in the first place.
Maintenance, release cadence, and what the GPL-3.0 licence implies for you
The release history shows v0.34.5, v0.34.6, and v0.34.7 within a week of each other in March 2026, and the last push to master is dated 2026-06-10. Frequent patch releases plus recent commits are the observable signals here; the README also points to a CHANGELOG for the detail. The practical cost is that you should expect to run the update path, which the README gives as nps update && nps restart on Linux and a stop, nps-update.exe update, start sequence on Windows. There is no documented long-term support branch, so pinning to a release and skipping updates is a decision you make deliberately.
On licensing: the repository is GPL-3.0. That is a copyleft licence, and it applies to the whole work. If you deploy NPS Enhanced internally as a service, the usual reading is that you are using it, not distributing it. If you redistribute it, or ship a product that incorporates it, the GPL-3.0 obligations attach to the combined work. This is not legal advice, and the fork's own README does not add any licensing clarification beyond the repository licence. If redistribution is part of your plan, get that reviewed rather than inferred from an article.
One more cost is documentation surface. The README links a documentation site, a Node Management Guide, a Management API Reference, and a Server Configuration Reference. Those are the places where nps.conf keys and the /api/* endpoints are actually specified. The README itself gives you the install commands and the client flags, and stops there.
The judgement: when the Web UI is worth the extra surface
NPS Enhanced is a reasonable choice when the person operating the tunnels is also the person who wants to see them, and when the private side is a mix of Linux boxes, Windows machines, and edge devices. The npc client flag set is small enough to embed in a provisioning script, and the README's instruction to copy -server, -vkey, and -type from the UI is a workflow that survives handover to a colleague who has never read the docs.
It is a worse choice when configuration must be declarative and reviewed in a pull request. The UI-first model means tunnel definitions live in the server's state, not in a file you can diff. Config export exists in the v0.35.0 API, per the release notes, but export is not the same as a file that is the source of truth.
And it is the wrong choice when you need someone to be accountable for a CVE. There is no vendor, no support contract, and no stated security response process in the material. That is not a criticism of the fork; it is a statement about what a single-maintainer GPL project is. If your requirement is a signed security advisory within a defined window, this project does not offer one, and no amount of protocol coverage changes that.
Editorial conclusion
Adopt NPS Enhanced if you need a self-hosted tunnel server with a browser panel and you are comfortable running a GPL-3.0 fork whose release cadence is set by one maintainer. Do not adopt it if you need a formal support contract, if you cannot accept the GPL-3.0 obligations on redistribution, or if your threat model requires an audited codebase; this is a community fork, not a vendor product. Before rolling it out, verify three things against your own deployment: that nps.conf parses under your edited ports and admin credentials, that the npc client connects with the -type you intend to use, and that the v0.35.0 /api/* surface is either needed by you or disabled, since the README describes it as a public management interface for external platforms.
Community notes