https://github.com/sh0rch/nf_wgobfs
User-space WireGuard traffic obfuscator for DPI/ML evasion, using NFQUEUE + ChaCha. Fast, lightweight, and container-ready.
https://github.com/sh0rch/nf_wgobfs
iptables linux netfilter nfqueue nftables obfuscation rust udp vpn wgobfs wireguard
Last synced: 9 months ago
JSON representation
User-space WireGuard traffic obfuscator for DPI/ML evasion, using NFQUEUE + ChaCha. Fast, lightweight, and container-ready.
- Host: GitHub
- URL: https://github.com/sh0rch/nf_wgobfs
- Owner: sh0rch
- License: mit
- Created: 2025-05-20T11:25:47.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-06-20T04:54:14.000Z (9 months ago)
- Last Synced: 2025-06-20T05:29:48.497Z (9 months ago)
- Topics: iptables, linux, netfilter, nfqueue, nftables, obfuscation, rust, udp, vpn, wgobfs, wireguard
- Language: Rust
- Homepage:
- Size: 50.8 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# đĄď¸ nf-wgobfs
**nfâwgobfs** is a highâperformance userâspace filter written in Rust for *obfuscating WireGuard traffic*.
It hides WireGuardâs easily recognizable packet structure from DPIâincluding machine learning enginesâby (1) encrypting the WG header and MAC2, (2) inserting random ballast and a nonce, and (3) reshaping keep-alives.
The filter works over **NFQUEUE**, so it can be dropped into iptables or nftables without kernel modulesâperfect for containers and cloud hosts.
---
## ⨠Features
* đ **Header + MAC2 obfuscation** with ChaCha (Fastest CPU-optimied ChaCha20 if available, pure Rust fallback)
* đŚ **Random ballast + nonce** â breaks length fingerprinting
* đ **Adaptive keepâalive dropper** â hides WG heartbeat patterns while respecting NAT TTL
* ⥠**Zeroâcopy hotâpath**: minimal `copy_within`, no heap per packet â multiâGbps
* đ§ **IPv4 & IPv6** support, full UDP/IP checksum recalculation
* â **Containerâfriendly** â pure userâspace, single binary, no kernel patches
* đŚ **No `unsafe` and no dependency on libc** â memory safety and maximum portability
---
## đŹ Packet layout (after obfuscation)
```
[IP] [UDP] [CS] [WG_HEADER*] [WG_PAYLOAD] [BALLAST] [L*] [MAC2*] [NONCE]
ââââ XOR âââ ââââ XOR âââ
L â ballast length (1Â byte)
* â encrypted bytes (ChaCha)
```
---
## đ Inspiration & Differences
The project is inspired by [infinet/xt_wgobfs](https://github.com/infinet/xt_wgobfs) (kernel module).
`nf-wgobfs` takes the idea to userâspace:
| | `xt_wgobfs`Â (kernel) | **nfâwgobfs**Â (userâspace) |
|---------------------|----------------------|----------------------------|
| Layer | kernel xt target | NFQUEUE userspace binary |
| Containerâready | â | â |
| Kernel upgrade pain | yes (rebuild) | none |
| SSE2/AVX2 / NEON | limited | CPU optimized, auto-detect |
| ARM VPS | depends | CPU optimized, auto-detect |
| Debug logging | `dmesg` | CLI debug mode |
---
## đŚ Build & Install
### Dependencies
```bash
sudo apt install libnetfilter-queue-dev # header + .so for build
rustup toolchain install stable # if not installed
```
### Compile
```bash
git clone https://github.com/sh0rch/nf-wgobfs.git
cd nf-wgobfs
cargo build --release # or cargo build --debug for verbose logs
```
Resulting binary: `target/release/nf-wgobfs`
---
## đ§ Quick start
### 1. Prepare configuration file
Default path is `/etc/nf_wgobfs.conf` (override with `NF_WGOBFS_CONF=/path`):
```ini
# queue:direction:name:key[:mtu]
1:out:wg_out:0123456789abcdef0123456789abcdef:1350
2:in:wg_in:fedcba9876543210fedcba9876543210 # auto cipher, mtu 1500
```
* **queue** â NFQUEUE number (matches iptables rule).
* **direction** â `in` or `out` (caseâinsensitive).
* **name** â Freeâform tag for logs.
* **key** â 32âbyte hex ASCII (same on both ends).
* **mtu** â *(optional)* effective MTU on external interface, *not WireGuard interface!* (default 1500).
### 2. Wire Firewall
#### Âť nftables rules
```bash
sudo nft add table inet myfilter
sudo nft add chain inet myfilter in_chain {
type filter hook prerouting priority 0; policy accept;
}
sudo nft add chain inet myfilter out_chain {
type filter hook postrouting priority 0; policy accept;
}
# Example: send all UDP to NFQUEUE
sudo nft add rule inet myfilter in_chain udp dport sport queue num 0
sudo nft add rule inet myfilter out_chain udp sport dport queue num 1
```
#### Âť iptables *(if you want)*
```bash
# Inbound (deobfuscation) â before routing
sudo iptables -t mangle -A PREROUTING -p udp --dport --sport -j NFQUEUE --queue-num 0
# Outbound (obfuscation) â after routing
sudo iptables -t mangle -A POSTROUTING -p udp --sport --dport -j NFQUEUE --queue-num 1
```
*One queue can manage all your WG tunnels. But you must differentiate INBOUND and OUTBOUND traffic to different queues. For better performance, it is better to choose two queues (IN, OUT) per tunnel.*
### 3. Run filter
```bash
sudo ./nf-wgobfs
```
#### Commandâline reference
```text
nf_wgobfs [COMMAND]
start all NFQUEUEs in foreground
--queue NFQUEUE number (default 0) in foreground
--generate-units prepare systemd units to /tmp/nf_wgobfs
```
---
Environment variables:
| Variable | Meaning |
| ----------------- | ------------------------------------------------------ |
| `NF_WGOBFS_CONF` | Alternative path to config file |
| `NF_WGOBFS_QUEUE` | Override queue number passed to program (rarely needed)|
---
## đ ď¸ Service example (systemd)
Generate and install automatically:
```bash
sudo ./nf-wgobfs --generate-units
sudo cp /tmp/nf_wgobfs/nf_wgobfs@*.service /etc/systemd/system/
sudo cp /tmp/nf_wgobfs/nf_wgobfs.target /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable nf_wgobfs.target
sudo systemctl start nf_wgobfs.target
```
---
## đŚ CPU Compatibility
Tested CPUs you can find on [fast_chacha](https://github.com/sh0rch/fast_chacha) [actions page](https://github.com/sh0rch/fast_chacha/actions/runs/15289911899)
---
## đ° Contributing
See **CONTRIBUTING.md** â PRs & issues are welcome!
---
## đ License
MIT Š sh0rch