Skip to content

Commit

Permalink
Fix ssh tunnel use case (#1400)
Browse files Browse the repository at this point in the history
* Fix for `--enable-ssh-tunnel` use case

* Update readme with correct instructions

* Update readme
  • Loading branch information
abhinavsingh authored Apr 26, 2024
1 parent 5b0c484 commit 8b929f0
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 39 deletions.
65 changes: 32 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1303,17 +1303,16 @@ See [requirements-tunnel.txt](https:/abhinavsingh/proxy.py/blob/deve
|
+------------+ | +----------+
| LOCAL | | | REMOTE |
| HOST | <== SSH ==== :8900 == | SERVER |
| HOST | <== SSH ==== :8900 == | PROXY |
+------------+ | +----------+
:8899 proxy.py |
|
FIREWALL
(allow tcp/22)

## What
### What

Proxy HTTP(s) requests made on a `remote` server through `proxy.py` server
running on `localhost`.
Proxy HTTP(s) requests made on a `remote` proxy server through `proxy.py` server running on `localhost`.

### How

Expand All @@ -1335,7 +1334,7 @@ Start `proxy.py` as:

```console
# On localhost
proxy --enable-tunnel \
proxy --enable-ssh-tunnel \
--tunnel-username username \
--tunnel-hostname ip.address.or.domain.name \
--tunnel-port 22 \
Expand Down Expand Up @@ -2341,19 +2340,19 @@ To run standalone benchmark for `proxy.py`, use the following command from repo

```console
❯ proxy -h
usage: -m [-h] [--threadless] [--threaded] [--num-workers NUM_WORKERS]
[--enable-events] [--local-executor LOCAL_EXECUTOR]
[--backlog BACKLOG] [--hostname HOSTNAME]
[--hostnames HOSTNAMES [HOSTNAMES ...]] [--port PORT]
[--ports PORTS [PORTS ...]] [--port-file PORT_FILE]
[--unix-socket-path UNIX_SOCKET_PATH]
[--num-acceptors NUM_ACCEPTORS] [--tunnel-hostname TUNNEL_HOSTNAME]
[--tunnel-port TUNNEL_PORT] [--tunnel-username TUNNEL_USERNAME]
usage: -m [-h] [--tunnel-hostname TUNNEL_HOSTNAME] [--tunnel-port TUNNEL_PORT]
[--tunnel-username TUNNEL_USERNAME]
[--tunnel-ssh-key TUNNEL_SSH_KEY]
[--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE]
[--tunnel-remote-port TUNNEL_REMOTE_PORT] [--version]
[--log-level LOG_LEVEL] [--log-file LOG_FILE]
[--log-format LOG_FORMAT] [--open-file-limit OPEN_FILE_LIMIT]
[--tunnel-remote-port TUNNEL_REMOTE_PORT] [--threadless]
[--threaded] [--num-workers NUM_WORKERS] [--enable-events]
[--local-executor LOCAL_EXECUTOR] [--backlog BACKLOG]
[--hostname HOSTNAME] [--hostnames HOSTNAMES [HOSTNAMES ...]]
[--port PORT] [--ports PORTS [PORTS ...]] [--port-file PORT_FILE]
[--unix-socket-path UNIX_SOCKET_PATH]
[--num-acceptors NUM_ACCEPTORS] [--version] [--log-level LOG_LEVEL]
[--log-file LOG_FILE] [--log-format LOG_FORMAT]
[--open-file-limit OPEN_FILE_LIMIT]
[--plugins PLUGINS [PLUGINS ...]] [--enable-dashboard]
[--basic-auth BASIC_AUTH] [--enable-ssh-tunnel]
[--work-klass WORK_KLASS] [--pid-file PID_FILE] [--openssl OPENSSL]
Expand All @@ -2379,10 +2378,25 @@ usage: -m [-h] [--threadless] [--threaded] [--num-workers NUM_WORKERS]
[--filtered-client-ips FILTERED_CLIENT_IPS]
[--filtered-url-regex-config FILTERED_URL_REGEX_CONFIG]

proxy.py v2.4.4rc6.dev164+g73497f30
proxy.py v2.4.4rc6.dev172+ge1879403.d20240425

options:
-h, --help show this help message and exit
--tunnel-hostname TUNNEL_HOSTNAME
Default: None. Remote hostname or IP address to which
SSH tunnel will be established.
--tunnel-port TUNNEL_PORT
Default: 22. SSH port of the remote host.
--tunnel-username TUNNEL_USERNAME
Default: None. Username to use for establishing SSH
tunnel.
--tunnel-ssh-key TUNNEL_SSH_KEY
Default: None. Private key path in pem format
--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE
Default: None. Private key passphrase
--tunnel-remote-port TUNNEL_REMOTE_PORT
Default: 8899. Remote port which will be forwarded
locally for proxy.
--threadless Default: True. Enabled by default on Python 3.8+ (mac,
linux). When disabled a new thread is spawned to
handle each client connection.
Expand Down Expand Up @@ -2419,21 +2433,6 @@ options:
--host and --port flags are ignored
--num-acceptors NUM_ACCEPTORS
Defaults to number of CPU cores.
--tunnel-hostname TUNNEL_HOSTNAME
Default: None. Remote hostname or IP address to which
SSH tunnel will be established.
--tunnel-port TUNNEL_PORT
Default: 22. SSH port of the remote host.
--tunnel-username TUNNEL_USERNAME
Default: None. Username to use for establishing SSH
tunnel.
--tunnel-ssh-key TUNNEL_SSH_KEY
Default: None. Private key path in pem format
--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE
Default: None. Private key passphrase
--tunnel-remote-port TUNNEL_REMOTE_PORT
Default: 8899. Remote port which will be forwarded
locally for proxy.
--version, -v Prints proxy.py version.
--log-level LOG_LEVEL
Valid options: DEBUG, INFO (default), WARNING, ERROR,
Expand Down Expand Up @@ -2506,7 +2505,7 @@ options:
Default: None. Signing certificate to use for signing
dynamically generated HTTPS certificates. If used,
must also pass --ca-key-file and --ca-signing-key-file
--ca-file CA_FILE Default: /Users/abhinavsingh/Dev/proxy.py/.venv31010/l
--ca-file CA_FILE Default: /Users/abhinavsingh/Dev/proxy.py/.venv31013/l
ib/python3.10/site-packages/certifi/cacert.pem.
Provide path to custom CA bundle for peer certificate
verification
Expand Down
12 changes: 10 additions & 2 deletions proxy/core/ssh/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
import logging
import argparse
from typing import TYPE_CHECKING

from .base import BaseSshTunnelHandler


logger = logging.getLogger(__name__)

if TYPE_CHECKING: # pragma: no cover
from ...common.types import HostPort
Expand All @@ -20,7 +25,7 @@
pass


class SshHttpProtocolHandler:
class SshHttpProtocolHandler(BaseSshTunnelHandler):
"""Handles incoming connections over forwarded SSH transport."""

def __init__(self, flags: argparse.Namespace) -> None:
Expand All @@ -32,4 +37,7 @@ def on_connection(
origin: 'HostPort',
server: 'HostPort',
) -> None:
pass
logger.debug('handle proxy request')

def shutdown(self) -> None:
logger.debug('ssh handler shutdown')
11 changes: 7 additions & 4 deletions proxy/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import threading
from typing import TYPE_CHECKING, Any, List, Type, Optional, cast

from .core.ssh import SshTunnelListener, SshHttpProtocolHandler
from .core.work import ThreadlessPool
from .core.event import EventManager
from .common.flag import FlagParser, flags
Expand Down Expand Up @@ -284,13 +285,15 @@ def setup(self) -> None:
@staticmethod
def _setup_tunnel(
flags: argparse.Namespace,
ssh_handler_klass: Type['BaseSshTunnelHandler'],
ssh_listener_klass: Any,
ssh_handler_klass: Optional[Type['BaseSshTunnelHandler']] = None,
ssh_listener_klass: Optional[Any] = None,
**kwargs: Any,
) -> BaseSshTunnelListener:
tunnel = cast(Type[BaseSshTunnelListener], ssh_listener_klass)(
listener_klass = ssh_listener_klass or SshTunnelListener
handler_klass = ssh_handler_klass or SshHttpProtocolHandler
tunnel = cast(Type[BaseSshTunnelListener], listener_klass)(
flags=flags,
handler=ssh_handler_klass(flags=flags),
handler=handler_klass(flags=flags),
**kwargs,
)
tunnel.setup()
Expand Down

0 comments on commit 8b929f0

Please sign in to comment.