Skip to main content

A small Python TCP reverse tunnel compatible with common frp/rathole config subsets.

Project description

py-frp

A small Python TCP reverse tunnel inspired by the public-server/private-client model used by frp and rathole. The current scope is TCP port forwarding with a server, a client, a practical subset of frp TOML/INI configs, and a practical subset of rathole TOML configs.

Installation

Install from PyPI:

pip install py-simple-nat-tunnel

Install from source:

pip install .

Install in editable development mode:

pip install -e .

Installed commands:

py-frp --version
py-frp server -c examples/frps.toml
py-frp client -c examples/frpc.toml
py-frps -c examples/frps.toml
py-frpc -c examples/frpc.toml

On Windows, if the scripts directory is not on PATH, use the module entry point directly:

python -m py_frp server -c examples/frps.toml
python -m py_frp client -c examples/frpc.toml

Quick Start

On the public server:

py-frp server -c examples/frps.toml

On the private client:

py-frp client -c examples/frpc.toml

The default examples/frpc.toml exposes the client's 127.0.0.1:22 on the server's 0.0.0.0:6000. Connect from outside with:

ssh -p 6000 user@your-server

Configless Port Pool Mode

The server can run without a config file by specifying a control port and a public port pool:

py-frp server --bind-port 7000 --port-pool 6000-6009

--port-pool can be repeated. The server merges all ranges and single ports; a-b means the inclusive range from a through b, and a by itself adds one port:

py-frp server --bind-port 7000 --port-pool 6000-6009 --port-pool 7000 --port-pool 7100-7102

At startup, the server prints one shared random token to stdout. Tokens use only unambiguous letters and digits, excluding I, O, 0, 1, and l. Give that one token to all clients that are allowed to use the pool.

Clients only need the server address and the shared token. The local target defaults to 127.0.0.1:22:

py-frp client --server your-server:7000 --token TOKEN_FROM_SERVER

After registration, the client prints the assigned remote port to stdout:

6003

If the local target is not SSH, set it explicitly:

py-frp client --server your-server:7000 --token TOKEN_FROM_SERVER --local 127.0.0.1:8080

Multiple clients can use the same shared token at the same time. Each client is assigned one currently unused port from the pool, using the lowest available port first. If the pool is exhausted, the server rejects the new client and the client logs a single insufficient-resource error instead of disconnecting an existing client.

frp Config Subset

Server frps.toml:

bindPort = 7000

[auth]
token = "change-me"

Client frpc.toml:

serverAddr = "your-server"
serverPort = 7000

[auth]
token = "change-me"

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

Legacy frp INI [common] and TCP proxy sections are also supported:

[common]
server_addr = your-server
server_port = 7000
token = change-me

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

rathole Config Subset

Server:

[server]
bind_addr = "0.0.0.0:2333"
default_token = "change-me"

[server.services.ssh]
bind_addr = "0.0.0.0:6000"

Client:

[client]
remote_addr = "your-server:2333"
default_token = "change-me"

[client.services.ssh]
local_addr = "127.0.0.1:22"

Privilege Elevation

When the server needs to bind a privileged listen port below 1024, it tries to relaunch once through py-admin-launch by default. You can also control this explicitly:

py-frp server -c frps.toml --elevate
py-frp server -c frps.toml --no-auto-elevate

The relaunched command receives an internal marker so elevation is attempted at most once.

Current Scope

Supported:

  • TCP reverse port forwarding
  • Multiple services/proxies
  • Token authentication
  • Configless shared-token port pool mode
  • Common frp TOML and legacy INI TCP configs
  • Common rathole TOML TCP configs
  • One-command installation through pip install
  • Console scripts

Not currently supported:

  • UDP
  • HTTP/HTTPS virtual hosts
  • frp plugins, load balancing, STCP, or XTCP
  • rathole Noise/TLS encrypted transport
  • Multiplexing; each public connection opens one independent tunnel TCP

Tests

python -m unittest discover -s tests -v

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_simple_nat_tunnel-0.1.5.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_simple_nat_tunnel-0.1.5-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file py_simple_nat_tunnel-0.1.5.tar.gz.

File metadata

  • Download URL: py_simple_nat_tunnel-0.1.5.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.11.15 Windows/10

File hashes

Hashes for py_simple_nat_tunnel-0.1.5.tar.gz
Algorithm Hash digest
SHA256 31c264cde15950cd95d52938fb1225f2fca6bad75b2f84d4e004277369c5375c
MD5 74b03dbc50256185ace0d501047b1aed
BLAKE2b-256 db22a472dc456f551c4b8dd0dca2606cd3f6f46d4b37299ba309d4c10a1d5479

See more details on using hashes here.

File details

Details for the file py_simple_nat_tunnel-0.1.5-py3-none-any.whl.

File metadata

File hashes

Hashes for py_simple_nat_tunnel-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e14cfb95cdbacc5b4c662556c8bd21fa5feca949544e35c18ffd13d8163e8be4
MD5 54341653db41d54b77ac81d223b2f278
BLAKE2b-256 afd490d8fe18aa2b94656eee717f28904ff5354d5931509c5daadc469f859853

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page