@serve.zone/dcrouter 11.0.4 → 11.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/dist_serve/bundle.js +1 -1
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/dist_ts/00_commitinfo_data.d.ts +0 -8
- package/dist_ts/00_commitinfo_data.js +0 -9
- package/dist_ts/cache/classes.cache.cleaner.d.ts +0 -47
- package/dist_ts/cache/classes.cache.cleaner.js +0 -130
- package/dist_ts/cache/documents/classes.cached.email.d.ts +0 -125
- package/dist_ts/cache/documents/classes.cached.email.js +0 -337
- package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +0 -119
- package/dist_ts/cache/documents/classes.cached.ip.reputation.js +0 -323
- package/dist_ts/cache/documents/index.d.ts +0 -2
- package/dist_ts/cache/documents/index.js +0 -3
- package/dist_ts/cache/index.d.ts +0 -4
- package/dist_ts/cache/index.js +0 -7
- package/dist_ts/classes.cert-provision-scheduler.d.ts +0 -53
- package/dist_ts/classes.cert-provision-scheduler.js +0 -110
- package/dist_ts/classes.dcrouter.d.ts +0 -337
- package/dist_ts/classes.dcrouter.js +0 -1405
- package/dist_ts/classes.storage-cert-manager.d.ts +0 -18
- package/dist_ts/classes.storage-cert-manager.js +0 -43
- package/dist_ts/config/classes.api-token-manager.d.ts +0 -46
- package/dist_ts/config/classes.api-token-manager.js +0 -150
- package/dist_ts/config/classes.route-config-manager.d.ts +0 -35
- package/dist_ts/config/classes.route-config-manager.js +0 -231
- package/dist_ts/config/index.d.ts +0 -3
- package/dist_ts/config/index.js +0 -5
- package/dist_ts/config/validator.d.ts +0 -104
- package/dist_ts/config/validator.js +0 -152
- package/dist_ts/errors/base.errors.d.ts +0 -224
- package/dist_ts/errors/base.errors.js +0 -320
- package/dist_ts/errors/error-handler.d.ts +0 -98
- package/dist_ts/errors/error-handler.js +0 -282
- package/dist_ts/errors/error.codes.d.ts +0 -115
- package/dist_ts/errors/error.codes.js +0 -136
- package/dist_ts/errors/index.d.ts +0 -54
- package/dist_ts/errors/index.js +0 -136
- package/dist_ts/errors/reputation.errors.d.ts +0 -183
- package/dist_ts/errors/reputation.errors.js +0 -292
- package/dist_ts/index.d.ts +0 -7
- package/dist_ts/index.js +0 -11
- package/dist_ts/logger.d.ts +0 -21
- package/dist_ts/logger.js +0 -81
- package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
- package/dist_ts/monitoring/classes.metricscache.js +0 -63
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -178
- package/dist_ts/monitoring/classes.metricsmanager.js +0 -642
- package/dist_ts/monitoring/index.d.ts +0 -1
- package/dist_ts/monitoring/index.js +0 -2
- package/dist_ts/opsserver/classes.opsserver.d.ts +0 -37
- package/dist_ts/opsserver/classes.opsserver.js +0 -85
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -31
- package/dist_ts/opsserver/handlers/admin.handler.js +0 -180
- package/dist_ts/opsserver/handlers/api-token.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -32
- package/dist_ts/opsserver/handlers/certificate.handler.js +0 -421
- package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
- package/dist_ts/opsserver/handlers/config.handler.js +0 -192
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
- package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
- package/dist_ts/opsserver/handlers/index.d.ts +0 -11
- package/dist_ts/opsserver/handlers/index.js +0 -12
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
- package/dist_ts/opsserver/handlers/logs.handler.js +0 -256
- package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
- package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
- package/dist_ts/opsserver/handlers/route-management.handler.js +0 -117
- package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
- package/dist_ts/opsserver/handlers/security.handler.js +0 -231
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
- package/dist_ts/opsserver/handlers/stats.handler.js +0 -399
- package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
- package/dist_ts/opsserver/helpers/guards.js +0 -43
- package/dist_ts/opsserver/index.d.ts +0 -1
- package/dist_ts/opsserver/index.js +0 -2
- package/dist_ts/paths.d.ts +0 -26
- package/dist_ts/paths.js +0 -45
- package/dist_ts/plugins.d.ts +0 -79
- package/dist_ts/plugins.js +0 -113
- package/dist_ts/radius/classes.accounting.manager.d.ts +0 -218
- package/dist_ts/radius/classes.accounting.manager.js +0 -417
- package/dist_ts/radius/classes.radius.server.d.ts +0 -171
- package/dist_ts/radius/classes.radius.server.js +0 -385
- package/dist_ts/radius/classes.vlan.manager.d.ts +0 -128
- package/dist_ts/radius/classes.vlan.manager.js +0 -279
- package/dist_ts/radius/index.d.ts +0 -13
- package/dist_ts/radius/index.js +0 -14
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -82
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -227
- package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
- package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
- package/dist_ts/remoteingress/index.d.ts +0 -2
- package/dist_ts/remoteingress/index.js +0 -3
- package/dist_ts/security/classes.contentscanner.d.ts +0 -164
- package/dist_ts/security/classes.contentscanner.js +0 -642
- package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -160
- package/dist_ts/security/classes.ipreputationchecker.js +0 -537
- package/dist_ts/security/classes.securitylogger.d.ts +0 -144
- package/dist_ts/security/classes.securitylogger.js +0 -233
- package/dist_ts/security/index.d.ts +0 -3
- package/dist_ts/security/index.js +0 -4
- package/dist_ts/sms/classes.smsservice.d.ts +0 -15
- package/dist_ts/sms/classes.smsservice.js +0 -72
- package/dist_ts/sms/config/sms.config.d.ts +0 -93
- package/dist_ts/sms/config/sms.config.js +0 -2
- package/dist_ts/sms/config/sms.schema.d.ts +0 -5
- package/dist_ts/sms/config/sms.schema.js +0 -121
- package/dist_ts/sms/index.d.ts +0 -1
- package/dist_ts/sms/index.js +0 -2
- package/dist_ts/storage/classes.storagemanager.d.ts +0 -83
- package/dist_ts/storage/classes.storagemanager.js +0 -350
- package/dist_ts/storage/index.d.ts +0 -1
- package/dist_ts/storage/index.js +0 -3
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import { logger } from '../logger.js';
|
|
3
|
-
import { VlanManager } from './classes.vlan.manager.js';
|
|
4
|
-
import { AccountingManager } from './classes.accounting.manager.js';
|
|
5
|
-
/**
|
|
6
|
-
* RADIUS Server wrapper that provides:
|
|
7
|
-
* - MAC Authentication Bypass (MAB) for network devices
|
|
8
|
-
* - VLAN assignment based on MAC address
|
|
9
|
-
* - Accounting for session tracking and billing
|
|
10
|
-
* - Integration with SmartProxy routing
|
|
11
|
-
*/
|
|
12
|
-
export class RadiusServer {
|
|
13
|
-
radiusServer;
|
|
14
|
-
vlanManager;
|
|
15
|
-
accountingManager;
|
|
16
|
-
config;
|
|
17
|
-
storageManager;
|
|
18
|
-
clientSecrets = new Map();
|
|
19
|
-
running = false;
|
|
20
|
-
// Statistics
|
|
21
|
-
stats = {
|
|
22
|
-
authRequests: 0,
|
|
23
|
-
authAccepts: 0,
|
|
24
|
-
authRejects: 0,
|
|
25
|
-
accountingRequests: 0,
|
|
26
|
-
startTime: 0,
|
|
27
|
-
};
|
|
28
|
-
constructor(config, storageManager) {
|
|
29
|
-
this.config = {
|
|
30
|
-
authPort: config.authPort ?? 1812,
|
|
31
|
-
acctPort: config.acctPort ?? 1813,
|
|
32
|
-
bindAddress: config.bindAddress ?? '0.0.0.0',
|
|
33
|
-
...config,
|
|
34
|
-
};
|
|
35
|
-
this.storageManager = storageManager;
|
|
36
|
-
// Initialize VLAN manager
|
|
37
|
-
this.vlanManager = new VlanManager(config.vlanAssignment, storageManager);
|
|
38
|
-
// Initialize accounting manager
|
|
39
|
-
this.accountingManager = new AccountingManager(config.accounting, storageManager);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Start the RADIUS server
|
|
43
|
-
*/
|
|
44
|
-
async start() {
|
|
45
|
-
if (this.running) {
|
|
46
|
-
logger.log('warn', 'RADIUS server is already running');
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
logger.log('info', `Starting RADIUS server on ${this.config.bindAddress}:${this.config.authPort} (auth) and ${this.config.acctPort} (acct)`);
|
|
50
|
-
// Initialize managers
|
|
51
|
-
await this.vlanManager.initialize();
|
|
52
|
-
await this.accountingManager.initialize();
|
|
53
|
-
// Import static VLAN mappings if provided
|
|
54
|
-
if (this.config.vlanAssignment?.mappings) {
|
|
55
|
-
await this.vlanManager.importMappings(this.config.vlanAssignment.mappings);
|
|
56
|
-
}
|
|
57
|
-
// Build client secrets map
|
|
58
|
-
this.buildClientSecretsMap();
|
|
59
|
-
// Create the RADIUS server
|
|
60
|
-
this.radiusServer = new plugins.smartradius.RadiusServer({
|
|
61
|
-
authPort: this.config.authPort,
|
|
62
|
-
acctPort: this.config.acctPort,
|
|
63
|
-
bindAddress: this.config.bindAddress,
|
|
64
|
-
defaultSecret: this.getDefaultSecret(),
|
|
65
|
-
authenticationHandler: this.handleAuthentication.bind(this),
|
|
66
|
-
accountingHandler: this.handleAccounting.bind(this),
|
|
67
|
-
});
|
|
68
|
-
// Configure per-client secrets
|
|
69
|
-
for (const [ip, secret] of this.clientSecrets) {
|
|
70
|
-
this.radiusServer.setClientSecret(ip, secret);
|
|
71
|
-
}
|
|
72
|
-
// Start the server
|
|
73
|
-
await this.radiusServer.start();
|
|
74
|
-
this.running = true;
|
|
75
|
-
this.stats.startTime = Date.now();
|
|
76
|
-
logger.log('info', `RADIUS server started with ${this.config.clients.length} configured clients`);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Stop the RADIUS server
|
|
80
|
-
*/
|
|
81
|
-
async stop() {
|
|
82
|
-
if (!this.running) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
logger.log('info', 'Stopping RADIUS server...');
|
|
86
|
-
if (this.radiusServer) {
|
|
87
|
-
await this.radiusServer.stop();
|
|
88
|
-
this.radiusServer = undefined;
|
|
89
|
-
}
|
|
90
|
-
this.running = false;
|
|
91
|
-
logger.log('info', 'RADIUS server stopped');
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Handle authentication request
|
|
95
|
-
*/
|
|
96
|
-
async handleAuthentication(request) {
|
|
97
|
-
this.stats.authRequests++;
|
|
98
|
-
const authData = {
|
|
99
|
-
username: request.attributes?.UserName || '',
|
|
100
|
-
password: request.attributes?.UserPassword,
|
|
101
|
-
nasIpAddress: request.attributes?.NasIpAddress || request.source?.address || '',
|
|
102
|
-
nasPort: request.attributes?.NasPort,
|
|
103
|
-
nasPortType: request.attributes?.NasPortType,
|
|
104
|
-
nasIdentifier: request.attributes?.NasIdentifier,
|
|
105
|
-
calledStationId: request.attributes?.CalledStationId,
|
|
106
|
-
callingStationId: request.attributes?.CallingStationId,
|
|
107
|
-
serviceType: request.attributes?.ServiceType,
|
|
108
|
-
};
|
|
109
|
-
logger.log('debug', `RADIUS Auth Request: user=${authData.username}, NAS=${authData.nasIpAddress}`);
|
|
110
|
-
// Perform MAC Authentication Bypass (MAB)
|
|
111
|
-
// In MAB, the username is typically the MAC address
|
|
112
|
-
const result = await this.performMabAuthentication(authData);
|
|
113
|
-
if (result.success) {
|
|
114
|
-
this.stats.authAccepts++;
|
|
115
|
-
logger.log('info', `RADIUS Auth Accept: user=${authData.username}, VLAN=${result.vlanId}`);
|
|
116
|
-
// Build response with VLAN attributes
|
|
117
|
-
const response = {
|
|
118
|
-
code: plugins.smartradius.ERadiusCode.AccessAccept,
|
|
119
|
-
replyMessage: result.replyMessage,
|
|
120
|
-
};
|
|
121
|
-
// Add VLAN attributes if assigned
|
|
122
|
-
if (result.vlanId !== undefined) {
|
|
123
|
-
response.tunnelType = 13; // VLAN
|
|
124
|
-
response.tunnelMediumType = 6; // IEEE 802
|
|
125
|
-
response.tunnelPrivateGroupId = String(result.vlanId);
|
|
126
|
-
}
|
|
127
|
-
// Add session timeout if specified
|
|
128
|
-
if (result.sessionTimeout) {
|
|
129
|
-
response.sessionTimeout = result.sessionTimeout;
|
|
130
|
-
}
|
|
131
|
-
// Add idle timeout if specified
|
|
132
|
-
if (result.idleTimeout) {
|
|
133
|
-
response.idleTimeout = result.idleTimeout;
|
|
134
|
-
}
|
|
135
|
-
// Add framed IP if specified
|
|
136
|
-
if (result.framedIpAddress) {
|
|
137
|
-
response.framedIpAddress = result.framedIpAddress;
|
|
138
|
-
}
|
|
139
|
-
return response;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
this.stats.authRejects++;
|
|
143
|
-
logger.log('warn', `RADIUS Auth Reject: user=${authData.username}, reason=${result.rejectReason}`);
|
|
144
|
-
return {
|
|
145
|
-
code: plugins.smartradius.ERadiusCode.AccessReject,
|
|
146
|
-
replyMessage: result.rejectReason || 'Access Denied',
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Handle accounting request
|
|
152
|
-
*/
|
|
153
|
-
async handleAccounting(request) {
|
|
154
|
-
this.stats.accountingRequests++;
|
|
155
|
-
if (!this.config.accounting?.enabled) {
|
|
156
|
-
// Still respond even if not tracking
|
|
157
|
-
return { code: plugins.smartradius.ERadiusCode.AccountingResponse };
|
|
158
|
-
}
|
|
159
|
-
const statusType = request.attributes?.AcctStatusType;
|
|
160
|
-
const sessionId = request.attributes?.AcctSessionId || '';
|
|
161
|
-
const accountingData = {
|
|
162
|
-
sessionId,
|
|
163
|
-
username: request.attributes?.UserName || '',
|
|
164
|
-
macAddress: request.attributes?.CallingStationId,
|
|
165
|
-
nasIpAddress: request.attributes?.NasIpAddress || request.source?.address || '',
|
|
166
|
-
nasPort: request.attributes?.NasPort,
|
|
167
|
-
nasPortType: request.attributes?.NasPortType,
|
|
168
|
-
nasIdentifier: request.attributes?.NasIdentifier,
|
|
169
|
-
calledStationId: request.attributes?.CalledStationId,
|
|
170
|
-
callingStationId: request.attributes?.CallingStationId,
|
|
171
|
-
inputOctets: request.attributes?.AcctInputOctets,
|
|
172
|
-
outputOctets: request.attributes?.AcctOutputOctets,
|
|
173
|
-
inputPackets: request.attributes?.AcctInputPackets,
|
|
174
|
-
outputPackets: request.attributes?.AcctOutputPackets,
|
|
175
|
-
sessionTime: request.attributes?.AcctSessionTime,
|
|
176
|
-
terminateCause: request.attributes?.AcctTerminateCause,
|
|
177
|
-
serviceType: request.attributes?.ServiceType,
|
|
178
|
-
};
|
|
179
|
-
try {
|
|
180
|
-
switch (statusType) {
|
|
181
|
-
case plugins.smartradius.EAcctStatusType.Start:
|
|
182
|
-
logger.log('debug', `RADIUS Acct Start: session=${sessionId}, user=${accountingData.username}`);
|
|
183
|
-
await this.accountingManager.handleAccountingStart(accountingData);
|
|
184
|
-
break;
|
|
185
|
-
case plugins.smartradius.EAcctStatusType.Stop:
|
|
186
|
-
logger.log('debug', `RADIUS Acct Stop: session=${sessionId}`);
|
|
187
|
-
await this.accountingManager.handleAccountingStop(accountingData);
|
|
188
|
-
break;
|
|
189
|
-
case plugins.smartradius.EAcctStatusType.InterimUpdate:
|
|
190
|
-
logger.log('debug', `RADIUS Acct Interim: session=${sessionId}`);
|
|
191
|
-
await this.accountingManager.handleAccountingUpdate(accountingData);
|
|
192
|
-
break;
|
|
193
|
-
default:
|
|
194
|
-
logger.log('debug', `RADIUS Acct Unknown status type: ${statusType}`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
logger.log('error', `RADIUS accounting error: ${error.message}`);
|
|
199
|
-
}
|
|
200
|
-
return { code: plugins.smartradius.ERadiusCode.AccountingResponse };
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Perform MAC Authentication Bypass
|
|
204
|
-
*/
|
|
205
|
-
async performMabAuthentication(data) {
|
|
206
|
-
// Extract MAC address from username or CallingStationId
|
|
207
|
-
const macAddress = this.extractMacAddress(data);
|
|
208
|
-
if (!macAddress) {
|
|
209
|
-
return {
|
|
210
|
-
success: false,
|
|
211
|
-
rejectReason: 'No MAC address found',
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
// Look up VLAN assignment
|
|
215
|
-
const vlanResult = this.vlanManager.assignVlan(macAddress);
|
|
216
|
-
if (!vlanResult.assigned) {
|
|
217
|
-
return {
|
|
218
|
-
success: false,
|
|
219
|
-
rejectReason: 'Unknown MAC address',
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
// Build successful result
|
|
223
|
-
const result = {
|
|
224
|
-
success: true,
|
|
225
|
-
vlanId: vlanResult.vlan,
|
|
226
|
-
replyMessage: vlanResult.isDefault
|
|
227
|
-
? `Assigned to default VLAN ${vlanResult.vlan}`
|
|
228
|
-
: `Assigned to VLAN ${vlanResult.vlan}`,
|
|
229
|
-
};
|
|
230
|
-
// Apply any additional settings from the matched rule
|
|
231
|
-
if (vlanResult.matchedRule) {
|
|
232
|
-
// Future: Add session timeout, idle timeout, etc. from rule
|
|
233
|
-
}
|
|
234
|
-
return result;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Extract MAC address from authentication data
|
|
238
|
-
*/
|
|
239
|
-
extractMacAddress(data) {
|
|
240
|
-
// Try CallingStationId first (most common for MAB)
|
|
241
|
-
if (data.callingStationId) {
|
|
242
|
-
return this.normalizeMac(data.callingStationId);
|
|
243
|
-
}
|
|
244
|
-
// Try username (often MAC address in MAB)
|
|
245
|
-
if (data.username && this.looksLikeMac(data.username)) {
|
|
246
|
-
return this.normalizeMac(data.username);
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Check if a string looks like a MAC address
|
|
252
|
-
*/
|
|
253
|
-
looksLikeMac(value) {
|
|
254
|
-
// Remove common separators and check length
|
|
255
|
-
const cleaned = value.replace(/[-:. ]/g, '');
|
|
256
|
-
return /^[0-9a-fA-F]{12}$/.test(cleaned);
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Normalize MAC address format
|
|
260
|
-
*/
|
|
261
|
-
normalizeMac(mac) {
|
|
262
|
-
return this.vlanManager.normalizeMac(mac);
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Build client secrets map from configuration
|
|
266
|
-
*/
|
|
267
|
-
buildClientSecretsMap() {
|
|
268
|
-
this.clientSecrets.clear();
|
|
269
|
-
for (const client of this.config.clients) {
|
|
270
|
-
if (!client.enabled) {
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
// Handle CIDR ranges
|
|
274
|
-
if (client.ipRange.includes('/')) {
|
|
275
|
-
// For CIDR ranges, we'll use the network address as key
|
|
276
|
-
// In practice, smartradius may handle this differently
|
|
277
|
-
const [network] = client.ipRange.split('/');
|
|
278
|
-
this.clientSecrets.set(network, client.secret);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
this.clientSecrets.set(client.ipRange, client.secret);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Get default secret for unknown clients
|
|
287
|
-
*/
|
|
288
|
-
getDefaultSecret() {
|
|
289
|
-
// Use first enabled client's secret as default, or a random one
|
|
290
|
-
for (const client of this.config.clients) {
|
|
291
|
-
if (client.enabled) {
|
|
292
|
-
return client.secret;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return plugins.crypto.randomBytes(16).toString('hex');
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Add a RADIUS client
|
|
299
|
-
*/
|
|
300
|
-
async addClient(client) {
|
|
301
|
-
// Check if client already exists
|
|
302
|
-
const existingIndex = this.config.clients.findIndex(c => c.name === client.name);
|
|
303
|
-
if (existingIndex >= 0) {
|
|
304
|
-
this.config.clients[existingIndex] = client;
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
307
|
-
this.config.clients.push(client);
|
|
308
|
-
}
|
|
309
|
-
// Update client secrets if running
|
|
310
|
-
if (this.running && this.radiusServer && client.enabled) {
|
|
311
|
-
if (client.ipRange.includes('/')) {
|
|
312
|
-
const [network] = client.ipRange.split('/');
|
|
313
|
-
this.radiusServer.setClientSecret(network, client.secret);
|
|
314
|
-
this.clientSecrets.set(network, client.secret);
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
this.radiusServer.setClientSecret(client.ipRange, client.secret);
|
|
318
|
-
this.clientSecrets.set(client.ipRange, client.secret);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
logger.log('info', `RADIUS client ${client.enabled ? 'added' : 'disabled'}: ${client.name} (${client.ipRange})`);
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Remove a RADIUS client
|
|
325
|
-
*/
|
|
326
|
-
removeClient(name) {
|
|
327
|
-
const index = this.config.clients.findIndex(c => c.name === name);
|
|
328
|
-
if (index >= 0) {
|
|
329
|
-
const client = this.config.clients[index];
|
|
330
|
-
this.config.clients.splice(index, 1);
|
|
331
|
-
// Remove from secrets map
|
|
332
|
-
if (client.ipRange.includes('/')) {
|
|
333
|
-
const [network] = client.ipRange.split('/');
|
|
334
|
-
this.clientSecrets.delete(network);
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
this.clientSecrets.delete(client.ipRange);
|
|
338
|
-
}
|
|
339
|
-
logger.log('info', `RADIUS client removed: ${name}`);
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
return false;
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Get configured clients
|
|
346
|
-
*/
|
|
347
|
-
getClients() {
|
|
348
|
-
return [...this.config.clients];
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Get VLAN manager for direct access to VLAN operations
|
|
352
|
-
*/
|
|
353
|
-
getVlanManager() {
|
|
354
|
-
return this.vlanManager;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Get accounting manager for direct access to accounting operations
|
|
358
|
-
*/
|
|
359
|
-
getAccountingManager() {
|
|
360
|
-
return this.accountingManager;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Get server statistics
|
|
364
|
-
*/
|
|
365
|
-
getStats() {
|
|
366
|
-
return {
|
|
367
|
-
running: this.running,
|
|
368
|
-
uptime: this.running ? Date.now() - this.stats.startTime : 0,
|
|
369
|
-
authRequests: this.stats.authRequests,
|
|
370
|
-
authAccepts: this.stats.authAccepts,
|
|
371
|
-
authRejects: this.stats.authRejects,
|
|
372
|
-
accountingRequests: this.stats.accountingRequests,
|
|
373
|
-
activeSessions: this.accountingManager.getStats().activeSessions,
|
|
374
|
-
vlanMappings: this.vlanManager.getStats().totalMappings,
|
|
375
|
-
clients: this.config.clients.filter(c => c.enabled).length,
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Check if server is running
|
|
380
|
-
*/
|
|
381
|
-
isRunning() {
|
|
382
|
-
return this.running;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5yYWRpdXMuc2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcmFkaXVzL2NsYXNzZXMucmFkaXVzLnNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXRDLE9BQU8sRUFBRSxXQUFXLEVBQWlELE1BQU0sMkJBQTJCLENBQUM7QUFDdkcsT0FBTyxFQUFFLGlCQUFpQixFQUEwRCxNQUFNLGlDQUFpQyxDQUFDO0FBOEU1SDs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUNmLFlBQVksQ0FBb0M7SUFDaEQsV0FBVyxDQUFjO0lBQ3pCLGlCQUFpQixDQUFvQjtJQUNyQyxNQUFNLENBQXNCO0lBQzVCLGNBQWMsQ0FBa0I7SUFDaEMsYUFBYSxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQy9DLE9BQU8sR0FBWSxLQUFLLENBQUM7SUFFakMsYUFBYTtJQUNMLEtBQUssR0FBRztRQUNkLFlBQVksRUFBRSxDQUFDO1FBQ2YsV0FBVyxFQUFFLENBQUM7UUFDZCxXQUFXLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixFQUFFLENBQUM7UUFDckIsU0FBUyxFQUFFLENBQUM7S0FDYixDQUFDO0lBRUYsWUFBWSxNQUEyQixFQUFFLGNBQStCO1FBQ3RFLElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDWixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJO1lBQ2pDLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxJQUFJLElBQUk7WUFDakMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLElBQUksU0FBUztZQUM1QyxHQUFHLE1BQU07U0FDVixDQUFDO1FBQ0YsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFFckMsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxX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
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import type { StorageManager } from '../storage/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* MAC address to VLAN mapping
|
|
4
|
-
*/
|
|
5
|
-
export interface IMacVlanMapping {
|
|
6
|
-
/** MAC address (full) or OUI pattern (e.g., "00:11:22" for vendor prefix) */
|
|
7
|
-
mac: string;
|
|
8
|
-
/** VLAN ID to assign */
|
|
9
|
-
vlan: number;
|
|
10
|
-
/** Optional description */
|
|
11
|
-
description?: string;
|
|
12
|
-
/** Whether this mapping is enabled */
|
|
13
|
-
enabled: boolean;
|
|
14
|
-
/** Creation timestamp */
|
|
15
|
-
createdAt: number;
|
|
16
|
-
/** Last update timestamp */
|
|
17
|
-
updatedAt: number;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* VLAN assignment result
|
|
21
|
-
*/
|
|
22
|
-
export interface IVlanAssignmentResult {
|
|
23
|
-
/** Whether a VLAN was successfully assigned */
|
|
24
|
-
assigned: boolean;
|
|
25
|
-
/** The assigned VLAN ID (or default if not matched) */
|
|
26
|
-
vlan: number;
|
|
27
|
-
/** The matching rule (if any) */
|
|
28
|
-
matchedRule?: IMacVlanMapping;
|
|
29
|
-
/** Whether default VLAN was used */
|
|
30
|
-
isDefault: boolean;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* VlanManager configuration
|
|
34
|
-
*/
|
|
35
|
-
export interface IVlanManagerConfig {
|
|
36
|
-
/** Default VLAN for unknown MACs */
|
|
37
|
-
defaultVlan?: number;
|
|
38
|
-
/** Whether to allow unknown MACs (assign default VLAN) or reject */
|
|
39
|
-
allowUnknownMacs?: boolean;
|
|
40
|
-
/** Storage key prefix for persistence */
|
|
41
|
-
storagePrefix?: string;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Manages MAC address to VLAN mappings with support for:
|
|
45
|
-
* - Exact MAC address matching
|
|
46
|
-
* - OUI (vendor prefix) pattern matching
|
|
47
|
-
* - Wildcard patterns
|
|
48
|
-
* - Default VLAN for unknown devices
|
|
49
|
-
*/
|
|
50
|
-
export declare class VlanManager {
|
|
51
|
-
private mappings;
|
|
52
|
-
private config;
|
|
53
|
-
private storageManager?;
|
|
54
|
-
private normalizedMacCache;
|
|
55
|
-
constructor(config?: IVlanManagerConfig, storageManager?: StorageManager);
|
|
56
|
-
/**
|
|
57
|
-
* Initialize the VLAN manager and load persisted mappings
|
|
58
|
-
*/
|
|
59
|
-
initialize(): Promise<void>;
|
|
60
|
-
/**
|
|
61
|
-
* Normalize a MAC address to lowercase with colons
|
|
62
|
-
* Accepts formats: 00:11:22:33:44:55, 00-11-22-33-44-55, 001122334455
|
|
63
|
-
*/
|
|
64
|
-
normalizeMac(mac: string): string;
|
|
65
|
-
/**
|
|
66
|
-
* Check if a MAC address matches a pattern
|
|
67
|
-
* Supports:
|
|
68
|
-
* - Exact match: "00:11:22:33:44:55"
|
|
69
|
-
* - OUI match: "00:11:22" (matches any device with this vendor prefix)
|
|
70
|
-
* - Wildcard: "*" (matches all)
|
|
71
|
-
*/
|
|
72
|
-
macMatchesPattern(mac: string, pattern: string): boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Add or update a MAC to VLAN mapping
|
|
75
|
-
*/
|
|
76
|
-
addMapping(mapping: Omit<IMacVlanMapping, 'createdAt' | 'updatedAt'>): Promise<IMacVlanMapping>;
|
|
77
|
-
/**
|
|
78
|
-
* Remove a MAC to VLAN mapping
|
|
79
|
-
*/
|
|
80
|
-
removeMapping(mac: string): Promise<boolean>;
|
|
81
|
-
/**
|
|
82
|
-
* Get a specific mapping by MAC
|
|
83
|
-
*/
|
|
84
|
-
getMapping(mac: string): IMacVlanMapping | undefined;
|
|
85
|
-
/**
|
|
86
|
-
* Get all mappings
|
|
87
|
-
*/
|
|
88
|
-
getAllMappings(): IMacVlanMapping[];
|
|
89
|
-
/**
|
|
90
|
-
* Determine VLAN assignment for a MAC address
|
|
91
|
-
* Returns the most specific matching rule (exact > OUI > wildcard > default)
|
|
92
|
-
*/
|
|
93
|
-
assignVlan(mac: string): IVlanAssignmentResult;
|
|
94
|
-
/**
|
|
95
|
-
* Bulk import mappings
|
|
96
|
-
*/
|
|
97
|
-
importMappings(mappings: Array<Omit<IMacVlanMapping, 'createdAt' | 'updatedAt'>>): Promise<number>;
|
|
98
|
-
/**
|
|
99
|
-
* Export all mappings
|
|
100
|
-
*/
|
|
101
|
-
exportMappings(): IMacVlanMapping[];
|
|
102
|
-
/**
|
|
103
|
-
* Update configuration
|
|
104
|
-
*/
|
|
105
|
-
updateConfig(config: Partial<IVlanManagerConfig>): void;
|
|
106
|
-
/**
|
|
107
|
-
* Get current configuration
|
|
108
|
-
*/
|
|
109
|
-
getConfig(): Required<IVlanManagerConfig>;
|
|
110
|
-
/**
|
|
111
|
-
* Get statistics
|
|
112
|
-
*/
|
|
113
|
-
getStats(): {
|
|
114
|
-
totalMappings: number;
|
|
115
|
-
enabledMappings: number;
|
|
116
|
-
exactMatches: number;
|
|
117
|
-
ouiPatterns: number;
|
|
118
|
-
wildcardPatterns: number;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Load mappings from storage
|
|
122
|
-
*/
|
|
123
|
-
private loadMappings;
|
|
124
|
-
/**
|
|
125
|
-
* Save mappings to storage
|
|
126
|
-
*/
|
|
127
|
-
private saveMappings;
|
|
128
|
-
}
|