# I2P Python A complete, from-scratch Python implementation of the [I2P](https://geti2p.net) anonymous network protocol. This is not a wrapper or binding — it is a full reimplementation of the Java I2P router, capable of connecting to the live I2P network. Built by [bimo.studio](https://bimo.studio). ## Installation ```bash pip install i2p-python ``` Or install individual components: ```bash pip install i2p-py-router # Router only pip install i2p-py-sam # SAM bridge only pip install i2p-crypto # All crypto primitives ``` ### Requirements - Python 3.11 or later - `cryptography` >= 41.0 ## Running the Router ### Quick Start ```bash i2p-router ``` This starts the router with default settings: | Setting | Default | Description | |---------|---------|-------------| | Listen host | `0.0.0.0` | Bind address for incoming connections | | Listen port | `9700` | NTCP2 transport port (TCP) | | Data directory | `~/.i2p-python` | Router identity and state | | Tunnel count | 3 in / 3 out | Exploratory tunnel pool size | | Tunnel length | 3 hops | Privacy level per tunnel | | Bandwidth limit | Unlimited | Set `I2P_BANDWIDTH_LIMIT_KBPS` to cap | ### Command-Line Options ```bash i2p-router --host 0.0.0.0 --port 9700 --data-dir ~/.i2p-python i2p-router --log-level DEBUG # Verbose logging i2p-router --reseed # Force reseed on startup ``` ### Environment Variables Every setting can also be controlled via environment variables: ```bash export I2P_LISTEN_HOST=0.0.0.0 export I2P_LISTEN_PORT=9700 export I2P_DATA_DIR=~/.i2p-python export I2P_INBOUND_TUNNEL_COUNT=3 export I2P_OUTBOUND_TUNNEL_COUNT=3 export I2P_TUNNEL_LENGTH=3 export I2P_TUNNEL_LIFETIME=600 export I2P_BANDWIDTH_LIMIT_KBPS=256 export I2P_FLOODFILL=false export I2P_HANDSHAKE_TIMEOUT=30 export I2P_IDLE_TIMEOUT=300 ``` ### Running the SAM Bridge The [SAM](https://geti2p.net/en/docs/api/samv3) bridge lets external applications (e.g., I2P-enabled IRC clients, torrent clients) connect through your router: ```bash i2p-sam # Default: 127.0.0.1:7656 i2p-sam --host 127.0.0.1 --port 7656 # Explicit ``` ## First-Run Bootstrap On first startup, the router must **bootstrap** into the I2P network: 1. **Identity generation** (~1 second) — creates Ed25519 signing keys and X25519 NTCP2 transport keys, saved to `~/.i2p-python/router.keys.json`. 2. **Reseed** (5-25 minutes) — downloads RouterInfo entries from reseed servers over HTTPS to populate the local NetDB. Triggers automatically when the NetDB has fewer than 50 entries. Downloads from at least 2 of 13 hardcoded reseed servers. 3. **Peer connections** (~1-2 minutes) — connects to 5 initial peers via NTCP2, exchanging RouterInfo. 4. **Tunnel building** (~1-2 minutes) — constructs 3 inbound and 3 outbound exploratory tunnels through the network. **Expect 10-30 minutes before the router is fully integrated.** Subsequent startups are faster because the router identity is reused and the NetDB may retain entries from the previous run. You can monitor progress via log output at `--log-level INFO` or higher. ## Known Issues and Operational Notes ### Ports and Firewalls The router listens on **TCP port 9700** by default (NTCP2 transport). For the router to accept inbound connections from the I2P network: - **Port 9700/TCP must be reachable** from the internet (or at least from I2P peers). - If your firewall blocks inbound TCP, the router will still function in **outbound-only mode** — it can build tunnels and route traffic, but other routers cannot initiate connections to you. This reduces your contribution to the network and may slightly increase latency. - The SAM bridge (port 7656) should **not** be exposed to the internet — it is a local API for applications on the same machine. ### NAT Traversal If your router is behind a NAT (home router, cloud VPC, etc.): - **Port forwarding** is the most reliable option. Forward TCP 9700 from your gateway to the machine running the I2P router. - **UPnP auto-configuration is not yet implemented** in this Python port. The Java I2P router has UPnP support; this is planned for a future release. - **SSU2 (UDP transport) includes NAT detection infrastructure** (peer testing and relay/introduction), but it is not yet integrated into the main router bootstrap. Until SSU2 integration is complete, the router operates NTCP2-only. - If you cannot forward ports, the router will work but will be classified as "firewalled" by the network. Other routers can still reach you through existing tunnels, but you cannot participate as a relay. ### Low-Memory and Residential Routers Running an I2P router on hardware with limited resources (e.g., Linksys, OpenWrt, Raspberry Pi, or small VPS instances) requires care: - **Connection count**: The router maintains up to **50 peer connections** by default. Each connection holds state, buffers, and crypto context. On devices with < 256 MB RAM, consider reducing tunnel counts to lower overall load. - **Tunnel overhead**: Each tunnel (default: 6 total, 3 hops each) requires per-hop encryption state. Reducing `I2P_INBOUND_TUNNEL_COUNT` and `I2P_OUTBOUND_TUNNEL_COUNT` to 1-2 lowers memory and CPU load. - **Residential NAT routers** (Linksys, Netgear, etc.) have limited connection tracking tables (typically 4,096-16,384 entries). An I2P router with 50 peers, each with multiple tunnels, can exhaust this table, causing the residential router to drop connections for *all* devices on the network. **Symptoms**: intermittent internet outages, DNS failures, smart home devices going offline. **Mitigation**: set `I2P_BANDWIDTH_LIMIT_KBPS` to a conservative value (128-256) and reduce tunnel counts, or run the I2P router behind a dedicated gateway. - **CPU**: Tunnel encryption uses AES-256-CBC and Ed25519 signatures. On ARM-based devices (Pi 3/4), expect higher CPU usage than x86. Python's `cryptography` library uses OpenSSL under the hood, which is reasonably optimized, but Python's async overhead adds up. - **NetDB growth**: The in-memory NetDB grows as the router learns about peers. A mature router may hold 1,000+ RouterInfo entries. Each is small (~256 bytes), but there is currently no eviction policy — the NetDB grows monotonically until restart. ### Bandwidth Limiting ```bash export I2P_BANDWIDTH_LIMIT_KBPS=256 # Cap at 256 KB/s ``` Set this on metered connections or shared infrastructure. `0` (default) means unlimited. ## Upgrading ### Safe Upgrade Path ```bash pip install --upgrade i2p-python ``` **Your configuration and identity are preserved.** The router stores its identity keys in `~/.i2p-python/router.keys.json` and this file is never modified by package upgrades. Your router will keep the same identity (and therefore the same network reputation) across upgrades. ### What Can Break - **Major version bumps** (e.g., 0.x to 1.x) may change the config format or data directory layout. Release notes will include migration instructions. - **Dependency updates** to `cryptography` are generally safe but may require recompiling native extensions (`pip install --force-reinstall cryptography`). - **Do not delete `~/.i2p-python/`** unless you want to start fresh with a new identity. Regenerating your identity means losing your reputation in the network and going through the full bootstrap process again. ### Rollback ```bash pip install i2p-python==0.1.0 ``` Pin to a known-good version if an upgrade causes issues. ## Architecture I2P Python is split into 34 independent packages grouped into layers: | Layer | Packages | Description | |-------|----------|-------------| | **Crypto** | `i2p-py-crypto-*` (14 packages) | AES, ChaCha20, DSA, EdDSA, ElGamal, X25519, HKDF, HMAC, SipHash, SHA-256, ML-KEM, Noise, Garlic, Session Keys | | **Data** | `i2p-py-data-*` (4 packages) | Core types, I2NP messages, RouterInfo, remaining data structures | | **Transport** | `i2p-py-transport-*` (3 packages) | Base transport, NTCP2 (TCP), SSU2 (UDP) | | **Network** | `i2p-py-netdb`, `i2p-py-tunnel`, `i2p-py-peer`, `i2p-py-kademlia` | Network database, tunnel management, peer connections, DHT | | **Applications** | `i2p-py-router`, `i2p-py-sam`, `i2p-py-streaming`, `i2p-py-apps`, `i2p-py-client` | Router, SAM bridge, streaming lib, applications, client API | | **Utilities** | `i2p-py-util`, `i2p-py-stat`, `i2p-py-time`, `i2p-py-integration` | Shared utilities, statistics, clock sync, integration tests | Six **meta-packages** provide convenient dependency groups: ```bash pip install i2p-python # Everything — full router + SAM + all deps pip install i2p-crypto # All 14 crypto packages pip install i2p-data # All 4 data packages pip install i2p-transport # All 3 transport packages pip install i2p-network # NetDB + tunnel + peer + kademlia pip install i2p-utils # Util + stat + time ``` ## Protocol Compatibility This implementation follows the I2P protocol specifications: - **NTCP2** transport (Noise XK handshake + AES-CBC frame obfuscation) - **I2NP** message format (DatabaseStore, DatabaseLookup, TunnelData, etc.) - **Ed25519** router signing keys (SigType 7) - **X25519** NTCP2 transport keys - **ElGamal/AES+SessionTag** garlic encryption - **Kademlia-based** network database (NetDB / floodfill) - **SAM v3.0-3.3** bridge protocol Tested against live Java I2P peers (version 2.x). NTCP2 handshake interoperability confirmed. ## License MIT License. Copyright (c) 2026 bimo.studio. This is an independent reimplementation. No code was copied from the original Java I2P project. The original Java I2P core (i2p.jar, router.jar, SAM, streaming) is public domain. See [LICENSE](LICENSE) for the full text.