NAT traversal tool - peer-to-peer communication through NATs without port forwarding
Project description
pwnatpy
NAT traversal tool - peer-to-peer communication through NATs without port forwarding
pwnatpy enables direct communication between a client behind a NAT and a server behind a separate NAT without any port forwarding, DMZ, UPnP, or third-party proxy. The connection is established peer-to-peer using ICMP Time Exceeded packets to penetrate NATs.
Install
pip install pwnatpy
Usage
Server Mode
pwnatpy -s [bind_ip] [proxy_port] [[allowed_host]:[allowed_port] ...]
Example:
sudo pwnatpy -s 0.0.0.0 2222
Client Mode
pwnatpy [local_ip] <local_port> <proxy_host> [proxy_port] <remote_host> <remote_port>
Example:
sudo pwnatpy 127.0.0.1 0 3.3.3.1 2222 192.168.1.100 22
How It Works
The pwnat protocol operates in three phases:
-
NAT Penetration (ICMP-based)
- Server sends periodic ICMP Echo Request packets to 3.3.3.3 (fake destination)
- Client sends ICMP Time Exceeded packets containing the server's original packet
- Server's NAT recognizes the inner packet and forwards the ICMP to the server
- Server extracts client's public IP address from the ICMP payload
-
UDP Session Establishment
- Server sends UDP packets to client (initially dropped by client's NAT)
- Client sends UDP packets to server (server's NAT allows as it's responding to server's outgoing packets)
- Both NATs now have "pinholes" allowing bidirectional UDP traffic
-
TCP Tunneling
- UDP tunnel carries TCP payload between client and server
- Custom protocol handles reliability, ordering, and flow control
Requirements
- Root/sudo privileges (required for raw socket access)
- Python 3.11+
CLI Options
| Option | Description |
|---|---|
-c |
Client mode (default) |
-s |
Server mode |
-6 |
Use IPv6 |
-v |
Increase debug verbosity |
-a |
Enable SO_REUSEADDR |
-p |
Enable SO_REUSEPORT |
Development
git clone https://github.com/user/pwnatpy.git
cd pwnatpy
pip install -e ".[test]"
# run tests
pytest
# format
ruff format src/ tests/
# lint
ruff check src/ tests/
# type check
mypy src/
Version
v0.1.0.1
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pwnatpy-0.1.0.1.tar.gz.
File metadata
- Download URL: pwnatpy-0.1.0.1.tar.gz
- Upload date:
- Size: 10.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b1266e1e877077238a36ae95925a75847488c73b5b8746d07d679486ad707e9
|
|
| MD5 |
507f306e24b47cd833b11cca32df4a83
|
|
| BLAKE2b-256 |
8e07ca654b2aff1c8dac5cf60bd3905dc3dc5960dab2102f204fffe07afd4a8e
|
Provenance
The following attestation bundles were made for pwnatpy-0.1.0.1.tar.gz:
Publisher:
pypi-publish.yml on daedalus/pwnatpy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pwnatpy-0.1.0.1.tar.gz -
Subject digest:
3b1266e1e877077238a36ae95925a75847488c73b5b8746d07d679486ad707e9 - Sigstore transparency entry: 1174339158
- Sigstore integration time:
-
Permalink:
daedalus/pwnatpy@ece1457a25b55db6b36c5f50e4f497f6df70c345 -
Branch / Tag:
refs/tags/v0.1.0.1 - Owner: https://github.com/daedalus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@ece1457a25b55db6b36c5f50e4f497f6df70c345 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pwnatpy-0.1.0.1-py3-none-any.whl.
File metadata
- Download URL: pwnatpy-0.1.0.1-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bbd45b5095a5c9cc2a06fdb880df7941b9c5654685379c12d19c7ee21d05508
|
|
| MD5 |
abc9c00a67c7d4047f2385ffd422615c
|
|
| BLAKE2b-256 |
7f568d9d06218ac49fe5ff45b37e71b76b54921d9690452f2ec81207bfa5701a
|
Provenance
The following attestation bundles were made for pwnatpy-0.1.0.1-py3-none-any.whl:
Publisher:
pypi-publish.yml on daedalus/pwnatpy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pwnatpy-0.1.0.1-py3-none-any.whl -
Subject digest:
8bbd45b5095a5c9cc2a06fdb880df7941b9c5654685379c12d19c7ee21d05508 - Sigstore transparency entry: 1174339265
- Sigstore integration time:
-
Permalink:
daedalus/pwnatpy@ece1457a25b55db6b36c5f50e4f497f6df70c345 -
Branch / Tag:
refs/tags/v0.1.0.1 - Owner: https://github.com/daedalus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@ece1457a25b55db6b36c5f50e4f497f6df70c345 -
Trigger Event:
release
-
Statement type: