# Ligolo-ng: TUN-based pivoting without SOCKS or proxychains

> Ligolo-ng replaces the SOCKS proxy in a pivot with a userland network stack and a TUN interface, so tools like nmap run directly against the target network. Here is how it is put together, how to set it up, and where it breaks down.

**nicocha30/ligolo-ng** — An advanced, yet simple, tunneling/pivoting tool that uses a TUN interface.

- Repository: https://github.com/nicocha30/ligolo-ng
- Website: https://docs.ligolo.ng
- Stars: 5,034 · Forks: 483
- Language: Go
- License: GPL-3.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/nicocha30-ligolo-ng

## What Ligolo-ng does that a SOCKS proxy cannot

A classic pivot puts a SOCKS proxy on the compromised host and then wraps every tool in proxychains. That works, but it changes how the tool behaves: proxychains intercepts connect() calls through LD_PRELOAD, which means statically linked binaries ignore it, and raw-socket tools such as nmap's default SYN scan never reach the network layer the way they expect. Ligolo-ng takes the opposite approach. The relay side creates a TUN interface on your machine, and packets written to that interface are translated into operations on the agent's remote network. To the operating system, the target subnet looks like a directly attached network, so nmap, curl or an SMB client connect normally and never know a pivot exists.

The project is aimed at penetration testers and red team operators working through an internal network from a foothold. The README states the agent needs no privileges at all, which is the main reason to pick it over a tool that requires a service account or a root shell on the pivot host. The relay or proxy side does need the ability to create a TUN interface, so that machine is under your control. Supported protocols listed in the README are TCP, UDP and ICMP echo requests.

## The Gvisor userland stack and how packets reach the agent

The mechanism is a userland network stack built on a fork of Gvisor, which the go.mod pins as github.com/nicocha30/gvisor-ligolo. The proxy reads from the TUN interface, hands the packet to that stack, and the stack's TCP state machine drives the connection. The README spells out the translation for a TCP connection: a SYN becomes a connect() on the remote side, a SYN-ACK is returned if that connect succeeds, and an RST is returned if connect fails with ECONNRESET, ECONNABORTED or ECONNREFUSED. If the connection simply times out, nothing is sent back.

That detail matters more than it looks. Because the stack terminates TCP locally, the agent does not have to be a transparent bridge. It performs ordinary socket calls on the target network, which is exactly why it can run unprivileged. The transport between proxy and agent is a reverse TCP or TLS connection, multiplexed with hashicorp/yamux, and the repository also depends on coder/websocket, which lines up with the websocket support listed in the feature list. The agent binary is built from cmd/agent and the proxy from cmd/proxy, so the two halves are separate programs you deploy independently.

## Installing Ligolo-ng and a first tunnel

The README points to https://docs.ligolo.ng/ for setup and quickstart rather than reproducing the steps, and the repository ships a Makefile that cross-compiles both binaries. Building from source requires Go 1.25.0, which is the version declared in go.mod. The Makefile targets are per platform and per architecture, and each one writes into ./dist with a name that encodes the platform, for example ligolo-ng-proxy-linux_amd64 and ligolo-ng-agent-linux_amd64.

```bash
make linux
make linux-arm64
make windows
```

Running make linux produces the two Linux amd64 executables in dist/. The agent is the binary you move to the target host; the proxy stays on your machine. On the proxy side you start the relay, and the README's feature list includes automatic certificate configuration with Let's Encrypt for the TLS listener. The proxy presents an interactive console with agent selection and network information, built on the grumble library, and that console is where you create the interface and add routes.

The agent connects back to the proxy over TCP or TLS. Once it registers, the proxy console lists it, and you create a TUN interface and attach the target routes to it before traffic flows. Because the agent is unprivileged, the README warns that an nmap SYN scan is downgraded to a TCP connect() on the agent side, and it recommends running nmap with --unprivileged or -PE to avoid false positives.

```bash
nmap --unprivileged -PE 10.10.0.1
```

With the interface up and the route in place, that scan reaches the internal host through the tunnel with no proxychains wrapper. The same applies to any other tool that opens normal sockets.

## Version 0.8 changed the operating model

The 0.8 release is the dividing line in this project's history. According to the README, it added an API and a web interface, a configuration file for tunneling and proxy settings, a daemon mode for running Ligolo-ng as a service, auto-bind so tunneling is configured automatically when a specific agent connects, autoroute for automatic route and interface management on Windows, Linux, macOS and BSD, and an agent kill command. The web interface came from a contributor credited as L'ami du Raisin, and the README describes it as enabling multiplayer, meaning more than one operator can work through the same relay.

That is a lot of surface added at once, and it has a practical consequence: instructions written before 0.8 describe a console-driven workflow that no longer matches the full feature set. If you follow an older walkthrough and cannot find the configuration file or the daemon flags, the reason is the version boundary, not a broken install. The repository also carries a web/ directory alongside cmd/ and pkg/, which is consistent with the UI being a separate build artifact rather than something compiled into the Go binaries by default. A search phrase people actually use, "Ligolo-ng webui is not built please read the documentation", points at exactly this gap.

## Where Ligolo-ng is the wrong tool

The caveats section is short and honest. Because the agent runs without privileges, it cannot forward raw packets. Every connection is re-originated as a socket call from the agent process, so anything that depends on packet-level fidelity will not behave the way it would on a real network path. The README's own example is the SYN scan, which becomes a connect() and can produce false positives in nmap output. A tool that needs to craft packets, spoof source addresses, or see ICMP errors other than echo requests is outside what the README claims to support.

The protocol list is the second boundary: TCP, UDP and ICMP echo requests. There is no mention of IPv6, and nothing in the README suggests fragment reassembly or protocols above that set. The Todo section lists two open items, suppressing RST when an ACK arrives for an invalid TCP connection so nmap stops reporting hosts as up, and adding mTLS support. Until mTLS lands, the transport authentication story is whatever the TLS setup provides, and the README does not document the certificate model beyond the Let's Encrypt automation. If your engagement requires mutual certificate authentication between agent and proxy, that is not in the current feature list.

## Ligolo-ng against Chisel and plain proxychains

Chisel is the closest comparison and the one people search for. Chisel gives you a TCP and UDP tunnel over HTTP, typically exposing a SOCKS5 listener on the operator side, and you then point tools at that SOCKS port. The difference is where the translation happens. With Chisel the target application has to be SOCKS-aware or wrapped, and proxychains handles the wrapping on Linux. With Ligolo-ng the translation happens in a userland stack behind a TUN interface, so the application is not aware of anything. The README makes this contrast explicitly, describing Ligolo-ng as creating a userland network stack with Gvisor instead of using a SOCKS proxy or TCP/UDP forwarders.

Against proxychains alone, the trade-off is different again. Proxychains needs a proxy underneath it, and it fails on statically linked or setuid binaries. Ligolo-ng sidesteps that class of failure entirely, at the cost of needing TUN creation rights on the operator machine and a route pointing at the tunnel interface. Chisel's advantage is that it runs as a single portable binary with fewer moving parts and no kernel interface requirement on either end, which matters when you are on a host where you cannot create a TUN device at all.

## Licence and the cost of keeping up

Ligolo-ng is GPL-3.0. The README carries the licence badge and the repository includes a LICENSE file at the top level. For internal penetration testing that distinction rarely bites, but if you plan to embed the agent in a commercial product, redistribute a modified build, or ship it inside a closed appliance, GPL-3.0 obligations attach to the distributed work. That is a description of the licence, not legal advice; get counsel if the deployment is commercial.

On maintenance, the last push was on 2026-08-11, the same date as the v0.9.1 release, with v0.9 on 2026-07-13 and v0.8.3 on 2026-02-15 before that. The release cadence is steady but not fast, and the 0.8 feature burst means the documentation at docs.ligolo.ng is the thing to check against your installed version rather than assuming any tutorial you find matches. Upgrading means rebuilding both binaries from the same tag, since the agent and proxy are versioned together and the Makefile builds them as a pair. The Makefile also runs a lint step as a prerequisite of the platform targets, so a source build pulls in the project's linting toolchain as well as the Go compiler.

## Conclusion

Adopt Ligolo-ng when your pivot host cannot be given root or Administrator and you still want nmap, Impacket or a browser pointed at the internal network without proxychains in the path. Skip it if you need raw packet injection, IPv6, or a stable CLI contract across versions, because the 0.8 release added an API, a configuration file and daemon mode on top of the older command set. Before you rely on it, build the proxy and agent from a tagged release with the Makefile targets, confirm the proxy side can create a TUN interface, and check whether the web UI assets are present in the binary you downloaded, since the repository builds them separately from the Go code.

## FAQ

### What is Ligolo-ng used for?

It establishes a tunnel from a reverse TCP or TLS connection and presents the remote network through a TUN interface, so a tester can reach internal hosts without a SOCKS proxy. The README describes it as a tunneling and pivoting tool for pentesters.

### How do I install Ligolo-ng?

The README points to https://docs.ligolo.ng/ for setup steps, and the repository Makefile builds the proxy and agent for each platform with targets such as make linux, writing the binaries into dist/. Building from source needs Go 1.25.0 per go.mod.

### How do I use Ligolo-ng for pivoting?

You run the agent on the target host, start the proxy on your own machine, select the agent in the proxy console, create a TUN interface and attach the target routes to it. The README states the agent requires no privileges, while the proxy side needs to be able to create a TUN interface.

### Is Ligolo-ng allowed in OSCP?

The repository material does not discuss certification exam rules, so there is nothing here to confirm either way. Check the exam provider's current tool policy instead of relying on the project documentation.

### How does Ligolo-ng compare to Chisel?

Chisel exposes a SOCKS-style proxy that tools must be pointed at or wrapped for, while Ligolo-ng creates a userland network stack behind a TUN interface. The README states this directly: packets sent to the interface are translated and transmitted to the agent's remote network, so no proxychains is needed.

## Sources

- [License: GPL-3.0](https://github.com/nicocha30/ligolo-ng/blob/master/LICENSE)
- [nicocha30/ligolo-ng on GitHub](https://github.com/nicocha30/ligolo-ng)
- [Project website](https://docs.ligolo.ng)
- [README](https://github.com/nicocha30/ligolo-ng/blob/master/README.md)
- [Releases](https://github.com/nicocha30/ligolo-ng/releases)

---

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