tunnex 26.10.9.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.
- tunnex-26.10.9.1/LICENSE +21 -0
- tunnex-26.10.9.1/MANIFEST.in +5 -0
- tunnex-26.10.9.1/PKG-INFO +251 -0
- tunnex-26.10.9.1/README.md +211 -0
- tunnex-26.10.9.1/client/__init__.py +2 -0
- tunnex-26.10.9.1/client/client.py +245 -0
- tunnex-26.10.9.1/client/client_config.yaml.example +16 -0
- tunnex-26.10.9.1/client/constants.py +4 -0
- tunnex-26.10.9.1/client/control_bus.py +19 -0
- tunnex-26.10.9.1/client/dashboard.py +446 -0
- tunnex-26.10.9.1/client/database.py +72 -0
- tunnex-26.10.9.1/client/models.py +72 -0
- tunnex-26.10.9.1/client/static/index.html +1404 -0
- tunnex-26.10.9.1/client/static/js/api.js +99 -0
- tunnex-26.10.9.1/client/static/js/codegen.js +28 -0
- tunnex-26.10.9.1/client/static/js/main.js +88 -0
- tunnex-26.10.9.1/client/static/js/ui.js +626 -0
- tunnex-26.10.9.1/client/static/js/utils.js +79 -0
- tunnex-26.10.9.1/client/tunnel_client.py +751 -0
- tunnex-26.10.9.1/client/utils.py +106 -0
- tunnex-26.10.9.1/setup.cfg +4 -0
- tunnex-26.10.9.1/setup.py +45 -0
- tunnex-26.10.9.1/shared/__init__.py +6 -0
- tunnex-26.10.9.1/shared/protocol.py +104 -0
- tunnex-26.10.9.1/tunnex.egg-info/PKG-INFO +251 -0
- tunnex-26.10.9.1/tunnex.egg-info/SOURCES.txt +28 -0
- tunnex-26.10.9.1/tunnex.egg-info/dependency_links.txt +1 -0
- tunnex-26.10.9.1/tunnex.egg-info/entry_points.txt +2 -0
- tunnex-26.10.9.1/tunnex.egg-info/requires.txt +10 -0
- tunnex-26.10.9.1/tunnex.egg-info/top_level.txt +2 -0
tunnex-26.10.9.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Tunnex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tunnex
|
|
3
|
+
Version: 26.10.9.1
|
|
4
|
+
Summary: Expose local HTTP, WebSocket, TCP and UDP services at a public *.tunnex.org address
|
|
5
|
+
Home-page: https://tunnex.org
|
|
6
|
+
Author: Tunnex
|
|
7
|
+
Author-email: dev@tunnex.org
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Source, https://gitlab.com/homycoder/tunnex
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Internet :: Proxy Servers
|
|
14
|
+
Classifier: Topic :: Software Development
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: click>=8.0.0
|
|
19
|
+
Requires-Dist: rich>=13.0.0
|
|
20
|
+
Requires-Dist: websockets>=12.0
|
|
21
|
+
Requires-Dist: httpx>=0.25.0
|
|
22
|
+
Requires-Dist: fastapi>=0.104.0
|
|
23
|
+
Requires-Dist: uvicorn>=0.24.0
|
|
24
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
25
|
+
Requires-Dist: aiosqlite>=0.19.0
|
|
26
|
+
Requires-Dist: pydantic>=2.0.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: author-email
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: description-content-type
|
|
33
|
+
Dynamic: home-page
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
Dynamic: project-url
|
|
37
|
+
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
40
|
+
|
|
41
|
+
# Tunnex
|
|
42
|
+
|
|
43
|
+
Expose local services to the internet through public domains. Supports HTTP/HTTPS, WebSocket, TCP and UDP.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
localhost:3000 → https://my-app.tunnex.org
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- **HTTP/HTTPS** — proxy web applications with automatic TLS
|
|
52
|
+
- **WebSocket** — full WS support (HMR, Socket.IO, chats)
|
|
53
|
+
- **TCP** — tunnels for databases, SSH and any TCP service
|
|
54
|
+
- **UDP** — tunnels for VoIP, game servers, IoT
|
|
55
|
+
- **Web dashboard** — live view of requests and TCP/UDP streams, settings management
|
|
56
|
+
- **Custom subdomains** — `your-name.tunnex.org`
|
|
57
|
+
- **Rate limiting** — on both the client and the server
|
|
58
|
+
- **Custom response** — stub mode with a configurable response
|
|
59
|
+
- **Replay** — resend HTTP requests from the dashboard
|
|
60
|
+
|
|
61
|
+
## Quick start
|
|
62
|
+
|
|
63
|
+
### Install
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install tunnex
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Run
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
tunnex --port 3000
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Once started:
|
|
76
|
+
- Public URL: `https://<subdomain>.tunnex.org`
|
|
77
|
+
- Dashboard: `http://127.0.0.1:8080`
|
|
78
|
+
|
|
79
|
+
Default server: `wss://connect.tunnex.org` (override with `--server`).
|
|
80
|
+
|
|
81
|
+
### CLI options
|
|
82
|
+
|
|
83
|
+
| Option | Description | Default |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `--port, -p` | Local application port | — (required) |
|
|
86
|
+
| `--dashboard-port, -d` | Dashboard port | `8080` |
|
|
87
|
+
| `--server, -s` | Tunnel server URL | `wss://connect.tunnex.org` |
|
|
88
|
+
| `--config` | Path to the client config | — |
|
|
89
|
+
|
|
90
|
+
### Subcommands
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
tunnex start --port 3000 # start (default)
|
|
94
|
+
tunnex list # list registered subdomains
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Architecture
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
┌──────────────┐ ┌───────────────┐ WebSocket (TLS) ┌───────────────┐
|
|
101
|
+
│ Your app │◄──────────────────►│ Tunnex client │◄─────────────────────►│ Tunnex server │
|
|
102
|
+
│ :3000 │ localhost proxy │ (Python) │ encrypted tunnel │ │
|
|
103
|
+
└──────────────┘ └───────────────┘ └───────┬───────┘
|
|
104
|
+
│ HTTPS/TCP/UDP
|
|
105
|
+
▼
|
|
106
|
+
┌───────────────┐
|
|
107
|
+
│ Users │
|
|
108
|
+
│ (internet) │
|
|
109
|
+
└───────────────┘
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Tech stack
|
|
113
|
+
|
|
114
|
+
| Component | Technologies |
|
|
115
|
+
|---|---|
|
|
116
|
+
| Server | Python 3.10+, FastAPI, Uvicorn, SQLAlchemy, aiosqlite |
|
|
117
|
+
| Client | Python 3.10+, websockets, httpx, Click, Rich |
|
|
118
|
+
| Protocol | WebSocket + JSON, Base64 for binary data |
|
|
119
|
+
| Deployment | Docker, Nginx, GitLab CI/CD |
|
|
120
|
+
| Database | SQLite (client), SQLite/PostgreSQL (server) |
|
|
121
|
+
|
|
122
|
+
## Dashboard
|
|
123
|
+
|
|
124
|
+
Local dashboard at `http://127.0.0.1:8080`:
|
|
125
|
+
|
|
126
|
+
- **Requests** — live list of HTTP requests, filtering by method/status, URL search, headers and bodies
|
|
127
|
+
- **Replay** — resend a request, optionally with modified parameters
|
|
128
|
+
- **TCP** — active TCP streams, hex view, send data, close connections
|
|
129
|
+
- **UDP** — UDP events, packet view (hex/text), send packets
|
|
130
|
+
- **Settings** — subdomain, local port, rate limit, custom response
|
|
131
|
+
- **Status** — connection state, public URL, uptime, errors
|
|
132
|
+
|
|
133
|
+
Updates arrive in real time over WebSocket.
|
|
134
|
+
|
|
135
|
+
## Server deployment
|
|
136
|
+
|
|
137
|
+
### Domain layout
|
|
138
|
+
|
|
139
|
+
| Host | Purpose |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `tunnex.org` | Landing page (`www` redirects here) |
|
|
142
|
+
| `connect.tunnex.org` | Control endpoint the client connects to (`/tunnel/connect`, `/api/*`) |
|
|
143
|
+
| `*.tunnex.org` | Public tunnels |
|
|
144
|
+
|
|
145
|
+
DNS is hosted on Cloudflare. All records are **DNS-only** (not proxied): tunnels use raw TCP/UDP
|
|
146
|
+
ports and second-level wildcards that the Cloudflare proxy cannot serve. Reserved subdomains
|
|
147
|
+
(`www`, `connect`, `api`, `mail`, …) cannot be claimed by tunnels.
|
|
148
|
+
|
|
149
|
+
### Bootstrap a fresh host
|
|
150
|
+
|
|
151
|
+
[deploy/bootstrap-server.sh](deploy/bootstrap-server.sh) prepares an Ubuntu 24.04 host: installs Docker,
|
|
152
|
+
Nginx, certbot and ufw, issues a wildcard Let's Encrypt certificate for `tunnex.org` + `*.tunnex.org`
|
|
153
|
+
via the `dns-cloudflare` plugin, installs [deploy/nginx/tunnex.conf](deploy/nginx/tunnex.conf) and
|
|
154
|
+
[deploy/server-config.yaml](deploy/server-config.yaml), and opens ports 22, 80, 443 and 45000–46000 (TCP/UDP).
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
CF_API_TOKEN=<token with Zone:DNS:Edit> ./deploy/bootstrap-server.sh root@<host>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Certificates renew automatically via `certbot.timer`; Nginx is reloaded after renewal.
|
|
161
|
+
|
|
162
|
+
### Docker
|
|
163
|
+
|
|
164
|
+
The server container is started by CI, equivalent to:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
docker run -d \
|
|
168
|
+
--name tunnex-server \
|
|
169
|
+
--restart unless-stopped \
|
|
170
|
+
--network host \
|
|
171
|
+
-v /opt/tunnex/config.yaml:/app/config.yaml:ro \
|
|
172
|
+
-v /opt/tunnex/certs:/app/certs:ro \
|
|
173
|
+
-v /opt/tunnex/data:/app/data \
|
|
174
|
+
-e SERVER_CONFIG=/app/config.yaml \
|
|
175
|
+
registry.gitlab.com/homycoder/tunnex/server:latest
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Server requirements
|
|
179
|
+
|
|
180
|
+
- Public IP address
|
|
181
|
+
- Domain with a wildcard DNS record (`*.example.com`)
|
|
182
|
+
- Reverse proxy (Nginx) for TLS termination
|
|
183
|
+
- Open ports: 80, 443, TCP/UDP range 45000–46000
|
|
184
|
+
|
|
185
|
+
## CI/CD (GitLab)
|
|
186
|
+
|
|
187
|
+
### Pipelines
|
|
188
|
+
|
|
189
|
+
**On changes to `server_/` or `shared/`:**
|
|
190
|
+
1. Build the Docker image and push it to the GitLab Container Registry
|
|
191
|
+
2. Deploy to the server (pull + restart the container)
|
|
192
|
+
|
|
193
|
+
**On changes to `client/`, `shared/`, `setup.py`:**
|
|
194
|
+
1. Bump the version (`YY.MM.DD.patch`)
|
|
195
|
+
2. Build wheel + sdist
|
|
196
|
+
3. Publish to PyPI
|
|
197
|
+
|
|
198
|
+
**On changes to `landing/`:** rsync to `/opt/tunnex/landing` on the server.
|
|
199
|
+
|
|
200
|
+
### CI/CD variables
|
|
201
|
+
|
|
202
|
+
**Server deployment** (GitLab → Settings → CI/CD → Variables):
|
|
203
|
+
- `SSH_PRIVATE_KEY` — SSH private key for deployment
|
|
204
|
+
- `SSH_USER` — server user
|
|
205
|
+
- `SERVER_HOST` — server address
|
|
206
|
+
|
|
207
|
+
**PyPI publishing:**
|
|
208
|
+
- `PYPI_USERNAME` — `__token__`
|
|
209
|
+
- `PYPI_PASSWORD` — PyPI API token
|
|
210
|
+
|
|
211
|
+
## Development
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
make install-dev # dev tools (ruff, black, mypy)
|
|
215
|
+
make lint # lint (ruff)
|
|
216
|
+
make fmt # format (black)
|
|
217
|
+
make mypy # type check
|
|
218
|
+
make test # tests
|
|
219
|
+
make build-client # build the client package
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Project layout
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
├── client/ # tunnel client
|
|
226
|
+
│ ├── client.py # CLI (Click)
|
|
227
|
+
│ ├── tunnel_client.py # tunnel logic
|
|
228
|
+
│ ├── dashboard.py # FastAPI dashboard
|
|
229
|
+
│ ├── models.py # SQLAlchemy models
|
|
230
|
+
│ └── static/ # dashboard frontend
|
|
231
|
+
├── server_/ # tunnel server
|
|
232
|
+
│ ├── main.py # FastAPI + WS + HTTP proxy
|
|
233
|
+
│ ├── tunnel_manager.py # tunnel registry
|
|
234
|
+
│ ├── tcp_udp_manager.py # TCP/UDP manager
|
|
235
|
+
│ ├── models.py # SQLAlchemy models
|
|
236
|
+
│ └── Dockerfile
|
|
237
|
+
├── shared/ # shared code
|
|
238
|
+
│ └── protocol.py # protocol message types
|
|
239
|
+
├── landing/ # tunnex.org landing page
|
|
240
|
+
├── deploy/ # server bootstrap, Nginx and server config
|
|
241
|
+
├── learn/ # step-by-step walkthroughs of the protocol
|
|
242
|
+
└── setup.py # tunnex package
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Contact
|
|
246
|
+
|
|
247
|
+
dev@tunnex.org
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Tunnex
|
|
2
|
+
|
|
3
|
+
Expose local services to the internet through public domains. Supports HTTP/HTTPS, WebSocket, TCP and UDP.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
localhost:3000 → https://my-app.tunnex.org
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **HTTP/HTTPS** — proxy web applications with automatic TLS
|
|
12
|
+
- **WebSocket** — full WS support (HMR, Socket.IO, chats)
|
|
13
|
+
- **TCP** — tunnels for databases, SSH and any TCP service
|
|
14
|
+
- **UDP** — tunnels for VoIP, game servers, IoT
|
|
15
|
+
- **Web dashboard** — live view of requests and TCP/UDP streams, settings management
|
|
16
|
+
- **Custom subdomains** — `your-name.tunnex.org`
|
|
17
|
+
- **Rate limiting** — on both the client and the server
|
|
18
|
+
- **Custom response** — stub mode with a configurable response
|
|
19
|
+
- **Replay** — resend HTTP requests from the dashboard
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
### Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install tunnex
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Run
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
tunnex --port 3000
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Once started:
|
|
36
|
+
- Public URL: `https://<subdomain>.tunnex.org`
|
|
37
|
+
- Dashboard: `http://127.0.0.1:8080`
|
|
38
|
+
|
|
39
|
+
Default server: `wss://connect.tunnex.org` (override with `--server`).
|
|
40
|
+
|
|
41
|
+
### CLI options
|
|
42
|
+
|
|
43
|
+
| Option | Description | Default |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `--port, -p` | Local application port | — (required) |
|
|
46
|
+
| `--dashboard-port, -d` | Dashboard port | `8080` |
|
|
47
|
+
| `--server, -s` | Tunnel server URL | `wss://connect.tunnex.org` |
|
|
48
|
+
| `--config` | Path to the client config | — |
|
|
49
|
+
|
|
50
|
+
### Subcommands
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
tunnex start --port 3000 # start (default)
|
|
54
|
+
tunnex list # list registered subdomains
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Architecture
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
┌──────────────┐ ┌───────────────┐ WebSocket (TLS) ┌───────────────┐
|
|
61
|
+
│ Your app │◄──────────────────►│ Tunnex client │◄─────────────────────►│ Tunnex server │
|
|
62
|
+
│ :3000 │ localhost proxy │ (Python) │ encrypted tunnel │ │
|
|
63
|
+
└──────────────┘ └───────────────┘ └───────┬───────┘
|
|
64
|
+
│ HTTPS/TCP/UDP
|
|
65
|
+
▼
|
|
66
|
+
┌───────────────┐
|
|
67
|
+
│ Users │
|
|
68
|
+
│ (internet) │
|
|
69
|
+
└───────────────┘
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Tech stack
|
|
73
|
+
|
|
74
|
+
| Component | Technologies |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Server | Python 3.10+, FastAPI, Uvicorn, SQLAlchemy, aiosqlite |
|
|
77
|
+
| Client | Python 3.10+, websockets, httpx, Click, Rich |
|
|
78
|
+
| Protocol | WebSocket + JSON, Base64 for binary data |
|
|
79
|
+
| Deployment | Docker, Nginx, GitLab CI/CD |
|
|
80
|
+
| Database | SQLite (client), SQLite/PostgreSQL (server) |
|
|
81
|
+
|
|
82
|
+
## Dashboard
|
|
83
|
+
|
|
84
|
+
Local dashboard at `http://127.0.0.1:8080`:
|
|
85
|
+
|
|
86
|
+
- **Requests** — live list of HTTP requests, filtering by method/status, URL search, headers and bodies
|
|
87
|
+
- **Replay** — resend a request, optionally with modified parameters
|
|
88
|
+
- **TCP** — active TCP streams, hex view, send data, close connections
|
|
89
|
+
- **UDP** — UDP events, packet view (hex/text), send packets
|
|
90
|
+
- **Settings** — subdomain, local port, rate limit, custom response
|
|
91
|
+
- **Status** — connection state, public URL, uptime, errors
|
|
92
|
+
|
|
93
|
+
Updates arrive in real time over WebSocket.
|
|
94
|
+
|
|
95
|
+
## Server deployment
|
|
96
|
+
|
|
97
|
+
### Domain layout
|
|
98
|
+
|
|
99
|
+
| Host | Purpose |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `tunnex.org` | Landing page (`www` redirects here) |
|
|
102
|
+
| `connect.tunnex.org` | Control endpoint the client connects to (`/tunnel/connect`, `/api/*`) |
|
|
103
|
+
| `*.tunnex.org` | Public tunnels |
|
|
104
|
+
|
|
105
|
+
DNS is hosted on Cloudflare. All records are **DNS-only** (not proxied): tunnels use raw TCP/UDP
|
|
106
|
+
ports and second-level wildcards that the Cloudflare proxy cannot serve. Reserved subdomains
|
|
107
|
+
(`www`, `connect`, `api`, `mail`, …) cannot be claimed by tunnels.
|
|
108
|
+
|
|
109
|
+
### Bootstrap a fresh host
|
|
110
|
+
|
|
111
|
+
[deploy/bootstrap-server.sh](deploy/bootstrap-server.sh) prepares an Ubuntu 24.04 host: installs Docker,
|
|
112
|
+
Nginx, certbot and ufw, issues a wildcard Let's Encrypt certificate for `tunnex.org` + `*.tunnex.org`
|
|
113
|
+
via the `dns-cloudflare` plugin, installs [deploy/nginx/tunnex.conf](deploy/nginx/tunnex.conf) and
|
|
114
|
+
[deploy/server-config.yaml](deploy/server-config.yaml), and opens ports 22, 80, 443 and 45000–46000 (TCP/UDP).
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
CF_API_TOKEN=<token with Zone:DNS:Edit> ./deploy/bootstrap-server.sh root@<host>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Certificates renew automatically via `certbot.timer`; Nginx is reloaded after renewal.
|
|
121
|
+
|
|
122
|
+
### Docker
|
|
123
|
+
|
|
124
|
+
The server container is started by CI, equivalent to:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
docker run -d \
|
|
128
|
+
--name tunnex-server \
|
|
129
|
+
--restart unless-stopped \
|
|
130
|
+
--network host \
|
|
131
|
+
-v /opt/tunnex/config.yaml:/app/config.yaml:ro \
|
|
132
|
+
-v /opt/tunnex/certs:/app/certs:ro \
|
|
133
|
+
-v /opt/tunnex/data:/app/data \
|
|
134
|
+
-e SERVER_CONFIG=/app/config.yaml \
|
|
135
|
+
registry.gitlab.com/homycoder/tunnex/server:latest
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Server requirements
|
|
139
|
+
|
|
140
|
+
- Public IP address
|
|
141
|
+
- Domain with a wildcard DNS record (`*.example.com`)
|
|
142
|
+
- Reverse proxy (Nginx) for TLS termination
|
|
143
|
+
- Open ports: 80, 443, TCP/UDP range 45000–46000
|
|
144
|
+
|
|
145
|
+
## CI/CD (GitLab)
|
|
146
|
+
|
|
147
|
+
### Pipelines
|
|
148
|
+
|
|
149
|
+
**On changes to `server_/` or `shared/`:**
|
|
150
|
+
1. Build the Docker image and push it to the GitLab Container Registry
|
|
151
|
+
2. Deploy to the server (pull + restart the container)
|
|
152
|
+
|
|
153
|
+
**On changes to `client/`, `shared/`, `setup.py`:**
|
|
154
|
+
1. Bump the version (`YY.MM.DD.patch`)
|
|
155
|
+
2. Build wheel + sdist
|
|
156
|
+
3. Publish to PyPI
|
|
157
|
+
|
|
158
|
+
**On changes to `landing/`:** rsync to `/opt/tunnex/landing` on the server.
|
|
159
|
+
|
|
160
|
+
### CI/CD variables
|
|
161
|
+
|
|
162
|
+
**Server deployment** (GitLab → Settings → CI/CD → Variables):
|
|
163
|
+
- `SSH_PRIVATE_KEY` — SSH private key for deployment
|
|
164
|
+
- `SSH_USER` — server user
|
|
165
|
+
- `SERVER_HOST` — server address
|
|
166
|
+
|
|
167
|
+
**PyPI publishing:**
|
|
168
|
+
- `PYPI_USERNAME` — `__token__`
|
|
169
|
+
- `PYPI_PASSWORD` — PyPI API token
|
|
170
|
+
|
|
171
|
+
## Development
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
make install-dev # dev tools (ruff, black, mypy)
|
|
175
|
+
make lint # lint (ruff)
|
|
176
|
+
make fmt # format (black)
|
|
177
|
+
make mypy # type check
|
|
178
|
+
make test # tests
|
|
179
|
+
make build-client # build the client package
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Project layout
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
├── client/ # tunnel client
|
|
186
|
+
│ ├── client.py # CLI (Click)
|
|
187
|
+
│ ├── tunnel_client.py # tunnel logic
|
|
188
|
+
│ ├── dashboard.py # FastAPI dashboard
|
|
189
|
+
│ ├── models.py # SQLAlchemy models
|
|
190
|
+
│ └── static/ # dashboard frontend
|
|
191
|
+
├── server_/ # tunnel server
|
|
192
|
+
│ ├── main.py # FastAPI + WS + HTTP proxy
|
|
193
|
+
│ ├── tunnel_manager.py # tunnel registry
|
|
194
|
+
│ ├── tcp_udp_manager.py # TCP/UDP manager
|
|
195
|
+
│ ├── models.py # SQLAlchemy models
|
|
196
|
+
│ └── Dockerfile
|
|
197
|
+
├── shared/ # shared code
|
|
198
|
+
│ └── protocol.py # protocol message types
|
|
199
|
+
├── landing/ # tunnex.org landing page
|
|
200
|
+
├── deploy/ # server bootstrap, Nginx and server config
|
|
201
|
+
├── learn/ # step-by-step walkthroughs of the protocol
|
|
202
|
+
└── setup.py # tunnex package
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Contact
|
|
206
|
+
|
|
207
|
+
dev@tunnex.org
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
MIT
|