@highstate/wireguard 0.9.3 → 0.9.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/{chunk-7BHZHUOK.js → chunk-PXOBQDLU.js} +121 -67
- package/dist/chunk-PXOBQDLU.js.map +1 -0
- package/dist/config/index.js +2 -4
- package/dist/config/index.js.map +1 -1
- package/dist/config-bundle/index.js +2 -4
- package/dist/config-bundle/index.js.map +1 -1
- package/dist/highstate.manifest.json +7 -6
- package/dist/identity/index.js +16 -62
- package/dist/identity/index.js.map +1 -1
- package/dist/network/index.js +3 -4
- package/dist/network/index.js.map +1 -1
- package/dist/node/index.js +114 -157
- package/dist/node/index.js.map +1 -1
- package/dist/peer/index.js +15 -30
- package/dist/peer/index.js.map +1 -1
- package/dist/peer-patch/index.js +52 -0
- package/dist/peer-patch/index.js.map +1 -0
- package/package.json +12 -10
- package/dist/chunk-7BHZHUOK.js.map +0 -1
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
// src/shared.ts
|
|
2
|
+
import {
|
|
3
|
+
l34EndpointToString,
|
|
4
|
+
l3EndpointToString,
|
|
5
|
+
l3ToL4Endpoint,
|
|
6
|
+
l4EndpointToString,
|
|
7
|
+
parseL34Endpoint,
|
|
8
|
+
parseL4Endpoint
|
|
9
|
+
} from "@highstate/common";
|
|
2
10
|
import { x25519 } from "@noble/curves/ed25519";
|
|
3
11
|
|
|
4
12
|
// ../../node_modules/@noble/hashes/esm/cryptoNode.js
|
|
@@ -79,6 +87,18 @@ function y2(t, i2) {
|
|
|
79
87
|
throw new Error("Wrong number of arguments");
|
|
80
88
|
}
|
|
81
89
|
|
|
90
|
+
// ../../node_modules/remeda/dist/chunk-7ZI6JRPB.js
|
|
91
|
+
function T(...e) {
|
|
92
|
+
return y2(y3, e);
|
|
93
|
+
}
|
|
94
|
+
function y3(e) {
|
|
95
|
+
let u = e, n = /* @__PURE__ */ new Set();
|
|
96
|
+
return (t, i2, d) => {
|
|
97
|
+
let r = u(t, i2, d);
|
|
98
|
+
return n.has(r) ? s : (n.add(r), { done: false, hasNext: true, next: t });
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
82
102
|
// ../../node_modules/remeda/dist/chunk-QJLMYOTX.js
|
|
83
103
|
function i(...e) {
|
|
84
104
|
return y2(a, e);
|
|
@@ -89,6 +109,7 @@ function a() {
|
|
|
89
109
|
}
|
|
90
110
|
|
|
91
111
|
// src/shared.ts
|
|
112
|
+
import { getBestEndpoint } from "@highstate/k8s";
|
|
92
113
|
function generateKey() {
|
|
93
114
|
const key = x25519.utils.randomPrivateKey();
|
|
94
115
|
return Buffer.from(key).toString("base64");
|
|
@@ -110,7 +131,7 @@ function combinePresharedKeyParts(part1, part2) {
|
|
|
110
131
|
}
|
|
111
132
|
return Buffer.from(result).toString("base64");
|
|
112
133
|
}
|
|
113
|
-
function generatePeerConfig(identity, peer) {
|
|
134
|
+
function generatePeerConfig(identity, peer, cluster) {
|
|
114
135
|
const lines = [
|
|
115
136
|
//
|
|
116
137
|
"[Peer]",
|
|
@@ -120,40 +141,47 @@ function generatePeerConfig(identity, peer) {
|
|
|
120
141
|
if (peer.allowedIps.length > 0) {
|
|
121
142
|
lines.push(`AllowedIPs = ${peer.allowedIps.join(", ")}`);
|
|
122
143
|
}
|
|
123
|
-
|
|
124
|
-
|
|
144
|
+
const bestEndpoint = getBestEndpoint(peer.endpoints, cluster);
|
|
145
|
+
if (bestEndpoint) {
|
|
146
|
+
lines.push(`Endpoint = ${l4EndpointToString(bestEndpoint)}`);
|
|
125
147
|
}
|
|
126
|
-
if (identity.presharedKeyPart && peer.presharedKeyPart) {
|
|
127
|
-
const presharedKey = combinePresharedKeyParts(
|
|
148
|
+
if (identity.peer.presharedKeyPart && peer.presharedKeyPart) {
|
|
149
|
+
const presharedKey = combinePresharedKeyParts(
|
|
150
|
+
identity.peer.presharedKeyPart,
|
|
151
|
+
peer.presharedKeyPart
|
|
152
|
+
);
|
|
128
153
|
lines.push(`PresharedKey = ${presharedKey}`);
|
|
129
|
-
} else if (identity.
|
|
130
|
-
if (
|
|
131
|
-
throw new Error(
|
|
154
|
+
} else if (peer.presharedKey || identity.peer.presharedKey) {
|
|
155
|
+
if (peer.presharedKey !== identity.peer.presharedKey) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Preshared keys do not match for peers: ${peer.name} and ${identity.peer.name}`
|
|
158
|
+
);
|
|
132
159
|
}
|
|
133
|
-
lines.push(`PresharedKey = ${
|
|
160
|
+
lines.push(`PresharedKey = ${peer.presharedKey}`);
|
|
134
161
|
}
|
|
135
162
|
return lines.join("\n");
|
|
136
163
|
}
|
|
137
164
|
function generateIdentityConfig({
|
|
138
165
|
identity,
|
|
139
166
|
peers,
|
|
140
|
-
listenPort,
|
|
141
|
-
dns,
|
|
142
|
-
preUp,
|
|
143
|
-
postUp,
|
|
144
|
-
preDown,
|
|
145
|
-
postDown,
|
|
146
|
-
defaultInterface
|
|
167
|
+
listenPort = identity.peer.listenPort,
|
|
168
|
+
dns = [],
|
|
169
|
+
preUp = [],
|
|
170
|
+
postUp = [],
|
|
171
|
+
preDown = [],
|
|
172
|
+
postDown = [],
|
|
173
|
+
defaultInterface,
|
|
174
|
+
cluster
|
|
147
175
|
}) {
|
|
148
|
-
const allDns = i(peers.flatMap((peer) => peer.dns
|
|
149
|
-
const excludedIps = i(peers.flatMap((peer) => peer.excludedIps
|
|
176
|
+
const allDns = i(peers.flatMap((peer) => peer.dns).concat(dns));
|
|
177
|
+
const excludedIps = i(peers.flatMap((peer) => peer.excludedIps));
|
|
150
178
|
const lines = [
|
|
151
179
|
//
|
|
152
180
|
"[Interface]",
|
|
153
|
-
`# ${identity.name}`
|
|
181
|
+
`# ${identity.peer.name}`
|
|
154
182
|
];
|
|
155
|
-
if (identity.address) {
|
|
156
|
-
lines.push(`Address = ${identity.address}`);
|
|
183
|
+
if (identity.peer.address) {
|
|
184
|
+
lines.push(`Address = ${identity.peer.address}`);
|
|
157
185
|
}
|
|
158
186
|
lines.push(
|
|
159
187
|
//
|
|
@@ -166,73 +194,89 @@ function generateIdentityConfig({
|
|
|
166
194
|
if (listenPort) {
|
|
167
195
|
lines.push(`ListenPort = ${listenPort}`);
|
|
168
196
|
}
|
|
169
|
-
if (preUp) {
|
|
197
|
+
if (preUp.length > 0) {
|
|
170
198
|
lines.push();
|
|
171
199
|
for (const command of preUp) {
|
|
172
200
|
lines.push(`PreUp = ${command}`);
|
|
173
201
|
}
|
|
174
202
|
}
|
|
175
|
-
if (postUp) {
|
|
203
|
+
if (postUp.length > 0) {
|
|
176
204
|
lines.push();
|
|
177
205
|
for (const command of postUp) {
|
|
178
206
|
lines.push(`PostUp = ${command}`);
|
|
179
207
|
}
|
|
180
208
|
}
|
|
181
|
-
if (preDown) {
|
|
209
|
+
if (preDown.length > 0) {
|
|
182
210
|
lines.push();
|
|
183
211
|
for (const command of preDown) {
|
|
184
212
|
lines.push(`PreDown = ${command}`);
|
|
185
213
|
}
|
|
186
214
|
}
|
|
187
|
-
if (postDown) {
|
|
215
|
+
if (postDown.length > 0) {
|
|
188
216
|
lines.push();
|
|
189
217
|
for (const command of postDown) {
|
|
190
218
|
lines.push(`PostDown = ${command}`);
|
|
191
219
|
}
|
|
192
220
|
}
|
|
193
221
|
if (defaultInterface) {
|
|
222
|
+
lines.push();
|
|
194
223
|
for (const excludedIp of excludedIps) {
|
|
195
224
|
lines.push(`PostUp = ip route add ${excludedIp} dev ${defaultInterface}`);
|
|
196
225
|
}
|
|
197
226
|
}
|
|
198
|
-
const otherPeers = peers.filter((peer) => peer.name !== identity.name);
|
|
227
|
+
const otherPeers = peers.filter((peer) => peer.name !== identity.peer.name);
|
|
199
228
|
for (const peer of otherPeers) {
|
|
200
229
|
lines.push("");
|
|
201
|
-
lines.push(generatePeerConfig(identity, peer));
|
|
230
|
+
lines.push(generatePeerConfig(identity, peer, cluster));
|
|
202
231
|
}
|
|
203
232
|
return lines.join("\n");
|
|
204
233
|
}
|
|
205
|
-
function
|
|
234
|
+
function calculateEndpoints({ endpoints, listenPort }, { l3Endpoints, l4Endpoints }) {
|
|
235
|
+
return T(
|
|
236
|
+
[
|
|
237
|
+
...l3Endpoints.map((e) => l3ToL4Endpoint(e, listenPort ?? 51820)),
|
|
238
|
+
...l4Endpoints,
|
|
239
|
+
...endpoints.map(parseL4Endpoint)
|
|
240
|
+
],
|
|
241
|
+
(endpoint) => l4EndpointToString(endpoint)
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
function calculateAllowedIps({ address, exitNode }, { network }, allowedEndpoints) {
|
|
206
245
|
const result = /* @__PURE__ */ new Set();
|
|
207
246
|
if (address) {
|
|
208
247
|
result.add(address);
|
|
209
248
|
}
|
|
210
|
-
if (allowedIps) {
|
|
211
|
-
for (const ip of allowedIps) {
|
|
212
|
-
result.add(ip);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
249
|
if (exitNode) {
|
|
216
250
|
result.add("0.0.0.0/0");
|
|
217
251
|
if (network?.ipv6) {
|
|
218
252
|
result.add("::/0");
|
|
219
253
|
}
|
|
220
254
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
result.add(service.spec.clusterIP);
|
|
225
|
-
}
|
|
255
|
+
for (const endpoint of allowedEndpoints) {
|
|
256
|
+
if (endpoint.type !== "hostname") {
|
|
257
|
+
result.add(l3EndpointToString(endpoint));
|
|
226
258
|
}
|
|
227
259
|
}
|
|
228
260
|
return Array.from(result);
|
|
229
261
|
}
|
|
230
|
-
function
|
|
262
|
+
function calculateAllowedEndpoints({ allowedEndpoints }, {
|
|
263
|
+
allowedL3Endpoints,
|
|
264
|
+
allowedL4Endpoints
|
|
265
|
+
}) {
|
|
266
|
+
return T(
|
|
267
|
+
[
|
|
268
|
+
//
|
|
269
|
+
...allowedL3Endpoints,
|
|
270
|
+
...allowedL4Endpoints,
|
|
271
|
+
...allowedEndpoints.map(parseL34Endpoint)
|
|
272
|
+
],
|
|
273
|
+
(endpoint) => l34EndpointToString(endpoint)
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
function calculateExcludedIps({ excludedIps, excludePrivateIps }, { network }) {
|
|
231
277
|
const result = /* @__PURE__ */ new Set();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
result.add(ip);
|
|
235
|
-
}
|
|
278
|
+
for (const ip of excludedIps) {
|
|
279
|
+
result.add(ip);
|
|
236
280
|
}
|
|
237
281
|
if (excludePrivateIps) {
|
|
238
282
|
result.add("10.0.0.0/8");
|
|
@@ -245,29 +289,36 @@ function calculateExcludedIps({ excludedIps, excludePrivateIps }, network) {
|
|
|
245
289
|
}
|
|
246
290
|
return Array.from(result);
|
|
247
291
|
}
|
|
248
|
-
function
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
292
|
+
function isExitNode(peer) {
|
|
293
|
+
return peer.allowedIps.includes("0.0.0.0/0") || peer.allowedIps.includes("::/0");
|
|
294
|
+
}
|
|
295
|
+
function createPeerEntity(name, args, inputs, publicKey, presharedKeyPart) {
|
|
296
|
+
const endpoints = calculateEndpoints(args, inputs);
|
|
297
|
+
const allowedEndpoints = calculateAllowedEndpoints(args, inputs);
|
|
298
|
+
const allowedIps = calculateAllowedIps(args, inputs, allowedEndpoints);
|
|
299
|
+
const excludedIps = calculateExcludedIps(args, inputs);
|
|
300
|
+
return {
|
|
301
|
+
name: args.peerName ?? name,
|
|
302
|
+
endpoints,
|
|
303
|
+
allowedIps,
|
|
304
|
+
allowedEndpoints,
|
|
305
|
+
excludedIps,
|
|
306
|
+
dns: args.dns,
|
|
307
|
+
publicKey,
|
|
308
|
+
address: args.address,
|
|
309
|
+
network: inputs.network,
|
|
310
|
+
presharedKeyPart,
|
|
311
|
+
listenPort: args.listenPort
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function shouldExpose(identity, exposePolicy) {
|
|
315
|
+
if (exposePolicy === "always") {
|
|
316
|
+
return true;
|
|
266
317
|
}
|
|
267
|
-
if (
|
|
268
|
-
return
|
|
318
|
+
if (exposePolicy === "never") {
|
|
319
|
+
return false;
|
|
269
320
|
}
|
|
270
|
-
return
|
|
321
|
+
return identity.peer.endpoints.length > 0;
|
|
271
322
|
}
|
|
272
323
|
|
|
273
324
|
export {
|
|
@@ -275,13 +326,16 @@ export {
|
|
|
275
326
|
convertPrivateKeyToPublicKey,
|
|
276
327
|
generatePresharedKey,
|
|
277
328
|
generateIdentityConfig,
|
|
329
|
+
calculateEndpoints,
|
|
278
330
|
calculateAllowedIps,
|
|
279
|
-
|
|
280
|
-
|
|
331
|
+
calculateAllowedEndpoints,
|
|
332
|
+
isExitNode,
|
|
333
|
+
createPeerEntity,
|
|
334
|
+
shouldExpose
|
|
281
335
|
};
|
|
282
336
|
/*! Bundled license information:
|
|
283
337
|
|
|
284
338
|
@noble/hashes/esm/utils.js:
|
|
285
339
|
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
286
340
|
*/
|
|
287
|
-
//# sourceMappingURL=chunk-
|
|
341
|
+
//# sourceMappingURL=chunk-PXOBQDLU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared.ts","../../../node_modules/@noble/hashes/src/cryptoNode.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/remeda/dist/chunk-ANXBDSUI.js","../../../node_modules/remeda/dist/chunk-3GOCSNFN.js","../../../node_modules/remeda/dist/chunk-LFJW7BOT.js","../../../node_modules/remeda/dist/chunk-7ZI6JRPB.js","../../../node_modules/remeda/dist/chunk-QJLMYOTX.js"],"sourcesContent":["import type { k8s, network, wireguard } from \"@highstate/library\"\nimport type { Input, Unwrap } from \"@highstate/pulumi\"\nimport {\n l34EndpointToString,\n l3EndpointToString,\n l3ToL4Endpoint,\n l4EndpointToString,\n parseL34Endpoint,\n parseL4Endpoint,\n} from \"@highstate/common\"\nimport { x25519 } from \"@noble/curves/ed25519\"\nimport { randomBytes } from \"@noble/hashes/utils\"\nimport { unique, uniqueBy } from \"remeda\"\nimport { getBestEndpoint } from \"@highstate/k8s\"\n\nexport function generateKey(): string {\n const key = x25519.utils.randomPrivateKey()\n\n return Buffer.from(key).toString(\"base64\")\n}\n\nexport function convertPrivateKeyToPublicKey(privateKey: string): string {\n const key = Buffer.from(privateKey, \"base64\")\n\n return Buffer.from(x25519.getPublicKey(key)).toString(\"base64\")\n}\n\nexport function generatePresharedKey(): string {\n const key = randomBytes(32)\n\n return Buffer.from(key).toString(\"base64\")\n}\n\nexport function combinePresharedKeyParts(part1: string, part2: string): string {\n const key1 = Buffer.from(part1, \"base64\")\n const key2 = Buffer.from(part2, \"base64\")\n const result = new Uint8Array(32)\n\n for (let i = 0; i < 32; i++) {\n result[i] = key1[i] ^ key2[i]\n }\n\n return Buffer.from(result).toString(\"base64\")\n}\n\nfunction generatePeerConfig(\n identity: wireguard.Identity,\n peer: wireguard.Peer,\n cluster?: k8s.Cluster,\n): string {\n const lines = [\n //\n \"[Peer]\",\n `# ${peer.name}`,\n `PublicKey = ${peer.publicKey}`,\n ]\n\n if (peer.allowedIps.length > 0) {\n lines.push(`AllowedIPs = ${peer.allowedIps.join(\", \")}`)\n }\n\n const bestEndpoint = getBestEndpoint(peer.endpoints, cluster)\n\n if (bestEndpoint) {\n lines.push(`Endpoint = ${l4EndpointToString(bestEndpoint)}`)\n }\n\n if (identity.peer.presharedKeyPart && peer.presharedKeyPart) {\n const presharedKey = combinePresharedKeyParts(\n identity.peer.presharedKeyPart,\n peer.presharedKeyPart,\n )\n\n lines.push(`PresharedKey = ${presharedKey}`)\n } else if (peer.presharedKey || identity.peer.presharedKey) {\n if (peer.presharedKey !== identity.peer.presharedKey) {\n throw new Error(\n `Preshared keys do not match for peers: ${peer.name} and ${identity.peer.name}`,\n )\n }\n\n lines.push(`PresharedKey = ${peer.presharedKey}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport type IdentityConfigArgs = {\n identity: wireguard.Identity\n peers: wireguard.Peer[]\n listenPort?: number\n dns?: string[]\n postUp?: string[]\n preUp?: string[]\n preDown?: string[]\n postDown?: string[]\n defaultInterface?: string\n cluster?: k8s.Cluster\n}\n\nexport function generateIdentityConfig({\n identity,\n peers,\n listenPort = identity.peer.listenPort,\n dns = [],\n preUp = [],\n postUp = [],\n preDown = [],\n postDown = [],\n defaultInterface,\n cluster,\n}: IdentityConfigArgs): string {\n const allDns = unique(peers.flatMap(peer => peer.dns).concat(dns))\n const excludedIps = unique(peers.flatMap(peer => peer.excludedIps))\n\n const lines = [\n //\n \"[Interface]\",\n `# ${identity.peer.name}`,\n ]\n\n if (identity.peer.address) {\n lines.push(`Address = ${identity.peer.address}`)\n }\n\n lines.push(\n //\n `PrivateKey = ${identity.privateKey}`,\n \"MTU = 1280\",\n )\n\n if (allDns.length > 0) {\n lines.push(`DNS = ${allDns.join(\", \")}`)\n }\n\n if (listenPort) {\n lines.push(`ListenPort = ${listenPort}`)\n }\n\n if (preUp.length > 0) {\n lines.push()\n for (const command of preUp) {\n lines.push(`PreUp = ${command}`)\n }\n }\n\n if (postUp.length > 0) {\n lines.push()\n for (const command of postUp) {\n lines.push(`PostUp = ${command}`)\n }\n }\n\n if (preDown.length > 0) {\n lines.push()\n for (const command of preDown) {\n lines.push(`PreDown = ${command}`)\n }\n }\n\n if (postDown.length > 0) {\n lines.push()\n for (const command of postDown) {\n lines.push(`PostDown = ${command}`)\n }\n }\n\n if (defaultInterface) {\n lines.push()\n for (const excludedIp of excludedIps) {\n lines.push(`PostUp = ip route add ${excludedIp} dev ${defaultInterface}`)\n }\n }\n\n const otherPeers = peers.filter(peer => peer.name !== identity.peer.name)\n\n for (const peer of otherPeers) {\n lines.push(\"\")\n lines.push(generatePeerConfig(identity, peer, cluster))\n }\n\n return lines.join(\"\\n\")\n}\n\ntype SharedPeerInputs = {\n network?: Input<wireguard.Network>\n l3Endpoints: Input<network.L3Endpoint>[]\n l4Endpoints: Input<network.L4Endpoint>[]\n allowedL3Endpoints: Input<network.L3Endpoint>[]\n allowedL4Endpoints: Input<network.L4Endpoint>[]\n}\n\nexport function calculateEndpoints(\n { endpoints, listenPort }: Pick<wireguard.SharedPeerArgs, \"endpoints\" | \"listenPort\">,\n { l3Endpoints, l4Endpoints }: Pick<Unwrap<SharedPeerInputs>, \"l3Endpoints\" | \"l4Endpoints\">,\n): network.L4Endpoint[] {\n return uniqueBy(\n [\n ...l3Endpoints.map(e => l3ToL4Endpoint(e, listenPort ?? 51820)),\n ...l4Endpoints,\n ...endpoints.map(parseL4Endpoint),\n ],\n endpoint => l4EndpointToString(endpoint),\n )\n}\n\nexport function calculateAllowedIps(\n { address, exitNode }: Pick<wireguard.SharedPeerArgs, \"address\" | \"exitNode\">,\n { network }: Unwrap<SharedPeerInputs>,\n allowedEndpoints: network.L34Endpoint[],\n): string[] {\n const result = new Set<string>()\n\n if (address) {\n result.add(address)\n }\n\n if (exitNode) {\n result.add(\"0.0.0.0/0\")\n\n if (network?.ipv6) {\n result.add(\"::/0\")\n }\n }\n\n for (const endpoint of allowedEndpoints) {\n if (endpoint.type !== \"hostname\") {\n result.add(l3EndpointToString(endpoint))\n }\n }\n\n return Array.from(result)\n}\n\nexport function calculateAllowedEndpoints(\n { allowedEndpoints }: Pick<wireguard.SharedPeerArgs, \"allowedEndpoints\">,\n {\n allowedL3Endpoints,\n allowedL4Endpoints,\n }: Pick<Unwrap<SharedPeerInputs>, \"allowedL3Endpoints\" | \"allowedL4Endpoints\">,\n): network.L34Endpoint[] {\n return uniqueBy(\n [\n //\n ...allowedL3Endpoints,\n ...allowedL4Endpoints,\n ...allowedEndpoints.map(parseL34Endpoint),\n ],\n endpoint => l34EndpointToString(endpoint),\n )\n}\n\nfunction calculateExcludedIps(\n { excludedIps, excludePrivateIps }: wireguard.SharedPeerArgs,\n { network }: Unwrap<SharedPeerInputs>,\n): string[] {\n const result = new Set<string>()\n\n for (const ip of excludedIps) {\n result.add(ip)\n }\n\n if (excludePrivateIps) {\n result.add(\"10.0.0.0/8\")\n result.add(\"172.16.0.0/12\")\n result.add(\"192.168.0.0/16\")\n\n if (network?.ipv6) {\n result.add(\"fc00::/7\")\n result.add(\"fe80::/10\")\n }\n }\n\n return Array.from(result)\n}\n\nexport function isExitNode(peer: wireguard.Peer): boolean {\n return peer.allowedIps.includes(\"0.0.0.0/0\") || peer.allowedIps.includes(\"::/0\")\n}\n\nexport function createPeerEntity(\n name: string,\n args: wireguard.SharedPeerArgs,\n inputs: Unwrap<SharedPeerInputs>,\n publicKey: string,\n presharedKeyPart?: string,\n): wireguard.Peer {\n const endpoints = calculateEndpoints(args, inputs)\n const allowedEndpoints = calculateAllowedEndpoints(args, inputs)\n const allowedIps = calculateAllowedIps(args, inputs, allowedEndpoints)\n const excludedIps = calculateExcludedIps(args, inputs)\n\n return {\n name: args.peerName ?? name,\n endpoints,\n allowedIps,\n allowedEndpoints,\n excludedIps,\n dns: args.dns,\n publicKey,\n address: args.address,\n network: inputs.network,\n presharedKeyPart,\n listenPort: args.listenPort,\n }\n}\n\nexport function shouldExpose(\n identity: wireguard.Identity,\n exposePolicy: wireguard.NodeExposePolicy,\n): boolean {\n if (exposePolicy === \"always\") {\n return true\n }\n\n if (exposePolicy === \"never\") {\n return false\n }\n\n return identity.peer.endpoints.length > 0\n}\n","/**\n * Internal webcrypto alias.\n * We prefer WebCrypto aka globalThis.crypto, which exists in node.js 16+.\n * Falls back to Node.js built-in crypto for Node.js <=v14.\n * See utils.ts for details.\n * @module\n */\n// @ts-ignore\nimport * as nc from 'node:crypto';\nexport const crypto: any =\n nc && typeof nc === 'object' && 'webcrypto' in nc\n ? (nc.webcrypto as any)\n : nc && typeof nc === 'object' && 'randomBytes' in nc\n ? nc\n : undefined;\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\nimport { abytes } from './_assert.js';\n// export { isBytes } from './_assert.js';\n// We can't reuse isBytes from _assert, because somehow this causes huge perf issues\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n// Cast array to different type\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n// Cast array to view\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n// The byte swap operation for uint32\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const byteSwapIfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n);\n\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr: Uint32Array): void {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n}\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n/**\n * Convert byte array to hex string.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols in both browsers and Node.js since v11\n// See https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Convert JS string to byte array.\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('utf8ToBytes expected string, got ' + typeof str);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** Accepted input of hash functions. Strings are converted to byte arrays. */\nexport type Input = Uint8Array | string;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\n/** For runtime check if class implements interface */\nexport abstract class Hash<T extends Hash<T>> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: Input): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n /**\n * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n * when no options are passed.\n * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n * There are no guarantees for clean-up because it's impossible in JS.\n */\n abstract _cloneInto(to?: T): T;\n // Safe version that clones internal state\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Hash function */\nexport type CHash = ReturnType<typeof wrapConstructor>;\n/** Hash function with output */\nexport type CHashO = ReturnType<typeof wrapConstructorWithOpts>;\n/** XOF with output */\nexport type CHashXO = ReturnType<typeof wrapXOFConstructorWithOpts>;\n\n/** Wraps hash function, creating an interface on top of it */\nexport function wrapConstructor<T extends Hash<T>>(\n hashCons: () => Hash<T>\n): {\n (msg: Input): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(): Hash<T>;\n} {\n const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\n\nexport function wrapConstructorWithOpts<H extends Hash<H>, T extends Object>(\n hashCons: (opts?: T) => Hash<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts: T): Hash<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\nexport function wrapXOFConstructorWithOpts<H extends HashXOF<H>, T extends Object>(\n hashCons: (opts?: T) => HashXOF<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts: T): HashXOF<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n // Legacy Node.js compatibility\n if (crypto && typeof crypto.randomBytes === 'function') {\n return crypto.randomBytes(bytesLength);\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n","var e={done:!0,hasNext:!1},s={done:!1,hasNext:!1},a=()=>e,o=t=>({hasNext:!0,next:t,done:!1});export{s as a,a as b,o as c};\n","import{a as A}from\"./chunk-ANXBDSUI.js\";function C(t,...o){let n=t,u=o.map(e=>\"lazy\"in e?y(e):void 0),p=0;for(;p<o.length;){if(u[p]===void 0||!B(n)){let i=o[p];n=i(n),p+=1;continue}let r=[];for(let i=p;i<o.length;i++){let l=u[i];if(l===void 0||(r.push(l),l.isSingle))break}let a=[];for(let i of n)if(f(i,a,r))break;let{isSingle:s}=r.at(-1);n=s?a[0]:a,p+=r.length}return n}function f(t,o,n){if(n.length===0)return o.push(t),!1;let u=t,p=A,e=!1;for(let[r,a]of n.entries()){let{index:s,items:i}=a;if(i.push(u),p=a(u,s,i),a.index+=1,p.hasNext){if(p.hasMany??!1){for(let l of p.next)if(f(l,o,n.slice(r+1)))return!0;return e}u=p.next}if(!p.hasNext)break;p.done&&(e=!0)}return p.hasNext&&o.push(u),e}function y(t){let{lazy:o,lazyArgs:n}=t,u=o(...n);return Object.assign(u,{isSingle:o.single??!1,index:0,items:[]})}function B(t){return typeof t==\"string\"||typeof t==\"object\"&&t!==null&&Symbol.iterator in t}export{C as a};\n","import{a as o}from\"./chunk-3GOCSNFN.js\";function y(t,i){let a=i.length-t.length;if(a===1){let[n,...r]=i;return o(n,{lazy:t,lazyArgs:r})}if(a===0){let n={lazy:t,lazyArgs:i};return Object.assign(e=>o(e,n),n)}throw new Error(\"Wrong number of arguments\")}export{y as a};\n","import{a as o}from\"./chunk-LFJW7BOT.js\";import{a}from\"./chunk-ANXBDSUI.js\";function T(...e){return o(y,e)}function y(e){let u=e,n=new Set;return(t,i,d)=>{let r=u(t,i,d);return n.has(r)?a:(n.add(r),{done:!1,hasNext:!0,next:t})}}export{T as a};\n","import{a as r}from\"./chunk-LFJW7BOT.js\";import{a as n}from\"./chunk-ANXBDSUI.js\";function i(...e){return r(a,e)}function a(){let e=new Set;return t=>e.has(t)?n:(e.add(t),{done:!1,hasNext:!0,next:t})}export{i as a};\n"],"mappings":"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","names":["i","a","s","y","i","a","y","i","y","i"]}
|
package/dist/config/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateIdentityConfig
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-PXOBQDLU.js";
|
|
4
4
|
|
|
5
5
|
// src/config/index.ts
|
|
6
6
|
import { wireguard } from "@highstate/library";
|
|
@@ -11,9 +11,7 @@ var { identity, peers } = await toPromise(inputs);
|
|
|
11
11
|
var configContent = generateIdentityConfig({
|
|
12
12
|
identity,
|
|
13
13
|
peers,
|
|
14
|
-
|
|
15
|
-
defaultInterface: args.defaultInterface,
|
|
16
|
-
listenPort: args.listenPort ?? identity.listenPort
|
|
14
|
+
defaultInterface: args.defaultInterface
|
|
17
15
|
});
|
|
18
16
|
var config_default = outputs({
|
|
19
17
|
$pages: {
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { text } from \"@highstate/contract\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { inputs, args, outputs } = forUnit(wireguard.config)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst configContent = generateIdentityConfig({\n identity,\n peers,\n
|
|
1
|
+
{"version":3,"sources":["../../src/config/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { text } from \"@highstate/contract\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { inputs, args, outputs } = forUnit(wireguard.config)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst configContent = generateIdentityConfig({\n identity,\n peers,\n defaultInterface: args.defaultInterface,\n})\n\nexport default outputs({\n $pages: {\n index: {\n title: \"WireGuard Configuration\",\n content: [\n {\n type: \"markdown\",\n content: text`\n You can use this configuration to setup an external WireGuard device via \\`wg-quick\\` command.\n `,\n },\n {\n type: \"qr\",\n content: configContent,\n showContent: true,\n language: \"ini\",\n },\n ],\n },\n },\n})\n"],"mappings":";;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,SAAS,iBAAiB;AACnC,SAAS,YAAY;AAGrB,IAAM,EAAE,QAAQ,MAAM,QAAQ,IAAI,QAAQ,UAAU,MAAM;AAE1D,IAAM,EAAE,UAAU,MAAM,IAAI,MAAM,UAAU,MAAM;AAElD,IAAM,gBAAgB,uBAAuB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA,kBAAkB,KAAK;AACzB,CAAC;AAED,IAAO,iBAAQ,QAAQ;AAAA,EACrB,QAAQ;AAAA,IACN,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA;AAAA;AAAA,QAGX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,UACb,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateIdentityConfig
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-PXOBQDLU.js";
|
|
4
4
|
|
|
5
5
|
// src/config-bundle/index.ts
|
|
6
6
|
import { wireguard } from "@highstate/library";
|
|
@@ -20,9 +20,7 @@ for (const peer of peers) {
|
|
|
20
20
|
const configContent = generateIdentityConfig({
|
|
21
21
|
identity,
|
|
22
22
|
peers: [...sharedPeers, peer],
|
|
23
|
-
|
|
24
|
-
defaultInterface: args.defaultInterface,
|
|
25
|
-
listenPort: args.listenPort ?? identity.listenPort
|
|
23
|
+
defaultInterface: args.defaultInterface
|
|
26
24
|
});
|
|
27
25
|
await new Promise((resolve, reject) => {
|
|
28
26
|
return zipStream.entry(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config-bundle/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport {\n fileFromBuffer,\n forUnit,\n secret,\n toPromise,\n type InstancePageBlock,\n} from \"@highstate/pulumi\"\nimport { text } from \"@highstate/contract\"\nimport ZipStream from \"zip-stream\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { name, inputs, args, outputs } = forUnit(wireguard.configBundle)\n\nconst { identity, peers, sharedPeers } = await toPromise(inputs)\n\nconst blocks: InstancePageBlock[] = []\nconst zipStream = new ZipStream()\n\nfor (const peer of peers) {\n const configContent = generateIdentityConfig({\n identity,\n peers: [...sharedPeers, peer],\n
|
|
1
|
+
{"version":3,"sources":["../../src/config-bundle/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport {\n fileFromBuffer,\n forUnit,\n secret,\n toPromise,\n type InstancePageBlock,\n} from \"@highstate/pulumi\"\nimport { text } from \"@highstate/contract\"\nimport ZipStream from \"zip-stream\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { name, inputs, args, outputs } = forUnit(wireguard.configBundle)\n\nconst { identity, peers, sharedPeers } = await toPromise(inputs)\n\nconst blocks: InstancePageBlock[] = []\nconst zipStream = new ZipStream()\n\nfor (const peer of peers) {\n const configContent = generateIdentityConfig({\n identity,\n peers: [...sharedPeers, peer],\n defaultInterface: args.defaultInterface,\n })\n\n await new Promise((resolve, reject) => {\n return zipStream.entry(\n configContent,\n {\n name: `${peer.name}.conf`,\n\n // to prevent zip-stream from using the current date, for reproducibility\n date: new Date(0),\n },\n err => {\n if (err) {\n reject(err)\n } else {\n resolve(null)\n }\n },\n )\n })\n\n blocks.push(\n {\n type: \"markdown\",\n content: `### ${peer.name}`,\n },\n {\n type: \"qr\",\n content: secret(configContent),\n showContent: true,\n language: \"ini\",\n },\n )\n}\n\nzipStream.finish()\n\nconst content = await new Promise<Buffer>((resolve, reject) => {\n const buffers: Buffer[] = []\n\n zipStream.on(\"data\", data => buffers.push(data as Buffer))\n zipStream.on(\"error\", err => reject(err as Error))\n zipStream.on(\"end\", () => resolve(Buffer.concat(buffers)))\n})\n\nconst zipFile = fileFromBuffer(`${name}.zip`, content, \"application/zip\", true)\n\nexport default outputs({\n $pages: {\n index: {\n title: \"WireGuard Configuration Bundle\",\n content: [\n {\n type: \"markdown\",\n content: text`\n You can use the following configurations to setup an external WireGuard device via \\`wg-quick\\` command or\n using the WireGuard app on your desktop or mobile device.\n \n You can also bulk import all configurations from zip file using the WireGuard app.\n `,\n },\n {\n type: \"file\",\n fileMeta: zipFile.meta,\n },\n ...blocks,\n ],\n },\n },\n $files: [zipFile],\n})\n"],"mappings":";;;;;AAAA,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,YAAY;AACrB,OAAO,eAAe;AAGtB,IAAM,EAAE,MAAM,QAAQ,MAAM,QAAQ,IAAI,QAAQ,UAAU,YAAY;AAEtE,IAAM,EAAE,UAAU,OAAO,YAAY,IAAI,MAAM,UAAU,MAAM;AAE/D,IAAM,SAA8B,CAAC;AACrC,IAAM,YAAY,IAAI,UAAU;AAEhC,WAAW,QAAQ,OAAO;AACxB,QAAM,gBAAgB,uBAAuB;AAAA,IAC3C;AAAA,IACA,OAAO,CAAC,GAAG,aAAa,IAAI;AAAA,IAC5B,kBAAkB,KAAK;AAAA,EACzB,CAAC;AAED,QAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,WAAO,UAAU;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM,GAAG,KAAK,IAAI;AAAA;AAAA,QAGlB,MAAM,oBAAI,KAAK,CAAC;AAAA,MAClB;AAAA,MACA,SAAO;AACL,YAAI,KAAK;AACP,iBAAO,GAAG;AAAA,QACZ,OAAO;AACL,kBAAQ,IAAI;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,SAAS,OAAO,KAAK,IAAI;AAAA,IAC3B;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS,OAAO,aAAa;AAAA,MAC7B,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,UAAU,OAAO;AAEjB,IAAM,UAAU,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC7D,QAAM,UAAoB,CAAC;AAE3B,YAAU,GAAG,QAAQ,UAAQ,QAAQ,KAAK,IAAc,CAAC;AACzD,YAAU,GAAG,SAAS,SAAO,OAAO,GAAY,CAAC;AACjD,YAAU,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,IAAM,UAAU,eAAe,GAAG,IAAI,QAAQ,SAAS,mBAAmB,IAAI;AAE9E,IAAO,wBAAQ,QAAQ;AAAA,EACrB,QAAQ;AAAA,IACN,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,QAAQ;AAAA,QACpB;AAAA,QACA,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ,CAAC,OAAO;AAClB,CAAC;","names":[]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sourceHashes": {
|
|
3
|
-
"./dist/network/index.js": "
|
|
4
|
-
"./dist/identity/index.js": "
|
|
5
|
-
"./dist/config/index.js": "
|
|
6
|
-
"./dist/config-bundle/index.js": "
|
|
7
|
-
"./dist/node/index.js": "
|
|
8
|
-
"./dist/peer/index.js": "
|
|
3
|
+
"./dist/network/index.js": "e555c95715812250cf73bf6aafe1f9b018d2b6949b2f667dd088e76a4480dea5",
|
|
4
|
+
"./dist/identity/index.js": "0149d0a35a81a0374e9cec441fd4f0706c62be15b325186c3b9d4c82596c5f0b",
|
|
5
|
+
"./dist/config/index.js": "8a2d24ae1f2668455b7a6ea8d6191194f956b0c5c30d6ac5bd08c376cab1361c",
|
|
6
|
+
"./dist/config-bundle/index.js": "e265102ca03beb9d91dfb81f32e39bb9fe296f429f248e11c18c9ae722588a5b",
|
|
7
|
+
"./dist/node/index.js": "f916dc580f47744272b84964c29c8adfd5298002cbc5cd8cb9e29e55c5a1efd7",
|
|
8
|
+
"./dist/peer/index.js": "37fd345356423cf2a2dc4d8a43c3287e91c3c30379db8a07c43d4bc1d7a22eb8",
|
|
9
|
+
"./dist/peer-patch/index.js": "6f6fc2307a41bfbdf46116bda5cec17e5500628ba3afab7b85fafc31ad2aa8b2"
|
|
9
10
|
}
|
|
10
11
|
}
|
package/dist/identity/index.js
CHANGED
|
@@ -1,82 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
|
-
calculateAllowedIps,
|
|
3
|
-
calculateEndpoint,
|
|
4
|
-
calculateExcludedIps,
|
|
5
2
|
convertPrivateKeyToPublicKey,
|
|
3
|
+
createPeerEntity,
|
|
6
4
|
generateKey,
|
|
7
5
|
generatePresharedKey
|
|
8
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-PXOBQDLU.js";
|
|
9
7
|
|
|
10
8
|
// src/identity/index.ts
|
|
11
9
|
import { wireguard } from "@highstate/library";
|
|
12
10
|
import { forUnit, getOrCreateSecret, toPromise } from "@highstate/pulumi";
|
|
13
|
-
import {
|
|
11
|
+
import { l4EndpointToString } from "@highstate/common";
|
|
14
12
|
var { name, args, inputs, secrets, outputs } = forUnit(wireguard.identity);
|
|
15
13
|
var privateKey = getOrCreateSecret(secrets, "privateKey", generateKey);
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var { network, k8sServices, k8sCluster } = await toPromise(inputs);
|
|
22
|
-
var allowedIps = calculateAllowedIps(args, network, k8sServices);
|
|
23
|
-
var excludedIps = calculateExcludedIps(args, network);
|
|
24
|
-
var { endpoint, externalIp, fqdn } = calculateEndpoint({ ...args, clusterInfo: k8sCluster?.info });
|
|
25
|
-
var publicKey = privateKey.apply(convertPrivateKeyToPublicKey);
|
|
26
|
-
if (args.fqdn && inputs.dnsProviders && externalIp) {
|
|
27
|
-
DnsRecord.createSet(args.fqdn, {
|
|
28
|
-
providers: inputs.dnsProviders,
|
|
29
|
-
type: "A",
|
|
30
|
-
value: externalIp
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
var isExitNode = allowedIps.includes("0.0.0.0/0") || allowedIps.includes("::/0");
|
|
14
|
+
var presharedKeyPartOutput = getOrCreateSecret(secrets, "presharedKeyPart", generatePresharedKey);
|
|
15
|
+
var resolvedInpus = await toPromise(inputs);
|
|
16
|
+
var publicKey = await toPromise(privateKey.apply(convertPrivateKeyToPublicKey));
|
|
17
|
+
var presharedKeyPart = await toPromise(presharedKeyPartOutput);
|
|
18
|
+
var peer = createPeerEntity(name, args, resolvedInpus, publicKey, presharedKeyPart);
|
|
34
19
|
var identity_default = outputs({
|
|
35
20
|
identity: {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
address: args.address,
|
|
39
|
-
privateKey,
|
|
40
|
-
presharedKeyPart,
|
|
41
|
-
k8sServices: inputs.k8sServices,
|
|
42
|
-
exitNode: args.exitNode ?? isExitNode,
|
|
43
|
-
listenPort: args.listenPort,
|
|
44
|
-
externalIp,
|
|
45
|
-
endpoint,
|
|
46
|
-
fqdn
|
|
47
|
-
},
|
|
48
|
-
peer: {
|
|
49
|
-
name: args.peerName ?? name,
|
|
50
|
-
network: inputs.network,
|
|
51
|
-
address: args.address,
|
|
52
|
-
publicKey,
|
|
53
|
-
allowedIps,
|
|
54
|
-
excludedIps,
|
|
55
|
-
endpoint,
|
|
56
|
-
dns: args.dns,
|
|
57
|
-
presharedKeyPart
|
|
21
|
+
peer,
|
|
22
|
+
privateKey
|
|
58
23
|
},
|
|
59
|
-
|
|
24
|
+
peer,
|
|
25
|
+
endpoints: peer.endpoints,
|
|
60
26
|
$status: {
|
|
61
27
|
publicKey,
|
|
62
|
-
|
|
63
|
-
value:
|
|
64
|
-
complementaryTo: "
|
|
65
|
-
},
|
|
66
|
-
externalIp: {
|
|
67
|
-
value: externalIp,
|
|
68
|
-
complementaryTo: "externalIp"
|
|
69
|
-
},
|
|
70
|
-
fqdn: {
|
|
71
|
-
value: fqdn,
|
|
72
|
-
complementaryTo: "fqdn"
|
|
73
|
-
},
|
|
74
|
-
allowedIps: {
|
|
75
|
-
value: allowedIps.join(", "),
|
|
76
|
-
complementaryTo: "allowedIps"
|
|
28
|
+
endpoints: {
|
|
29
|
+
value: peer.endpoints.map(l4EndpointToString),
|
|
30
|
+
complementaryTo: "endpoints"
|
|
77
31
|
},
|
|
78
32
|
excludedIps: {
|
|
79
|
-
value: excludedIps
|
|
33
|
+
value: peer.excludedIps,
|
|
80
34
|
complementaryTo: "excludedIps"
|
|
81
35
|
}
|
|
82
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/identity/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, getOrCreateSecret, toPromise } from \"@highstate/pulumi\"\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/identity/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, getOrCreateSecret, toPromise } from \"@highstate/pulumi\"\nimport { l4EndpointToString } from \"@highstate/common\"\nimport {\n convertPrivateKeyToPublicKey,\n createPeerEntity,\n generateKey,\n generatePresharedKey,\n} from \"../shared\"\n\nconst { name, args, inputs, secrets, outputs } = forUnit(wireguard.identity)\n\nconst privateKey = getOrCreateSecret(secrets, \"privateKey\", generateKey)\nconst presharedKeyPartOutput = getOrCreateSecret(secrets, \"presharedKeyPart\", generatePresharedKey)\n\nconst resolvedInpus = await toPromise(inputs)\nconst publicKey = await toPromise(privateKey.apply(convertPrivateKeyToPublicKey))\nconst presharedKeyPart = await toPromise(presharedKeyPartOutput)\n\nconst peer = createPeerEntity(name, args, resolvedInpus, publicKey, presharedKeyPart)\n\nexport default outputs({\n identity: {\n peer,\n privateKey,\n },\n\n peer,\n\n endpoints: peer.endpoints,\n\n $status: {\n publicKey,\n endpoints: {\n value: peer.endpoints.map(l4EndpointToString),\n complementaryTo: \"endpoints\",\n },\n excludedIps: {\n value: peer.excludedIps,\n complementaryTo: \"excludedIps\",\n },\n },\n})\n"],"mappings":";;;;;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,SAAS,mBAAmB,iBAAiB;AACtD,SAAS,0BAA0B;AAQnC,IAAM,EAAE,MAAM,MAAM,QAAQ,SAAS,QAAQ,IAAI,QAAQ,UAAU,QAAQ;AAE3E,IAAM,aAAa,kBAAkB,SAAS,cAAc,WAAW;AACvE,IAAM,yBAAyB,kBAAkB,SAAS,oBAAoB,oBAAoB;AAElG,IAAM,gBAAgB,MAAM,UAAU,MAAM;AAC5C,IAAM,YAAY,MAAM,UAAU,WAAW,MAAM,4BAA4B,CAAC;AAChF,IAAM,mBAAmB,MAAM,UAAU,sBAAsB;AAE/D,IAAM,OAAO,iBAAiB,MAAM,MAAM,eAAe,WAAW,gBAAgB;AAEpF,IAAO,mBAAQ,QAAQ;AAAA,EACrB,UAAU;AAAA,IACR;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,WAAW,KAAK;AAAA,EAEhB,SAAS;AAAA,IACP;AAAA,IACA,WAAW;AAAA,MACT,OAAO,KAAK,UAAU,IAAI,kBAAkB;AAAA,MAC5C,iBAAiB;AAAA,IACnB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/dist/network/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// src/network/index.ts
|
|
2
2
|
import { wireguard } from "@highstate/library";
|
|
3
3
|
import { forUnit } from "@highstate/pulumi";
|
|
4
|
-
var { args,
|
|
4
|
+
var { args, outputs } = forUnit(wireguard.network);
|
|
5
5
|
var network_default = outputs({
|
|
6
6
|
network: {
|
|
7
|
-
backend: args.backend
|
|
8
|
-
|
|
9
|
-
globalPresharedKey: secrets.globalPresharedKey
|
|
7
|
+
backend: args.backend,
|
|
8
|
+
ipv6: args.ipv6
|
|
10
9
|
}
|
|
11
10
|
});
|
|
12
11
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/network/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit } from \"@highstate/pulumi\"\n\nconst { args,
|
|
1
|
+
{"version":3,"sources":["../../src/network/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit } from \"@highstate/pulumi\"\n\nconst { args, outputs } = forUnit(wireguard.network)\n\nexport default outputs({\n network: {\n backend: args.backend,\n ipv6: args.ipv6,\n },\n})\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AAExB,IAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ,UAAU,OAAO;AAEnD,IAAO,kBAAQ,QAAQ;AAAA,EACrB,SAAS;AAAA,IACP,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,EACb;AACF,CAAC;","names":[]}
|
package/dist/node/index.js
CHANGED
|
@@ -1,47 +1,37 @@
|
|
|
1
1
|
import {
|
|
2
|
-
generateIdentityConfig
|
|
3
|
-
|
|
2
|
+
generateIdentityConfig,
|
|
3
|
+
isExitNode,
|
|
4
|
+
shouldExpose
|
|
5
|
+
} from "../chunk-PXOBQDLU.js";
|
|
4
6
|
|
|
5
7
|
// src/node/index.ts
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Deployment,
|
|
10
|
-
getAppDisplayName,
|
|
11
|
-
getAppName,
|
|
12
|
-
getNamespace,
|
|
13
|
-
mapMetadata,
|
|
14
|
-
NetworkPolicy,
|
|
15
|
-
StatefulSet
|
|
16
|
-
} from "@highstate/k8s";
|
|
17
|
-
import { wireguard } from "@highstate/library";
|
|
18
|
-
import { forUnit, toPromise } from "@highstate/pulumi";
|
|
19
|
-
import { core } from "@pulumi/kubernetes";
|
|
8
|
+
import { NetworkPolicy, Namespace, ExposableWorkload, Secret } from "@highstate/k8s";
|
|
9
|
+
import { wireguard as wireguard2 } from "@highstate/library";
|
|
10
|
+
import { forUnit, output, toPromise } from "@highstate/pulumi";
|
|
20
11
|
import { deepmerge } from "deepmerge-ts";
|
|
21
|
-
|
|
12
|
+
import { l34EndpointToString, l4EndpointToString, updateEndpoints } from "@highstate/common";
|
|
13
|
+
|
|
14
|
+
// assets/images.json
|
|
15
|
+
var wireguard = {
|
|
16
|
+
name: "docker.io/linuxserver/wireguard",
|
|
17
|
+
tag: "latest",
|
|
18
|
+
image: "docker.io/linuxserver/wireguard:latest@sha256:7792dcef56c51e6b4d499a209e980ed74309bf3bee6af12168ea02bf289eddd9"
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// src/node/index.ts
|
|
22
|
+
var { args, inputs, outputs } = forUnit(wireguard2.node);
|
|
22
23
|
var { identity, peers } = await toPromise(inputs);
|
|
23
|
-
var identityName =
|
|
24
|
+
var identityName = identity.peer.name.replaceAll(".", "-");
|
|
24
25
|
var appName = args.appName ?? `wg-${identityName}`;
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
new core.v1.NamespacePatch(
|
|
32
|
-
"allow-privileged",
|
|
33
|
-
{
|
|
34
|
-
metadata: {
|
|
35
|
-
name: namespace.metadata.name,
|
|
36
|
-
labels: {
|
|
37
|
-
"pod-security.kubernetes.io/enforce": "privileged"
|
|
38
|
-
}
|
|
26
|
+
var namespace = Namespace.createOrPatch(appName, {
|
|
27
|
+
cluster: inputs.k8sCluster,
|
|
28
|
+
resource: inputs.workload ?? inputs.interface?.workload,
|
|
29
|
+
metadata: {
|
|
30
|
+
labels: {
|
|
31
|
+
"pod-security.kubernetes.io/enforce": "privileged"
|
|
39
32
|
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
);
|
|
43
|
-
var listenPort = identity.listenPort ?? args.listenPort;
|
|
44
|
-
var externalIp = identity.externalIp ?? args.externalIp;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
45
35
|
var downstreamInterface = await toPromise(inputs.interface);
|
|
46
36
|
var preUp = [
|
|
47
37
|
// idk why
|
|
@@ -69,31 +59,31 @@ if (downstreamInterface) {
|
|
|
69
59
|
preDown.push("ip rule del from all fwmark 0x1 lookup 51820");
|
|
70
60
|
}
|
|
71
61
|
var interfaceName = identityName.substring(0, 15);
|
|
72
|
-
var
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
metadata: mapMetadata({ name: appName, namespace }),
|
|
76
|
-
stringData: {
|
|
77
|
-
[`${interfaceName}.conf`]: generateIdentityConfig({
|
|
78
|
-
identity,
|
|
79
|
-
peers,
|
|
80
|
-
listenPort,
|
|
81
|
-
dns: args.dns,
|
|
82
|
-
preUp,
|
|
83
|
-
postUp,
|
|
84
|
-
preDown,
|
|
85
|
-
defaultInterface: "eth0"
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{ provider }
|
|
90
|
-
);
|
|
91
|
-
var workloadOptions = {
|
|
62
|
+
var containerPort = inputs.workload ?? inputs.interface?.workload ? 51821 : 51820;
|
|
63
|
+
var configSecret = Secret.create(appName, {
|
|
64
|
+
cluster: inputs.k8sCluster,
|
|
92
65
|
namespace,
|
|
66
|
+
stringData: {
|
|
67
|
+
[`${interfaceName}.conf`]: generateIdentityConfig({
|
|
68
|
+
identity,
|
|
69
|
+
peers,
|
|
70
|
+
listenPort: containerPort,
|
|
71
|
+
preUp,
|
|
72
|
+
postUp,
|
|
73
|
+
preDown,
|
|
74
|
+
defaultInterface: "eth0",
|
|
75
|
+
cluster: await toPromise(inputs.k8sCluster)
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
var workload = ExposableWorkload.createOrPatchGeneric(appName, {
|
|
80
|
+
type: "Deployment",
|
|
93
81
|
cluster: inputs.k8sCluster,
|
|
82
|
+
namespace,
|
|
83
|
+
existing: inputs.workload ?? inputs.interface?.workload,
|
|
94
84
|
container: deepmerge(
|
|
95
85
|
{
|
|
96
|
-
image:
|
|
86
|
+
image: wireguard.image,
|
|
97
87
|
environment: {
|
|
98
88
|
PUID: "1000",
|
|
99
89
|
PGID: "1000",
|
|
@@ -104,7 +94,10 @@ var workloadOptions = {
|
|
|
104
94
|
add: ["NET_ADMIN"]
|
|
105
95
|
}
|
|
106
96
|
},
|
|
107
|
-
port:
|
|
97
|
+
port: {
|
|
98
|
+
containerPort,
|
|
99
|
+
protocol: "UDP"
|
|
100
|
+
},
|
|
108
101
|
volumeMount: {
|
|
109
102
|
volume: configSecret,
|
|
110
103
|
mountPath: "/config/wg_confs"
|
|
@@ -112,119 +105,83 @@ var workloadOptions = {
|
|
|
112
105
|
},
|
|
113
106
|
args.containerSpec ?? {}
|
|
114
107
|
),
|
|
115
|
-
service: identity.
|
|
116
|
-
|
|
117
|
-
externalIPs: externalIp ? [externalIp] : void 0,
|
|
108
|
+
service: shouldExpose(identity, args.exposePolicy) ? {
|
|
109
|
+
external: args.external,
|
|
118
110
|
port: {
|
|
119
|
-
port: listenPort,
|
|
111
|
+
port: identity.peer.listenPort ?? 51820,
|
|
112
|
+
targetPort: containerPort,
|
|
120
113
|
protocol: "UDP",
|
|
121
|
-
nodePort:
|
|
114
|
+
nodePort: args.external ? identity.peer.listenPort : void 0
|
|
122
115
|
}
|
|
123
116
|
} : void 0
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"allow-wireguard-ingress",
|
|
136
|
-
{
|
|
137
|
-
namespace,
|
|
138
|
-
cluster: inputs.k8sCluster,
|
|
139
|
-
selector,
|
|
140
|
-
description: "Allow encapsulated WireGuard traffic to the node from anywhere.",
|
|
141
|
-
ingressRule: {
|
|
142
|
-
fromAll: true,
|
|
143
|
-
toPort: { port: listenPort, protocol: "UDP" }
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
{ provider }
|
|
147
|
-
);
|
|
117
|
+
});
|
|
118
|
+
if (shouldExpose(identity, args.exposePolicy)) {
|
|
119
|
+
NetworkPolicy.create("allow-wireguard-ingress", {
|
|
120
|
+
namespace,
|
|
121
|
+
cluster: inputs.k8sCluster,
|
|
122
|
+
selector: workload.spec.selector,
|
|
123
|
+
description: "Allow encapsulated WireGuard traffic to the node from anywhere.",
|
|
124
|
+
ingressRule: {
|
|
125
|
+
fromAll: true
|
|
126
|
+
}
|
|
127
|
+
});
|
|
148
128
|
}
|
|
149
|
-
if (identity.
|
|
150
|
-
NetworkPolicy.create(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
{ provider }
|
|
162
|
-
);
|
|
129
|
+
if (isExitNode(identity.peer)) {
|
|
130
|
+
NetworkPolicy.create("allow-all-egress", {
|
|
131
|
+
namespace,
|
|
132
|
+
cluster: inputs.k8sCluster,
|
|
133
|
+
selector: workload.spec.selector,
|
|
134
|
+
description: "Allow all egress traffic from the WireGuard node since it is an exit node.",
|
|
135
|
+
egressRule: {
|
|
136
|
+
toAll: true
|
|
137
|
+
}
|
|
138
|
+
});
|
|
163
139
|
}
|
|
164
|
-
for (const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
{
|
|
175
|
-
toNamespace: service2.metadata.namespace,
|
|
176
|
-
toSelector: service2.spec.selector
|
|
177
|
-
},
|
|
178
|
-
// for compatibility with Cilium which cannot correctly detect the destination endpoint when the packet is redirected by the WireGuard node
|
|
179
|
-
...service2.spec.clusterIP ? [{ toCidr: `${service2.spec.clusterIP}/32` }] : []
|
|
180
|
-
]
|
|
181
|
-
},
|
|
182
|
-
{ provider }
|
|
183
|
-
);
|
|
184
|
-
NetworkPolicy.create(
|
|
185
|
-
`allow-ingress-to-${getAppName(service2.metadata)}`,
|
|
186
|
-
{
|
|
187
|
-
name: `allow-ingress-from-${appName}`,
|
|
188
|
-
namespace: service2.metadata.namespace,
|
|
189
|
-
cluster: inputs.k8sCluster,
|
|
190
|
-
selector: service2.spec.selector,
|
|
191
|
-
description: `Allow ingress traffic from the WireGuard node "${appName}" to the service "${displayName}".`,
|
|
192
|
-
ingressRule: {
|
|
193
|
-
fromNamespace: namespace,
|
|
194
|
-
fromSelector: selector
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
{ provider }
|
|
198
|
-
);
|
|
140
|
+
for (const endpoint of identity.peer.allowedEndpoints) {
|
|
141
|
+
NetworkPolicy.create(`allow-egress-to-${l34EndpointToString(endpoint)}`, {
|
|
142
|
+
namespace,
|
|
143
|
+
cluster: inputs.k8sCluster,
|
|
144
|
+
selector: workload.spec.selector,
|
|
145
|
+
description: `Allow egress traffic from the WireGuard node to the allowed endpoint "${l34EndpointToString(endpoint)}".`,
|
|
146
|
+
egressRule: {
|
|
147
|
+
toEndpoint: endpoint
|
|
148
|
+
}
|
|
149
|
+
});
|
|
199
150
|
}
|
|
200
151
|
for (const peer of peers) {
|
|
201
|
-
if (!peer.
|
|
152
|
+
if (!peer.endpoints.length) {
|
|
202
153
|
continue;
|
|
203
154
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
toEndpoint: endpoint,
|
|
214
|
-
toPort: { port: port ? parseInt(port) : 51820, protocol: "UDP" }
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
{ provider }
|
|
218
|
-
);
|
|
155
|
+
NetworkPolicy.create(`allow-egress-to-peer-${peer.name}`, {
|
|
156
|
+
namespace,
|
|
157
|
+
cluster: inputs.k8sCluster,
|
|
158
|
+
selector: workload.spec.selector,
|
|
159
|
+
description: `Allow egress traffic from the WireGuard node to the endpoints of the peer "${peer.name}".`,
|
|
160
|
+
egressRule: {
|
|
161
|
+
toEndpoints: peer.endpoints
|
|
162
|
+
}
|
|
163
|
+
});
|
|
219
164
|
}
|
|
165
|
+
var endpoints = await updateEndpoints(
|
|
166
|
+
identity.peer.endpoints,
|
|
167
|
+
[],
|
|
168
|
+
output(workload.optionalService.apply((service) => service?.endpoints ?? [])),
|
|
169
|
+
"prepend"
|
|
170
|
+
);
|
|
220
171
|
var node_default = outputs({
|
|
221
|
-
deployment: deployment?.entity,
|
|
222
172
|
interface: {
|
|
223
173
|
name: interfaceName,
|
|
224
|
-
|
|
174
|
+
workload: workload.entity
|
|
175
|
+
},
|
|
176
|
+
peer: {
|
|
177
|
+
...identity.peer,
|
|
178
|
+
endpoints
|
|
179
|
+
},
|
|
180
|
+
endpoints,
|
|
181
|
+
$status: {
|
|
182
|
+
endpoints: endpoints.map(l4EndpointToString)
|
|
225
183
|
},
|
|
226
|
-
|
|
227
|
-
$terminals: [deployment?.terminal]
|
|
184
|
+
$terminals: [workload.terminal]
|
|
228
185
|
});
|
|
229
186
|
export {
|
|
230
187
|
node_default as default
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/node/index.ts"],"sourcesContent":["import {\n createNamespace,\n createProvider,\n Deployment,\n getAppDisplayName,\n getAppName,\n getNamespace,\n mapMetadata,\n NetworkPolicy,\n StatefulSet,\n type DeploymentArgs,\n type StatefulSetArgs,\n} from \"@highstate/k8s\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { core } from \"@pulumi/kubernetes\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { name, args, inputs, outputs } = forUnit(wireguard.node)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst identityName = (identity.name ?? name).replaceAll(\".\", \"-\")\nconst appName = args.appName ?? `wg-${identityName}`\nconst serviceType = args.serviceType ?? \"ClusterIP\"\n\nconst provider = await createProvider(inputs.k8sCluster)\n\nconst existingNamespace = await toPromise(\n inputs.deployment?.metadata?.namespace ??\n inputs.statefulSet?.metadata?.namespace ??\n inputs.interface?.deployment.metadata.namespace,\n)\n\nconst namespace = existingNamespace\n ? getNamespace(existingNamespace, provider)\n : createNamespace(appName, provider)\n\nnew core.v1.NamespacePatch(\n \"allow-privileged\",\n {\n metadata: {\n name: namespace.metadata.name,\n labels: {\n \"pod-security.kubernetes.io/enforce\": \"privileged\",\n },\n },\n },\n { provider },\n)\n\nconst listenPort = identity.listenPort ?? args.listenPort\nconst externalIp = identity.externalIp ?? args.externalIp\n\nconst downstreamInterface = await toPromise(inputs.interface)\n\nconst preUp: string[] = [\n // idk why\n \"sleep 5\",\n]\n\nconst postUp: string[] = [\n // enable masquerading for all traffic going out of the WireGuard node\n // TODO: consider adding more specific and restrictive rules\n \"iptables -t nat -A POSTROUTING -j MASQUERADE\",\n]\n\nconst preDown: string[] = [\n // remove the masquerading rule\n \"iptables -t nat -D POSTROUTING -j MASQUERADE\",\n]\n\nif (downstreamInterface) {\n // wait until the interface is up\n preUp.push(`while ! ip link show ${downstreamInterface.name} | grep -q 'UP' ; do sleep 1; done`)\n\n // remove the default rule to route all non-encapsulated traffic to upstream wireguard interface\n postUp.push(\"ip rule del not from all fwmark 0xca6c lookup 51820\")\n\n // add a rule to route all downstream traffic to the upstream wireguard interface\n postUp.push(\"ip rule add from all fwmark 0x1 lookup 51820\")\n\n // mark all downstream traffic with 0x1\n postUp.push(\n `iptables -t mangle -A PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all downstream traffic to the upstream wireguard interface\n preDown.push(\n `iptables -t mangle -D PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all non-encapsulated traffic to upstream wireguard interface\n preDown.push(\"ip rule del from all fwmark 0x1 lookup 51820\")\n}\n\nconst interfaceName = identityName.substring(0, 15) // linux kernel limit\n\nconst configSecret = new core.v1.Secret(\n appName,\n {\n metadata: mapMetadata({ name: appName, namespace }),\n stringData: {\n [`${interfaceName}.conf`]: generateIdentityConfig({\n identity,\n peers,\n listenPort,\n dns: args.dns,\n preUp,\n postUp,\n preDown,\n defaultInterface: \"eth0\",\n }),\n },\n },\n { provider },\n)\n\nconst workloadOptions: DeploymentArgs & StatefulSetArgs = {\n namespace,\n cluster: inputs.k8sCluster,\n\n container: deepmerge(\n {\n image: \"linuxserver/wireguard:latest\",\n\n environment: {\n PUID: \"1000\",\n PGID: \"1000\",\n TZ: \"Etc/UTC\",\n },\n\n securityContext: {\n capabilities: {\n add: [\"NET_ADMIN\"],\n },\n },\n\n port:\n identity.endpoint && listenPort\n ? { containerPort: listenPort, protocol: \"UDP\" }\n : undefined,\n\n volumeMount: {\n volume: configSecret,\n mountPath: \"/config/wg_confs\",\n },\n },\n args.containerSpec ?? {},\n ),\n\n service:\n identity.endpoint && listenPort\n ? {\n type: serviceType,\n externalIPs: externalIp ? [externalIp] : undefined,\n\n port: {\n port: listenPort,\n protocol: \"UDP\",\n nodePort: serviceType !== \"ClusterIP\" ? listenPort : undefined,\n },\n }\n : undefined,\n}\n\nconst deployment = !inputs.statefulSet\n ? Deployment.create(\n appName,\n { ...workloadOptions, patch: inputs.deployment ?? inputs.interface?.deployment },\n { provider },\n )\n : undefined\n\nconst statefulSet = inputs.statefulSet\n ? StatefulSet.create(appName, { ...workloadOptions, patch: inputs.statefulSet }, { provider })\n : undefined\n\nconst selector = deployment?.spec.selector ?? statefulSet?.spec.selector\nconst service = deployment?.optionalService ?? statefulSet?.optionalService\n\nif (externalIp && listenPort) {\n NetworkPolicy.create(\n \"allow-wireguard-ingress\",\n {\n namespace,\n cluster: inputs.k8sCluster,\n selector,\n\n description: \"Allow encapsulated WireGuard traffic to the node from anywhere.\",\n\n ingressRule: {\n fromAll: true,\n toPort: { port: listenPort, protocol: \"UDP\" },\n },\n },\n { provider },\n )\n}\n\nif (identity.exitNode) {\n NetworkPolicy.create(\n \"allow-all-egress\",\n {\n namespace,\n cluster: inputs.k8sCluster,\n selector,\n\n description: \"Allow all egress traffic from the WireGuard node.\",\n\n egressRule: {\n toAll: true,\n },\n },\n { provider },\n )\n}\n\nfor (const service of identity.k8sServices) {\n const displayName = getAppDisplayName(service.metadata)\n\n NetworkPolicy.create(\n `allow-egress-to-${getAppName(service.metadata)}`,\n {\n namespace,\n cluster: inputs.k8sCluster,\n selector,\n\n description: `Allow egress traffic from the WireGuard node to the service \"${displayName}\".`,\n\n egressRules: [\n {\n toNamespace: service.metadata.namespace,\n toSelector: service.spec.selector,\n },\n\n // for compatibility with Cilium which cannot correctly detect the destination endpoint when the packet is redirected by the WireGuard node\n ...(service.spec.clusterIP ? [{ toCidr: `${service.spec.clusterIP}/32` }] : []),\n ],\n },\n { provider },\n )\n\n NetworkPolicy.create(\n `allow-ingress-to-${getAppName(service.metadata)}`,\n {\n name: `allow-ingress-from-${appName}`,\n\n namespace: service.metadata.namespace,\n cluster: inputs.k8sCluster,\n selector: service.spec.selector,\n\n description: `Allow ingress traffic from the WireGuard node \"${appName}\" to the service \"${displayName}\".`,\n\n ingressRule: {\n fromNamespace: namespace,\n fromSelector: selector,\n },\n },\n { provider },\n )\n}\n\nfor (const peer of peers) {\n if (!peer.endpoint) {\n continue\n }\n\n const [endpoint, port] = peer.endpoint.split(\":\")\n\n NetworkPolicy.create(\n `allow-egress-to-peer-${peer.name}`,\n {\n namespace,\n cluster: inputs.k8sCluster,\n selector,\n\n description: `Allow egress traffic from the WireGuard node to the endpoint of the peer \"${peer.name}\".`,\n\n egressRule: {\n toEndpoint: endpoint,\n toPort: { port: port ? parseInt(port) : 51820, protocol: \"UDP\" },\n },\n },\n { provider },\n )\n}\n\nexport default outputs({\n deployment: deployment?.entity,\n interface: {\n name: interfaceName,\n deployment: deployment?.entity,\n },\n service: service?.apply(service => service?.entity),\n $terminals: [deployment?.terminal],\n})\n"],"mappings":"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","names":["service"]}
|
|
1
|
+
{"version":3,"sources":["../../src/node/index.ts","../../assets/images.json"],"sourcesContent":["import { NetworkPolicy, Namespace, ExposableWorkload, Secret } from \"@highstate/k8s\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, output, toPromise } from \"@highstate/pulumi\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport { l34EndpointToString, l4EndpointToString, updateEndpoints } from \"@highstate/common\"\nimport { generateIdentityConfig, isExitNode, shouldExpose } from \"../shared\"\nimport * as images from \"../../assets/images.json\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.node)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst identityName = identity.peer.name.replaceAll(\".\", \"-\")\nconst appName = args.appName ?? `wg-${identityName}`\n\nconst namespace = Namespace.createOrPatch(appName, {\n cluster: inputs.k8sCluster,\n resource: inputs.workload ?? inputs.interface?.workload,\n\n metadata: {\n labels: {\n \"pod-security.kubernetes.io/enforce\": \"privileged\",\n },\n },\n})\n\nconst downstreamInterface = await toPromise(inputs.interface)\n\nconst preUp: string[] = [\n // idk why\n \"sleep 5\",\n]\n\nconst postUp: string[] = [\n // enable masquerading for all traffic going out of the WireGuard node\n // TODO: consider adding more specific and restrictive rules\n \"iptables -t nat -A POSTROUTING -j MASQUERADE\",\n]\n\nconst preDown: string[] = [\n // remove the masquerading rule\n \"iptables -t nat -D POSTROUTING -j MASQUERADE\",\n]\n\nif (downstreamInterface) {\n // wait until the interface is up\n preUp.push(`while ! ip link show ${downstreamInterface.name} | grep -q 'UP' ; do sleep 1; done`)\n\n // remove the default rule to route all non-encapsulated traffic to upstream wireguard interface\n postUp.push(\"ip rule del not from all fwmark 0xca6c lookup 51820\")\n\n // add a rule to route all downstream traffic to the upstream wireguard interface\n postUp.push(\"ip rule add from all fwmark 0x1 lookup 51820\")\n\n // mark all downstream traffic with 0x1\n postUp.push(\n `iptables -t mangle -A PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all downstream traffic to the upstream wireguard interface\n preDown.push(\n `iptables -t mangle -D PREROUTING -i ${downstreamInterface.name} -j MARK --set-mark 0x1`,\n )\n\n // remove the rule to route all non-encapsulated traffic to upstream wireguard interface\n preDown.push(\"ip rule del from all fwmark 0x1 lookup 51820\")\n}\n\nconst interfaceName = identityName.substring(0, 15) // linux kernel limit\n\n// if there is a workload, we will use a different port to prevent potential conflicts\nconst containerPort = (inputs.workload ?? inputs.interface?.workload) ? 51821 : 51820\n\nconst configSecret = Secret.create(appName, {\n cluster: inputs.k8sCluster,\n namespace,\n\n stringData: {\n [`${interfaceName}.conf`]: generateIdentityConfig({\n identity,\n peers,\n listenPort: containerPort,\n preUp,\n postUp,\n preDown,\n defaultInterface: \"eth0\",\n cluster: await toPromise(inputs.k8sCluster),\n }),\n },\n})\n\nconst workload = ExposableWorkload.createOrPatchGeneric(appName, {\n type: \"Deployment\",\n cluster: inputs.k8sCluster,\n namespace,\n\n existing: inputs.workload ?? inputs.interface?.workload,\n\n container: deepmerge(\n {\n image: images[\"wireguard\"].image,\n\n environment: {\n PUID: \"1000\",\n PGID: \"1000\",\n TZ: \"Etc/UTC\",\n },\n\n securityContext: {\n capabilities: {\n add: [\"NET_ADMIN\"],\n },\n },\n\n port: {\n containerPort,\n protocol: \"UDP\",\n },\n\n volumeMount: {\n volume: configSecret,\n mountPath: \"/config/wg_confs\",\n },\n },\n args.containerSpec ?? {},\n ),\n\n service: shouldExpose(identity, args.exposePolicy)\n ? {\n external: args.external,\n port: {\n port: identity.peer.listenPort ?? 51820,\n targetPort: containerPort,\n protocol: \"UDP\",\n nodePort: args.external ? identity.peer.listenPort : undefined,\n },\n }\n : undefined,\n})\n\nif (shouldExpose(identity, args.exposePolicy)) {\n NetworkPolicy.create(\"allow-wireguard-ingress\", {\n namespace,\n cluster: inputs.k8sCluster,\n selector: workload.spec.selector,\n\n description: \"Allow encapsulated WireGuard traffic to the node from anywhere.\",\n\n ingressRule: {\n fromAll: true,\n },\n })\n}\n\nif (isExitNode(identity.peer)) {\n NetworkPolicy.create(\"allow-all-egress\", {\n namespace,\n cluster: inputs.k8sCluster,\n selector: workload.spec.selector,\n\n description: \"Allow all egress traffic from the WireGuard node since it is an exit node.\",\n\n egressRule: {\n toAll: true,\n },\n })\n}\n\nfor (const endpoint of identity.peer.allowedEndpoints) {\n NetworkPolicy.create(`allow-egress-to-${l34EndpointToString(endpoint)}`, {\n namespace,\n cluster: inputs.k8sCluster,\n selector: workload.spec.selector,\n\n description: `Allow egress traffic from the WireGuard node to the allowed endpoint \"${l34EndpointToString(endpoint)}\".`,\n\n egressRule: {\n toEndpoint: endpoint,\n },\n })\n}\n\nfor (const peer of peers) {\n if (!peer.endpoints.length) {\n continue\n }\n\n NetworkPolicy.create(`allow-egress-to-peer-${peer.name}`, {\n namespace,\n cluster: inputs.k8sCluster,\n selector: workload.spec.selector,\n\n description: `Allow egress traffic from the WireGuard node to the endpoints of the peer \"${peer.name}\".`,\n\n egressRule: {\n toEndpoints: peer.endpoints,\n },\n })\n}\n\nconst endpoints = await updateEndpoints(\n identity.peer.endpoints,\n [],\n output(workload.optionalService.apply(service => service?.endpoints ?? [])),\n \"prepend\",\n)\n\nexport default outputs({\n interface: {\n name: interfaceName,\n workload: workload.entity,\n },\n peer: {\n ...identity.peer,\n endpoints,\n },\n endpoints,\n\n $status: {\n endpoints: endpoints.map(l4EndpointToString),\n },\n\n $terminals: [workload.terminal],\n})\n","{\n \"wireguard\": {\n \"name\": \"docker.io/linuxserver/wireguard\",\n \"tag\": \"latest\",\n \"image\": \"docker.io/linuxserver/wireguard:latest@sha256:7792dcef56c51e6b4d499a209e980ed74309bf3bee6af12168ea02bf289eddd9\"\n }\n}\n"],"mappings":"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","names":["wireguard","wireguard"]}
|
package/dist/peer/index.js
CHANGED
|
@@ -1,41 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "../chunk-7BHZHUOK.js";
|
|
2
|
+
createPeerEntity
|
|
3
|
+
} from "../chunk-PXOBQDLU.js";
|
|
5
4
|
|
|
6
5
|
// src/peer/index.ts
|
|
7
6
|
import { wireguard } from "@highstate/library";
|
|
8
7
|
import { forUnit, toPromise } from "@highstate/pulumi";
|
|
9
|
-
import { l4EndpointToString } from "@highstate/common";
|
|
10
|
-
var { name, args, inputs, outputs } = forUnit(wireguard.peer);
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var excludedIps = calculateExcludedIps(args, network);
|
|
15
|
-
var publicKey = args.publicKey ?? peer?.publicKey;
|
|
16
|
-
if (!publicKey) {
|
|
17
|
-
throw new Error("Public key was not provided neither in args nor in peer");
|
|
18
|
-
}
|
|
8
|
+
import { l3EndpointToString, l4EndpointToString } from "@highstate/common";
|
|
9
|
+
var { name, args, secrets, inputs, outputs } = forUnit(wireguard.peer);
|
|
10
|
+
var resolvedInpus = await toPromise(inputs);
|
|
11
|
+
var presharedKey = await toPromise(secrets.presharedKey);
|
|
12
|
+
var peer = createPeerEntity(name, args, resolvedInpus, args.publicKey, presharedKey);
|
|
19
13
|
var peer_default = outputs({
|
|
20
|
-
peer
|
|
21
|
-
|
|
22
|
-
network: inputs.network ?? peer?.network,
|
|
23
|
-
address: args.address ?? peer?.address,
|
|
24
|
-
publicKey,
|
|
25
|
-
allowedIps: allowedIps.length ? allowedIps : peer?.allowedIps,
|
|
26
|
-
endpoint: inputs.l4Endpoint?.apply(l4EndpointToString) ?? args.endpoint ?? peer?.endpoint,
|
|
27
|
-
excludedIps: excludedIps.length ? excludedIps : peer?.excludedIps,
|
|
28
|
-
dns: args.dns ?? peer?.dns,
|
|
29
|
-
presharedKeyPart: peer?.presharedKeyPart
|
|
30
|
-
},
|
|
14
|
+
peer,
|
|
15
|
+
endpoints: peer.endpoints,
|
|
31
16
|
$status: {
|
|
32
|
-
|
|
33
|
-
value:
|
|
34
|
-
complementaryTo: "
|
|
17
|
+
endpoints: {
|
|
18
|
+
value: peer.endpoints.map(l4EndpointToString),
|
|
19
|
+
complementaryTo: "endpoints"
|
|
35
20
|
},
|
|
36
|
-
|
|
37
|
-
value:
|
|
38
|
-
complementaryTo: "
|
|
21
|
+
allowedEndpoints: {
|
|
22
|
+
value: peer.allowedEndpoints.map(l3EndpointToString),
|
|
23
|
+
complementaryTo: "allowedEndpoints"
|
|
39
24
|
}
|
|
40
25
|
}
|
|
41
26
|
});
|
package/dist/peer/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/peer/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { l4EndpointToString } from \"@highstate/common\"\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/peer/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { l3EndpointToString, l4EndpointToString } from \"@highstate/common\"\nimport { createPeerEntity } from \"../shared\"\n\nconst { name, args, secrets, inputs, outputs } = forUnit(wireguard.peer)\n\nconst resolvedInpus = await toPromise(inputs)\nconst presharedKey = await toPromise(secrets.presharedKey)\n\nconst peer = createPeerEntity(name, args, resolvedInpus, args.publicKey, presharedKey)\n\nexport default outputs({\n peer,\n endpoints: peer.endpoints,\n\n $status: {\n endpoints: {\n value: peer.endpoints.map(l4EndpointToString),\n complementaryTo: \"endpoints\",\n },\n allowedEndpoints: {\n value: peer.allowedEndpoints.map(l3EndpointToString),\n complementaryTo: \"allowedEndpoints\",\n },\n },\n})\n"],"mappings":";;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,SAAS,iBAAiB;AACnC,SAAS,oBAAoB,0BAA0B;AAGvD,IAAM,EAAE,MAAM,MAAM,SAAS,QAAQ,QAAQ,IAAI,QAAQ,UAAU,IAAI;AAEvE,IAAM,gBAAgB,MAAM,UAAU,MAAM;AAC5C,IAAM,eAAe,MAAM,UAAU,QAAQ,YAAY;AAEzD,IAAM,OAAO,iBAAiB,MAAM,MAAM,eAAe,KAAK,WAAW,YAAY;AAErF,IAAO,eAAQ,QAAQ;AAAA,EACrB;AAAA,EACA,WAAW,KAAK;AAAA,EAEhB,SAAS;AAAA,IACP,WAAW;AAAA,MACT,OAAO,KAAK,UAAU,IAAI,kBAAkB;AAAA,MAC5C,iBAAiB;AAAA,IACnB;AAAA,IACA,kBAAkB;AAAA,MAChB,OAAO,KAAK,iBAAiB,IAAI,kBAAkB;AAAA,MACnD,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
calculateAllowedEndpoints,
|
|
3
|
+
calculateAllowedIps,
|
|
4
|
+
calculateEndpoints
|
|
5
|
+
} from "../chunk-PXOBQDLU.js";
|
|
6
|
+
|
|
7
|
+
// src/peer-patch/index.ts
|
|
8
|
+
import { wireguard } from "@highstate/library";
|
|
9
|
+
import { forUnit, toPromise } from "@highstate/pulumi";
|
|
10
|
+
import { l3EndpointToString, l4EndpointToString, updateEndpoints } from "@highstate/common";
|
|
11
|
+
var { args, inputs, outputs } = forUnit(wireguard.peerPatch);
|
|
12
|
+
var resolvedInputs = await toPromise(inputs);
|
|
13
|
+
var endpoints = await updateEndpoints(
|
|
14
|
+
inputs.peer.endpoints,
|
|
15
|
+
[],
|
|
16
|
+
calculateEndpoints({ ...args, listenPort: resolvedInputs.peer.listenPort }, resolvedInputs),
|
|
17
|
+
args.endpointsPatchMode
|
|
18
|
+
);
|
|
19
|
+
var allowedEndpoints = await updateEndpoints(
|
|
20
|
+
inputs.peer.allowedEndpoints,
|
|
21
|
+
[],
|
|
22
|
+
calculateAllowedEndpoints(args, resolvedInputs),
|
|
23
|
+
args.allowedEndpointsPatchMode
|
|
24
|
+
);
|
|
25
|
+
var peer_patch_default = outputs({
|
|
26
|
+
peer: {
|
|
27
|
+
...resolvedInputs.peer,
|
|
28
|
+
endpoints,
|
|
29
|
+
allowedEndpoints,
|
|
30
|
+
dns: args.dns.length > 0 ? args.dns : resolvedInputs.peer.dns,
|
|
31
|
+
allowedIps: calculateAllowedIps(
|
|
32
|
+
{ address: args.address ?? resolvedInputs.peer.address, exitNode: args.exitNode },
|
|
33
|
+
resolvedInputs,
|
|
34
|
+
allowedEndpoints
|
|
35
|
+
)
|
|
36
|
+
},
|
|
37
|
+
endpoints,
|
|
38
|
+
$status: {
|
|
39
|
+
endpoints: {
|
|
40
|
+
value: endpoints.map(l4EndpointToString),
|
|
41
|
+
complementaryTo: "endpoints"
|
|
42
|
+
},
|
|
43
|
+
allowedEndpoints: {
|
|
44
|
+
value: allowedEndpoints.map(l3EndpointToString),
|
|
45
|
+
complementaryTo: "allowedEndpoints"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
export {
|
|
50
|
+
peer_patch_default as default
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/peer-patch/index.ts"],"sourcesContent":["import { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { l3EndpointToString, l4EndpointToString, updateEndpoints } from \"@highstate/common\"\nimport { calculateAllowedEndpoints, calculateAllowedIps, calculateEndpoints } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.peerPatch)\n\nconst resolvedInputs = await toPromise(inputs)\n\nconst endpoints = await updateEndpoints(\n inputs.peer.endpoints,\n [],\n calculateEndpoints({ ...args, listenPort: resolvedInputs.peer.listenPort }, resolvedInputs),\n args.endpointsPatchMode,\n)\n\nconst allowedEndpoints = await updateEndpoints(\n inputs.peer.allowedEndpoints,\n [],\n calculateAllowedEndpoints(args, resolvedInputs),\n args.allowedEndpointsPatchMode,\n)\n\nexport default outputs({\n peer: {\n ...resolvedInputs.peer,\n endpoints,\n allowedEndpoints,\n dns: args.dns.length > 0 ? args.dns : resolvedInputs.peer.dns,\n allowedIps: calculateAllowedIps(\n { address: args.address ?? resolvedInputs.peer.address, exitNode: args.exitNode },\n resolvedInputs,\n allowedEndpoints,\n ),\n },\n\n endpoints,\n\n $status: {\n endpoints: {\n value: endpoints.map(l4EndpointToString),\n complementaryTo: \"endpoints\",\n },\n allowedEndpoints: {\n value: allowedEndpoints.map(l3EndpointToString),\n complementaryTo: \"allowedEndpoints\",\n },\n },\n})\n"],"mappings":";;;;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,SAAS,iBAAiB;AACnC,SAAS,oBAAoB,oBAAoB,uBAAuB;AAGxE,IAAM,EAAE,MAAM,QAAQ,QAAQ,IAAI,QAAQ,UAAU,SAAS;AAE7D,IAAM,iBAAiB,MAAM,UAAU,MAAM;AAE7C,IAAM,YAAY,MAAM;AAAA,EACtB,OAAO,KAAK;AAAA,EACZ,CAAC;AAAA,EACD,mBAAmB,EAAE,GAAG,MAAM,YAAY,eAAe,KAAK,WAAW,GAAG,cAAc;AAAA,EAC1F,KAAK;AACP;AAEA,IAAM,mBAAmB,MAAM;AAAA,EAC7B,OAAO,KAAK;AAAA,EACZ,CAAC;AAAA,EACD,0BAA0B,MAAM,cAAc;AAAA,EAC9C,KAAK;AACP;AAEA,IAAO,qBAAQ,QAAQ;AAAA,EACrB,MAAM;AAAA,IACJ,GAAG,eAAe;AAAA,IAClB;AAAA,IACA;AAAA,IACA,KAAK,KAAK,IAAI,SAAS,IAAI,KAAK,MAAM,eAAe,KAAK;AAAA,IAC1D,YAAY;AAAA,MACV,EAAE,SAAS,KAAK,WAAW,eAAe,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,MAChF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,SAAS;AAAA,IACP,WAAW;AAAA,MACT,OAAO,UAAU,IAAI,kBAAkB;AAAA,MACvC,iBAAiB;AAAA,IACnB;AAAA,IACA,kBAAkB;AAAA,MAChB,OAAO,iBAAiB,IAAI,kBAAkB;AAAA,MAC9C,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/wireguard",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -11,28 +11,30 @@
|
|
|
11
11
|
"./config": "./dist/config/index.js",
|
|
12
12
|
"./config-bundle": "./dist/config-bundle/index.js",
|
|
13
13
|
"./node": "./dist/node/index.js",
|
|
14
|
-
"./peer": "./dist/peer/index.js"
|
|
14
|
+
"./peer": "./dist/peer/index.js",
|
|
15
|
+
"./peer-patch": "./dist/peer-patch/index.js"
|
|
15
16
|
},
|
|
16
17
|
"publishConfig": {
|
|
17
18
|
"access": "public"
|
|
18
19
|
},
|
|
19
20
|
"scripts": {
|
|
20
|
-
"build": "highstate build"
|
|
21
|
+
"build": "highstate build",
|
|
22
|
+
"update-images": "../../scripts/update-images.sh ./assets/images.json"
|
|
21
23
|
},
|
|
22
24
|
"dependencies": {
|
|
23
|
-
"@highstate/common": "^0.9.
|
|
24
|
-
"@highstate/contract": "^0.9.
|
|
25
|
-
"@highstate/k8s": "^0.9.
|
|
26
|
-
"@highstate/library": "^0.9.
|
|
27
|
-
"@highstate/pulumi": "^0.9.
|
|
25
|
+
"@highstate/common": "^0.9.5",
|
|
26
|
+
"@highstate/contract": "^0.9.5",
|
|
27
|
+
"@highstate/k8s": "^0.9.5",
|
|
28
|
+
"@highstate/library": "^0.9.5",
|
|
29
|
+
"@highstate/pulumi": "^0.9.5",
|
|
28
30
|
"@noble/curves": "^1.8.0",
|
|
29
31
|
"@pulumi/kubernetes": "^4.18.0",
|
|
30
32
|
"deepmerge-ts": "^7.1.5",
|
|
31
33
|
"zip-stream": "^7.0.2"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
|
-
"@highstate/cli": "^0.9.
|
|
36
|
+
"@highstate/cli": "^0.9.5",
|
|
35
37
|
"@types/zip-stream": "^7.0.0"
|
|
36
38
|
},
|
|
37
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "93fa1e8b1189a5232055c852fd79a684d8b80444"
|
|
38
40
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared.ts","../../../node_modules/@noble/hashes/src/cryptoNode.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/remeda/dist/chunk-ANXBDSUI.js","../../../node_modules/remeda/dist/chunk-3GOCSNFN.js","../../../node_modules/remeda/dist/chunk-LFJW7BOT.js","../../../node_modules/remeda/dist/chunk-QJLMYOTX.js"],"sourcesContent":["import type { k8s, wireguard } from \"@highstate/library\"\nimport { x25519 } from \"@noble/curves/ed25519\"\nimport { randomBytes } from \"@noble/hashes/utils\"\nimport { unique } from \"remeda\"\n\nexport function generateKey(): string {\n const key = x25519.utils.randomPrivateKey()\n\n return Buffer.from(key).toString(\"base64\")\n}\n\nexport function convertPrivateKeyToPublicKey(privateKey: string): string {\n const key = Buffer.from(privateKey, \"base64\")\n\n return Buffer.from(x25519.getPublicKey(key)).toString(\"base64\")\n}\n\nexport function generatePresharedKey(): string {\n const key = randomBytes(32)\n\n return Buffer.from(key).toString(\"base64\")\n}\n\nexport function combinePresharedKeyParts(part1: string, part2: string): string {\n const key1 = Buffer.from(part1, \"base64\")\n const key2 = Buffer.from(part2, \"base64\")\n const result = new Uint8Array(32)\n\n for (let i = 0; i < 32; i++) {\n result[i] = key1[i] ^ key2[i]\n }\n\n return Buffer.from(result).toString(\"base64\")\n}\n\nfunction generatePeerConfig(identity: wireguard.Identity, peer: wireguard.Peer): string {\n const lines = [\n //\n \"[Peer]\",\n `# ${peer.name}`,\n `PublicKey = ${peer.publicKey}`,\n ]\n\n if (peer.allowedIps.length > 0) {\n lines.push(`AllowedIPs = ${peer.allowedIps.join(\", \")}`)\n }\n\n if (peer.endpoint) {\n lines.push(`Endpoint = ${peer.endpoint}`)\n }\n\n if (identity.presharedKeyPart && peer.presharedKeyPart) {\n const presharedKey = combinePresharedKeyParts(identity.presharedKeyPart, peer.presharedKeyPart)\n\n lines.push(`PresharedKey = ${presharedKey}`)\n } else if (identity.network?.globalPresharedKey) {\n if (identity.network.globalPresharedKey !== peer.network?.globalPresharedKey) {\n throw new Error(\"The global preshared key must be the same for all peers.\")\n }\n\n lines.push(`PresharedKey = ${identity.network.globalPresharedKey}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport type IdentityConfigArgs = {\n identity: wireguard.Identity\n peers: wireguard.Peer[]\n listenPort?: number\n dns?: string[]\n postUp?: string[]\n preUp?: string[]\n preDown?: string[]\n postDown?: string[]\n defaultInterface?: string\n}\n\nexport function generateIdentityConfig({\n identity,\n peers,\n listenPort,\n dns,\n preUp,\n postUp,\n preDown,\n postDown,\n defaultInterface,\n}: IdentityConfigArgs): string {\n const allDns = unique(peers.flatMap(peer => peer.dns ?? []).concat(dns ?? []))\n const excludedIps = unique(peers.flatMap(peer => peer.excludedIps ?? []))\n\n const lines = [\n //\n \"[Interface]\",\n `# ${identity.name}`,\n ]\n\n if (identity.address) {\n lines.push(`Address = ${identity.address}`)\n }\n\n lines.push(\n //\n `PrivateKey = ${identity.privateKey}`,\n \"MTU = 1280\",\n )\n\n if (allDns.length > 0) {\n lines.push(`DNS = ${allDns.join(\", \")}`)\n }\n\n if (listenPort) {\n lines.push(`ListenPort = ${listenPort}`)\n }\n\n if (preUp) {\n lines.push()\n for (const command of preUp) {\n lines.push(`PreUp = ${command}`)\n }\n }\n\n if (postUp) {\n lines.push()\n for (const command of postUp) {\n lines.push(`PostUp = ${command}`)\n }\n }\n\n if (preDown) {\n lines.push()\n for (const command of preDown) {\n lines.push(`PreDown = ${command}`)\n }\n }\n\n if (postDown) {\n lines.push()\n for (const command of postDown) {\n lines.push(`PostDown = ${command}`)\n }\n }\n\n if (defaultInterface) {\n for (const excludedIp of excludedIps) {\n lines.push(`PostUp = ip route add ${excludedIp} dev ${defaultInterface}`)\n }\n }\n\n const otherPeers = peers.filter(peer => peer.name !== identity.name)\n\n for (const peer of otherPeers) {\n lines.push(\"\")\n lines.push(generatePeerConfig(identity, peer))\n }\n\n return lines.join(\"\\n\")\n}\n\ntype AllowedIpsArgs = {\n address?: string\n allowedIps?: string[]\n exitNode?: boolean\n}\n\nexport function calculateAllowedIps(\n { address, allowedIps, exitNode }: AllowedIpsArgs,\n network: wireguard.Network | undefined,\n k8sServices?: k8s.Service[],\n): string[] {\n const result = new Set<string>()\n\n if (address) {\n result.add(address)\n }\n\n if (allowedIps) {\n for (const ip of allowedIps) {\n result.add(ip)\n }\n }\n\n if (exitNode) {\n result.add(\"0.0.0.0/0\")\n\n if (network?.ipv6) {\n result.add(\"::/0\")\n }\n }\n\n if (k8sServices) {\n for (const service of k8sServices) {\n if (service.spec.clusterIP) {\n result.add(service.spec.clusterIP)\n }\n }\n }\n\n return Array.from(result)\n}\n\ntype ExcludedIpsArgs = {\n excludedIps?: string[]\n excludePrivateIps?: boolean\n}\n\nexport function calculateExcludedIps(\n { excludedIps, excludePrivateIps }: ExcludedIpsArgs,\n network: wireguard.Network | undefined,\n): string[] {\n const result = new Set<string>()\n\n if (excludedIps) {\n for (const ip of excludedIps) {\n result.add(ip)\n }\n }\n\n if (excludePrivateIps) {\n result.add(\"10.0.0.0/8\")\n result.add(\"172.16.0.0/12\")\n result.add(\"192.168.0.0/16\")\n\n if (network?.ipv6) {\n result.add(\"fc00::/7\")\n result.add(\"fe80::/10\")\n }\n }\n\n return Array.from(result)\n}\n\ntype EndpointArgs = {\n externalIp?: string\n listenPort?: number\n endpoint?: string\n fqdn?: string\n clusterInfo?: k8s.ClusterInfo\n}\n\nexport function calculateEndpoint({\n externalIp,\n listenPort,\n fqdn,\n endpoint,\n clusterInfo,\n}: EndpointArgs): EndpointArgs {\n if (endpoint) {\n return {\n endpoint,\n externalIp,\n listenPort,\n }\n }\n\n fqdn ??= clusterInfo?.fqdn\n externalIp ??= clusterInfo?.externalIps[0]\n\n if (fqdn && listenPort) {\n return { endpoint: `${fqdn}:${listenPort}`, fqdn, externalIp }\n }\n\n if (externalIp && listenPort) {\n return { endpoint: `${externalIp}:${listenPort}`, externalIp, fqdn }\n }\n\n return { endpoint, externalIp, listenPort, fqdn }\n}\n","/**\n * Internal webcrypto alias.\n * We prefer WebCrypto aka globalThis.crypto, which exists in node.js 16+.\n * Falls back to Node.js built-in crypto for Node.js <=v14.\n * See utils.ts for details.\n * @module\n */\n// @ts-ignore\nimport * as nc from 'node:crypto';\nexport const crypto: any =\n nc && typeof nc === 'object' && 'webcrypto' in nc\n ? (nc.webcrypto as any)\n : nc && typeof nc === 'object' && 'randomBytes' in nc\n ? nc\n : undefined;\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\nimport { abytes } from './_assert.js';\n// export { isBytes } from './_assert.js';\n// We can't reuse isBytes from _assert, because somehow this causes huge perf issues\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n// Cast array to different type\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n// Cast array to view\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n// The byte swap operation for uint32\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const byteSwapIfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n);\n\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr: Uint32Array): void {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n}\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n/**\n * Convert byte array to hex string.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols in both browsers and Node.js since v11\n// See https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Convert JS string to byte array.\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('utf8ToBytes expected string, got ' + typeof str);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** Accepted input of hash functions. Strings are converted to byte arrays. */\nexport type Input = Uint8Array | string;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n abytes(data);\n return data;\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\n/** For runtime check if class implements interface */\nexport abstract class Hash<T extends Hash<T>> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: Input): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n /**\n * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n * when no options are passed.\n * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n * There are no guarantees for clean-up because it's impossible in JS.\n */\n abstract _cloneInto(to?: T): T;\n // Safe version that clones internal state\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\ntype EmptyObj = {};\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Hash function */\nexport type CHash = ReturnType<typeof wrapConstructor>;\n/** Hash function with output */\nexport type CHashO = ReturnType<typeof wrapConstructorWithOpts>;\n/** XOF with output */\nexport type CHashXO = ReturnType<typeof wrapXOFConstructorWithOpts>;\n\n/** Wraps hash function, creating an interface on top of it */\nexport function wrapConstructor<T extends Hash<T>>(\n hashCons: () => Hash<T>\n): {\n (msg: Input): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(): Hash<T>;\n} {\n const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\n\nexport function wrapConstructorWithOpts<H extends Hash<H>, T extends Object>(\n hashCons: (opts?: T) => Hash<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts: T): Hash<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\nexport function wrapXOFConstructorWithOpts<H extends HashXOF<H>, T extends Object>(\n hashCons: (opts?: T) => HashXOF<H>\n): {\n (msg: Input, opts?: T): Uint8Array;\n outputLen: number;\n blockLen: number;\n create(opts: T): HashXOF<H>;\n} {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n // Legacy Node.js compatibility\n if (crypto && typeof crypto.randomBytes === 'function') {\n return crypto.randomBytes(bytesLength);\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n","var e={done:!0,hasNext:!1},s={done:!1,hasNext:!1},a=()=>e,o=t=>({hasNext:!0,next:t,done:!1});export{s as a,a as b,o as c};\n","import{a as A}from\"./chunk-ANXBDSUI.js\";function C(t,...o){let n=t,u=o.map(e=>\"lazy\"in e?y(e):void 0),p=0;for(;p<o.length;){if(u[p]===void 0||!B(n)){let i=o[p];n=i(n),p+=1;continue}let r=[];for(let i=p;i<o.length;i++){let l=u[i];if(l===void 0||(r.push(l),l.isSingle))break}let a=[];for(let i of n)if(f(i,a,r))break;let{isSingle:s}=r.at(-1);n=s?a[0]:a,p+=r.length}return n}function f(t,o,n){if(n.length===0)return o.push(t),!1;let u=t,p=A,e=!1;for(let[r,a]of n.entries()){let{index:s,items:i}=a;if(i.push(u),p=a(u,s,i),a.index+=1,p.hasNext){if(p.hasMany??!1){for(let l of p.next)if(f(l,o,n.slice(r+1)))return!0;return e}u=p.next}if(!p.hasNext)break;p.done&&(e=!0)}return p.hasNext&&o.push(u),e}function y(t){let{lazy:o,lazyArgs:n}=t,u=o(...n);return Object.assign(u,{isSingle:o.single??!1,index:0,items:[]})}function B(t){return typeof t==\"string\"||typeof t==\"object\"&&t!==null&&Symbol.iterator in t}export{C as a};\n","import{a as o}from\"./chunk-3GOCSNFN.js\";function y(t,i){let a=i.length-t.length;if(a===1){let[n,...r]=i;return o(n,{lazy:t,lazyArgs:r})}if(a===0){let n={lazy:t,lazyArgs:i};return Object.assign(e=>o(e,n),n)}throw new Error(\"Wrong number of arguments\")}export{y as a};\n","import{a as r}from\"./chunk-LFJW7BOT.js\";import{a as n}from\"./chunk-ANXBDSUI.js\";function i(...e){return r(a,e)}function a(){let e=new Set;return t=>e.has(t)?n:(e.add(t),{done:!1,hasNext:!0,next:t})}export{i as a};\n"],"mappings":"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","names":["i","a","s","y","i","a","y","i"]}
|