Quick Answer: paqctl is a unified tool for two censorship bypass methods. Paqet uses KCP over raw sockets with custom TCP flags. GFW-Knocker uses violated TCP packets + QUIC tunneling. Install the server:
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | sudo bash. Then set up the client on Windows/Mac/Linux and connect through a local SOCKS5 proxy.
Need a VPS? Get started with Vultr (free credit for new accounts), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals starting ~$10/year).
Note: paqctl is currently in alpha (v1.0.0-alpha). Expect breaking changes between releases.
What Is paqctl?
paqctl is a unified management tool for two different censorship bypass methods. You run the server on a VPS outside the restricted network and the client on your local machine. Both methods create a local SOCKS5 proxy that routes traffic through the tunnel.
The two methods:
| Paqet | GFW-Knocker (GFK) | |
|---|---|---|
| Difficulty | Easy | Advanced |
| Best for | Most situations | Heavy censorship (GFW, deep throttling) |
| Local proxy | 127.0.0.1:1080 |
127.0.0.1:14000 |
| Technology | KCP over raw sockets | Violated TCP + QUIC tunnel |
| Server needs | Just paqet | GFK + Xray |
| Client type | Binary (Go) | Python scripts |
How Paqet Works
Paqet sends traffic using the KCP protocol over raw TCP sockets with custom TCP flags.
Your Device Your VPS Internet
+--------------+ +--------------+ +----------+
| Browser | | Paqet | | Google |
| | | KCP over | Server | | YouTube |
| v | raw TCP | | | | etc. |
| Paqet | ---------> | v | --------> | |
| Client | (custom | SOCKS5 | | |
| 127.0.0.1 | flags) | forward | | |
| :1080 | | | | |
+--------------+ +--------------+ +----------+
Why DPI cannot detect it:
- Raw sockets bypass the kernel TCP stack. Paqet constructs packets manually rather than using the OS networking API. The kernel never sees a TCP connection, so there is no connection state for DPI to track.
- Custom TCP flags. The packets carry non-standard flag combinations that do not match any known protocol fingerprint. DPI systems looking for SSH, TLS, or HTTP handshakes find nothing recognizable.
- KCP reliability layer. KCP (a protocol similar to UDP-based reliability) provides ordering and retransmission on top of these raw packets. It looks like random data with unusual TCP headers.
The result: firewalls see TCP packets that do not belong to any connection they are tracking and that match no known protocol signature. Most DPI systems pass them through.
How GFW-Knocker Works
GFK uses two layers: violated TCP to get past the firewall, and QUIC tunneling inside to carry actual data.
Your Device Your VPS Internet
+--------------+ +--------------+ +----------+
| Browser | | GFK Server | | Google |
| | | Violated | | | | YouTube |
| v | TCP | v | | etc. |
| GFK Client | ---------> | QUIC Tunnel | --------> | |
| (VIO+QUIC) | (malformed | | | | |
| | | packets) | v | | |
| 127.0.0.1 | | Xray | | |
| :14000 | | (SOCKS5) | | |
+--------------+ +--------------+ +----------+
Why DPI cannot detect it:
- Violated TCP. The client sends TCP packets that are intentionally malformed — wrong flags, no proper handshake, missing sequence numbers. DPI state machines expect normal TCP (SYN, SYN-ACK, ACK) and cannot track these connections. The packets pass through because the firewall does not know what to do with them.
- QUIC tunnel inside. Inside these violated packets, an encrypted QUIC connection carries the actual data. Even if someone captures the traffic, the payload is encrypted QUIC with authentication.
- Xray backend. On the server side, Xray provides the SOCKS5 proxy service. GFK handles transport; Xray handles proxying.
This two-layer approach is effective against deep packet inspection that has learned to detect KCP, Shadowsocks, and other single-layer protocols.
Comparison: paqctl vs Other Methods
| Method | DPI Resistance | Speed | Setup Difficulty | Protocol |
|---|---|---|---|---|
| Paqet | High (raw sockets + custom flags) | Fast | Easy | KCP/TCP |
| GFK | Very high (violated TCP + QUIC) | Good | Advanced | TCP+QUIC |
| VLESS+Reality | High (mimics real TLS) | Fast | Medium | TCP/TLS |
| Hysteria2 | Good (looks like HTTP/3) | Very fast | Medium | QUIC/UDP |
| SSH Tunnel | Low (easily fingerprinted) | Moderate | Easy | TCP |
| WireGuard | Low (known signature) | Very fast | Easy | UDP |
| Shadowsocks | Medium (can be detected) | Fast | Easy | TCP/UDP |
| Tor | Very high (onion routing) | Slow | Easy | TCP |
Prerequisites
- A VPS with a public IP and root access (Ubuntu/Debian recommended)
- A client machine: Windows 10/11, macOS, or Linux
- Windows only: Npcap (the installer handles this automatically)
- Server connection info: IP, port, and key/auth code
Server Setup
Install paqctl
SSH into your VPS and run:
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | sudo bash
The installer downloads the latest paqet release from GitHub and sets up the management commands.
Interactive Menu
Open the menu to configure your server:
sudo paqctl menu
The menu walks you through choosing a method (Paqet, GFK, or both), setting ports, and generating keys.
Management Commands
sudo paqctl menu # Interactive setup menu
sudo paqctl status # Check if services are running
sudo paqctl start # Start the service
sudo paqctl stop # Stop the service
sudo paqctl restart # Restart the service
sudo paqctl status # Show connection info for clients (IP, port, key)
sudo paqctl logs # View recent logs
sudo paqctl update # Update to the latest version
sudo paqctl health # Run health checks
sudo paqctl uninstall # Remove paqctl completely
sudo paqctl telegram # Configure Telegram bot notifications
After setup, the installer displays your connection info (IP, port, key). You can also view it anytime with sudo paqctl status.
Firewall Configuration
Paqet: Open Port 8443
Paqet needs its port open in the firewall because it sends real (raw) packets that the kernel firewall inspects:
sudo ufw allow 8443/tcp
sudo ufw reload
GFK: Keep VIO Port BLOCKED
GFK's VIO port (default 45000) must stay blocked in the firewall. Do not open it with ufw.
Why? GFK uses raw sockets that operate below the kernel's network stack. The packets bypass iptables/nftables entirely — they never hit the firewall. If you open the port, you expose a raw socket listener to the internet unnecessarily.
# Verify the port is NOT open (this is correct)
sudo ufw status | grep 45000
# Should return nothing — that means it is blocked (correct)
If you accidentally opened it:
sudo ufw delete allow 45000/tcp
sudo ufw reload
Paqet Client Setup
Download
Go to the paqet releases page and download the archive for your platform. Download the .tar.gz (Linux/macOS) or .zip (Windows) archive — not a bare binary.
| Platform | File |
|---|---|
| Windows (x64) | paqet-windows-amd64-v1.0.0-alpha.17.zip |
| Linux (x64) | paqet-linux-amd64-v1.0.0-alpha.17.tar.gz |
| Linux (ARM64) | paqet-linux-arm64-v1.0.0-alpha.17.tar.gz |
| macOS (Intel) | paqet-darwin-amd64-v1.0.0-alpha.17.tar.gz |
| macOS (Apple Silicon) | paqet-darwin-arm64-v1.0.0-alpha.17.tar.gz |
Extract the archive:
# Linux / macOS
mkdir -p ~/paqet && cd ~/paqet
tar -xzf paqet-linux-amd64-v1.0.0-alpha.17.tar.gz
chmod +x paqet_linux_amd64
Configuration (config.yaml)
Create config.yaml in the same directory as the paqet binary:
role: "client"
log:
level: "info"
socks5:
- listen: "127.0.0.1:1080"
network:
interface: "eth0"
ipv4:
addr: "192.168.1.100:0"
router_mac: "aa:bb:cc:dd:ee:ff"
server:
addr: "YOUR_SERVER_IP:8443"
transport:
protocol: "kcp"
kcp:
mode: "fast"
key: "YOUR_SECRET_KEY"
Field reference:
| Field | Description |
|---|---|
role |
Always "client" for the client side |
log.level |
"info" for normal use, "debug" for troubleshooting |
socks5[].listen |
Local SOCKS5 proxy address. Default 127.0.0.1:1080 |
network.interface |
Network interface name. Linux: eth0 or wlan0. macOS: en0. Windows: leave empty "" for auto-detect |
network.ipv4.addr |
Your local IP + :0. Find it with ip addr (Linux), ifconfig en0 (macOS), or ipconfig (Windows) |
network.ipv4.router_mac |
Your gateway's MAC address. Find with ip neigh (Linux), arp -a (macOS/Windows) |
server.addr |
Server IP and port from paqctl status |
kcp.mode |
KCP speed mode: "fast", "fast2", "fast3", or "normal". Use "fast" for most connections. "fast3" for very lossy networks (uses more bandwidth) |
kcp.key |
Encryption key from sudo paqctl status on the server (minimum 16 characters) |
Run
Paqet requires root/admin because it uses raw sockets:
# Linux / macOS
sudo ./paqet_linux_amd64 run -c config.yaml
Your SOCKS5 proxy is now at 127.0.0.1:1080.
Configure Your Browser
Firefox (recommended):
- Settings > Network Settings > Manual Proxy
- SOCKS Host:
127.0.0.1, Port:1080(Paqet) or14000(GFK) - Select SOCKS v5
- Check "Proxy DNS when using SOCKS v5" (prevents DNS leaks)
Chrome: Use the SwitchyOmega extension with SOCKS5 proxy 127.0.0.1:1080.
Windows Client
Windows uses .bat launcher files and requires Npcap for raw socket access.
- Go to the paqctl repository and download the ZIP (Code > Download ZIP)
- Extract and open the
windowsfolder - Right-click
Paqet-Client.batand select Run as administrator - First run installs Npcap automatically (follow the installer prompts)
- Enter your server IP, port, and key when prompted
Alternatively, use the PowerShell script for an interactive menu:
# Run PowerShell as Administrator first
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
irm https://raw.githubusercontent.com/SamNet-dev/paqctl/main/windows/paqet-client.ps1 | iex
GFK Client Setup
GFK uses Python scripts (not compiled binaries). You need Python 3.10+ with scapy and aioquic.
Install Dependencies
# Clone the repository
git clone https://github.com/SamNet-dev/paqctl.git
cd paqctl/gfk/client
# Install Python packages
pip3 install scapy aioquic
Configuration (parameters.py)
Create parameters.py in the gfk/client directory:
# GFW-knocker client configuration
from scapy.all import conf
# Server settings
vps_ip = "YOUR_SERVER_IP"
xray_server_ip = "127.0.0.1"
# Port mappings (local_port: remote_port)
tcp_port_mapping = {14000: 443}
udp_port_mapping = {}
# VIO (raw socket) ports
vio_tcp_server_port = 45000
vio_tcp_client_port = 40000
vio_udp_server_port = 35000
vio_udp_client_port = 30000
# QUIC tunnel ports
quic_server_port = 25000
quic_client_port = 20000
quic_local_ip = "127.0.0.1"
# QUIC settings
quic_verify_cert = False
quic_idle_timeout = 86400
udp_timeout = 300
quic_mtu = 1420
quic_max_data = 1073741824
quic_max_stream_data = 1073741824
quic_auth_code = "YOUR_AUTH_CODE"
quic_certificate = "cert.pem"
quic_private_key = "key.pem"
# SOCKS proxy
socks_port = 14000
Key fields to change:
| Field | Description |
|---|---|
vps_ip |
Your server's public IP |
tcp_port_mapping |
Maps local port to remote port. {14000: 443} means local 14000 forwards to server port 443 |
vio_tcp_server_port |
Must match the server's VIO port (default 45000) |
quic_auth_code |
Authentication code from paqctl status on the server |
Run
# Requires root for raw sockets
sudo python3 mainclient.py
Your SOCKS5 proxy is now at 127.0.0.1:14000.
Windows GFK Client
- Download the paqctl ZIP from GitHub
- Open the
windowsfolder - Right-click
GFK-Client.batand select Run as administrator - The script installs Python 3, Npcap, scapy, and aioquic automatically
- Enter your server IP and auth code when prompted
3X-UI Panel Integration
paqctl auto-detects existing Xray panels (3x-ui, Marzban). When it finds a running panel, it works alongside it without modifying your existing configuration.
| Scenario | What paqctl does |
|---|---|
| No Xray installed | Installs Xray with SOCKS5 automatically |
| Xray panel running | Keeps your panel, adds SOCKS5 inbound on a free port (e.g. 10443) |
| Xray installed but not running | Installs its own SOCKS5 config |
When a panel is detected, paqctl provides two connections automatically:
- Panel mapping (
14000:443) — for server-to-server panel traffic (vmess/vless) - SOCKS5 mapping (
14001:10443) — for direct proxy use from a client (no v2rayN needed)
Server-to-Server Bridge
This setup routes traffic from an Iran-based panel through a GFK tunnel to a foreign panel. The end user connects to the Iran panel normally; the Iran panel forwards traffic through GFK to the foreign server.
Setup
1. Foreign server (server role):
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | sudo bash
Choose server role. Set port mapping 14000:443 (where 443 is your panel inbound port). paqctl detects Xray and adds SOCKS5 alongside it.
2. Iran server (client role):
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | sudo bash
Choose client role. Use the exact same port mappings from the server output. Use the same auth code.
3. Update the Iran panel outbound:
Change the outbound in your Iran panel (3x-ui or Marzban) to route through the local GFK tunnel instead of connecting directly to the foreign server.
Before (direct — blocked by DPI):
{
"tag": "vmess_out",
"protocol": "vmess",
"settings": {
"vnext": [{
"address": "FOREIGN_SERVER_IP",
"port": 443,
"users": [{"id": "your-uuid", "security": "auto"}]
}]
}
}
After (routed through GFK tunnel):
{
"tag": "vmess_out",
"protocol": "vmess",
"settings": {
"vnext": [{
"address": "127.0.0.1",
"port": 14000,
"users": [{"id": "your-uuid", "security": "auto"}]
}]
}
}
The change: address becomes 127.0.0.1 and port becomes 14000 (the local VIO port). Everything else (UUID, protocol, encryption) stays the same. Set security/TLS to none since traffic is already encrypted inside the GFK tunnel.
Traffic flow:
End user --> Iran panel inbound --> Iran panel outbound (127.0.0.1:14000)
--> GFK client (VIO) --> QUIC tunnel over violated TCP
--> Foreign GFK server --> 127.0.0.1:443 (foreign panel) --> Internet
Running Both Methods Simultaneously
Paqet and GFK use different ports and can run at the same time on the same server:
# On the server, install both via paqctl menu
sudo paqctl menu
# Select both Paqet and GFK during setup
On the client side, run both clients. You get two independent SOCKS5 proxies:
- Paqet:
127.0.0.1:1080 - GFK:
127.0.0.1:14000
This is useful as a fallback — if one method gets blocked, switch your browser proxy to the other.
Decision Flowchart
START
|
v
Is your network heavily censored?
(Iran during shutdowns, China GFW, deep throttling)
| |
YES NO
| |
v v
Try GFK Use Paqet
first (simpler setup)
| |
v v
GFK working? Paqet working?
| | | |
YES NO YES NO
| | | |
v v v v
Done Try Done Try GFK
Paqet instead
| |
v v
Install BOTH for redundancy
General guidance:
- Start with Paqet if you are not sure. It is simpler and works in most situations.
- Switch to GFK if Paqet gets blocked or you are behind heavy DPI (Iran during major filtering events, China GFW).
- Run both if you need maximum reliability.
Security Recommendations
Use Strong Keys
Paqet encryption keys should be at least 16 characters, random, and unique per server. Do not use example values from documentation.
# Generate a random 32-character key
openssl rand -base64 24
For GFK, the auth code is generated during server setup. Do not share it publicly.
Harden the Server with Fortify
Use Fortify to harden your VPS before or after deploying paqctl:
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/fortify/main/install.sh | sudo bash
Fortify auto-detects paqctl and configures firewall rules, SSH hardening, and fail2ban without breaking your proxy setup.
Block SMTP
Block outbound SMTP to prevent your VPS from being flagged for spam (which can get your IP blacklisted):
sudo iptables -A OUTPUT -p tcp --dport 25 -j DROP
sudo iptables -A OUTPUT -p tcp --dport 587 -j DROP
sudo iptables -A OUTPUT -p tcp --dport 465 -j DROP
Test for DNS Leaks
When testing your connection, always use --socks5-hostname (not --socks5) to prevent DNS leaks:
# Correct — DNS resolves through the proxy
curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.me
# WRONG — DNS leaks to your local resolver
curl --socks5 127.0.0.1:1080 https://ifconfig.me
In Firefox, make sure "Proxy DNS when using SOCKS v5" is checked (Settings > Network Settings).
Offline Installation
If GitHub is blocked in your country, you need to download the files from a machine that has access and transfer them.
Server (Offline)
- On a machine with internet access, download the paqctl installer script and the paqet binary from the releases page.
- Transfer both files to your VPS via SCP, USB, or any other method.
- Run the installer script locally:
chmod +x paqctl.sh
sudo bash paqctl.sh
Client (Offline)
- Download the correct paqet archive for your OS from the releases page (use a VPN, a friend's connection, or download on the VPS and SCP to your machine).
- Extract and create
config.yamlmanually (see the Paqet Client Setup section above). - Run with
sudo ./paqet run -c config.yaml.
For GFK, you also need the Python packages. On a machine with access:
pip3 download scapy aioquic -d ./packages
Transfer the packages folder, then install offline:
pip3 install --no-index --find-links=./packages scapy aioquic
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Connection refused | Server not running | Run sudo paqctl status on server, then sudo paqctl start |
| Connection timeout | Port blocked by firewall | For Paqet: sudo ufw allow 8443/tcp. For GFK: verify port is NOT open (raw sockets bypass firewall) |
| Permission denied | Not running as root/admin | Linux/macOS: use sudo. Windows: Run as Administrator |
| "Gateway MAC not found" | Router MAC not detected | Find manually: arp -a (Windows/macOS) or ip neigh (Linux), enter in config |
| Slow speed | KCP mode too conservative | Change kcp.mode to "fast2" or "fast3" in config.yaml |
| GFK: "auth failed" | Auth code mismatch | Re-check quic_auth_code in parameters.py matches server output from paqctl status |
| Paqet works, GFK does not | VIO port accidentally opened in firewall | Run sudo ufw delete allow 45000/tcp && sudo ufw reload |
| Works on WiFi, not mobile data | ISP blocks raw packets on mobile | Try the other method, or use a different port |
| Npcap install fails (Windows) | Conflict with existing install | Uninstall old Npcap from Control Panel, reboot, reinstall |
| "Running scripts is disabled" (Windows) | PowerShell execution policy | Run: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser |
| Server disconnects periodically | Resource exhaustion or ISP throttling | Check sudo paqctl logs, ensure VPS has adequate memory |
| DNS leaks detected | Using --socks5 instead of --socks5-hostname |
Use curl --socks5-hostname and enable "Proxy DNS" in Firefox |
Related Guides
- Every Way to Bypass Internet Censorship — all methods compared
- Hysteria2 Setup Guide — QUIC-based alternative protocol
- SSH Tunneling with tunnelforge — SSH tunnel with TLS obfuscation
- 3X-UI Panel Setup — manage Xray protocols in one panel
- SOCKS5 Proxy Setup — simpler proxy option
- Complete Proxy Guide — every proxy protocol explained
- DNS Tunneling Guide — last-resort bypass when all else is blocked
- Fortify Server Hardening — secure your proxy server
- WireGuard Setup — VPN alternative
- Complete Self-Hosting Guide — VPS basics
SamNet Open Source Tools
| Tool | Purpose |
|---|---|
| paqctl | Censorship bypass with Paqet + GFW-Knocker (this guide) |
| fortify | Server security hardening (auto-detects paqctl) |
| tunnelforge | SSH tunneling with TLS obfuscation |
| cfray | Find clean Cloudflare IPs for CDN fallback |
| MTProxyMax | Telegram proxy manager |
| wg-orchestrator | WireGuard VPN management |
| torware | Tor Bridge/Relay setup |
Related Tools
- VPN Leak Test — verify proxy is working and no DNS leaks
- Port Scanner — check if server port is reachable
- What's My IP — verify your IP changed after connecting
- Speed Test — test connection speed through the proxy