ssh-auto-forward 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ssh_auto_forward-0.0.1/.github/workflows/test.yml +18 -0
- ssh_auto_forward-0.0.1/.gitignore +31 -0
- ssh_auto_forward-0.0.1/.python-version +1 -0
- ssh_auto_forward-0.0.1/Makefile +28 -0
- ssh_auto_forward-0.0.1/PKG-INFO +165 -0
- ssh_auto_forward-0.0.1/README.md +147 -0
- ssh_auto_forward-0.0.1/pyproject.toml +54 -0
- ssh_auto_forward-0.0.1/ssh_auto_forward/__init__.py +5 -0
- ssh_auto_forward-0.0.1/ssh_auto_forward/__version__.py +1 -0
- ssh_auto_forward-0.0.1/ssh_auto_forward/cli.py +653 -0
- ssh_auto_forward-0.0.1/tests/__init__.py +0 -0
- ssh_auto_forward-0.0.1/tests/test_cli.py +350 -0
- ssh_auto_forward-0.0.1/tests_integration/__init__.py +0 -0
- ssh_auto_forward-0.0.1/tests_integration/test_auto_forward.py +696 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: ${{ matrix.python-version }}
|
|
16
|
+
- run: pip install uv
|
|
17
|
+
- run: uv sync
|
|
18
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.so
|
|
5
|
+
.Python
|
|
6
|
+
build/
|
|
7
|
+
develop-eggs/
|
|
8
|
+
dist/
|
|
9
|
+
downloads/
|
|
10
|
+
eggs/
|
|
11
|
+
.eggs/
|
|
12
|
+
lib/
|
|
13
|
+
lib64/
|
|
14
|
+
parts/
|
|
15
|
+
sdist/
|
|
16
|
+
var/
|
|
17
|
+
wheels/
|
|
18
|
+
*.egg-info/
|
|
19
|
+
.installed.cfg
|
|
20
|
+
*.egg
|
|
21
|
+
MANIFEST
|
|
22
|
+
.pytest_cache/
|
|
23
|
+
.coverage
|
|
24
|
+
htmlcov/
|
|
25
|
+
.vscode/
|
|
26
|
+
.idea/
|
|
27
|
+
*.swp
|
|
28
|
+
*.swo
|
|
29
|
+
*~
|
|
30
|
+
.DS_Store
|
|
31
|
+
uv.lock
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.PHONY: test setup shell coverage publish-build publish-test publish publish-clean run
|
|
2
|
+
|
|
3
|
+
test:
|
|
4
|
+
uv run pytest
|
|
5
|
+
|
|
6
|
+
setup:
|
|
7
|
+
uv sync --dev
|
|
8
|
+
|
|
9
|
+
shell:
|
|
10
|
+
uv shell
|
|
11
|
+
|
|
12
|
+
coverage:
|
|
13
|
+
uv run pytest --cov=ssh_auto_forward --cov-report=term-missing
|
|
14
|
+
|
|
15
|
+
publish-build:
|
|
16
|
+
uv run hatch build
|
|
17
|
+
|
|
18
|
+
publish-test:
|
|
19
|
+
uv run hatch publish --repo test
|
|
20
|
+
|
|
21
|
+
publish:
|
|
22
|
+
uv run hatch publish
|
|
23
|
+
|
|
24
|
+
publish-clean:
|
|
25
|
+
rm -r dist/
|
|
26
|
+
|
|
27
|
+
run:
|
|
28
|
+
uv run python -m ssh_auto_forward.cli hetzner
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ssh-auto-forward
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Auto-forward SSH ports
|
|
5
|
+
Author: alexe
|
|
6
|
+
License: WTFPL
|
|
7
|
+
Keywords: port-forwarding,remote-development,ssh,tunnel
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: paramiko>=3.4.0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# SSH Auto Port Forwarder
|
|
20
|
+
|
|
21
|
+
Automatically detect and forward ports from a remote SSH server to your local machine. Similar to VS Code's port forwarding feature, but fully automatic.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- Automatically discovers listening ports on the remote server
|
|
26
|
+
- Shows process names for each forwarded port
|
|
27
|
+
- Forwards ports to your local machine via SSH tunneling
|
|
28
|
+
- Handles port conflicts by finding alternative local ports
|
|
29
|
+
- Auto-detects new ports and starts forwarding
|
|
30
|
+
- Auto-detects closed ports and stops forwarding
|
|
31
|
+
- Terminal title shows tunnel count
|
|
32
|
+
- Runs in the background with status updates
|
|
33
|
+
- Reads connection details from your SSH config
|
|
34
|
+
- Skips well-known ports (< 1000) by default
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
### With uv (recommended):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uvx ssh-auto-forward hetzner
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Install locally:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cd portforwards
|
|
48
|
+
uv sync
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This installs the `ssh-auto-forward` command.
|
|
52
|
+
|
|
53
|
+
### Local development:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
make run ARGS=hetzner
|
|
57
|
+
make run ARGS="hetzner -v"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
### Basic usage - uses host from your SSH config:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ssh-auto-forward hetzner
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Options:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
-v, --verbose Enable verbose logging
|
|
72
|
+
-i, --interval SECS Scan interval in seconds (default: 5)
|
|
73
|
+
-p, --port-range MIN:MAX Local port range for remapping (default: 3000:10000)
|
|
74
|
+
-s, --skip PORTS Comma-separated ports to skip (default: all ports < 1000)
|
|
75
|
+
-c, --config PATH Path to SSH config file
|
|
76
|
+
--version Show version and exit
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Examples:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Scan every 3 seconds
|
|
83
|
+
ssh-auto-forward hetzner -i 3
|
|
84
|
+
|
|
85
|
+
# Use specific port range
|
|
86
|
+
ssh-auto-forward hetzner -p 4000:9000
|
|
87
|
+
|
|
88
|
+
# Skip specific ports
|
|
89
|
+
ssh-auto-forward hetzner -s 22,80,443
|
|
90
|
+
|
|
91
|
+
# Verbose mode
|
|
92
|
+
ssh-auto-forward hetzner -v
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## How it works
|
|
96
|
+
|
|
97
|
+
1. Connects to your remote server using your SSH config
|
|
98
|
+
2. Runs `ss -tlnp` on the remote to find listening ports
|
|
99
|
+
3. Creates SSH tunnels for each discovered port
|
|
100
|
+
4. Continuously monitors for new/closed ports
|
|
101
|
+
5. Handles port conflicts on your local machine
|
|
102
|
+
|
|
103
|
+
## Status messages
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
✓ Connected!
|
|
107
|
+
✓ Forwarding port 2999 (python3)
|
|
108
|
+
✓ Forwarding port 7681 (ttyd)
|
|
109
|
+
✓ Forwarding remote port 19840 -> local port 3000 (node)
|
|
110
|
+
✗ Remote port 2999 is no longer listening, stopping tunnel
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The terminal title also updates to show: `ssh-auto-forward: hetzner (18 tunnels active)`
|
|
114
|
+
|
|
115
|
+
## Testing
|
|
116
|
+
|
|
117
|
+
Start a test server on your remote machine:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
ssh hetzner "python3 -m http.server 9999 --bind 127.0.0.1 &"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Then run `ssh-auto-forward hetzner` and you should see:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
✓ Forwarding remote port 9999 -> local port 3003 (python3)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Access it locally:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
curl http://localhost:3003/
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Stopping
|
|
136
|
+
|
|
137
|
+
Press `Ctrl+C` to stop the forwarder and close all tunnels.
|
|
138
|
+
|
|
139
|
+
## Requirements
|
|
140
|
+
|
|
141
|
+
- Python 3.10+
|
|
142
|
+
- paramiko
|
|
143
|
+
- Remote server must have `ss` or `netstat` command available
|
|
144
|
+
|
|
145
|
+
## Tests
|
|
146
|
+
|
|
147
|
+
### Unit tests (run locally, no SSH required):
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
make test
|
|
151
|
+
# or
|
|
152
|
+
uv run pytest tests/ -v
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Integration tests (require SSH access):
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
SSH_AUTO_FORWARD_TEST_HOST=hetzner uv run pytest tests_integration/ -v
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The integration tests:
|
|
162
|
+
- Test that remote ports are forwarded to the same local port when available
|
|
163
|
+
- Test that ports increment by 1 when the local port is busy
|
|
164
|
+
- Test auto-detection of new ports
|
|
165
|
+
- Test auto-cleanup when remote ports close
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# SSH Auto Port Forwarder
|
|
2
|
+
|
|
3
|
+
Automatically detect and forward ports from a remote SSH server to your local machine. Similar to VS Code's port forwarding feature, but fully automatic.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Automatically discovers listening ports on the remote server
|
|
8
|
+
- Shows process names for each forwarded port
|
|
9
|
+
- Forwards ports to your local machine via SSH tunneling
|
|
10
|
+
- Handles port conflicts by finding alternative local ports
|
|
11
|
+
- Auto-detects new ports and starts forwarding
|
|
12
|
+
- Auto-detects closed ports and stops forwarding
|
|
13
|
+
- Terminal title shows tunnel count
|
|
14
|
+
- Runs in the background with status updates
|
|
15
|
+
- Reads connection details from your SSH config
|
|
16
|
+
- Skips well-known ports (< 1000) by default
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
### With uv (recommended):
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uvx ssh-auto-forward hetzner
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Install locally:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd portforwards
|
|
30
|
+
uv sync
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This installs the `ssh-auto-forward` command.
|
|
34
|
+
|
|
35
|
+
### Local development:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
make run ARGS=hetzner
|
|
39
|
+
make run ARGS="hetzner -v"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
### Basic usage - uses host from your SSH config:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ssh-auto-forward hetzner
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Options:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
-v, --verbose Enable verbose logging
|
|
54
|
+
-i, --interval SECS Scan interval in seconds (default: 5)
|
|
55
|
+
-p, --port-range MIN:MAX Local port range for remapping (default: 3000:10000)
|
|
56
|
+
-s, --skip PORTS Comma-separated ports to skip (default: all ports < 1000)
|
|
57
|
+
-c, --config PATH Path to SSH config file
|
|
58
|
+
--version Show version and exit
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Examples:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Scan every 3 seconds
|
|
65
|
+
ssh-auto-forward hetzner -i 3
|
|
66
|
+
|
|
67
|
+
# Use specific port range
|
|
68
|
+
ssh-auto-forward hetzner -p 4000:9000
|
|
69
|
+
|
|
70
|
+
# Skip specific ports
|
|
71
|
+
ssh-auto-forward hetzner -s 22,80,443
|
|
72
|
+
|
|
73
|
+
# Verbose mode
|
|
74
|
+
ssh-auto-forward hetzner -v
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## How it works
|
|
78
|
+
|
|
79
|
+
1. Connects to your remote server using your SSH config
|
|
80
|
+
2. Runs `ss -tlnp` on the remote to find listening ports
|
|
81
|
+
3. Creates SSH tunnels for each discovered port
|
|
82
|
+
4. Continuously monitors for new/closed ports
|
|
83
|
+
5. Handles port conflicts on your local machine
|
|
84
|
+
|
|
85
|
+
## Status messages
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
✓ Connected!
|
|
89
|
+
✓ Forwarding port 2999 (python3)
|
|
90
|
+
✓ Forwarding port 7681 (ttyd)
|
|
91
|
+
✓ Forwarding remote port 19840 -> local port 3000 (node)
|
|
92
|
+
✗ Remote port 2999 is no longer listening, stopping tunnel
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The terminal title also updates to show: `ssh-auto-forward: hetzner (18 tunnels active)`
|
|
96
|
+
|
|
97
|
+
## Testing
|
|
98
|
+
|
|
99
|
+
Start a test server on your remote machine:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
ssh hetzner "python3 -m http.server 9999 --bind 127.0.0.1 &"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then run `ssh-auto-forward hetzner` and you should see:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
✓ Forwarding remote port 9999 -> local port 3003 (python3)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Access it locally:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
curl http://localhost:3003/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Stopping
|
|
118
|
+
|
|
119
|
+
Press `Ctrl+C` to stop the forwarder and close all tunnels.
|
|
120
|
+
|
|
121
|
+
## Requirements
|
|
122
|
+
|
|
123
|
+
- Python 3.10+
|
|
124
|
+
- paramiko
|
|
125
|
+
- Remote server must have `ss` or `netstat` command available
|
|
126
|
+
|
|
127
|
+
## Tests
|
|
128
|
+
|
|
129
|
+
### Unit tests (run locally, no SSH required):
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
make test
|
|
133
|
+
# or
|
|
134
|
+
uv run pytest tests/ -v
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Integration tests (require SSH access):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
SSH_AUTO_FORWARD_TEST_HOST=hetzner uv run pytest tests_integration/ -v
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The integration tests:
|
|
144
|
+
- Test that remote ports are forwarded to the same local port when available
|
|
145
|
+
- Test that ports increment by 1 when the local port is busy
|
|
146
|
+
- Test auto-detection of new ports
|
|
147
|
+
- Test auto-cleanup when remote ports close
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ssh-auto-forward"
|
|
7
|
+
description = "Auto-forward SSH ports"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
license = {text = "WTFPL"}
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dynamic = ["version"]
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
"paramiko>=3.4.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
authors = [
|
|
18
|
+
{name = "alexe"}
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
keywords = ["ssh", "port-forwarding", "tunnel", "remote-development"]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 3 - Alpha",
|
|
24
|
+
"Intended Audience :: Developers",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
ssh-auto-forward = "ssh_auto_forward.cli:main"
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
37
|
+
"hatch",
|
|
38
|
+
"pytest",
|
|
39
|
+
"pytest-cov",
|
|
40
|
+
"ruff",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[tool.hatch.build.targets.wheel]
|
|
44
|
+
packages = ["ssh_auto_forward"]
|
|
45
|
+
|
|
46
|
+
[tool.hatch.version]
|
|
47
|
+
path = "ssh_auto_forward/__version__.py"
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
testpaths = ["tests"]
|
|
51
|
+
|
|
52
|
+
[tool.ruff]
|
|
53
|
+
line-length = 100
|
|
54
|
+
target-version = "py310"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.1"
|