x3ui-api 1.0.3 → 1.0.5
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 +274 -26
- package/package.json +1 -1
- package/src/core/ClientBuilder.d.ts +37 -0
- package/src/core/ClientBuilder.js +57 -0
- package/src/core/IndoundBuilder.d.ts +1 -0
- package/src/core/X3UIClient.d.ts +31 -0
- package/src/core/X3UIClient.js +147 -0
- package/src/index.d.ts +12 -148
- package/src/index.d.ts~ +185 -0
- package/src/index.js +2 -455
- package/src/protocols/vless/RealityBuilder.d.ts +69 -0
- package/src/protocols/vless/RealityBuilder.js +223 -0
- package/src/protocols/vless/RealityClientBuilder.d.ts +11 -0
- package/src/protocols/vless/RealityClientBuilder.js +25 -0
- package/src/protocols/vless/index.d.ts +9 -0
- package/src/protocols/vless/index.js +4 -0
- package/src/protocols/vmess/VmessBuilder.d.ts +77 -0
- package/src/protocols/vmess/VmessBuilder.js +189 -0
- package/src/protocols/vmess/VmessClientBuilder.d.ts +13 -0
- package/src/protocols/vmess/VmessClientBuilder.js +92 -0
- package/src/protocols/vmess/index.d.ts +9 -0
- package/src/protocols/vmess/index.js +4 -0
- package/src/protocols/wireguard/WireguardBuilder.d.ts +118 -0
- package/src/protocols/wireguard/WireguardBuilder.js +204 -0
- package/src/protocols/wireguard/WireguardClientBuilder.d.ts +79 -0
- package/src/protocols/wireguard/WireguardClientBuilder.js +88 -0
- package/src/protocols/wireguard/index.d.ts +9 -0
- package/src/protocols/wireguard/index.js +4 -0
- package/src/protocols/wireguard/keyUtils.js +95 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import WireguardClientBuilder from './WireguardClientBuilder';
|
|
2
|
+
import {ClientSettings} from "../../index";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* WireguardBuilder class for creating and managing Wireguard server configurations.
|
|
6
|
+
* This builder provides a fluent interface for setting up Wireguard servers and managing clients.
|
|
7
|
+
*/
|
|
8
|
+
export default class WireguardBuilder {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new WireguardBuilder instance.
|
|
11
|
+
* @param client - The client connection or context to use for building the configuration
|
|
12
|
+
* @param options - Optional configuration parameters for the Wireguard server
|
|
13
|
+
*/
|
|
14
|
+
constructor(client: any, options?: any);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Sets the port for the Wireguard server.
|
|
18
|
+
* @param port - The port number to listen on
|
|
19
|
+
* @returns The current builder instance for method chaining
|
|
20
|
+
*/
|
|
21
|
+
setPort(port: number): this;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Sets a descriptive remark for the Wireguard server.
|
|
25
|
+
* @param remark - The remark or name for this server
|
|
26
|
+
* @returns The current builder instance for method chaining
|
|
27
|
+
*/
|
|
28
|
+
setRemark(remark: string): this;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Sets the Maximum Transmission Unit (MTU) size.
|
|
32
|
+
* @param mtu - The MTU value in bytes
|
|
33
|
+
* @returns The current builder instance for method chaining
|
|
34
|
+
*/
|
|
35
|
+
setMtu(mtu: number): this;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Sets the server's private key.
|
|
39
|
+
* @param secretKey - The Wireguard private key in base64 format
|
|
40
|
+
* @returns The current builder instance for method chaining
|
|
41
|
+
*/
|
|
42
|
+
setSecretKey(secretKey: string): this;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Configures whether to use kernel TUN interface or userspace implementation.
|
|
46
|
+
* @param noKernelTun - If true, uses userspace implementation instead of kernel TUN
|
|
47
|
+
* @returns The current builder instance for method chaining
|
|
48
|
+
*/
|
|
49
|
+
setNoKernelTun(noKernelTun: boolean): this;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Configures traffic sniffing options.
|
|
53
|
+
* @param enabled - Whether sniffing is enabled
|
|
54
|
+
* @param destOverride - Array of protocols to override destination with sniffed value
|
|
55
|
+
* @param metadataOnly - If true, only sniffs metadata
|
|
56
|
+
* @param routeOnly - If true, only uses sniffed information for routing
|
|
57
|
+
* @returns The current builder instance for method chaining
|
|
58
|
+
*/
|
|
59
|
+
setSniffing(enabled: boolean, destOverride?: string[], metadataOnly?: boolean, routeOnly?: boolean): this;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sets the IP address the server listens on.
|
|
63
|
+
* @param ip - The IP address to bind to
|
|
64
|
+
* @returns The current builder instance for method chaining
|
|
65
|
+
*/
|
|
66
|
+
setListenIP(ip: string): this;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Sets the expiration time for the server configuration.
|
|
70
|
+
* @param timestamp - Unix timestamp when the configuration expires
|
|
71
|
+
* @returns The current builder instance for method chaining
|
|
72
|
+
*/
|
|
73
|
+
setExpiryTime(timestamp: number): this;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Creates and adds a new client to this Wireguard server.
|
|
77
|
+
* @param options - Optional client settings
|
|
78
|
+
* @returns A new WireguardClientBuilder instance for configuring the client
|
|
79
|
+
*/
|
|
80
|
+
addClient(options?: Partial<ClientSettings>): WireguardClientBuilder;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Generates a connection link for a client.
|
|
84
|
+
* @param clientIndex - Index of the client (default: 0)
|
|
85
|
+
* @param host - Host address to use in the link (defaults to server address)
|
|
86
|
+
* @param port - Port to use in the link (defaults to server port)
|
|
87
|
+
* @returns A formatted connection link string
|
|
88
|
+
*/
|
|
89
|
+
getClientLink(clientIndex?: number, host?: string, port?: number): string;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Generates a configuration file for a client.
|
|
93
|
+
* @param clientIndex - Index of the client (default: 0)
|
|
94
|
+
* @param host - Host address to use in the config (defaults to server address)
|
|
95
|
+
* @param port - Port to use in the config (defaults to server port)
|
|
96
|
+
* @returns A formatted configuration file content as string
|
|
97
|
+
*/
|
|
98
|
+
getClientConfig(clientIndex?: number, host?: string, port?: number): string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Generates a random port number for the Wireguard server.
|
|
102
|
+
* @returns A random port number
|
|
103
|
+
*/
|
|
104
|
+
generateRandomPort(): number;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Derives the public key from a given private key.
|
|
108
|
+
* @param secretKey - The Wireguard private key in base64 format
|
|
109
|
+
* @returns The corresponding public key in base64 format
|
|
110
|
+
*/
|
|
111
|
+
derivePublicKey(secretKey: string): string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Builds and finalizes the Wireguard server configuration.
|
|
115
|
+
* @returns A Promise that resolves to the built configuration
|
|
116
|
+
*/
|
|
117
|
+
build(): Promise<any>;
|
|
118
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
const keyUtils = require('./keyUtils');
|
|
2
|
+
const WireguardClientBuilder = require('./WireguardClientBuilder');
|
|
3
|
+
|
|
4
|
+
module.exports = class WireguardBuilder {
|
|
5
|
+
constructor(client, options = {}) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
// Initialize from InboundConfig
|
|
8
|
+
this.id = options.id || undefined;
|
|
9
|
+
this.port = options.port || 0;
|
|
10
|
+
this.remark = options.remark || '';
|
|
11
|
+
this.listenIP = options.listen || '';
|
|
12
|
+
this.expiryTime = options.expiryTime || 0;
|
|
13
|
+
this.enable = true;
|
|
14
|
+
this.up = options.up || 0;
|
|
15
|
+
this.down = options.down || 0;
|
|
16
|
+
this.total = options.total || 0;
|
|
17
|
+
|
|
18
|
+
// Initialize WireGuard specific settings
|
|
19
|
+
const settings = typeof options.settings === 'string'
|
|
20
|
+
? JSON.parse(options.settings)
|
|
21
|
+
: options.settings || {};
|
|
22
|
+
|
|
23
|
+
this.mtu = settings.mtu || 1420;
|
|
24
|
+
this.secretKey = settings.secretKey || '';
|
|
25
|
+
this.publicKey = ''; // Will be derived from secretKey
|
|
26
|
+
this.noKernelTun = settings.noKernelTun || false;
|
|
27
|
+
|
|
28
|
+
// Initialize sniffing
|
|
29
|
+
this.sniffing = options.sniffing || {
|
|
30
|
+
enabled: false,
|
|
31
|
+
destOverride: ['http', 'tls', 'quic', 'fakedns'],
|
|
32
|
+
metadataOnly: false,
|
|
33
|
+
routeOnly: false
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Initialize allocate
|
|
37
|
+
this.allocate = options.allocate || {
|
|
38
|
+
strategy: 'always',
|
|
39
|
+
refresh: 5,
|
|
40
|
+
concurrency: 3
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Initialize clients
|
|
44
|
+
this.clients = [];
|
|
45
|
+
|
|
46
|
+
if (settings?.peers) {
|
|
47
|
+
settings.peers.forEach(peer => {
|
|
48
|
+
this.addClient(peer);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// If secretKey is provided, derive publicKey
|
|
53
|
+
if (this.secretKey) {
|
|
54
|
+
this.publicKey = keyUtils.derivePublicKey(this.secretKey);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// If no secretKey provided, generate one
|
|
58
|
+
if (!this.secretKey) {
|
|
59
|
+
let pair = keyUtils.generateKeyPair();
|
|
60
|
+
this.secretKey = pair.privateKey;
|
|
61
|
+
this.publicKey = pair.publicKey;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
setPort(port) {
|
|
66
|
+
this.port = port;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setRemark(remark) {
|
|
71
|
+
this.remark = remark;
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
setMtu(mtu) {
|
|
76
|
+
this.mtu = mtu;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setSecretKey(secretKey) {
|
|
81
|
+
this.secretKey = secretKey;
|
|
82
|
+
this.publicKey = keyUtils.derivePublicKey(secretKey);
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
setNoKernelTun(noKernelTun) {
|
|
87
|
+
this.noKernelTun = noKernelTun;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
setSniffing(enabled, destOverride = ['http', 'tls', 'quic', 'fakedns'], metadataOnly = false, routeOnly = false) {
|
|
92
|
+
this.sniffing = {
|
|
93
|
+
enabled,
|
|
94
|
+
destOverride,
|
|
95
|
+
metadataOnly,
|
|
96
|
+
routeOnly
|
|
97
|
+
};
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
setListenIP(ip) {
|
|
102
|
+
this.listenIP = ip;
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
setExpiryTime(timestamp) {
|
|
107
|
+
this.expiryTime = timestamp;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
addClient(options = {}) {
|
|
112
|
+
const builder = new WireguardClientBuilder(this);
|
|
113
|
+
if (options.privateKey) builder.setPrivateKey(options.privateKey);
|
|
114
|
+
if (options.publicKey) builder.setPublicKey(options.publicKey);
|
|
115
|
+
if (options.preSharedKey) builder.setPreSharedKey(options.preSharedKey);
|
|
116
|
+
if (options.allowedIPs) builder.setAllowedIPs(options.allowedIPs);
|
|
117
|
+
if (options.keepAlive !== undefined) builder.setKeepAlive(options.keepAlive);
|
|
118
|
+
if (options.email) builder.setEmail(options.email);
|
|
119
|
+
if (options.totalGB) builder.setTotalGB(options.totalGB);
|
|
120
|
+
if (options.expiryTime) builder.setExpiryTime(options.expiryTime);
|
|
121
|
+
if (options.tgId) builder.setTgId(options.tgId);
|
|
122
|
+
|
|
123
|
+
this.clients.push(builder);
|
|
124
|
+
return builder;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
getClientLink(clientIndex = 0, host, port) {
|
|
128
|
+
if (clientIndex < 0 || clientIndex >= this.clients.length) {
|
|
129
|
+
throw new Error('Invalid client index');
|
|
130
|
+
}
|
|
131
|
+
const client = this.clients[clientIndex];
|
|
132
|
+
return client.getLink(host || this.listenIP || 'localhost', port || this.port);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
getClientConfig(clientIndex = 0, host, port) {
|
|
136
|
+
if (clientIndex < 0 || clientIndex >= this.clients.length) {
|
|
137
|
+
throw new Error('Invalid client index');
|
|
138
|
+
}
|
|
139
|
+
const client = this.clients[clientIndex];
|
|
140
|
+
return client.getConfigFile(host || this.listenIP || 'localhost', port || this.port);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
generateRandomPort() {
|
|
144
|
+
return Math.floor(Math.random() * (65535 - 1024) + 1024);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async build() {
|
|
148
|
+
if (!this.remark) {
|
|
149
|
+
throw new Error('Remark is required');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// If no port specified, find unused one
|
|
153
|
+
if (!this.port) {
|
|
154
|
+
const inbounds = await this.client.getInbounds();
|
|
155
|
+
const usedPorts = new Set(inbounds.map(i => i.port));
|
|
156
|
+
let port;
|
|
157
|
+
do {
|
|
158
|
+
port = this.generateRandomPort();
|
|
159
|
+
} while (usedPorts.has(port));
|
|
160
|
+
this.port = port;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// If no secretKey provided, generate one
|
|
164
|
+
if (!this.secretKey) {
|
|
165
|
+
this.secretKey = keyUtils.generatePrivateKey();
|
|
166
|
+
this.publicKey = keyUtils.derivePublicKey(this.secretKey);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// If no clients added, create one default client
|
|
170
|
+
if (this.clients.length === 0) {
|
|
171
|
+
this.addClient();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Build all clients
|
|
175
|
+
const clientConfigs = await Promise.all(this.clients.map(builder => builder.build()));
|
|
176
|
+
|
|
177
|
+
// Create tag for inbound
|
|
178
|
+
const tag = `inbound-${this.port}`;
|
|
179
|
+
|
|
180
|
+
// Build the complete inbound configuration
|
|
181
|
+
return {
|
|
182
|
+
id: this.id,
|
|
183
|
+
up: this.up,
|
|
184
|
+
down: this.down,
|
|
185
|
+
total: this.total,
|
|
186
|
+
remark: this.remark,
|
|
187
|
+
enable: this.enable,
|
|
188
|
+
expiryTime: this.expiryTime,
|
|
189
|
+
listen: this.listenIP,
|
|
190
|
+
port: this.port,
|
|
191
|
+
protocol: 'wireguard',
|
|
192
|
+
settings: {
|
|
193
|
+
mtu: this.mtu,
|
|
194
|
+
secretKey: this.secretKey,
|
|
195
|
+
peers: clientConfigs,
|
|
196
|
+
noKernelTun: this.noKernelTun
|
|
197
|
+
},
|
|
198
|
+
streamSettings: {},
|
|
199
|
+
tag,
|
|
200
|
+
sniffing: this.sniffing,
|
|
201
|
+
allocate: this.allocate
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for WireguardClientBuilder
|
|
3
|
+
* Provides functionality for building WireGuard client configurations
|
|
4
|
+
*/
|
|
5
|
+
import ClientBuilder from '../../core/ClientBuilder';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WireguardClientBuilder class for creating and managing WireGuard client configurations
|
|
9
|
+
* Extends the base ClientBuilder to provide WireGuard-specific functionality
|
|
10
|
+
*/
|
|
11
|
+
export default class WireguardClientBuilder extends ClientBuilder {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new WireguardClientBuilder instance
|
|
14
|
+
* @param parent - The parent object that owns this builder
|
|
15
|
+
* @param options - Optional client settings
|
|
16
|
+
*/
|
|
17
|
+
constructor(parent: any, options?: any);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Sets the client's private key
|
|
21
|
+
* @param privateKey - The WireGuard private key in base64 format
|
|
22
|
+
* @returns The builder instance for method chaining
|
|
23
|
+
*/
|
|
24
|
+
setPrivateKey(privateKey: string): this;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Sets the server's public key
|
|
28
|
+
* @param publicKey - The WireGuard public key in base64 format
|
|
29
|
+
* @returns The builder instance for method chaining
|
|
30
|
+
*/
|
|
31
|
+
setPublicKey(publicKey: string): this;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sets the pre-shared key for additional security
|
|
35
|
+
* @param preSharedKey - The pre-shared key in base64 format
|
|
36
|
+
* @returns The builder instance for method chaining
|
|
37
|
+
*/
|
|
38
|
+
setPreSharedKey(preSharedKey: string): this;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Sets the allowed IP addresses/ranges for routing through the tunnel
|
|
42
|
+
* @param allowedIPs - Array of IP addresses/ranges in CIDR notation
|
|
43
|
+
* @returns The builder instance for method chaining
|
|
44
|
+
*/
|
|
45
|
+
setAllowedIPs(allowedIPs: string[]): this;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Sets the persistent keepalive interval
|
|
49
|
+
* @param keepAlive - Interval in seconds between keepalive packets
|
|
50
|
+
* @returns The builder instance for method chaining
|
|
51
|
+
*/
|
|
52
|
+
setKeepAlive(keepAlive: number): this;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Generates a random pre-shared key
|
|
56
|
+
* @returns The builder instance for method chaining
|
|
57
|
+
*/
|
|
58
|
+
generatePresharedKey(): this;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generates a new public/private key pair
|
|
62
|
+
* @returns The builder instance for method chaining
|
|
63
|
+
*/
|
|
64
|
+
generateKeyPair(): this;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Builds and returns the complete WireGuard client configuration
|
|
68
|
+
* @returns The WireGuard client configuration object
|
|
69
|
+
*/
|
|
70
|
+
build(): any;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generates a WireGuard connection URI/link for easy client configuration
|
|
74
|
+
* @param host - The server hostname or IP address
|
|
75
|
+
* @param port - The server port number
|
|
76
|
+
* @returns A WireGuard connection URI string
|
|
77
|
+
*/
|
|
78
|
+
getLink(host: string, port: number): string;
|
|
79
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const crypto = require("crypto");
|
|
2
|
+
const keyUtils = require('./keyUtils');
|
|
3
|
+
const ClientBuilder = require('./../../core/ClientBuilder');
|
|
4
|
+
|
|
5
|
+
module.exports = class WireguardClientBuilder extends ClientBuilder {
|
|
6
|
+
constructor(parent, options) {
|
|
7
|
+
super(parent);
|
|
8
|
+
this.privateKey = options.privateKey || '';
|
|
9
|
+
this.publicKey = options.publicKey || '';
|
|
10
|
+
this.preSharedKey = options.preSharedKey || '';
|
|
11
|
+
this.allowedIPs = options.allowedIPs || ['10.0.0.2/32'];
|
|
12
|
+
this.keepAlive = options.keepAlive || 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
setPrivateKey(privateKey) {
|
|
16
|
+
this.privateKey = privateKey;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setPublicKey(publicKey) {
|
|
21
|
+
this.publicKey = publicKey;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setPreSharedKey(preSharedKey) {
|
|
26
|
+
this.preSharedKey = preSharedKey;
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setAllowedIPs(allowedIPs) {
|
|
31
|
+
this.allowedIPs = allowedIPs;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setKeepAlive(keepAlive) {
|
|
36
|
+
this.keepAlive = keepAlive;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
generatePresharedKey() {
|
|
41
|
+
this.preSharedKey = keyUtils.generatePresharedKey();
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
generateKeyPair() {
|
|
46
|
+
const keyPair = keyUtils.generateKeyPair();
|
|
47
|
+
this.privateKey = keyPair.privateKey;
|
|
48
|
+
this.publicKey = keyPair.publicKey;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
build() {
|
|
53
|
+
const baseConfig = super.build();
|
|
54
|
+
return {
|
|
55
|
+
...baseConfig,
|
|
56
|
+
privateKey: this.privateKey || '',
|
|
57
|
+
publicKey: this.publicKey || '',
|
|
58
|
+
preSharedKey: this.preSharedKey || '',
|
|
59
|
+
allowedIPs: this.allowedIPs,
|
|
60
|
+
keepAlive: this.keepAlive
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
getLink(host, port) {
|
|
65
|
+
// Generate WireGuard client configuration
|
|
66
|
+
const serverPublicKey = this.parent.secretKey ?
|
|
67
|
+
this.parent.publicKey :
|
|
68
|
+
'MISSING_SERVER_PUBLIC_KEY';
|
|
69
|
+
|
|
70
|
+
const config = [
|
|
71
|
+
'[Interface]',
|
|
72
|
+
`PrivateKey = ${this.privateKey}`,
|
|
73
|
+
`Address = ${this.allowedIPs[0]}`,
|
|
74
|
+
'DNS = 1.1.1.1, 1.0.0.1',
|
|
75
|
+
`MTU = ${this.parent.mtu || 1420}`,
|
|
76
|
+
'',
|
|
77
|
+
`# ${this.parent.remark || 'WireGuard'}-${this.email || 'default'}`,
|
|
78
|
+
'[Peer]',
|
|
79
|
+
`PublicKey = ${serverPublicKey}`,
|
|
80
|
+
'AllowedIPs = 0.0.0.0/0, ::/0',
|
|
81
|
+
`Endpoint = ${host}:${port}`,
|
|
82
|
+
this.preSharedKey ? `PresharedKey = ${this.preSharedKey}` : '',
|
|
83
|
+
].filter(Boolean).join('\n');
|
|
84
|
+
|
|
85
|
+
// Return the configuration as a data URI
|
|
86
|
+
return config;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import WireguardBuilder from "./WireguardBuilder";
|
|
2
|
+
import WireguardClientBuilder from "./WireguardClientBuilder";
|
|
3
|
+
|
|
4
|
+
declare const _default: {
|
|
5
|
+
WireguardBuilder: typeof WireguardBuilder;
|
|
6
|
+
WireguardClientBuilder: typeof WireguardClientBuilder;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WireGuard key utilities
|
|
3
|
+
* Pure JavaScript implementation of Curve25519 for WireGuard key generation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const crypto = require('crypto');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate a new WireGuard private key
|
|
10
|
+
* @returns {string} Base64-encoded private key
|
|
11
|
+
*/
|
|
12
|
+
function generatePrivateKey() {
|
|
13
|
+
const key = crypto.randomBytes(32);
|
|
14
|
+
return key.toString('base64');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generate a new WireGuard pre-shared key
|
|
19
|
+
* @returns {string} Base64-encoded pre-shared key
|
|
20
|
+
*/
|
|
21
|
+
function generatePresharedKey() {
|
|
22
|
+
const key = crypto.randomBytes(32);
|
|
23
|
+
return key.toString('base64');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Derive a public key from a private key using Curve25519
|
|
28
|
+
* @param {string} privateKeyBase64 Base64-encoded private key
|
|
29
|
+
* @returns {string} Base64-encoded public key
|
|
30
|
+
*/
|
|
31
|
+
function derivePublicKey(privateKeyBase64) {
|
|
32
|
+
const privateKey = Buffer.from(privateKeyBase64, 'base64');
|
|
33
|
+
const publicKey = crypto.createPublicKey({
|
|
34
|
+
key: crypto.createPrivateKey({
|
|
35
|
+
key: Buffer.concat([
|
|
36
|
+
Buffer.from('302e020100300506032b656e04220420', 'hex'),
|
|
37
|
+
privateKey
|
|
38
|
+
]),
|
|
39
|
+
format: 'der',
|
|
40
|
+
type: 'pkcs8'
|
|
41
|
+
}),
|
|
42
|
+
format: 'der',
|
|
43
|
+
type: 'spki'
|
|
44
|
+
}).export({ format: 'der', type: 'spki' });
|
|
45
|
+
|
|
46
|
+
// Extract the raw public key bytes
|
|
47
|
+
return publicKey.slice(-32).toString('base64');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Generate a new WireGuard key pair
|
|
52
|
+
* @returns {Object} Object containing privateKey and publicKey in base64 format
|
|
53
|
+
*/
|
|
54
|
+
function generateKeyPair() {
|
|
55
|
+
const privateKey = generatePrivateKey();
|
|
56
|
+
const publicKey = derivePublicKey(privateKey);
|
|
57
|
+
return { privateKey, publicKey };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Validate a WireGuard private key
|
|
62
|
+
* @param {string} privateKeyBase64 Base64-encoded private key
|
|
63
|
+
* @returns {boolean} True if valid, false otherwise
|
|
64
|
+
*/
|
|
65
|
+
function isValidPrivateKey(privateKeyBase64) {
|
|
66
|
+
try {
|
|
67
|
+
const buf = Buffer.from(privateKeyBase64, 'base64');
|
|
68
|
+
return buf.length === 32;
|
|
69
|
+
} catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Validate a WireGuard public key
|
|
76
|
+
* @param {string} publicKeyBase64 Base64-encoded public key
|
|
77
|
+
* @returns {boolean} True if valid, false otherwise
|
|
78
|
+
*/
|
|
79
|
+
function isValidPublicKey(publicKeyBase64) {
|
|
80
|
+
try {
|
|
81
|
+
const buf = Buffer.from(publicKeyBase64, 'base64');
|
|
82
|
+
return buf.length === 32;
|
|
83
|
+
} catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
generatePrivateKey,
|
|
90
|
+
generatePresharedKey,
|
|
91
|
+
derivePublicKey,
|
|
92
|
+
generateKeyPair,
|
|
93
|
+
isValidPrivateKey,
|
|
94
|
+
isValidPublicKey
|
|
95
|
+
};
|