# Backpack: a Go reverse tunnel engine for Iran to kharej server pairs

> Backpack is a single Go binary that carries forwarded ports between an Iran entry server and a kharej origin server, with thirteen transports and a full IP tunnel mode. The install path is one script, and the role split between the two machines is the part that trips people up.

**AminMGMT/BackPack** — High Performance reverse tunnel engine in Go, built for edge ⇄ origin server setups

- Repository: https://github.com/AminMGMT/BackPack
- Website: https://t.me/BlackProtocols/10
- Stars: 435 · Forks: 100
- Language: Go
- License: AGPL-3.0
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/aminmgmt-backpack

## The problem Backpack solves, and who it is actually for

Backpack targets a specific topology: a server inside Iran that end users can reach, and a second server abroad (the README calls it kharej) that holds the real service. The Iran machine exposes forwarded ports; the kharej machine holds the service and dials out. Because the client initiates the connection, the kharej side needs no open inbound port, which is the whole reason the reverse shape exists.

The README is explicit that the project is "purpose-built for Iran ⇄ abroad (kharej) server setups." That is narrower than a general purpose tunnel tool. If your two machines are both reachable and you just want to join two networks, the framing here is more specific than you need. If you are running a service that users inside Iran must reach, and the origin sits outside, the role split and the transport menu map directly onto your problem.

The audience is an operator with root on two VPS instances, comfortable in a terminal but not necessarily a Go developer. The README offers both an interactive CLI and a secured web dashboard, and it states you can run and manage everything "with or without a terminal." That dual path is a deliberate choice: the wizard writes the config, so you are not expected to hand-author it.

## Reverse, direct, and the full IP tunnel: what changes between the three shapes

The README describes three ways to carry a tunnel. In the reverse shape, kharej dials Iran and the tunnel carries forwarded ports. In the direct shape, Iran dials out to kharej, and the tunnel carries a private network plus forwarded ports over it. The third is a full IP tunnel that puts both servers on one private network.

The README's own diagram is the clearest statement of the data flow: end users reach a forwarded port on the Iran server, the engine carries it through one transport to the kharej client, and the client forwards it to the real service. The ports never move. Iran exposes them; kharej holds the service. What varies is who reaches out first and what the tunnel carries.

The direct tunnel is the more interesting design. According to the README, it is an interface on each host carrying whole IP packets, wrapped in Backpack's own GRE inside a Noise session, then handed to one of three carriers. It measures its own MTU once it is up. The README calls MTU "the setting that fails worst when it is wrong," which is a fair warning: an MTU mismatch on a full IP tunnel produces symptoms that look like application bugs rather than a configuration error.

IP spoofing is documented as a carrier of the direct tunnel, not one of the thirteen transports. The README raises it for the case where the path "blocks or counts by source address." That distinction matters when you are reading the transport table and wondering where spoofing fits.

## Installing Backpack on a VPS and running the first tunnel

The README gives one install command, run as root on the VPS. It downloads the prebuilt release for your architecture, verifies it against the published checksum, installs it, and opens the menu.

```bash
bash <(curl -fsSL https://raw.githubusercontent.com/AminMGMT/BackPack/main/install.sh)
```

After that, the menu is reachable at any time with `sudo backpack`. The README also notes an offline path for servers with no internet: copy one archive over and go. Building from source is listed as a fallback. The Makefile confirms the source route, with a `build` target that runs `go mod tidy` and then compiles with `CGO_ENABLED=0`, and a `release-linux` target that cross-compiles static Linux binaries.

The role assignment is the step the README warns about most directly. Set up the Iran server first, because the client needs the Iran address and the token the server generates.

```bash
# on the IRAN server
sudo backpack   →  1. Setup Iran
#   transport → tunnel port → name → COPY THE TOKEN → exposed ports
#   → UDP? → preset (Turbo) → done

# on the KHAREJ server
sudo backpack   →  2. Setup Kharej
#   same transport → Iran IP + same tunnel port → name → SAME TOKEN
#   → same preset → done
```

The wizard asks for the transport, the tunnel port, a name, and then the token. On the kharej side you supply the Iran IP, the same tunnel port, the same token and the same preset. The README's own warning is that the token must match. If you are unsure which transport to pick, the README points at Manage, then Link Test, which measures your route and recommends one. TCP is described as the starting point when you are not sure.

Once both ends are configured, Manage, then Status shows both ends. If something is wrong, Manage, then Health Check prints a fix under each problem rather than just a failure flag.

## Thirteen transports, and the honesty problem in choosing one

The transport list is long: TCP, TCP Mux, TCP with Stealth, TCP with PCK, UDP with KCP and FEC, UDP with QUIC, WS, WS Mux, WSS, WSS Mux, and xDi over ICMP. The README frames the count as a feature: match the route instead of fighting it. That is reasonable, but it also means the choice is yours to get wrong, and the failure modes differ by transport.

A few of the entries are clearly aimed at specific symptoms rather than general preference. TCP with Stealth is described as Noise-encrypted with "no fingerprint at all," for heavy filtering. TCP with PCK is for the case where TCP connects and then stalls, resets or is throttled. UDP with KCP and FEC is aimed at gaming or a lossy route, with error correction always on. xDi over ICMP is for when TCP and UDP are filtered but ping works.

That last one is worth pausing on. An ICMP tunnel is a narrow tool. If the path blocks ICMP as well, the option is gone, and the README does not offer a fallback for that case. The README also separates transport problems from network-layer problems: an IP blocked at the network layer, or a dirty exit, is described as a clean-IP or CDN-edge matter rather than something a transport change fixes. That is a useful boundary, and it is stated plainly rather than used to sell the transport list.

## Where Backpack is the wrong tool, and what to use instead

The clearest wrong-tool case is a pair of hosts that can already reach each other directly. Backpack's value comes from the asymmetric setup: one side reachable, one side not. If both are reachable, WireGuard is the more conventional choice, and it is already in Backpack's dependency list (`golang.zx2c4.com/wireguard`), which tells you the project is not trying to replace it so much as wrap a similar idea in transport selection and a wizard.

The difference in approach is real. WireGuard gives you one encrypted UDP transport and expects you to handle the routing, the key exchange and the firewall yourself. Backpack gives you a menu of transports, a token-based pairing step, and a health check that prints fixes. The trade is control for convenience, and the convenience is concentrated in the setup flow. If you already have a working WireGuard mesh and a reason to keep it, Backpack adds a second layer rather than simplifying the first.

A second wrong-tool case is anyone who needs a published configuration schema. The README describes the wizard writing the config, and the repository has a `config/` directory and a TOML dependency (`github.com/BurntSushi/toml`), but the README does not document the config file format, the key names, or how to edit a config by hand. If your workflow depends on generating configs from a template or a configuration management system, that is a gap you would have to close by reading the source. The same applies to rollback: the README does not document how to revert an upgrade, and the in-app updater is described only in terms of what it downloads.

## Maintenance, upgrade cost, and what AGPL-3.0 means here

The repository is not archived, and the last push was on 2026-09-16. The release cadence is visible in the release list: v1.7.7.5 on 2026-09-07, v1.8.0 on 2026-09-09, and v1.8.1 on 2026-09-15. That is a fast cadence, and it cuts both ways. You get fixes quickly. You also get a moving target, and the README does not describe an upgrade path beyond the in-app updater.

The Makefile reveals one upgrade detail worth knowing before you adopt. The 32-bit ARM variants are built separately, and the comment explains why: a v7 binary on a v5 board is an illegal instruction, not a slow one. The build stamps the variant into the binary via `-X github.com/backpack/backpack/internal/app.GOARM`, because every ARM build reports `GOARCH=arm` at runtime regardless of what it was compiled for. The comment states this is what lets a running binary ask for its own successor rather than a sibling that will not execute. If you run Backpack on an ARM board, that stamping is the mechanism that keeps the updater from bricking the install. It is also a sign that the update path has been thought about, though the README itself does not document rollback if an update goes wrong.

The licence is AGPL-3.0, and the repository carries a NOTICE file alongside LICENSE. AGPL-3.0 is a strong copyleft licence with a network clause. If you run a modified Backpack as a network service, the licence's terms on offering source to users of that service are likely to apply to you. This is not legal advice, and the specific obligations depend on what you modify and how you deploy it. If you plan to redistribute Backpack or build a hosted product on it, read the LICENSE and NOTICE files and get your own advice before shipping.

## Conclusion

Backpack fits operators running an Iran entry server in front of a kharej origin who want the tunnel, the port forwarding and the transport choice in one binary rather than a stack of separate tools. It does not fit anyone who needs a documented, stable configuration schema, because the README does not publish one, or anyone unwilling to run the installer as root. Before committing, verify three things on your own hosts: that the installer's checksum verification succeeds for your architecture, that the transport you intend to use survives your actual route (Manage, then Link Test, then Health Check), and that the AGPL-3.0 obligations are acceptable for how you plan to redistribute or host the software. The repository was last pushed on 2026-09-16, so the code is moving quickly and you should read the CHANGELOG between the release you install and the next one before upgrading in place.

## FAQ

### Is it bagpack or backpack?

The project spells it "Backpack" throughout its README, repository name and release titles. The "bagpack" spelling does not appear in the repository.

### What is the best backpack for everything?

The README does not rank its transports for general use, but it names TCP as the starting point when you are not sure, and it points at Manage, then Link Test, which measures your route and recommends one.

### How do you install Backpack on a server?

The README gives one command to run as root on the VPS, which downloads the prebuilt release for your architecture, verifies it against the published checksum, installs it and opens the menu. The menu is reachable afterwards with sudo backpack.

### Which server should be set up first in Backpack, Iran or kharej?

The README says to set up the Iran server first, because the kharej client needs the Iran address and the token that the Iran server generates. The token must match on both ends.

### Does Backpack document how to roll back an upgrade?

The README does not document rollback. It describes the installer and the in-app updater in terms of what they download, and the Makefile shows ARM variants are stamped so a running binary requests the correct successor, but no revert procedure is given.

## Sources

- [AminMGMT/BackPack on GitHub](https://github.com/AminMGMT/BackPack)
- [License: AGPL-3.0](https://github.com/AminMGMT/BackPack/blob/main/LICENSE)
- [Project website](https://t.me/BlackProtocols/10)
- [README](https://github.com/AminMGMT/BackPack/blob/main/README.md)
- [Releases](https://github.com/AminMGMT/BackPack/releases)

---

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