@qingchencloud/qy-server 1.0.2

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 ADDED
@@ -0,0 +1,110 @@
1
+ # @qingchencloud/qy-server
2
+
3
+ 晴云私有代理服务端 - 一个轻量级、高性能的私有代理服务器。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ TLS 1.3 加密 - 流量伪装成 HTTPS
8
+ - ✅ TCP/UDP 代理 - 全协议支持
9
+ - ✅ 端口转发 - 本地端口映射到远程
10
+ - ✅ 内网穿透 - 将内网服务暴露到公网
11
+ - ✅ 流量统计 - 实时监控
12
+ - ✅ 多密钥支持 - 灵活的访问控制
13
+
14
+ ## 快速安装
15
+
16
+ ```bash
17
+ # 全局安装
18
+ npm install -g @qingchencloud/qy-server
19
+
20
+ # 或使用 npx 直接运行
21
+ npx @qingchencloud/qy-server
22
+ ```
23
+
24
+ ## 使用方法
25
+
26
+ ### 命令行
27
+
28
+ ```bash
29
+ # 显示帮助
30
+ qy-server --help
31
+
32
+ # 使用配置文件启动
33
+ qy-server -c config.yaml
34
+
35
+ # 生成密钥哈希
36
+ qy-server -genkey "my-secret-key"
37
+ ```
38
+
39
+ ### 编程方式
40
+
41
+ ```javascript
42
+ const qyServer = require('@qingchencloud/qy-server');
43
+
44
+ // 生成配置文件
45
+ const { configPath, key } = qyServer.generateConfig('./config.yaml', {
46
+ listen: ':443',
47
+ cert: '/path/to/cert.pem',
48
+ keyFile: '/path/to/key.pem'
49
+ });
50
+ console.log('访问密钥:', key);
51
+
52
+ // 启动服务器
53
+ const server = qyServer.start({ config: configPath });
54
+
55
+ // 获取版本
56
+ console.log(qyServer.version());
57
+
58
+ // 生成密钥哈希
59
+ const hash = qyServer.generateKeyHash('my-secret-key');
60
+ ```
61
+
62
+ ## 配置文件示例
63
+
64
+ ```yaml
65
+ server:
66
+ listen: ":443"
67
+ cert: "/etc/ssl/cert.pem"
68
+ key: "/etc/ssl/key.pem"
69
+
70
+ auth:
71
+ keys:
72
+ - "your-secret-key"
73
+
74
+ features:
75
+ proxy: true
76
+ port_forward: true
77
+ nat_penetration: true
78
+
79
+ limits:
80
+ max_connections: 1000
81
+ bandwidth_limit: 0
82
+ idle_timeout: 300
83
+ ```
84
+
85
+ ## 客户端配置
86
+
87
+ 在 ClashDIY 中添加节点:
88
+
89
+ ```yaml
90
+ proxies:
91
+ - name: "我的私有节点"
92
+ type: qyproto
93
+ server: your-server.com
94
+ port: 443
95
+ password: "your-secret-key"
96
+ ```
97
+
98
+ ## 系统要求
99
+
100
+ - Node.js >= 14
101
+ - 支持平台:Windows (x64), Linux (x64/arm64), macOS (x64/arm64)
102
+
103
+ ## 许可证
104
+
105
+ MIT
106
+
107
+ ## 相关链接
108
+
109
+ - [GitHub](https://github.com/1186258278/QingYun)
110
+ - [问题反馈](https://github.com/1186258278/QingYun/issues)
package/bin/qy-server ADDED
Binary file
package/lib/index.js ADDED
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * QY-Server NPM 包入口
4
+ * 提供编程方式启动和命令行调用
5
+ */
6
+
7
+ const { spawn, execSync } = require('child_process');
8
+ const path = require('path');
9
+ const fs = require('fs');
10
+
11
+ // 获取二进制文件路径
12
+ function getBinaryPath() {
13
+ const ext = process.platform === 'win32' ? '.exe' : '';
14
+ const binaryPath = path.join(__dirname, '..', 'bin', `qy-server${ext}`);
15
+
16
+ if (!fs.existsSync(binaryPath)) {
17
+ throw new Error(
18
+ '二进制文件不存在,请运行: npm run postinstall\n' +
19
+ '或手动下载二进制文件到: ' + binaryPath
20
+ );
21
+ }
22
+
23
+ return binaryPath;
24
+ }
25
+
26
+ /**
27
+ * 启动 QY-Server
28
+ * @param {Object} options 选项
29
+ * @param {string} options.config 配置文件路径
30
+ * @param {boolean} options.daemon 是否后台运行
31
+ * @returns {ChildProcess} 子进程
32
+ */
33
+ function start(options = {}) {
34
+ const binaryPath = getBinaryPath();
35
+ const args = [];
36
+
37
+ if (options.config) {
38
+ args.push('-c', options.config);
39
+ }
40
+
41
+ const child = spawn(binaryPath, args, {
42
+ stdio: options.daemon ? 'ignore' : 'inherit',
43
+ detached: options.daemon || false
44
+ });
45
+
46
+ if (options.daemon) {
47
+ child.unref();
48
+ }
49
+
50
+ return child;
51
+ }
52
+
53
+ /**
54
+ * 获取版本信息
55
+ * @returns {string} 版本号
56
+ */
57
+ function version() {
58
+ const binaryPath = getBinaryPath();
59
+ try {
60
+ const output = execSync(`"${binaryPath}" -v`, { encoding: 'utf8' });
61
+ return output.trim();
62
+ } catch (error) {
63
+ return require('../package.json').version;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * 生成密钥哈希
69
+ * @param {string} key 原始密钥
70
+ * @returns {string} SHA256 哈希
71
+ */
72
+ function generateKeyHash(key) {
73
+ const binaryPath = getBinaryPath();
74
+ try {
75
+ const output = execSync(`"${binaryPath}" -genkey "${key}"`, { encoding: 'utf8' });
76
+ const match = output.match(/SHA256 哈希: ([a-f0-9]+)/);
77
+ return match ? match[1] : null;
78
+ } catch (error) {
79
+ // 如果二进制调用失败,使用 Node.js 计算
80
+ const crypto = require('crypto');
81
+ return crypto.createHash('sha256').update(key).digest('hex');
82
+ }
83
+ }
84
+
85
+ /**
86
+ * 生成配置文件
87
+ * @param {string} outputPath 输出路径
88
+ * @param {Object} options 配置选项
89
+ */
90
+ function generateConfig(outputPath, options = {}) {
91
+ const key = options.key || require('crypto').randomBytes(16).toString('hex');
92
+
93
+ const config = `# QY-Server 配置文件
94
+ # 生成时间: ${new Date().toISOString()}
95
+
96
+ server:
97
+ listen: "${options.listen || ':443'}"
98
+ cert: "${options.cert || ''}"
99
+ key: "${options.keyFile || ''}"
100
+ fallback: "${options.fallback || 'https://www.baidu.com'}"
101
+
102
+ auth:
103
+ keys:
104
+ - "${key}"
105
+
106
+ features:
107
+ proxy: ${options.proxy !== false}
108
+ port_forward: ${options.portForward !== false}
109
+ nat_penetration: ${options.natPenetration !== false}
110
+
111
+ limits:
112
+ max_connections: ${options.maxConnections || 1000}
113
+ bandwidth_limit: ${options.bandwidthLimit || 0}
114
+ idle_timeout: ${options.idleTimeout || 300}
115
+
116
+ logging:
117
+ level: "${options.logLevel || 'info'}"
118
+ file: "${options.logFile || ''}"
119
+ `;
120
+
121
+ fs.writeFileSync(outputPath, config, { mode: 0o600 });
122
+
123
+ return { configPath: outputPath, key };
124
+ }
125
+
126
+ // 导出 API
127
+ module.exports = {
128
+ start,
129
+ version,
130
+ generateKeyHash,
131
+ generateConfig,
132
+ getBinaryPath
133
+ };
134
+
135
+ // 如果直接运行,执行 CLI
136
+ if (require.main === module) {
137
+ const args = process.argv.slice(2);
138
+
139
+ if (args.includes('--version') || args.includes('-v')) {
140
+ console.log(version());
141
+ process.exit(0);
142
+ }
143
+
144
+ if (args.includes('--help') || args.includes('-h')) {
145
+ console.log(`
146
+ QY-Server 晴云私有代理服务端
147
+
148
+ 用法:
149
+ qy-server [选项]
150
+ npx @qingchencloud/qy-server [选项]
151
+
152
+ 选项:
153
+ -c <path> 配置文件路径 (默认: config.yaml)
154
+ -v 显示版本信息
155
+ -genkey <key> 生成密钥的 SHA256 哈希
156
+ -h, --help 显示帮助信息
157
+
158
+ 示例:
159
+ qy-server -c /etc/qy-server/config.yaml
160
+ qy-server -genkey "my-secret-key"
161
+
162
+ 更多信息: https://github.com/1186258278/QingYun
163
+ `);
164
+ process.exit(0);
165
+ }
166
+
167
+ // 传递给二进制执行
168
+ try {
169
+ const binaryPath = getBinaryPath();
170
+ const child = spawn(binaryPath, args, { stdio: 'inherit' });
171
+
172
+ child.on('exit', (code) => {
173
+ process.exit(code || 0);
174
+ });
175
+
176
+ child.on('error', (error) => {
177
+ console.error('启动失败:', error.message);
178
+ process.exit(1);
179
+ });
180
+ } catch (error) {
181
+ console.error(error.message);
182
+ process.exit(1);
183
+ }
184
+ }
package/lib/install.js ADDED
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * QY-Server 安装脚本
4
+ * 在 npm install 后自动下载对应平台的二进制文件
5
+ */
6
+
7
+ const https = require('https');
8
+ const http = require('http');
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { execSync } = require('child_process');
12
+ const zlib = require('zlib');
13
+
14
+ // 配置
15
+ const PACKAGE_NAME = '@qingchencloud/qy-server';
16
+ const VERSION = require('../package.json').version;
17
+ const GITHUB_REPO = '1186258278/QingYun';
18
+
19
+ // 获取平台信息
20
+ function getPlatformInfo() {
21
+ const platform = process.platform;
22
+ const arch = process.arch;
23
+
24
+ const platformMap = {
25
+ 'darwin': 'darwin',
26
+ 'linux': 'linux',
27
+ 'win32': 'windows'
28
+ };
29
+
30
+ const archMap = {
31
+ 'x64': 'amd64',
32
+ 'arm64': 'arm64'
33
+ };
34
+
35
+ const os = platformMap[platform];
36
+ const cpu = archMap[arch];
37
+
38
+ if (!os || !cpu) {
39
+ throw new Error(`不支持的平台: ${platform}-${arch}`);
40
+ }
41
+
42
+ const ext = platform === 'win32' ? '.exe' : '';
43
+ const binaryName = `qy-server-${os}-${cpu}${ext}`;
44
+
45
+ return { os, cpu, ext, binaryName, platform, arch };
46
+ }
47
+
48
+ // 下载文件
49
+ function downloadFile(url, destPath) {
50
+ return new Promise((resolve, reject) => {
51
+ console.log(`下载: ${url}`);
52
+
53
+ const file = fs.createWriteStream(destPath);
54
+ const protocol = url.startsWith('https') ? https : http;
55
+
56
+ const request = protocol.get(url, (response) => {
57
+ // 处理重定向
58
+ if (response.statusCode === 301 || response.statusCode === 302) {
59
+ file.close();
60
+ fs.unlinkSync(destPath);
61
+ return downloadFile(response.headers.location, destPath)
62
+ .then(resolve)
63
+ .catch(reject);
64
+ }
65
+
66
+ if (response.statusCode !== 200) {
67
+ file.close();
68
+ fs.unlinkSync(destPath);
69
+ reject(new Error(`下载失败: HTTP ${response.statusCode}`));
70
+ return;
71
+ }
72
+
73
+ const total = parseInt(response.headers['content-length'], 10);
74
+ let downloaded = 0;
75
+
76
+ response.on('data', (chunk) => {
77
+ downloaded += chunk.length;
78
+ if (total) {
79
+ const percent = ((downloaded / total) * 100).toFixed(1);
80
+ process.stdout.write(`\r下载进度: ${percent}%`);
81
+ }
82
+ });
83
+
84
+ response.pipe(file);
85
+
86
+ file.on('finish', () => {
87
+ file.close();
88
+ console.log('\n下载完成');
89
+ resolve();
90
+ });
91
+ });
92
+
93
+ request.on('error', (err) => {
94
+ file.close();
95
+ fs.unlinkSync(destPath);
96
+ reject(err);
97
+ });
98
+ });
99
+ }
100
+
101
+ // 获取下载 URL
102
+ function getDownloadUrl(binaryName) {
103
+ // 优先使用 GitHub Releases
104
+ const githubUrl = `https://github.com/${GITHUB_REPO}/releases/download/v${VERSION}/${binaryName}`;
105
+
106
+ // 备用:使用 npm registry 存储(需要额外配置)
107
+ // const npmUrl = `https://registry.npmmirror.com/${PACKAGE_NAME}/-/${binaryName}`;
108
+
109
+ return githubUrl;
110
+ }
111
+
112
+ // 检查本地编译的二进制文件
113
+ function checkLocalBinary(info) {
114
+ const localPaths = [
115
+ path.join(__dirname, '..', '..', 'dist', info.binaryName),
116
+ path.join(__dirname, '..', '..', info.binaryName),
117
+ path.join(__dirname, '..', '..', `qy-server${info.ext}`)
118
+ ];
119
+
120
+ for (const localPath of localPaths) {
121
+ if (fs.existsSync(localPath)) {
122
+ console.log(`使用本地二进制文件: ${localPath}`);
123
+ return localPath;
124
+ }
125
+ }
126
+ return null;
127
+ }
128
+
129
+ // 主安装函数
130
+ async function install() {
131
+ console.log('========================================');
132
+ console.log(' QY-Server 安装程序');
133
+ console.log('========================================\n');
134
+
135
+ try {
136
+ const info = getPlatformInfo();
137
+ console.log(`平台: ${info.platform} (${info.arch})`);
138
+ console.log(`二进制文件: ${info.binaryName}\n`);
139
+
140
+ const binDir = path.join(__dirname, '..', 'bin');
141
+ const binaryPath = path.join(binDir, `qy-server${info.ext}`);
142
+
143
+ // 确保 bin 目录存在
144
+ if (!fs.existsSync(binDir)) {
145
+ fs.mkdirSync(binDir, { recursive: true });
146
+ }
147
+
148
+ // 检查是否已安装
149
+ if (fs.existsSync(binaryPath)) {
150
+ console.log('二进制文件已存在,跳过下载');
151
+ return;
152
+ }
153
+
154
+ // 检查本地编译的文件
155
+ const localBinary = checkLocalBinary(info);
156
+ if (localBinary) {
157
+ fs.copyFileSync(localBinary, binaryPath);
158
+ fs.chmodSync(binaryPath, 0o755);
159
+ console.log('安装完成(使用本地文件)');
160
+ return;
161
+ }
162
+
163
+ // 下载二进制文件
164
+ const downloadUrl = getDownloadUrl(info.binaryName);
165
+
166
+ try {
167
+ await downloadFile(downloadUrl, binaryPath);
168
+ fs.chmodSync(binaryPath, 0o755);
169
+ console.log('\n安装完成!');
170
+ } catch (downloadError) {
171
+ console.error(`\n下载失败: ${downloadError.message}`);
172
+ console.log('\n请手动下载或编译二进制文件:');
173
+ console.log(` 1. 从 GitHub Releases 下载: https://github.com/${GITHUB_REPO}/releases`);
174
+ console.log(' 2. 或克隆仓库后运行: go build -o qy-server ./cmd/qy-server');
175
+ console.log(` 3. 将二进制文件复制到: ${binaryPath}`);
176
+
177
+ // 创建一个占位脚本
178
+ const placeholder = info.platform === 'win32'
179
+ ? '@echo 请先下载 qy-server 二进制文件\n@exit /b 1'
180
+ : '#!/bin/sh\necho "请先下载 qy-server 二进制文件"\nexit 1';
181
+
182
+ fs.writeFileSync(binaryPath, placeholder);
183
+ fs.chmodSync(binaryPath, 0o755);
184
+ }
185
+
186
+ } catch (error) {
187
+ console.error('安装失败:', error.message);
188
+ process.exit(1);
189
+ }
190
+ }
191
+
192
+ // 运行安装
193
+ install().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@qingchencloud/qy-server",
3
+ "version": "1.0.2",
4
+ "description": "晴云私有代理服务端 - 支持 TLS 加密、端口转发、内网穿透",
5
+ "keywords": [
6
+ "proxy",
7
+ "vpn",
8
+ "tunnel",
9
+ "nat",
10
+ "port-forward",
11
+ "tls",
12
+ "private-proxy"
13
+ ],
14
+ "homepage": "https://github.com/1186258278/QingYun",
15
+ "bugs": {
16
+ "url": "https://github.com/1186258278/QingYun/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/1186258278/QingYun.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "qingchencloud",
24
+ "main": "lib/index.js",
25
+ "bin": {
26
+ "qy-server": "bin/qy-server"
27
+ },
28
+ "scripts": {
29
+ "postinstall": "node lib/install.js",
30
+ "test": "node lib/index.js --version"
31
+ },
32
+ "files": [
33
+ "bin/",
34
+ "lib/",
35
+ "README.md"
36
+ ],
37
+ "engines": {
38
+ "node": ">=14"
39
+ },
40
+ "os": [
41
+ "darwin",
42
+ "linux",
43
+ "win32"
44
+ ],
45
+ "cpu": [
46
+ "x64",
47
+ "arm64"
48
+ ],
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }