# gecit

System-level transparent DPI bypass. One command (`sudo gecit run`) and every TLS connection on the box gets a fake ClientHello injected before the real one, so SNI-inspecting middleboxes log a benign hostname and let the real connection through. No tunnel, no remote server, no per-app config. It does **not** hide your IP, encrypt your traffic, or provide anonymity — it only prevents DPI middleboxes from reading the SNI in your TLS handshakes.

Built by Bora Tanrıkulu ([[bora-blog]]); the [[bypassing-dpi-with-ebpf]] post is the design write-up.

## Architecture

Same idea on every platform — fake ClientHello with `SNI = www.google.com` and TTL 8, plus MSS clamped to 88 bytes to fragment the real ClientHello so the SNI extension splits across segments. What differs is the kernel hook.

- **Linux: eBPF `sock_ops`.** Attaches a BPF program to a cgroup. `BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB` fires the moment an outgoing TCP connection finishes its three-way handshake — connection up, app hasn't sent data yet. The program clamps `TCP_MAXSEG` via `bpf_setsockopt` and forwards seq/ack to a Go goroutine via a perf event. Userspace builds the fake ClientHello and sends it through a raw socket with `IP_HDRINCL`. After the handshake, traffic stays in-kernel — zero overhead on bulk transfer. See [[ebpf-sock-ops]].
- **macOS: TUN + gVisor.** No eBPF on macOS. Network Extensions need an Apple-approved entitlement, so that path was unrealistic for an open-source tool. gecit uses [`sing-tun`](https://github.com/SagerNet/sing-tun) on top of gVisor's userspace TCP/IP stack. Connections to port 443 are routed to the TUN, gVisor terminates the handshake locally, gecit opens its own connection to the real server, fires the fake, then forwards the real ClientHello. Seq/ack scraped from SYN-ACKs via pcap. All traffic crosses the kernel-user boundary — same overhead profile as a VPN.
- **Windows: TUN + Npcap.** Same TUN+gVisor architecture as macOS. Two extra headaches: TCP raw sockets are blocked since Vista (so packet injection goes through Npcap's `pcap_sendpacket`, which means gecit builds full Ethernet frames including gateway MAC from the ARP table); and most Windows DPI tools use WinDivert, whose code-signing cert expired in 2023 and trips Defender, so gecit uses WireGuard's WinTUN instead. Npcap can't be redistributed without an OEM license, so users grab it from `npcap.com` themselves.

## DNS handling

gecit runs a local DoH server on `127.0.0.1:53` and points the system resolver at it. Queries leave the box over HTTPS to Cloudflare, Google, NextDNS, or whatever upstream you configure — no plaintext DNS for the censor to poison. There's a chicken-and-egg problem: the DoH client itself needs to resolve the upstream hostname before it can take over DNS, so gecit pins all upstream hostnames to IPs at startup.

On macOS, DNS configuration is per network service; gecit picks the active one off the default route (so it sets DNS on the USB-tethering service when you're tethered, not Wi-Fi). On Linux with Flatpak, sandboxed apps don't see `/etc/resolv.conf` changes, so DNS bypass has to be set manually inside each Flatpak — but the DPI bypass still works there because eBPF runs below every sandbox.

## Usage

```bash
sudo gecit run
```

That's the whole interface. TTL, fake SNI, MSS, target ports, and DoH upstream are all tunable; defaults are TTL=8, SNI=`www.google.com`, MSS=88, ports=443.

Tuning hints from the post: if it doesn't work, `traceroute` to figure out a TTL that lands between the middlebox and the server. If pcap can't catch the SYN-ACK on macOS/Windows, the fake ships with garbage seq/ack and the DPI rejects it.

## Where it fits in the bypass landscape

gecit defeats SNI-only DPI. It does not give you a foreign exit IP, so it does not defeat [[whitelist-internet-blocking|CIDR-whitelist]] regimes like the one [[tspu]] runs on Russian mobile carriers — for that you still need a tunnel. It's the kernel-level cousin of zapret / GoodbyeDPI / ByeDPI, listed in [[russia-vpn-bypass-state-2026-04]] as orthogonal companions to a real VPN. The implementation is a useful reference point for anyone who's wondered why eBPF is structurally different from the macOS/Windows network-extension story; see [[ebpf-sock-ops]] for the hook details.

## Related

- [[tls-desync-fake-clienthello]] — the technique
- [[ebpf-sock-ops]] — the Linux kernel hook
- [[bypassing-dpi-with-ebpf]] — the design post
- [[bora-blog]] — author
- [[little-snitch-linux]] — different eBPF networking tool, different hook category (per-app monitoring vs handshake injection)

## Repo

[github.com/boratanrikulu/gecit](https://github.com/boratanrikulu/gecit), GPL-3.0. Linux, macOS, Windows.
