# NATBypass: a Go port forwarder that tunnels out to beat inbound firewall rules

> NATBypass is a single file Go implementation of the lcx tunnel, with three modes for pairing two listening ports, relaying to a local target, or dialling out to two hosts. It is small enough to read in one sitting, it only moves TCP, and its logging switch writes the forwarded traffic to disk in the clear.

**cw1997/NATBypass** — 一款lcx.exe在golang下的实现, 可用于内网穿透, 建立TCP反弹隧道用以绕过防火墙入站限制等, This tool is used to establish reverse tunnel in NAT network environment, it can bypass firewall inbound restriction, support all functions of lcx.exe

- Repository: https://github.com/cw1997/NATBypass
- Website: https://github.com/cw1997/NATBypass
- Stars: 1,141 · Forks: 277
- Language: Go
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/cw1997-natbypass

## Two listening ports and a client that dials out

NATBypass is a port forwarding tool, and the mechanism is the classic one for getting a service out of a NATed network. The inner host cannot be reached inbound, but it can make outbound connections, so the inner host dials out to a public host, and the public host then bridges that connection to a second listening port where external clients arrive.

The project describes itself as a Go implementation of lcx, also known as htran, and states the use case plainly: by actively connecting to a computer with a public IP, a tunnel is opened so that a service offered by an internal host becomes reachable through the external host. It also describes itself as implementing software port forwarding and transparent proxying, and as able to bypass a firewall in the specific case where inbound rules are restricted but outbound rules are not.

That last qualifier is the whole scope of the tool, and it is narrower than the phrase firewall bypass usually suggests. It works because of a rule asymmetry, not because it exploits anything. If the egress policy blocks the outbound connection too, or if the network inspects and rejects the traffic, this design does nothing.

The implementation is a single Go file, nb.go, in a repository whose top level also holds only the README, the licence and a .gitignore. There is no module definition, no dependency list and no build system. For a tool whose job is to move bytes between two sockets, that is a reasonable size, and it also means the entire security surface is small enough to audit by reading one file.

## Three modes: listen, tran and slave

The command line has three mandatory modes, and they are the pieces of a tunnel rather than separate features.

The listen mode opens two ports at once. When two clients connect to those two listening ports, the tool forwards data between them.

```bash
nb -listen 1997 2017
```

The tran mode listens on one local port and, when a client connects to it, actively connects to a target address and forwards between the two.

```bash
nb -tran 1997 192.168.1.2:338
```

The slave mode makes the tool connect outward to two hosts at once, and once both connections are up it forwards between those two hosts.

```bash
nb -slave 127.0.0.1:3389 8.8.8.8:1997
```

The worked example in the documentation puts the three modes together in the order you would actually use them. On the public host, `nb -listen 1997 2017` opens the two ports that carry the tunnel and the client connections. On the internal host, `nb -slave 127.0.0.1:3389 123.123.123.123:1997` dials out to establish the tunnel from the inside. After that, any client connecting to the public host on port 2017 is effectively connected to 192.168.1.2:3389 on the internal network, which in the example is a remote desktop session.

The three names are inherited from the lcx lineage and are terse, but the mapping is clear once you see that the public side listens and the internal side dials.

## Building it from nb.go and running it on Linux, macOS or Windows

There is no install step. The build is a single go build invocation against the one file, and the documentation notes that if no message appears the compilation succeeded.

```bash
go build nb.go
```

The result is ./nb on Linux and macOS, and nb.exe on Windows. If a welcome message appears when you run it, the binary is working. The documentation also offers prebuilt binaries, with the release page linked from the README, and a v1.0.0 release for the Windows 386 and amd64 platforms dated 2017-10-20, with v1.0.1 for Windows dated 2017-10-23.

The platform section is the part that dates the project. The build and test matrix is listed as Windows 7 build 7601 with go1.7.5 on windows/amd64, Ubuntu 16.04.1 with go1.6.2 on linux/amd64, and Windows Server 2003 SP2 build 3790 with go1.9.1 on windows/386. Those are the toolchains the author used. The Go versions are old, but the code is a plain socket program, and a modern toolchain will build a program that uses only the standard library, though the project does not say so itself.

The troubleshooting notes in the README are practical enough to repeat. If the program will not start, check the arguments and whether the port is already in use, then change ports. If the welcome message does not appear, set permissions to 777 on the executable. If it cannot write the log, check that the current user can read and write the log path. That last one is a real deployment consideration rather than a nicety, because the log path is where the forwarded traffic goes.

## The log switch writes the forwarded stream to disk in the clear

The -log switch is optional and takes a directory. Appending it to any of the three mandatory modes makes the tool record all forwarded data into a file in that directory, with a name built from the timestamp and the arguments, for example D:/nb/Y_m_d_H_i_s-agrs1-args2-args3.log, where the date and time placeholders and the argument names are replaced with the actual values. The documentation notes that consecutive runs can be merged by time order and arguments if a continuous record is needed.

This is a feature with a sharp edge. The recording is of the forwarded data itself, and the documentation is explicit that the data may not be text, recommending a binary capable editor such as UltraEdit. In practice that means a session capture of whatever the tunnel carries, in the clear, on disk.

Two warnings come with it. The path must not contain spaces or special characters, and the documentation gives the Windows system path as an example of an invalid one. And it advises storing the log on a mechanical disk partition rather than a solid state drive, USB stick or SD card, because the write pattern is a large volume of small files.

For a tool whose purpose is to expose an internal service, an option that silently persists the traffic in the clear is a design decision you should evaluate deliberately rather than enable by habit. If you enable it on a machine with a rotating disk, you have written a plaintext session record to that disk.

One small convenience is documented: the log stream is written in real time, so the Linux tail -f command shows the forwarded data as it goes.

## TCP only, with UDP forwarding still on the list of things to do

The TODO section at the end of the README contains one item: support for forwarding the UDP protocol. Everything the tool does is TCP.

That constraint is easy to underestimate when choosing a tunnel. It rules out DNS over UDP, QUIC and HTTP/3, most VPNs, WireGuard, and any protocol that requires UDP to function, including many game protocols and voice and video calls. For a protocol where a client falls back to TCP, the tunnel works. For a client that insists on UDP, it does not.

The tool also has no authentication, no encryption and no access control, and the documentation does not describe any. The listening ports are open sockets that forward whatever arrives. That is acceptable for a short lived test between two machines you control, and it is a serious problem on a public host whose listening port is reachable from the internet.

The example in the documentation assumes an external host with the ports 1997 and 2017 open, which is exactly the arrangement the tool expects and also exactly the arrangement an attacker would want. The tunnel is unauthenticated in both directions: the public host will bridge any client that connects to the second port, and the internal host will dial out to whatever the first port tells it to.

So the operational boundary is narrow and clear. Use it where both ends are yours, on a port that is not exposed to the internet, or where the exposure is deliberate and short lived. It is a diagnostic and lab tool rather than a long lived production tunnel.

## Against lcx.exe and against an SSH reverse tunnel

The project states that it is a Go implementation of lcx, also called htran, and that it supports all functions of lcx.exe. The difference in approach against the original is the implementation language and the resulting reach: a single portable Go source file that builds on Linux, macOS and Windows, against a Windows executable. The Go rewrite also means the code is readable and the tool can be built from source with one command.

The other real alternative is not a competing program but a different category. An SSH reverse tunnel forwards a port over an existing SSH connection, which means the transport is already encrypted and authenticated, and the remote side is a normal SSH server you have to log into. NATBypass moves raw TCP with no encryption and no authentication, which is faster to set up because the only requirement is that the public host can accept a TCP connection and that the inner host can make one out.

That difference is the whole trade. The SSH route costs you an SSH server and a key, and gives you encryption, a known protocol, and a service that appears in every log. The NATBypass route costs you one Go binary and two open ports, and gives you a cleartext, unauthenticated relay.

There is a middle option worth naming: build the tool from source yourself and put your own authentication or encryption in front of it, since the source is one file. The project does not document how to do that, and it is the kind of modification you would own rather than inherit.

## Conclusion

NATBypass fits an operator or developer who needs a TCP tunnel for a service behind an inbound firewall, and who prefers a single readable Go file to a larger tunnel system, or who needs it on Linux or macOS where the original lcx executable was not the obvious choice. It does not fit anything that needs UDP, TLS termination, authentication, or a tunnel that must survive a hostile network, because the tool forwards raw bytes and the project does not document any access control on the listening ports. Check three things before you rely on it. Check that the port you expose is one you intended to expose, because a listening socket with no authentication means anyone who can reach it reaches the service behind it. Check whether you need the log switch at all, since it records the forwarded stream verbatim, and forwarded traffic is frequently the traffic carrying credentials. And check the UDP requirement, because UDP forwarding is listed as a TODO rather than a feature. The repository is not archived, the last push was on 2026-07-03, the last tagged binary is v1.0.1 from 2017 for Windows, and the license is Apache-2.0.

## FAQ

### How do I build NATBypass?

Run go build nb.go in the repository. If no message appears the compilation succeeded, and the result is ./nb on Linux and macOS or nb.exe on Windows. A welcome message on startup means the binary is working.

### What is the difference between the -listen, -tran and -slave modes in NATBypass?

-listen opens two ports and forwards between two clients that connect to them, -tran listens locally and forwards to a target address once a client connects, and -slave connects outward to two hosts and forwards between them once both connections are up.

### Does NATBypass support UDP?

No. UDP protocol forwarding is listed in the project TODO list, so all forwarding in NATBypass is TCP. Protocols that require UDP will not work over the tunnel.

### What does the -log option in NATBypass do?

It records all forwarded data into a file in the given directory, named from the timestamp and the arguments. The data may not be text, and the documentation recommends a binary capable editor and storing the log on a mechanical disk rather than flash storage.

### Are there prebuilt NATBypass binaries?

Yes, the README links the releases page, and a v1.0.0 release for Windows 386 and amd64 is dated 2017-10-20 with v1.0.1 for Windows dated 2017-10-23. The repository itself was last pushed to on 2026-07-03.

### What license is NATBypass released under?

Apache-2.0, with a LICENSE file at the root of the repository.

## Sources

- [cw1997/NATBypass on GitHub](https://github.com/cw1997/NATBypass)
- [License: Apache-2.0](https://github.com/cw1997/NATBypass/blob/master/LICENSE)
- [Project website](https://github.com/cw1997/NATBypass)
- [README](https://github.com/cw1997/NATBypass/blob/master/README.md)
- [Releases](https://github.com/cw1997/NATBypass/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cw1997-natbypass
