# Pingtunnel: sending TCP and UDP traffic over ICMP

> Pingtunnel wraps TCP and UDP streams inside ICMP echo packets, so a client can reach a server through networks that only allow ping. This review covers how the tunnel is built, how to install it, and where it stops being the right tool.

**esrrhs/pingtunnel** — Pingtunnel is a tool that send TCP/UDP traffic over ICMP

- Repository: https://github.com/esrrhs/pingtunnel
- Stars: 3,721 · Forks: 602
- Language: Go
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/esrrhs-pingtunnel

## What problem Pingtunnel solves, and for whom

Some networks block everything except ICMP echo. Captive portals, hotel and campus Wi-Fi, and locked-down corporate segments often let ping through while dropping outbound TCP and UDP. Pingtunnel exists for that gap. It carries a TCP or UDP stream inside ICMP echo packets, so from the network's point of view the connection looks like ordinary ping traffic between a client and a server you control.

The intended users are engineers who own both ends of the link. You need a server with a public IP and root access, and a client machine where you can run a binary with administrator privileges. The README's note is explicit: the tool is only to be used for study and research, and not for illegal purposes. That framing matters. Pingtunnel is not marketed as a censorship-circumvention product or a commercial VPN, and the project does not ship a hosted service. You supply the server, the key, and the judgement about whether the network you are crossing permits this.

## How the ICMP tunnel is built

The repository layout shows the split clearly. There is a server.go and a client.go at the top level, an icmp_listen_other.go and an icmp_listen_android.go for the platform-specific ICMP listener, and a socks5.go for the proxy mode. Messages between the two sides are defined in msg.proto and generated into msg.pb.go, so the wire format is protobuf rather than a hand-rolled header. crypto.go handles the optional AES and ChaCha20 end-to-end encryption that USAGE.md describes.

The data flow is a standard tunnel arrangement. The client listens locally, either as a SOCKS5 proxy or as a fixed port forward, and accepts ordinary TCP or UDP connections from local applications. It then encapsulates that payload into ICMP echo request packets and sends them to the server's public IP. The server receives them through its own ICMP listener, unwraps the payload, and forwards it to the real destination, which can be an address on the server's network or a public host such as 8.8.8.8:53. Replies travel back the same way. A key value, passed as -key on both sides, identifies the session so the server knows which client a packet belongs to. The loop_adaptive.go file suggests the client adjusts its polling loop, which is the kind of tuning an ICMP tunnel needs because each packet is a full IP packet with an echo header rather than a stream segment.

## Installing Pingtunnel and running a first tunnel

The project ships prebuilt archives on its releases page, named by platform, for example pingtunnel_linux64.zip. Download, unzip, and run the server binary with root privileges. The README's quick start uses a key of 123456; pick your own and use the same value on both sides.

```bash
sudo ./pingtunnel -type server -key 123456
```

The server binds to the host's ICMP socket and waits. Optionally, the README suggests disabling the operating system's own ICMP echo reply so the kernel does not answer pings that are meant for the tunnel:

```bash
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
```

On the client, run the binary with administrator privileges. The SOCKS5 mode is the most general starting point: it opens a local SOCKS5 listener on port 4455 and routes whatever you point at it through the server.

```bash
pingtunnel -type client -l :4455 -s www.yourserver.com -sock5 1 -key 123456
```

If you only need one destination, forward a single TCP port instead, for example SSH on 192.168.1.100:22:

```bash
pingtunnel -type client -l :4455 -s www.yourserver.com -t 192.168.1.100:22 -tcp 1 -key 123456
```

UDP works the same way, with the target address replacing -tcp 1. The README gives DNS as the example: -t 8.8.8.8:53. Both client and server also accept a JSON config file via -c, for example sudo ./pingtunnel -c server.json, with templates in USAGE.md. Docker is supported as well; the server image needs --privileged and --network host because it opens a raw ICMP socket, while the client example publishes port 1080 for SOCKS5.

## Where Pingtunnel is the wrong tool

The first limitation is privilege. The server must run as root to open the ICMP socket, and the client needs administrator rights. On shared or managed hosts, that alone can rule it out. The Docker server command in the README carries --privileged and --network host, which grants the container far more than a normal application needs.

The second is that ICMP is not a reliable transport. Many networks rate-limit or deprioritise echo traffic, and some drop it entirely, in which case the tunnel simply does not connect. ICMP also gives you no port to target; the tunnel depends on the server answering echo requests, which is why the README suggests silencing the kernel's own reply. If the path between client and server filters ICMP in either direction, there is no fallback in the documentation.

The third is throughput and latency. Every byte you send is wrapped in an ICMP packet with its own IP and echo headers, so the overhead per payload byte is higher than a TCP or UDP tunnel, and the adaptive loop suggests the client is polling rather than streaming. For interactive SSH or DNS queries this is workable. For bulk transfer or anything latency-sensitive, a WireGuard or QUIC-based tunnel that is allowed by the network will be faster and simpler. Pingtunnel is a tool for the case where nothing else gets through, not a default choice.

## Alternatives and the difference in approach

Ptunnel is the obvious comparison, and it appears in what people search for alongside this project. Both carry TCP over ICMP echo, and both require a server on a public IP. The difference is in scope and packaging. Ptunnel is a long-standing C implementation with a narrower feature set; Pingtunnel is written in Go, ships prebuilt release archives for several platforms, publishes a Docker image, and adds SOCKS5 proxy mode, UDP forwarding, JSON config files, and optional AES or ChaCha20 encryption. If you want a small C daemon you can read end to end, Ptunnel is the smaller surface. If you want a single binary with a SOCKS5 front end and per-platform releases, Pingtunnel is the more packaged option.

For most readers the more relevant alternative is not another ICMP tunnel but a different transport entirely. WireGuard over UDP, or a QUIC-based tunnel, is the right answer whenever the network permits UDP or a non-standard TCP port. The trade-off is explicit: those tools are faster and better maintained for general use, but they fail on networks that allow only ICMP. Pingtunnel's whole reason to exist is that specific constraint.

## Maintenance, licence, and upgrade cost

The repository is not archived, and its last push was on 2026-09-19, four days before this review. Releases 2.10 and 2.9 were both published in September 2026, after a gap that goes back to 2.8 in November 2023, so the project has seen a recent burst of activity following a long quiet period. That pattern is worth noting when you plan upgrades: the version you pin today may sit unchanged for a while.

The licence is MIT, which permits commercial and private use, modification, and redistribution provided the copyright notice and permission notice are included. That is a permissive licence with no copyleft obligation. It says nothing about whether using an ICMP tunnel is allowed on a given network, and the README's study-and-research note is a project statement rather than a legal position. If you deploy this inside an organisation, the policy question is separate from the licence question.

Upgrade cost is low. The tool is a single binary, configuration is a handful of flags or one JSON file, and the wire protocol is internal to the client and server pair, so both ends should be upgraded together. The go.mod requires Go 1.26.0 and pulls in golang.org/x/crypto, golang.org/x/net, and google.golang.org/protobuf, plus indirect dependencies including quic-go and kcp-go. Building from source therefore means matching that toolchain; using the release archives or the Docker image avoids it.

## Conclusion

Pingtunnel is for engineers who control both ends of a link and need to move TCP or UDP through a network that permits only ICMP, and who accept that the server must run as root and that the README labels the tool study and research only. Do not adopt it as a general VPN, as a way to hide traffic from a network you do not own, or on hosts where ICMP is filtered or rate limited. Before deploying, verify that ICMP echo passes in both directions between the two hosts, that you can set icmp_echo_ignore_all on the server, and that both sides use the same key; the README does not document rollback, so test on a disposable pair of hosts first.

## FAQ

### What is a ping tunnel and what does Pingtunnel do?

A ping tunnel carries other traffic inside ICMP echo packets so it looks like ordinary ping. Pingtunnel implements this for TCP and UDP: a client encapsulates the payload and a server with a public IP unwraps and forwards it.

### Does Pingtunnel need root or administrator privileges?

Yes. The README runs the server with sudo and the client with administrator privileges, because both open raw ICMP sockets. The Docker server example also uses --privileged and --network host.

### Can Pingtunnel forward both TCP and UDP?

Yes. The README shows TCP forwarding with -tcp 1, for example to 192.168.1.100:22, and UDP forwarding with a target such as -t 8.8.8.8:53. It also offers a SOCKS5 mode via -sock5 1.

## Sources

- [esrrhs/pingtunnel on GitHub](https://github.com/esrrhs/pingtunnel)
- [Issues](https://github.com/esrrhs/pingtunnel/issues)
- [License: MIT](https://github.com/esrrhs/pingtunnel/blob/master/LICENSE)
- [README](https://github.com/esrrhs/pingtunnel/blob/master/README.md)
- [Releases](https://github.com/esrrhs/pingtunnel/releases)

---

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