@chenpu17/tcpmapping 2.0.0 → 2.1.0
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.
- package/README.md +148 -66
- package/bin/tcpmapping.js +131 -34
- package/package.json +2 -3
- package/public/dashboard.html +388 -125
- package/public/login.html +157 -67
- package/server.js +83 -20
- package/setup-password.js +19 -2
- package/config.json +0 -46
package/README.md
CHANGED
|
@@ -1,103 +1,185 @@
|
|
|
1
|
-
#
|
|
1
|
+
# TcpMapping
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TCP port forwarding server with WebUI management and real-time connection monitoring.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
TCP端口转发服务器,支持WebUI管理界面和实时连接监控。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **TCP协议端口转发** - 将TCP请求转发到后端服务器
|
|
9
|
-
- **多端口映射配置** - 同时支持多个端口转发规则
|
|
10
|
-
- **动态配置管理** - 通过WebUI实时添加/删除/启动/停止端口映射
|
|
11
|
-
- **连接监控** - 实时显示每个映射的连接数和流量统计
|
|
7
|
+
---
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
- 现代化响应式Web界面
|
|
15
|
-
- 实时系统状态监控(映射数、连接数、运行时间)
|
|
16
|
-
- 每个端口映射的连接数和流量统计
|
|
17
|
-
- 映射的启动/停止控制
|
|
9
|
+
## Features | 功能特性
|
|
18
10
|
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- bcrypt
|
|
24
|
-
- 自动生成的Session Secret
|
|
11
|
+
- **TCP Port Forwarding** - Forward TCP traffic to backend servers | TCP端口转发
|
|
12
|
+
- **Multiple Mappings** - Manage multiple forwarding rules simultaneously | 多端口映射
|
|
13
|
+
- **WebUI Management** - Modern web interface for real-time monitoring | WebUI管理界面
|
|
14
|
+
- **Connection Monitoring** - Real-time connection count and traffic statistics | 实时连接监控
|
|
15
|
+
- **Secure Authentication** - bcrypt password hashing, login protection | 安全认证
|
|
25
16
|
|
|
26
|
-
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Installation | 安装
|
|
20
|
+
|
|
21
|
+
### NPM Global Install (Recommended) | NPM全局安装(推荐)
|
|
27
22
|
|
|
28
|
-
### 安装
|
|
29
23
|
```bash
|
|
30
|
-
|
|
31
|
-
npm install
|
|
24
|
+
npm install -g @chenpu17/tcpmapping
|
|
32
25
|
|
|
33
|
-
# 设置管理员密码
|
|
34
|
-
|
|
26
|
+
tcpmapping setup-password # Set admin password | 设置管理员密码
|
|
27
|
+
tcpmapping init # Create config file | 创建配置文件
|
|
28
|
+
tcpmapping start # Start server | 启动服务
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Local Install | 本地安装
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
```bash
|
|
34
|
+
git clone https://github.com/chenpu17/TcpMapping.git
|
|
35
|
+
cd TcpMapping
|
|
36
|
+
npm install
|
|
37
|
+
npm run setup-password
|
|
37
38
|
npm start
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## CLI Commands | CLI命令
|
|
44
|
+
|
|
45
|
+
| Command | Description |
|
|
46
|
+
|---------|-------------|
|
|
47
|
+
| `tcpmapping start` | Start server in background | 后台启动服务 |
|
|
48
|
+
| `tcpmapping stop` | Stop server | 停止服务 |
|
|
49
|
+
| `tcpmapping restart` | Restart server | 重启服务 |
|
|
50
|
+
| `tcpmapping status` | Show status and config paths | 查看状态和配置路径 |
|
|
51
|
+
| `tcpmapping logs` | Show recent logs | 查看最近日志 |
|
|
52
|
+
| `tcpmapping logs -f` | Follow logs in real-time | 实时跟踪日志 |
|
|
53
|
+
| `tcpmapping setup-password` | Set admin password | 设置管理员密码 |
|
|
54
|
+
| `tcpmapping init` | Create config file | 创建配置文件 |
|
|
55
|
+
|
|
56
|
+
---
|
|
42
57
|
|
|
43
|
-
##
|
|
58
|
+
## WebUI
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
After starting, visit **http://localhost:9999**
|
|
61
|
+
|
|
62
|
+
启动后访问 **http://localhost:9999**
|
|
63
|
+
|
|
64
|
+
Default username | 默认用户名: `admin`
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Configuration | 配置
|
|
69
|
+
|
|
70
|
+
Config file location (priority order) | 配置文件位置(优先级):
|
|
71
|
+
1. `./config.json` - Current directory | 当前目录
|
|
72
|
+
2. `~/.tcpmapping/config.json` - User data directory | 用户数据目录
|
|
73
|
+
|
|
74
|
+
### Example | 示例
|
|
46
75
|
|
|
47
76
|
```json
|
|
48
77
|
{
|
|
49
78
|
"mappings": [
|
|
50
79
|
{
|
|
51
|
-
"name": "
|
|
80
|
+
"name": "web-server",
|
|
52
81
|
"listen": { "host": "0.0.0.0", "port": 8080 },
|
|
53
82
|
"target": { "host": "192.168.1.100", "port": 3000 }
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "database",
|
|
86
|
+
"listen": { "host": "127.0.0.1", "port": 3307 },
|
|
87
|
+
"target": { "host": "db.example.com", "port": 3306 }
|
|
54
88
|
}
|
|
55
89
|
],
|
|
56
|
-
"webui": { "
|
|
57
|
-
"logging": { "
|
|
90
|
+
"webui": { "port": 9999 },
|
|
91
|
+
"logging": { "level": "info" }
|
|
58
92
|
}
|
|
59
93
|
```
|
|
60
94
|
|
|
61
|
-
|
|
95
|
+
### Config Options | 配置项
|
|
96
|
+
|
|
97
|
+
| Option | Description |
|
|
98
|
+
|--------|-------------|
|
|
99
|
+
| `mappings[].name` | Mapping name | 映射名称 |
|
|
100
|
+
| `mappings[].listen.host` | Listen address (0.0.0.0 for all) | 监听地址 |
|
|
101
|
+
| `mappings[].listen.port` | Listen port | 监听端口 |
|
|
102
|
+
| `mappings[].target.host` | Target host IP or domain | 目标主机 |
|
|
103
|
+
| `mappings[].target.port` | Target port | 目标端口 |
|
|
104
|
+
| `webui.port` | WebUI port (default: 9999) | WebUI端口 |
|
|
105
|
+
| `logging.level` | Log level: debug/info/warn/error | 日志级别 |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Data Persistence | 数据持久化
|
|
110
|
+
|
|
111
|
+
User configuration is stored in `~/.tcpmapping/`:
|
|
112
|
+
|
|
113
|
+
用户配置存储在 `~/.tcpmapping/` 目录:
|
|
62
114
|
|
|
115
|
+
- `config.json` - Port mapping configuration | 端口映射配置
|
|
116
|
+
- `auth-config.json` - Authentication configuration | 认证配置
|
|
117
|
+
- `tcpmapping.log` - Log file | 日志文件
|
|
118
|
+
- `tcpmapping.pid` - PID file | PID文件
|
|
119
|
+
|
|
120
|
+
**Upgrading will NOT overwrite your configuration.**
|
|
121
|
+
|
|
122
|
+
**升级不会覆盖你的配置文件。**
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Security | 安全特性
|
|
127
|
+
|
|
128
|
+
- **Strong Password Policy** - 8+ chars, uppercase, lowercase, numbers | 强密码策略
|
|
129
|
+
- **Login Protection** - Lock after 5 failed attempts for 30 minutes | 登录保护
|
|
130
|
+
- **Session Timeout** - 24 hours auto expiration | 会话超时
|
|
131
|
+
- **Password Encryption** - bcrypt with 12 rounds | bcrypt加密
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## API
|
|
136
|
+
|
|
137
|
+
See [docs/API.md](docs/API.md) for API documentation.
|
|
138
|
+
|
|
139
|
+
详细API文档请参阅 [docs/API.md](docs/API.md)
|
|
140
|
+
|
|
141
|
+
### Quick Reference | 快速参考
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Health check (no auth) | 健康检查
|
|
145
|
+
curl http://localhost:9999/api/health
|
|
146
|
+
|
|
147
|
+
# Login | 登录
|
|
148
|
+
curl -X POST http://localhost:9999/api/login \
|
|
149
|
+
-H "Content-Type: application/json" \
|
|
150
|
+
-d '{"username":"admin","password":"YourPassword"}' \
|
|
151
|
+
-c cookies.txt
|
|
152
|
+
|
|
153
|
+
# Get mappings | 获取映射列表
|
|
154
|
+
curl http://localhost:9999/api/mappings -b cookies.txt
|
|
63
155
|
```
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
├── 功能总结.md # 功能清单
|
|
76
|
-
└── 安全配置说明.md # 安全指南
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## FAQ | 常见问题
|
|
160
|
+
|
|
161
|
+
### Forgot password? | 忘记密码?
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
tcpmapping setup-password
|
|
165
|
+
# or | 或
|
|
166
|
+
npm run reset-password
|
|
77
167
|
```
|
|
78
168
|
|
|
79
|
-
|
|
169
|
+
### Check if running? | 检查运行状态?
|
|
80
170
|
|
|
81
|
-
|
|
171
|
+
```bash
|
|
172
|
+
tcpmapping status
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Port already in use? | 端口被占用?
|
|
82
176
|
|
|
83
|
-
|
|
84
|
-
- `GET /api/health` - 健康检查(无需认证)
|
|
85
|
-
- `POST /api/login` - 登录
|
|
86
|
-
- `GET /api/mappings` - 获取映射列表(含连接数统计)
|
|
87
|
-
- `POST /api/mappings` - 添加映射
|
|
88
|
-
- `PUT /api/mappings/:id` - 更新映射
|
|
89
|
-
- `DELETE /api/mappings/:id` - 删除映射
|
|
90
|
-
- `POST /api/mappings/:id/start` - 启动映射
|
|
91
|
-
- `POST /api/mappings/:id/stop` - 停止映射
|
|
92
|
-
- `GET /api/connections` - 获取连接状态
|
|
93
|
-
- `GET /api/status` - 获取系统状态
|
|
177
|
+
Edit `webui.port` or `mappings[].listen.port` in config.json.
|
|
94
178
|
|
|
95
|
-
|
|
179
|
+
修改 config.json 中的 `webui.port` 或 `mappings[].listen.port`。
|
|
96
180
|
|
|
97
|
-
|
|
98
|
-
- **前端**: 原生HTML/CSS/JavaScript
|
|
99
|
-
- **安全**: bcrypt密码哈希, Session管理
|
|
181
|
+
---
|
|
100
182
|
|
|
101
|
-
## 许可证
|
|
183
|
+
## License | 许可证
|
|
102
184
|
|
|
103
|
-
MIT License
|
|
185
|
+
MIT License
|
package/bin/tcpmapping.js
CHANGED
|
@@ -6,8 +6,9 @@ const fs = require('fs');
|
|
|
6
6
|
const os = require('os');
|
|
7
7
|
|
|
8
8
|
const APP_NAME = 'tcpmapping';
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const DATA_DIR = path.join(os.homedir(), '.tcpmapping');
|
|
10
|
+
const PID_FILE = path.join(DATA_DIR, 'tcpmapping.pid');
|
|
11
|
+
const LOG_FILE = path.join(DATA_DIR, 'tcpmapping.log');
|
|
11
12
|
const SERVER_FILE = path.join(__dirname, '..', 'server.js');
|
|
12
13
|
const SETUP_PASSWORD_FILE = path.join(__dirname, '..', 'setup-password.js');
|
|
13
14
|
|
|
@@ -21,11 +22,52 @@ const colors = {
|
|
|
21
22
|
red: (text) => `\x1b[31m${text}\x1b[0m`,
|
|
22
23
|
yellow: (text) => `\x1b[33m${text}\x1b[0m`,
|
|
23
24
|
blue: (text) => `\x1b[34m${text}\x1b[0m`,
|
|
24
|
-
cyan: (text) => `\x1b[36m${text}\x1b[0m
|
|
25
|
+
cyan: (text) => `\x1b[36m${text}\x1b[0m`,
|
|
26
|
+
gray: (text) => `\x1b[90m${text}\x1b[0m`
|
|
25
27
|
};
|
|
26
28
|
|
|
29
|
+
// 确保数据目录存在
|
|
30
|
+
function ensureDataDir() {
|
|
31
|
+
if (!fs.existsSync(DATA_DIR)) {
|
|
32
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 获取配置文件路径(按优先级)
|
|
37
|
+
function getConfigPath() {
|
|
38
|
+
// 优先级1: 当前工作目录
|
|
39
|
+
const cwdPath = path.join(process.cwd(), 'config.json');
|
|
40
|
+
if (fs.existsSync(cwdPath)) {
|
|
41
|
+
return cwdPath;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 优先级2: 用户数据目录
|
|
45
|
+
const dataPath = path.join(DATA_DIR, 'config.json');
|
|
46
|
+
if (fs.existsSync(dataPath)) {
|
|
47
|
+
return dataPath;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 获取认证配置文件路径
|
|
54
|
+
function getAuthConfigPath() {
|
|
55
|
+
const cwdPath = path.join(process.cwd(), 'auth-config.json');
|
|
56
|
+
if (fs.existsSync(cwdPath)) {
|
|
57
|
+
return cwdPath;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const dataPath = path.join(DATA_DIR, 'auth-config.json');
|
|
61
|
+
if (fs.existsSync(dataPath)) {
|
|
62
|
+
return dataPath;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
27
68
|
// 检查进程是否运行
|
|
28
69
|
function isRunning() {
|
|
70
|
+
ensureDataDir();
|
|
29
71
|
if (!fs.existsSync(PID_FILE)) {
|
|
30
72
|
return false;
|
|
31
73
|
}
|
|
@@ -50,6 +92,17 @@ function start() {
|
|
|
50
92
|
return;
|
|
51
93
|
}
|
|
52
94
|
|
|
95
|
+
// 检查是否已初始化
|
|
96
|
+
const configPath = getConfigPath();
|
|
97
|
+
const authPath = getAuthConfigPath();
|
|
98
|
+
|
|
99
|
+
if (!authPath) {
|
|
100
|
+
console.log(colors.yellow('未设置管理员密码,请先运行:'));
|
|
101
|
+
console.log(colors.cyan(' tcpmapping setup-password'));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
ensureDataDir();
|
|
53
106
|
console.log(colors.blue(`Starting ${APP_NAME}...`));
|
|
54
107
|
|
|
55
108
|
const out = fs.openSync(LOG_FILE, 'a');
|
|
@@ -58,7 +111,7 @@ function start() {
|
|
|
58
111
|
const child = spawn('node', [SERVER_FILE], {
|
|
59
112
|
detached: true,
|
|
60
113
|
stdio: ['ignore', out, err],
|
|
61
|
-
cwd:
|
|
114
|
+
cwd: process.cwd() // 使用当前目录,以便server可以找到当前目录的config
|
|
62
115
|
});
|
|
63
116
|
|
|
64
117
|
fs.writeFileSync(PID_FILE, child.pid.toString());
|
|
@@ -66,7 +119,10 @@ function start() {
|
|
|
66
119
|
|
|
67
120
|
console.log(colors.green(`${APP_NAME} started successfully (PID: ${child.pid})`));
|
|
68
121
|
console.log(colors.cyan(`WebUI: http://localhost:9999`));
|
|
69
|
-
console.log(colors.
|
|
122
|
+
console.log(colors.gray(`Log file: ${LOG_FILE}`));
|
|
123
|
+
if (configPath) {
|
|
124
|
+
console.log(colors.gray(`Config: ${configPath}`));
|
|
125
|
+
}
|
|
70
126
|
}
|
|
71
127
|
|
|
72
128
|
// 停止服务
|
|
@@ -126,8 +182,14 @@ function restart() {
|
|
|
126
182
|
// 查看状态
|
|
127
183
|
function status() {
|
|
128
184
|
const pid = isRunning();
|
|
185
|
+
const configPath = getConfigPath();
|
|
186
|
+
const authPath = getAuthConfigPath();
|
|
187
|
+
|
|
188
|
+
console.log(colors.cyan('=== TcpMapping Status ===\n'));
|
|
189
|
+
|
|
190
|
+
// 服务状态
|
|
129
191
|
if (pid) {
|
|
130
|
-
console.log(colors.green(
|
|
192
|
+
console.log(colors.green(`Service: Running (PID: ${pid})`));
|
|
131
193
|
|
|
132
194
|
// 尝试获取健康状态
|
|
133
195
|
try {
|
|
@@ -138,23 +200,36 @@ function status() {
|
|
|
138
200
|
res.on('end', () => {
|
|
139
201
|
try {
|
|
140
202
|
const health = JSON.parse(data);
|
|
141
|
-
console.log(
|
|
142
|
-
console.log(
|
|
143
|
-
console.log(
|
|
144
|
-
console.log(colors.cyan(` Active Connections: ${health.activeConnections}`));
|
|
203
|
+
console.log(` Uptime: ${Math.floor(health.uptime / 60)} minutes`);
|
|
204
|
+
console.log(` Active Mappings: ${health.activeMappings}`);
|
|
205
|
+
console.log(` Active Connections: ${health.activeConnections}`);
|
|
145
206
|
} catch (e) {}
|
|
207
|
+
showPaths();
|
|
146
208
|
});
|
|
147
209
|
});
|
|
148
|
-
req.on('error', () =>
|
|
149
|
-
req.on('timeout', () => req.destroy());
|
|
150
|
-
} catch (e) {
|
|
210
|
+
req.on('error', () => showPaths());
|
|
211
|
+
req.on('timeout', () => { req.destroy(); showPaths(); });
|
|
212
|
+
} catch (e) {
|
|
213
|
+
showPaths();
|
|
214
|
+
}
|
|
151
215
|
} else {
|
|
152
|
-
console.log(colors.red(
|
|
216
|
+
console.log(colors.red('Service: Stopped'));
|
|
217
|
+
showPaths();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function showPaths() {
|
|
221
|
+
console.log('');
|
|
222
|
+
console.log(colors.cyan('=== Configuration ===\n'));
|
|
223
|
+
console.log(`Data Dir: ${DATA_DIR}`);
|
|
224
|
+
console.log(`Config: ${configPath || colors.yellow('Not found (run: tcpmapping init)')}`);
|
|
225
|
+
console.log(`Auth: ${authPath || colors.yellow('Not found (run: tcpmapping setup-password)')}`);
|
|
226
|
+
console.log(`Log: ${LOG_FILE}`);
|
|
153
227
|
}
|
|
154
228
|
}
|
|
155
229
|
|
|
156
230
|
// 查看日志
|
|
157
231
|
function logs(follow = false) {
|
|
232
|
+
ensureDataDir();
|
|
158
233
|
if (!fs.existsSync(LOG_FILE)) {
|
|
159
234
|
console.log(colors.yellow('No log file found'));
|
|
160
235
|
return;
|
|
@@ -176,10 +251,15 @@ function logs(follow = false) {
|
|
|
176
251
|
|
|
177
252
|
// 设置密码
|
|
178
253
|
function setupPassword() {
|
|
254
|
+
ensureDataDir();
|
|
179
255
|
console.log(colors.blue('Setting up password...'));
|
|
256
|
+
console.log(colors.gray(`Config will be saved to: ${DATA_DIR}`));
|
|
257
|
+
console.log('');
|
|
258
|
+
|
|
180
259
|
const child = spawn('node', [SETUP_PASSWORD_FILE], {
|
|
181
260
|
stdio: 'inherit',
|
|
182
|
-
cwd:
|
|
261
|
+
cwd: DATA_DIR, // 在数据目录运行,使auth-config.json保存到数据目录
|
|
262
|
+
env: { ...process.env, TCPMAPPING_DATA_DIR: DATA_DIR }
|
|
183
263
|
});
|
|
184
264
|
|
|
185
265
|
child.on('exit', (code) => {
|
|
@@ -189,29 +269,41 @@ function setupPassword() {
|
|
|
189
269
|
|
|
190
270
|
// 初始化配置
|
|
191
271
|
function init() {
|
|
192
|
-
|
|
193
|
-
|
|
272
|
+
ensureDataDir();
|
|
273
|
+
|
|
274
|
+
// 检查当前目录和数据目录是否已有配置
|
|
275
|
+
const cwdConfig = path.join(process.cwd(), 'config.json');
|
|
276
|
+
const dataConfig = path.join(DATA_DIR, 'config.json');
|
|
277
|
+
|
|
278
|
+
if (fs.existsSync(cwdConfig)) {
|
|
279
|
+
console.log(colors.yellow(`config.json already exists in current directory`));
|
|
280
|
+
console.log(colors.gray(` ${cwdConfig}`));
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
194
283
|
|
|
195
|
-
if (fs.existsSync(
|
|
196
|
-
console.log(colors.yellow(
|
|
284
|
+
if (fs.existsSync(dataConfig)) {
|
|
285
|
+
console.log(colors.yellow(`config.json already exists in data directory`));
|
|
286
|
+
console.log(colors.gray(` ${dataConfig}`));
|
|
287
|
+
console.log('');
|
|
288
|
+
console.log('To create a local config, copy it to current directory:');
|
|
289
|
+
console.log(colors.cyan(` cp ${dataConfig} ./config.json`));
|
|
197
290
|
return;
|
|
198
291
|
}
|
|
199
292
|
|
|
200
293
|
const defaultConfig = {
|
|
201
|
-
mappings: [
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
listen: { host: "0.0.0.0", port: 8080 },
|
|
205
|
-
target: { host: "127.0.0.1", port: 3000 }
|
|
206
|
-
}
|
|
207
|
-
],
|
|
208
|
-
webui: { enabled: true, port: 9999, host: "0.0.0.0" },
|
|
209
|
-
logging: { enabled: true, level: "info" }
|
|
294
|
+
mappings: [],
|
|
295
|
+
webui: { port: 9999 },
|
|
296
|
+
logging: { level: "info" }
|
|
210
297
|
};
|
|
211
298
|
|
|
212
|
-
|
|
299
|
+
// 保存到数据目录
|
|
300
|
+
fs.writeFileSync(dataConfig, JSON.stringify(defaultConfig, null, 2));
|
|
213
301
|
console.log(colors.green('Created config.json'));
|
|
214
|
-
console.log(colors.
|
|
302
|
+
console.log(colors.gray(` ${dataConfig}`));
|
|
303
|
+
console.log('');
|
|
304
|
+
console.log('Edit the config file to add your port mappings.');
|
|
305
|
+
console.log('Or copy it to current directory for project-specific config:');
|
|
306
|
+
console.log(colors.cyan(` cp ${dataConfig} ./config.json`));
|
|
215
307
|
}
|
|
216
308
|
|
|
217
309
|
// 显示版本
|
|
@@ -232,7 +324,7 @@ ${colors.yellow('Commands:')}
|
|
|
232
324
|
${colors.green('start')} Start the server in background
|
|
233
325
|
${colors.green('stop')} Stop the server
|
|
234
326
|
${colors.green('restart')} Restart the server
|
|
235
|
-
${colors.green('status')} Show server status
|
|
327
|
+
${colors.green('status')} Show server status and config paths
|
|
236
328
|
${colors.green('logs')} Show recent logs
|
|
237
329
|
${colors.green('logs -f')} Follow logs in real-time
|
|
238
330
|
${colors.green('setup-password')} Set up admin password
|
|
@@ -240,10 +332,15 @@ ${colors.yellow('Commands:')}
|
|
|
240
332
|
${colors.green('version')} Show version
|
|
241
333
|
${colors.green('help')} Show this help message
|
|
242
334
|
|
|
335
|
+
${colors.yellow('Config Paths (priority order):')}
|
|
336
|
+
1. ./config.json (current directory - project config)
|
|
337
|
+
2. ~/.tcpmapping/ (user data directory - global config)
|
|
338
|
+
|
|
243
339
|
${colors.yellow('Examples:')}
|
|
244
|
-
tcpmapping
|
|
245
|
-
tcpmapping
|
|
246
|
-
tcpmapping
|
|
340
|
+
tcpmapping init # Create config file
|
|
341
|
+
tcpmapping setup-password # Set admin password
|
|
342
|
+
tcpmapping start # Start server
|
|
343
|
+
tcpmapping status # Check status and config paths
|
|
247
344
|
|
|
248
345
|
${colors.yellow('WebUI:')}
|
|
249
346
|
After starting, visit http://localhost:9999
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chenpu17/tcpmapping",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "TCP端口转发服务器,支持多端口映射、WebUI管理界面和实时连接监控",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
"bin/",
|
|
17
17
|
"public/",
|
|
18
18
|
"server.js",
|
|
19
|
-
"setup-password.js"
|
|
20
|
-
"config.json"
|
|
19
|
+
"setup-password.js"
|
|
21
20
|
],
|
|
22
21
|
"keywords": [
|
|
23
22
|
"tcp",
|