Skip to content

pwnat

pwnat (Peer-to-Peer With NAT) is a cross-platform peer-to-peer network tunneling utility that enables direct communication between clients and servers behind NAT devices without requiring port forwarding, UPnP, or external relay servers. It uses creative packet spoofing and asymmetric routing techniques to establish bidirectional tunnels through restrictive firewalls.

  • NAT Traversal: Establishes peer-to-peer connections across NAT boundaries
  • No Port Forwarding Required: Works without manual router configuration
  • Cross-Platform: Supports Linux, macOS, Windows, and BSD
  • Bidirectional Communication: Enables full-duplex tunneling between peers
  • Packet Spoofing: Uses ICMP and UDP techniques for traversal
  • Low Overhead: Minimal bandwidth consumption for tunnel establishment
  • Raw Socket Access: Requires elevated privileges for some operations
PlatformMethodCommand
Linux (Debian/Ubuntu)apt-getsudo apt-get install pwnat
Linux (Fedora/RHEL)dnfsudo dnf install pwnat
macOSHomebrewbrew install pwnat
WindowsBinaryDownload from GitHub releases
Source BuildGitgit clone https://github.com/samyk/pwnat && cd pwnat && make

Listen for incoming peer connections and establish tunnel:

# Start server listening on port 8000
sudo pwnat -s -p 8000

# Listen with verbose output
sudo pwnat -s -p 8000 -v

# Specify bind address
sudo pwnat -s -p 8000 -l 192.168.1.100

Connect to server peer through NAT:

# Connect to server behind NAT
sudo pwnat -c -s <SERVER_IP> -p 8000

# With local bind address
sudo pwnat -c -s <SERVER_IP> -p 8000 -l 192.168.1.50

# Verbose mode for debugging
sudo pwnat -c -s <SERVER_IP> -p 8000 -v
CommandDescriptionExample
-sStart in server modepwnat -s
-cStart in client modepwnat -c -s 203.0.113.5
-p PORTSpecify port numberpwnat -s -p 9000
-l ADDRESSBind to local addresspwnat -s -l 192.168.1.100
-vVerbose outputpwnat -s -v
-hDisplay helppwnat -h
-e PROGExecute programpwnat -c -s 203.0.113.5 -e /bin/bash

Establishing Tunnels with Program Execution

Section titled “Establishing Tunnels with Program Execution”
# Server mode: execute shell on successful connection
sudo pwnat -s -p 8000 -e '/bin/bash -i'

# Client mode: establish tunnel and execute local program
sudo pwnat -c -s 203.0.113.5 -p 8000 -e 'nc localhost 22'
# Server: Listen and execute SSH shell
sudo pwnat -s -p 8000 -e '/bin/bash'

# Client: Connect through pwnat tunnel
sudo pwnat -c -s <SERVER_IP> -p 8000

# From another terminal, connect to local tunnel
ssh user@127.0.0.1
# Server with UDP mode
sudo pwnat -s -p 8000 -u

# Client connecting via UDP
sudo pwnat -c -s 203.0.113.5 -p 8000 -u
  1. Endpoint Discovery: Client and server exchange packets with external relay
  2. Asymmetric Routing: Leverages different return paths for outbound/inbound traffic
  3. Packet Spoofing: Uses ICMP echo replies and UDP packets
  4. Tunnel Establishment: Creates bidirectional communication channel
  5. Data Forwarding: Routes traffic between local and remote endpoints
┌─────────────────────────────────────────┐
│          Internet / WAN                 │
├──────────────────────────────────────────┤
│  Relay/Intermediate Router (Optional)   │
├──────────────────────────────────────────┤
│  NAT Device                              │
│  ┌────────────────┐      ┌────────────┐ │
│  │ Server/Peer1   │◄────►│ Client/Peer2 │ │
│  └────────────────┘      └────────────┘ │
└──────────────────────────────────────────┘
# Terminal 1 - Server behind NAT
sudo pwnat -s -p 5555 -v

# Terminal 2 - Client (different network)
sudo pwnat -c -s 203.0.113.10 -p 5555 -v

# Terminal 3 - Verify tunnel (after establishment)
netstat -tuln | grep 5555
# Server side - bind shell
sudo pwnat -s -p 9000 -e 'nc -l -p 4444'

# Client side - establish tunnel
sudo pwnat -c -s <SERVER_EXTERNAL_IP> -p 9000

# Connect to remote shell
nc localhost 4444
# Server - setup HTTP file server through pwnat
sudo pwnat -s -p 8888 -e 'python3 -m http.server 7777'

# Client - access server's file share
sudo pwnat -c -s 203.0.113.5 -p 8888

# Download files
curl http://localhost:7777/

Connection Fails with “Permission Denied"

Section titled “Connection Fails with “Permission Denied"”
# pwnat requires root/sudo for raw socket access
sudo pwnat -s -p 8000

# Verify sudoers (Linux)
sudo visudo
# Ensure user can run pwnat without password if needed
# Check network connectivity
ping <SERVER_IP>

# Verify firewall doesn't block ICMP
sudo ufw allow icmp

# Run with verbose debugging
sudo pwnat -c -s 203.0.113.5 -p 8000 -v -v
# Monitor tunnel quality with verbose output
sudo pwnat -c -s 203.0.113.5 -p 8000 -v

# Check MTU size (may need adjustment)
ip link show | grep mtu

# Set MTU for tunnel interface
sudo ip link set mtu 1400
# Check what's using the port
sudo netstat -tlnp | grep :8000
sudo lsof -i :8000

# Use different port
sudo pwnat -s -p 8001
  • Elevation Required: pwnat needs root/administrator access for packet operations
  • Firewall Rules: Verify firewall allows necessary ICMP and UDP traffic
  • Encryption: pwnat creates tunnel but doesn’t encrypt traffic—use SSL/TLS over it
  • Authentication: Implement additional authentication for production use
  • Logging: Monitor tunnel establishment for unauthorized access attempts
  • Network Topology: Test before deployment to ensure asymmetric routing works in your environment
# Server with optimizations
sudo pwnat -s -p 8000 -b 65536

# Monitor performance
iftop -i eth0
nethogs
# Check current latency
ping -c 5 <REMOTE_IP>

# Adjust buffer sizes if needed
sysctl -w net.core.rmem_max=134217728
sysctl -w net.core.wmem_max=134217728
Use CaseConfigurationCommand
Remote AccessServer listens, client initiatespwnat -s -p 8000 / pwnat -c -s IP -p 8000
File TransferWith SCP/rsyncpwnat -s -p 2222 -e /usr/lib/openssh/sftp-server
Service TunnelingAny TCP servicepwnat -s -p 8000 -e 'nc localhost 3000'
Mesh NetworkingMultiple peer tunnelsRun multiple pwnat instances
Game ServerPeer-to-peer gamingpwnat -s -p 9000 on both sides
ToolNAT TraversalRelay RequiredEncryptionUse Case
pwnatYes (asymmetric)NoNoP2P tunneling
ngrokYesCloud relayYesQuick tunneling
TailscaleYesCloud coordinationYesVPN mesh
SSHLimitedManual portsYesRemote access
UPnPYesRouter supportNoAutomatic forwarding
#!/bin/bash

REMOTE_IP="203.0.113.10"
REMOTE_PORT="8000"
INTERVAL=30

while true; do
  if sudo pwnat -c -s $REMOTE_IP -p $REMOTE_PORT -v 2>&1 | grep -q "Established"; then
    echo "[$(date)] Tunnel established successfully"
  else
    echo "[$(date)] Tunnel establishment failed"
  fi
  sleep $INTERVAL
done
#!/bin/bash

PEERS=("203.0.113.5" "203.0.113.6" "203.0.113.7")
BASE_PORT=8000

for i in "${!PEERS[@]}"; do
  PORT=$((BASE_PORT + i))
  sudo pwnat -c -s ${PEERS[$i]} -p $PORT &
  echo "Started tunnel to ${PEERS[$i]} on port $PORT"
done

wait
  • GitHub Repository: https://github.com/samyk/pwnat
  • Author: Samy Kamkar
  • License: GPL-3.0
  • Documentation: See README and inline comments in source code
  • Community: GitHub issues for bug reports and feature requests
VersionRelease DateKey Features
0.7.22013UDP support, verbose logging
0.7.12013Bug fixes, IPv4 support
0.72012Initial stable release

pwnat is a legitimate tool for authorized network testing and research. Ensure you have proper authorization before establishing tunnels or bypassing network restrictions. Use responsibly for:

  • Testing NAT traversal implementations
  • Network research and education
  • Authorized penetration testing
  • Internal network connectivity
  • Peer-to-peer application development

Unauthorized network access is illegal in most jurisdictions.