|
1 | 1 | # BackChannel Server |
2 | 2 |
|
3 | | -A FastAPI application with JWT authentication, SQLAlchemy ORM, and Docker support. |
| 3 | +BackChannel is a web application what provides centralized remote control for connected clients, and monitors their status in real-time. |
| 4 | + |
| 5 | +### Screenshots |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +### Architecture |
| 12 | +```mermaid |
| 13 | +architecture-beta |
| 14 | + group server[Server] |
| 15 | + group client[Client] |
| 16 | + group backlink_server[BackLink] in server |
| 17 | +
|
| 18 | + service laptop(server)[Laptop] |
| 19 | + service http_port(server)[http port] in server |
| 20 | + service forwarding_port1(server)[forwarding port] in server |
| 21 | + service forwarding_port2(server)[forwarding port] in server |
| 22 | + service web_app(server)[WebApp] in backlink_server |
| 23 | + service forwarder(server)[Forwarder] in backlink_server |
| 24 | + service blacklink_client(server)[BlackLink] in client |
| 25 | + service ssh_port(server)[SSH port] in client |
| 26 | +
|
| 27 | + laptop:R --> L:http_port |
| 28 | + laptop:B --> L:forwarding_port1 |
| 29 | + http_port:R --> L:web_app |
| 30 | + forwarding_port1:R --> L:forwarder |
| 31 | + forwarder:R <--> L:forwarding_port2 |
| 32 | + forwarding_port2:R <--> L:blacklink_client |
| 33 | + blacklink_client:R <--> L:ssh_port |
4 | 34 |
|
5 | | -## Features |
6 | | - |
7 | | -- 🚀 FastAPI web framework |
8 | | -- 🔐 Cookie-based authentication with master password |
9 | | -- 🍪 Secure session management |
10 | | -- 📦 Poetry dependency management |
11 | | -- 🐳 Docker containerization |
12 | | -- 📊 API documentation with Swagger UI |
13 | | - |
14 | | -## Project Structure |
15 | | - |
16 | | -``` |
17 | | -BackChannelServer/ |
18 | | -├── app/ |
19 | | -│ ├── core/ |
20 | | -│ │ ├── __init__.py |
21 | | -│ │ ├── config.py # App configuration |
22 | | -│ │ ├── database.py # Database setup |
23 | | -│ │ └── security.py # JWT & password utilities |
24 | | -│ ├── models/ |
25 | | -│ │ ├── __init__.py |
26 | | -│ │ └── user.py # SQLAlchemy models |
27 | | -│ ├── routers/ |
28 | | -│ │ ├── __init__.py |
29 | | -│ │ ├── auth.py # Authentication endpoints |
30 | | -│ │ └── client.py # Client endpoints |
31 | | -│ ├── schemas/ |
32 | | -│ │ ├── __init__.py |
33 | | -│ │ └── user.py # Pydantic schemas |
34 | | -│ ├── __init__.py |
35 | | -│ └── main.py # FastAPI app |
36 | | -├── Dockerfile |
37 | | -├── .dockerignore |
38 | | -├── .gitignore |
39 | | -└── pyproject.toml |
40 | 35 | ``` |
41 | 36 |
|
42 | | -## Quick Start |
43 | 37 |
|
44 | | -### Using Poetry (Recommended) |
45 | | - |
46 | | -1. **Install dependencies:** |
47 | | - ```bash |
48 | | - poetry install |
49 | | - ``` |
50 | | - |
51 | | -2. **Run the application:** |
52 | | - ```bash |
53 | | - poetry run python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload |
54 | | - ``` |
55 | | - |
56 | | -3. **Access the API:** |
57 | | - - API Documentation: http://localhost:8000/docs |
58 | | - - ReDoc: http://localhost:8000/redoc |
| 38 | +Sequence of monitoring: |
| 39 | +```mermaid |
| 40 | +sequenceDiagram |
| 41 | + actor User |
| 42 | + participant Server |
| 43 | + participant Client |
| 44 | + loop 30 sec |
| 45 | + Client->>Server: Get order |
| 46 | + activate Server |
| 47 | + Server-->>Client: Return empty |
| 48 | + deactivate Server |
| 49 | + Client->>Server: Put metrics |
| 50 | + end |
| 51 | + User->>Server: Get all client data |
| 52 | + activate Server |
| 53 | + Server-->>User: return |
| 54 | + deactivate Server |
| 55 | +``` |
59 | 56 |
|
60 | | -### Using Docker |
61 | 57 |
|
62 | | -1. **Build the image:** |
63 | | - ```bash |
64 | | - docker build -t backchannel-server . |
65 | | - ``` |
| 58 | +Sequence of connecting: |
| 59 | +```mermaid |
| 60 | +sequenceDiagram |
| 61 | + actor User |
| 62 | + participant Server |
| 63 | + participant Client |
| 64 | + Client->>Server: Get order |
| 65 | + activate Server |
| 66 | + Server-->>Client: Return empty |
| 67 | + Client->>Server: Put metrics |
| 68 | + deactivate Server |
| 69 | + User->>Server: Initiate connection |
| 70 | + activate Server |
| 71 | + Client->>Server: Get order |
| 72 | + activate Server |
| 73 | + Server-->>Client: Return opened port |
| 74 | + deactivate Server |
| 75 | + Client->>Server: Connect to opened port |
| 76 | + Server-->>User: Return opened port |
| 77 | + User<<->>Client: Two way connection |
| 78 | + deactivate Server |
| 79 | +``` |
66 | 80 |
|
67 | | -2. **Run the container:** |
68 | | - ```bash |
69 | | - docker run -p 8000:8000 backchannel-server |
70 | | - ``` |
| 81 | +## Getting started |
71 | 82 |
|
72 | | -## Authentication |
| 83 | +### Generate Secret Key |
73 | 84 |
|
74 | | -The application uses a simple master password for authentication: |
75 | | -- **Master Password:** `admin123` (configurable via environment) |
| 85 | +Pull the latest docker image: |
76 | 86 |
|
77 | | -### Password Hashing |
| 87 | +```bash |
| 88 | +docker pull ghcr.io/radaron/backchannel:latest |
| 89 | +``` |
78 | 90 |
|
79 | | -For enhanced security, you can use hashed passwords instead of plain text: |
| 91 | +Or use docker-compose: |
| 92 | + |
| 93 | +```yaml |
| 94 | +version: '3.8' |
| 95 | +services: |
| 96 | + backchannel: |
| 97 | + image: ghcr.io/radaron/backchannel:latest |
| 98 | + ports: |
| 99 | + - "8000:8000" |
| 100 | + - 20000-20100:20000-20100 |
| 101 | + environment: |
| 102 | + - SECRET_KEY=your-secret-key |
| 103 | + - MASTER_PASSWORD_HASH=your-master-password-hash |
| 104 | + - ALLOWED_ORIGINS=* |
| 105 | + volumes: |
| 106 | + - ./data:/app/data |
| 107 | +``` |
80 | 108 |
|
81 | | -#### Generate Password Hash |
82 | 109 |
|
83 | | -**Option 1: Using Poetry scripts (recommended)** |
84 | | -```bash |
85 | | -# Hash any password |
86 | | -poetry run hash-password admin123 |
87 | 110 |
|
88 | | -# Hash the current master password from config |
89 | | -poetry run hash-master-password |
90 | | -``` |
| 111 | +For production deployment, you need to generate a secure secret key: |
91 | 112 |
|
92 | | -**Option 1b: Using Make commands** |
93 | 113 | ```bash |
94 | | -make hash-password |
| 114 | +make generate-secret |
95 | 115 | ``` |
96 | 116 |
|
97 | | -#### Using Hashed Passwords |
| 117 | +This will generate a UUID-based secret key that you should set in your environment. |
| 118 | +### Generate Password Hash |
98 | 119 |
|
99 | | -Set the hashed password in your `.env` file: |
100 | 120 | ```bash |
101 | | -MASTER_PASSWORD_HASH=$2b$12$example.hash.here |
102 | | -# When MASTER_PASSWORD_HASH is set, MASTER_PASSWORD is ignored for authentication |
| 121 | +make hash-password |
103 | 122 | ``` |
| 123 | +The script will prompt you to enter a password and return a base64-encoded bcrypt hash. Set this in your environment. |
104 | 124 |
|
105 | | -### API Endpoints |
106 | | - |
107 | | -#### Authentication (`/api/v1/auth`) |
108 | | - |
109 | | -- `POST /api/v1/auth/login` - Login with master password (sets session cookie) |
110 | | -- `POST /api/v1/auth/logout` - Logout and clear session cookie |
111 | | -- `GET /api/v1/auth/me` - Get current session info |
112 | | -- `GET /api/v1/auth/status` - Check authentication status |
113 | | -- `POST /api/v1/auth/hash-password` - Hash a password (requires authentication) |
| 125 | +## Development |
114 | 126 |
|
115 | | -#### Client (`/api/v1/client`) |
| 127 | +### Prerequisites |
116 | 128 |
|
117 | | -- `GET /api/v1/client/profile` - Get session profile |
118 | | -- `GET /api/v1/client/dashboard` - Get dashboard data |
119 | | -- `GET /api/v1/client/stats` - Get session statistics |
120 | | -- `GET /api/v1/client/protected` - Example protected endpoint |
| 129 | +- Python 3.12+ |
| 130 | +- [uv](https://docs.astral.sh/uv/) package manager |
| 131 | +- Node.js 18+ (for frontend development) |
| 132 | +- Docker or OCI-compatible container runtime |
121 | 133 |
|
122 | | -### Example Usage |
| 134 | +### Development Setup |
123 | 135 |
|
124 | | -1. **Login with master password:** |
| 136 | +1. **Install dependencies:** |
125 | 137 | ```bash |
126 | | - curl -c cookies.txt -X POST "http://localhost:8000/api/v1/auth/login" \ |
127 | | - -H "Content-Type: application/json" \ |
128 | | - -d '{"password": "admin123"}' |
| 138 | + make install |
129 | 139 | ``` |
130 | 140 |
|
131 | | -2. **Access protected endpoint:** |
| 141 | +2. **Generate security credentials:** |
132 | 142 | ```bash |
133 | | - curl -b cookies.txt -X GET "http://localhost:8000/api/v1/client/profile" |
| 143 | + # Generate a secret key |
| 144 | + make generate-secret |
| 145 | + |
| 146 | + # Generate password hash |
| 147 | + make hash-password |
134 | 148 | ``` |
135 | 149 |
|
136 | | -3. **Check authentication status:** |
| 150 | +3. **Set up environment:** |
137 | 151 | ```bash |
138 | | - curl -b cookies.txt -X GET "http://localhost:8000/api/v1/auth/status" |
| 152 | + cp backchannel.env.example backchannel.env |
| 153 | + # Edit backchannel.env with your generated credentials |
139 | 154 | ``` |
140 | 155 |
|
141 | | -4. **Logout:** |
| 156 | +4. **Build frontend and run the application:** |
142 | 157 | ```bash |
143 | | - curl -b cookies.txt -c cookies.txt -X POST "http://localhost:8000/api/v1/auth/logout" |
| 158 | + make up |
144 | 159 | ``` |
145 | 160 |
|
| 161 | +5. **Access the application:** |
| 162 | + - http://localhost:8000 |
| 163 | + |
146 | 164 | ## Configuration |
147 | 165 |
|
148 | | -Configuration can be customized via environment variables or the `.env` file: |
| 166 | +Configuration can be customized via environment variables or the `backchannel.env` file: |
149 | 167 |
|
150 | | -- `SECRET_KEY` - Session secret key (change in production!) |
151 | | -- `MASTER_PASSWORD` - Master password for authentication (default: admin123) |
| 168 | +- `SECRET_KEY` - Session secret key (required for production) |
152 | 169 | - `MASTER_PASSWORD_HASH` - Hashed master password (preferred over plain text) |
153 | 170 | - `SESSION_EXPIRE_MINUTES` - Session expiration time (default: 60 minutes) |
154 | 171 | - `COOKIE_NAME` - Session cookie name (default: backchannel_session) |
155 | | - |
156 | | -## Development |
157 | | - |
158 | | -### Install development dependencies: |
159 | | -```bash |
160 | | -poetry install --with dev |
161 | | -``` |
162 | | - |
163 | | -### Code formatting: |
164 | | -```bash |
165 | | -poetry run black app/ |
166 | | -poetry run isort app/ |
167 | | -``` |
168 | | - |
169 | | -### Type checking: |
170 | | -```bash |
171 | | -poetry run mypy app/ |
172 | | -``` |
173 | | - |
174 | | -### Available Make Commands: |
175 | | -```bash |
176 | | -make install # Install dependencies |
177 | | -make run # Run FastAPI server in development mode |
178 | | -make hash-password PASSWORD=yourpass # Hash any password |
179 | | -make hash-master # Hash current master password from config |
180 | | -make format # Format code with isort and black |
181 | | -make up # Run with Docker Compose |
182 | | -``` |
183 | | - |
184 | | -### Run tests: |
185 | | -```bash |
186 | | -poetry run pytest |
187 | | -``` |
188 | | - |
189 | | -## Docker Commands |
190 | | - |
191 | | -```bash |
192 | | -# Build image |
193 | | -docker build -t backchannel-server . |
194 | | - |
195 | | -# Run container |
196 | | -docker run -p 8000:8000 backchannel-server |
197 | | - |
198 | | -# Run with environment variables |
199 | | -docker run -p 8000:8000 -e SECRET_KEY=your-secret-key -e MASTER_PASSWORD=your-password backchannel-server |
200 | | - |
201 | | -# Run in background |
202 | | -docker run -d -p 8000:8000 --name backchannel backchannel-server |
203 | | -``` |
204 | | - |
205 | | -## License |
206 | | - |
207 | | -This project is open source and available under the [MIT License](LICENSE). |
| 172 | +- `ALLOWED_ORIGINS` - CORS allowed origins (default: "*") |
| 173 | +- `PORT_RANGE_START` - Start of port range for dynamic forwarding (default: 20000) |
| 174 | +- `PORT_RANGE_END` - End of port range for dynamic forwarding (default: 20100) |
| 175 | +- `LOCAL_ADDRESS` - Local address to bind (default: "0.0.0.0") |
| 176 | +- `CUSTOM_MESSAGES` - Custom connection instructions (default provided) |
0 commit comments