Help us shape the future of Go! Take the 2026 Go Developer Survey

loft

module
v1.0.20 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: Apache-2.0

README

loft

English · Русский · 中文

loft is an overlay that runs inside TLS. Streams are multiplexed over GET, WebSocket, HTTP/2, QUIC, or HTTP/3 and sealed with ChaCha20-Poly1305. On the public path the session looks like ordinary HTTPS, so it passes CDNs, reverse proxies, and TLS terminators. The session holds through short disconnects and packet loss.

Protocol loft/1.0. Share URI loft://. YAML kind: loft.

This repository is the open specification and a reference node plus clients (macOS app, Linux and macOS CLI). Software 1.0.20. A third party can implement loft from docs/protocol.md.

Operators

Typical use is operator access: a lab LAN from outside, a server fleet, site-to-site. Members present a browser-shaped ClientHello. If a middlebox rewrites the handshake, the session does not come up.

Download

Files from the latest GitHub Release. Dist uploads these names on every v* tag, so the links follow the current release.

Apple Silicon / arm64 Intel / amd64
macOS app DMG DMG
macOS CLI tar.gz tar.gz
Linux CLI tar.gz tar.gz
Node tar.gz · deb tar.gz · deb

Checksums: clients · node. macOS DMG is the menu-bar app (ad-hoc signed). CLI archives are loft, loft-front, loft-probe, loft-bench.

App

The macOS client lives in the menu bar. It opens the overlay, keeps several named connections, and imports a loft:// link or a .loft file. SOCKS5 and TUN stay local.

Status Connections
loft status window Named connections

How it works

flowchart LR
    subgraph Client["loft client"]
        App["SSH · browser · curl"] --> In["SOCKS5 / TUN"]
        In --> Mux["mux<br/>Open / Data / Close / Dgram"]
        Mux --> Seal["ChaCha20-Poly1305"]
        Seal --> Front["get · ws · h2 · quic · h3"]
    end
    Front -- "TLS 1.3 HTTPS" --> Edge["CDN / reverse proxy"] --> Node["loft-node"]
    Node --> Dest["lab · fleet · site"]
  1. Apps talk to local SOCKS5 or TUN. Holder keeps that listener while the front rotates.
  2. Streams share one mux and are sealed with ChaCha20-Poly1305.
  3. On the public path the session is ordinary HTTPS, so a CDN or reverse proxy can sit in front of the node.
  4. A short disconnect parks the mux for gap_hold_ms (default 8 s). Resume uses a fresh 0x02 and the same instance_id; inner TCP stays up.
docs/protocol.md Wire protocol. Sufficient to implement a third-party client or node.
docs/architecture.md Layout of this tree.
docs/guide.md Build, configure, run, Debian.
docs/yandex-cdn_ru.md Yandex Cloud CDN operator guide (RU).
docs/keenetic.md KeeneticOS Entware client (OpkgTun). Catalog: clients/Keenetic/.
docs/ios.md iOS Packet Tunnel client. Catalog: clients/iOS/.
docs/android.md Android VpnService client. Catalog: clients/Android/.
docs/aurora.md Aurora OS ConnMan client. Catalog: clients/Aurora/.
docs/share.md Import URI loft:// and .loft files (one or several connections).

Repository

docs/             protocol, architecture, guide
internal/         wire, mux, crypto, transport, overlay
server/           loft-node (controller or relay)
server/panel      loft-panel web admin (plan and mock)
clients/go        loft, loft-front, loft-probe
clients/macOS     menu-bar app (launches loft-front)
clients/Keenetic  Entware / OpkgTun (plan and mock)
clients/iOS       Packet Tunnel (thin host + appex)
clients/Android   VpnService (thin Java host)
clients/Aurora    ConnMan overlay (thin QML host)
clients/mobile    shared Go engine (gomobile bind)
brand/            mark and icons

Build

Go 1.24+. From the repository root:

make test
make node       # ./loft-node
make client     # dist/clients/go/loft
make macos      # dist/clients/macOS/loft.app
make macos-dmg  # dist/clients/macOS/loft-*-macos-<arch>.dmg
make macos-dmgs # both arm64 and x86_64 DMGs (CI)
make dist       # node tarballs/.deb + CLI archives

Tag vX.Y.Z (must match VERSION) runs GitHub Actions: tests, make dist, macOS DMGs arm64 and x86_64 (ad-hoc), a Release, and a pkg.go.dev ping. Manual: Actions → Dist.

export LOFT_TOKEN='change-me-long-random'
./loft-node -c server/configs/server.yaml -dir /var/lib/loft
./dist/clients/go/loft -c clients/go/configs/client.yaml
ALL_PROXY=socks5://127.0.0.1:1080 curl https://example.com

Debian package and installer: server/debian/README.md.

License

Apache License 2.0. loft/1.0 may be implemented from docs/protocol.md without a fee.

Directories

Path Synopsis
clients
go/cmd/loft command
Command loft is the CLI client: config-driven GET/WS/QUIC outbound, SOCKS5, and optional TUN with kill-switch.
Command loft is the CLI client: config-driven GET/WS/QUIC outbound, SOCKS5, and optional TUN with kill-switch.
go/cmd/loft-bench command
Command loft-bench repeats the macOS app connect path (front, SOCKS5, TCP probe) and measures mux/SOCKS throughput for GET and WS.
Command loft-bench repeats the macOS app connect path (front, SOCKS5, TCP probe) and measures mux/SOCKS throughput for GET and WS.
go/cmd/loft-front command
Command loft-front is the GUI helper: GET/WS/H2/QUIC/H3 front, SOCKS5, and in-process or loft-priv TUN.
Command loft-front is the GUI helper: GET/WS/H2/QUIC/H3 front, SOCKS5, and in-process or loft-priv TUN.
go/cmd/loft-probe command
Command loft-probe sends ICMP, TCP, UDP, DNS, HTTP, and HTTPS through loft mux or SOCKS5 without rewriting system routes or opening utun.
Command loft-probe sends ICMP, TCP, UDP, DNS, HTTP, and HTTPS through loft mux or SOCKS5 without rewriting system routes or opening utun.
go/inbound
Package inbound is the loft client listener: SOCKS5, userspace TUN (ICMP/UDP/TCP), Darwin/Linux DNS and routes, optional overlay IPv6.
Package inbound is the loft client listener: SOCKS5, userspace TUN (ICMP/UDP/TCP), Darwin/Linux DNS and routes, optional overlay IPv6.
go/tools/wsprobe command
Command wsprobe is a one-shot HTTP GET through a loft GET front.
Command wsprobe is a one-shot HTTP GET through a loft GET front.
mobile
Package mobile is the shared Go session for iOS Packet Tunnel and Android VpnService.
Package mobile is the shared Go session for iOS Packet Tunnel and Android VpnService.
internal
cdn
Package cdn holds vendor edge profiles on top of protocol fronts get/ws.
Package cdn holds vendor edge profiles on top of protocol fronts get/ws.
config
Package config loads client.yaml and node config (YAML or switch-style commands).
Package config loads client.yaml and node config (YAML or switch-style commands).
crypto
Package crypto seals mux with ChaCha20-Poly1305, proves membership with clockless HMAC (0x02) bound to a client X25519 pub, and derives the session key from the DH secret (HKDF info "loft-v1").
Package crypto seals mux with ChaCha20-Poly1305, proves membership with clockless HMAC (0x02) bound to a client X25519 pub, and derives the session key from the DH secret (HKDF info "loft-v1").
identity
Package identity is the member key: lt_ plus 48 hex characters (24 bytes).
Package identity is the member key: lt_ plus 48 hex characters (24 bytes).
mux
Package mux multiplexes streams and datagrams over AEAD-protected frames after Status.
Package mux multiplexes streams and datagrams over AEAD-protected frames after Status.
netconf
Package netconf is Loft overlay 1.0 network.conf: members, overlay IPs, leases, Cisco-style ACL, IPAM, DNS policy, session timers, managed routes and VLANs.
Package netconf is Loft overlay 1.0 network.conf: members, overlay IPs, leases, Cisco-style ACL, IPAM, DNS policy, session timers, managed routes and VLANs.
protect
Package protect marks VPN process sockets so they use the physical path (Android VpnService.protect).
Package protect marks VPN process sockets so they use the physical path (Android VpnService.protect).
startup
Package startup scans loft node and overlay config written as switch-style commands (Keenetic / D-Link / Cisco extended ACL).
Package startup scans loft node and overlay config written as switch-style commands (Keenetic / D-Link / Cisco extended ACL).
testcfg
Package testcfg loads hostnames for tests.
Package testcfg loads hostnames for tests.
transport
Package transport implements Loft 1.0 fronts, TLS camouflage, decoy splice, borrowed-cert mask, CONNECT splice, and client dialing.
Package transport implements Loft 1.0 fronts, TLS camouflage, decoy splice, borrowed-cert mask, CONNECT splice, and client dialing.
version
Package version holds the program release (injected from VERSION, currently 1.0.20 when built) distinct from protocol 1.0 (0x0100).
Package version holds the program release (injected from VERSION, currently 1.0.20 when built) distinct from protocol 1.0 (0x0100).
wire
Package wire is loft overlay protocol 1.0 (0x0100): Hello/Status handshake, mux frames, signed roster/lists, and fleet control.
Package wire is loft overlay protocol 1.0 (0x0100): Hello/Status handshake, mux frames, signed roster/lists, and fleet control.
server
cmd/loft-node command
Command loft-node is the overlay node daemon: controller or relay.
Command loft-node is the overlay node daemon: controller or relay.
cmd/loft-panel command
Command loft-panel is the web admin for one loft server.
Command loft-panel is the web admin for one loft server.
cmd/loft-panel-adm command
Command loft-panel-adm is the root helper of loft-panel.
Command loft-panel-adm is the root helper of loft-panel.
origin
Package origin serves the node's public HTTPS origin.
Package origin serves the node's public HTTPS origin.
origin/cover
Package cover serves the embedded TLS/QUIC cover site shown to ordinary browsers.
Package cover serves the embedded TLS/QUIC cover site shown to ordinary browsers.
panel/adm
Package adm is what loft-panel-adm does as root: read and replace the node's network.conf with rollback, issue member keys, restart loft-node.
Package adm is what loft-panel-adm does as root: read and replace the node's network.conf with rollback, issue member keys, restart loft-node.
panel/admproto
Package admproto is the wire between loft-panel (no privileges) and loft-panel-adm (root).
Package admproto is the wire between loft-panel (no privileges) and loft-panel-adm (root).
panel/auth
Package auth is panel sign-in: argon2id password hashes, sessions, and a per-address limit on failed logins.
Package auth is panel sign-in: argon2id password hashes, sessions, and a per-address limit on failed logins.
panel/devstand command
Command devstand runs the real panel and the real adm ops on a laptop: node files live in a temp directory and systemctl is faked (the "node" accepts any config unless it contains "# crash").
Command devstand runs the real panel and the real adm ops on a laptop: node files live in a temp directory and systemctl is faked (the "node" accepts any config unless it contains "# crash").
panel/store
Package store keeps panel users in one JSON file, written atomically.
Package store keeps panel users in one JSON file, written atomically.
panel/web
Package web is loft-panel's HTTP side: sign-in, the JSON API under /api/, and the embedded UI.
Package web is loft-panel's HTTP side: sign-in, the JSON API under /api/, and the embedded UI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL