@highstate/wireguard 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-I7BWSAN6.js +49 -0
- package/dist/chunk-I7BWSAN6.js.map +1 -0
- package/dist/{chunk-GVOR653I.js → chunk-OSJ6YUBV.js} +56 -80
- package/dist/chunk-OSJ6YUBV.js.map +1 -0
- package/dist/config/index.js +24 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config-bundle/index.js +17 -3
- package/dist/config-bundle/index.js.map +1 -1
- package/dist/feed/index.js +109 -0
- package/dist/feed/index.js.map +1 -0
- package/dist/highstate.manifest.json +9 -8
- package/dist/identity/index.js +6 -13
- package/dist/identity/index.js.map +1 -1
- package/dist/network/index.js +1 -1
- package/dist/node/index.js +3 -3
- package/dist/node/index.js.map +1 -1
- package/dist/node.k8s/index.js +69 -67
- package/dist/node.k8s/index.js.map +1 -1
- package/dist/peer/index.js +6 -12
- package/dist/peer/index.js.map +1 -1
- package/dist/peer-patch/index.js +14 -35
- package/dist/peer-patch/index.js.map +1 -1
- package/package.json +12 -7
- package/dist/chunk-GVOR653I.js.map +0 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
2
|
+
var __typeError = (msg) => {
|
|
3
|
+
throw TypeError(msg);
|
|
4
|
+
};
|
|
5
|
+
var __using = (stack, value, async) => {
|
|
6
|
+
if (value != null) {
|
|
7
|
+
if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
|
|
8
|
+
var dispose, inner;
|
|
9
|
+
if (async) dispose = value[__knownSymbol("asyncDispose")];
|
|
10
|
+
if (dispose === void 0) {
|
|
11
|
+
dispose = value[__knownSymbol("dispose")];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") __typeError("Object not disposable");
|
|
15
|
+
if (inner) dispose = function() {
|
|
16
|
+
try {
|
|
17
|
+
inner.call(this);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return Promise.reject(e);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
stack.push([async, dispose, value]);
|
|
23
|
+
} else if (async) {
|
|
24
|
+
stack.push([async]);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
var __callDispose = (stack, error, hasError) => {
|
|
29
|
+
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
|
|
30
|
+
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
|
|
31
|
+
};
|
|
32
|
+
var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
|
|
33
|
+
var next = (it) => {
|
|
34
|
+
while (it = stack.pop()) {
|
|
35
|
+
try {
|
|
36
|
+
var result = it[1] && it[1].call(it[2]);
|
|
37
|
+
if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
38
|
+
} catch (e) {
|
|
39
|
+
fail(e);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (hasError) throw error;
|
|
43
|
+
};
|
|
44
|
+
return next();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { __callDispose, __using };
|
|
48
|
+
//# sourceMappingURL=chunk-I7BWSAN6.js.map
|
|
49
|
+
//# sourceMappingURL=chunk-I7BWSAN6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-I7BWSAN6.js"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { addressToCidr, subnetToString, parseAddress, filterWithMetadataByExpression, l4EndpointToString, l3EndpointToL4, parseEndpoint, parseSubnets, createAddressSpace } from '@highstate/common';
|
|
2
2
|
import { getBestEndpoint } from '@highstate/k8s';
|
|
3
3
|
import { secret } from '@highstate/pulumi';
|
|
4
4
|
import { x25519 } from '@noble/curves/ed25519';
|
|
5
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
5
6
|
import { randomBytes } from '@noble/hashes/utils.js';
|
|
6
7
|
import { unique, uniqueBy } from 'remeda';
|
|
7
8
|
|
|
@@ -21,23 +22,21 @@ function generatePresharedKey() {
|
|
|
21
22
|
function combinePresharedKeyParts(part1, part2) {
|
|
22
23
|
const key1 = Buffer.from(part1, "base64");
|
|
23
24
|
const key2 = Buffer.from(part2, "base64");
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
result[i] = key1[i] ^ key2[i];
|
|
27
|
-
}
|
|
28
|
-
return Buffer.from(result).toString("base64");
|
|
25
|
+
const combined = Buffer.concat([key1, key2].toSorted((a, b) => a.compare(b)));
|
|
26
|
+
return Buffer.from(sha256(combined)).toString("base64");
|
|
29
27
|
}
|
|
30
|
-
function generatePeerConfig(identity, peer, cluster) {
|
|
28
|
+
function generatePeerConfig(identity, peer, cluster, peerEndpointFilter) {
|
|
31
29
|
const lines = [
|
|
32
30
|
//
|
|
33
31
|
"[Peer]",
|
|
34
32
|
`# ${peer.name}`,
|
|
35
33
|
`PublicKey = ${peer.publicKey}`
|
|
36
34
|
];
|
|
37
|
-
if (peer.
|
|
38
|
-
lines.push(`AllowedIPs = ${peer.
|
|
35
|
+
if (peer.allowedSubnets.length > 0) {
|
|
36
|
+
lines.push(`AllowedIPs = ${peer.allowedSubnets.map(subnetToString).join(", ")}`);
|
|
39
37
|
}
|
|
40
|
-
const
|
|
38
|
+
const endpoints = peerEndpointFilter ? filterWithMetadataByExpression(peer.endpoints, peerEndpointFilter) : peer.endpoints;
|
|
39
|
+
const bestEndpoint = getBestEndpoint(endpoints, cluster);
|
|
41
40
|
if (bestEndpoint) {
|
|
42
41
|
lines.push(`Endpoint = ${l4EndpointToString(bestEndpoint)}`);
|
|
43
42
|
}
|
|
@@ -69,18 +68,19 @@ function generateIdentityConfig({
|
|
|
69
68
|
postUp = [],
|
|
70
69
|
preDown = [],
|
|
71
70
|
postDown = [],
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
cluster,
|
|
72
|
+
peerEndpointFilter
|
|
74
73
|
}) {
|
|
75
|
-
const allDns = unique(
|
|
76
|
-
|
|
74
|
+
const allDns = unique(
|
|
75
|
+
peers.flatMap((peer) => peer.dns).map((dns2) => dns2.value).concat(dns)
|
|
76
|
+
);
|
|
77
77
|
const lines = [
|
|
78
78
|
//
|
|
79
79
|
"[Interface]",
|
|
80
80
|
`# ${identity.peer.name}`
|
|
81
81
|
];
|
|
82
|
-
if (identity.peer.
|
|
83
|
-
lines.push(`Address = ${identity.peer.
|
|
82
|
+
if (identity.peer.addresses) {
|
|
83
|
+
lines.push(`Address = ${identity.peer.addresses.map(addressToCidr).join(", ")}`);
|
|
84
84
|
}
|
|
85
85
|
lines.push(
|
|
86
86
|
//
|
|
@@ -117,97 +117,73 @@ function generateIdentityConfig({
|
|
|
117
117
|
lines.push(`PostDown = ${command}`);
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
if (defaultInterface) {
|
|
121
|
-
lines.push();
|
|
122
|
-
for (const excludedIp of excludedIps) {
|
|
123
|
-
lines.push(`PostUp = ip route add ${excludedIp} dev ${defaultInterface}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
120
|
const otherPeers = peers.filter((peer) => peer.name !== identity.peer.name);
|
|
127
121
|
for (const peer of otherPeers) {
|
|
128
122
|
lines.push("");
|
|
129
|
-
lines.push(generatePeerConfig(identity, peer, cluster));
|
|
123
|
+
lines.push(generatePeerConfig(identity, peer, cluster, peerEndpointFilter));
|
|
130
124
|
}
|
|
131
125
|
return secret(lines.join("\n"));
|
|
132
126
|
}
|
|
133
|
-
function calculateEndpoints({
|
|
127
|
+
function calculateEndpoints({
|
|
128
|
+
endpoints: argsEnpoints,
|
|
129
|
+
listenPort
|
|
130
|
+
}, { endpoints }) {
|
|
134
131
|
return uniqueBy(
|
|
135
132
|
[
|
|
136
|
-
...
|
|
137
|
-
...
|
|
138
|
-
...endpoints.map(parseL4Endpoint)
|
|
133
|
+
...endpoints.map((e) => l3EndpointToL4(e, e.port ?? listenPort ?? 51820)),
|
|
134
|
+
...argsEnpoints.map((endpoint) => parseEndpoint(endpoint, 4))
|
|
139
135
|
],
|
|
140
136
|
(endpoint) => l4EndpointToString(endpoint)
|
|
141
137
|
);
|
|
142
138
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
139
|
+
async function calculateAllowedSubnets({
|
|
140
|
+
includeAddresses,
|
|
141
|
+
excludePrivateSubnets,
|
|
142
|
+
exitNode,
|
|
143
|
+
allowedSubnets
|
|
144
|
+
}, { network, allowedSubnets: inputAllowedSubnets }, addresses) {
|
|
145
|
+
const included = await parseSubnets(allowedSubnets, inputAllowedSubnets);
|
|
146
|
+
const excluded = [];
|
|
147
|
+
if (includeAddresses) {
|
|
148
|
+
included.push(...addresses);
|
|
147
149
|
}
|
|
148
150
|
if (exitNode) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
result.add("::/0");
|
|
151
|
+
if (network?.ipv4) {
|
|
152
|
+
included.push("0.0.0.0/0");
|
|
152
153
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (endpoint.type !== "hostname") {
|
|
156
|
-
result.add(l3EndpointToString(endpoint));
|
|
154
|
+
if (network?.ipv6) {
|
|
155
|
+
included.push("::/0");
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
allowedL4Endpoints
|
|
164
|
-
}) {
|
|
165
|
-
return uniqueBy(
|
|
166
|
-
[
|
|
167
|
-
//
|
|
168
|
-
...allowedL3Endpoints,
|
|
169
|
-
...allowedL4Endpoints,
|
|
170
|
-
...allowedEndpoints.map(parseL34Endpoint)
|
|
171
|
-
],
|
|
172
|
-
(endpoint) => l34EndpointToString(endpoint)
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
function calculateExcludedIps({ excludedIps, excludePrivateIps }, { network }) {
|
|
176
|
-
const result = /* @__PURE__ */ new Set();
|
|
177
|
-
for (const ip of excludedIps) {
|
|
178
|
-
result.add(ip);
|
|
179
|
-
}
|
|
180
|
-
if (excludePrivateIps) {
|
|
181
|
-
result.add("10.0.0.0/8");
|
|
182
|
-
result.add("172.16.0.0/12");
|
|
183
|
-
result.add("192.168.0.0/16");
|
|
158
|
+
if (excludePrivateSubnets) {
|
|
159
|
+
excluded.push("10.0.0.0/8");
|
|
160
|
+
excluded.push("172.16.0.0/12");
|
|
161
|
+
excluded.push("192.168.0.0/16");
|
|
184
162
|
if (network?.ipv6) {
|
|
185
|
-
|
|
186
|
-
|
|
163
|
+
excluded.push("fc00::/7");
|
|
164
|
+
excluded.push("fe80::/10");
|
|
187
165
|
}
|
|
188
166
|
}
|
|
189
|
-
|
|
167
|
+
const space = createAddressSpace({ included, excluded });
|
|
168
|
+
return space.subnets;
|
|
190
169
|
}
|
|
191
170
|
function isExitNode(peer) {
|
|
192
|
-
return peer.
|
|
171
|
+
return peer.allowedSubnets.some((subnet) => subnetToString(subnet) === "0.0.0.0/0") || peer.allowedSubnets.some((subnet) => subnetToString(subnet) === "::/0");
|
|
193
172
|
}
|
|
194
|
-
function createPeerEntity(name, args, inputs, publicKey, presharedKeyPart) {
|
|
173
|
+
async function createPeerEntity(name, args, inputs, publicKey, presharedKeyPart) {
|
|
195
174
|
const endpoints = calculateEndpoints(args, inputs);
|
|
196
|
-
const
|
|
197
|
-
const
|
|
198
|
-
const excludedIps = calculateExcludedIps(args, inputs);
|
|
175
|
+
const addresses = args.addresses.map(parseAddress);
|
|
176
|
+
const allowedSubnets = await calculateAllowedSubnets(args, inputs, addresses);
|
|
199
177
|
return {
|
|
200
178
|
name: args.peerName ?? name,
|
|
201
179
|
endpoints,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
excludedIps,
|
|
205
|
-
dns: args.dns,
|
|
180
|
+
allowedSubnets,
|
|
181
|
+
dns: args.dns.map(parseAddress),
|
|
206
182
|
publicKey,
|
|
207
|
-
|
|
183
|
+
addresses,
|
|
208
184
|
network: inputs.network,
|
|
209
185
|
presharedKeyPart,
|
|
210
|
-
listenPort: args.listenPort,
|
|
186
|
+
listenPort: args.listenPort ?? 51820,
|
|
211
187
|
persistentKeepalive: args.persistentKeepalive
|
|
212
188
|
};
|
|
213
189
|
}
|
|
@@ -221,6 +197,6 @@ function shouldExpose(identity, exposePolicy) {
|
|
|
221
197
|
return identity.peer.endpoints.length > 0;
|
|
222
198
|
}
|
|
223
199
|
|
|
224
|
-
export {
|
|
225
|
-
//# sourceMappingURL=chunk-
|
|
226
|
-
//# sourceMappingURL=chunk-
|
|
200
|
+
export { convertPrivateKeyToPublicKey, createPeerEntity, generateIdentityConfig, generateKey, generatePresharedKey, isExitNode, shouldExpose };
|
|
201
|
+
//# sourceMappingURL=chunk-OSJ6YUBV.js.map
|
|
202
|
+
//# sourceMappingURL=chunk-OSJ6YUBV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared.ts"],"names":["dns"],"mappings":"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","file":"chunk-OSJ6YUBV.js","sourcesContent":["import type { k8s, network, wireguard } from \"@highstate/library\"\nimport {\n addressToCidr,\n createAddressSpace,\n filterWithMetadataByExpression,\n type InputAddressSpace,\n l3EndpointToL4,\n l4EndpointToString,\n parseAddress,\n parseEndpoint,\n parseSubnets,\n subnetToString,\n} from \"@highstate/common\"\nimport { getBestEndpoint } from \"@highstate/k8s\"\nimport { type Input, type Output, secret, type Unwrap } from \"@highstate/pulumi\"\nimport { x25519 } from \"@noble/curves/ed25519\"\nimport { sha256 } from \"@noble/hashes/sha2.js\"\nimport { randomBytes } from \"@noble/hashes/utils.js\"\nimport { unique, uniqueBy } from \"remeda\"\n\nexport function generateKey(): string {\n const key = x25519.utils.randomSecretKey()\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\n // combine the two parts in a deterministic order to ensure both sides generate the same key\n const combined = Buffer.concat([key1, key2].toSorted((a, b) => a.compare(b)))\n\n return Buffer.from(sha256(combined)).toString(\"base64\")\n}\n\nfunction generatePeerConfig(\n identity: wireguard.Identity,\n peer: wireguard.Peer,\n cluster?: k8s.Cluster,\n peerEndpointFilter?: string,\n): string {\n const lines = [\n //\n \"[Peer]\",\n `# ${peer.name}`,\n `PublicKey = ${peer.publicKey}`,\n ]\n\n if (peer.allowedSubnets.length > 0) {\n lines.push(`AllowedIPs = ${peer.allowedSubnets.map(subnetToString).join(\", \")}`)\n }\n\n const endpoints = peerEndpointFilter\n ? filterWithMetadataByExpression(peer.endpoints, peerEndpointFilter)\n : peer.endpoints\n\n const bestEndpoint = getBestEndpoint(endpoints, cluster)\n\n if (bestEndpoint) {\n lines.push(`Endpoint = ${l4EndpointToString(bestEndpoint)}`)\n }\n\n if (peer.persistentKeepalive > 0) {\n lines.push(`PersistentKeepalive = ${peer.persistentKeepalive}`)\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 cluster?: k8s.Cluster\n peerEndpointFilter?: string\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 cluster,\n peerEndpointFilter,\n}: IdentityConfigArgs): Output<string> {\n const allDns = unique(\n peers\n .flatMap(peer => peer.dns)\n .map(dns => dns.value)\n .concat(dns),\n )\n\n const lines = [\n //\n \"[Interface]\",\n `# ${identity.peer.name}`,\n ]\n\n if (identity.peer.addresses) {\n lines.push(`Address = ${identity.peer.addresses.map(addressToCidr).join(\", \")}`)\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 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, peerEndpointFilter))\n }\n\n return secret(lines.join(\"\\n\"))\n}\n\ntype SharedPeerInputs = {\n network?: Input<wireguard.Network>\n endpoints: Input<network.L3Endpoint>[]\n allowedSubnets: Input<network.Subnet>[]\n allowedEndpoints: Input<network.L3Endpoint>[]\n}\n\nexport function calculateEndpoints(\n {\n endpoints: argsEnpoints,\n listenPort,\n }: Pick<wireguard.SharedPeerArgs, \"endpoints\" | \"listenPort\">,\n { endpoints }: Pick<Unwrap<SharedPeerInputs>, \"endpoints\">,\n): network.L4Endpoint[] {\n return uniqueBy(\n [\n ...endpoints.map(e => l3EndpointToL4(e, e.port ?? listenPort ?? 51820)),\n ...argsEnpoints.map(endpoint => parseEndpoint(endpoint, 4)),\n ],\n endpoint => l4EndpointToString(endpoint),\n )\n}\n\nexport async function calculateAllowedSubnets(\n {\n includeAddresses,\n excludePrivateSubnets,\n exitNode,\n allowedSubnets,\n }: Pick<\n wireguard.SharedPeerArgs,\n \"includeAddresses\" | \"excludePrivateSubnets\" | \"exitNode\" | \"allowedSubnets\"\n >,\n { network, allowedSubnets: inputAllowedSubnets }: Unwrap<SharedPeerInputs>,\n addresses: network.Address[],\n): Promise<network.Subnet[]> {\n const included: InputAddressSpace[] = await parseSubnets(allowedSubnets, inputAllowedSubnets)\n const excluded: InputAddressSpace[] = []\n\n if (includeAddresses) {\n included.push(...addresses)\n }\n\n if (exitNode) {\n if (network?.ipv4) {\n included.push(\"0.0.0.0/0\")\n }\n\n if (network?.ipv6) {\n included.push(\"::/0\")\n }\n }\n\n if (excludePrivateSubnets) {\n excluded.push(\"10.0.0.0/8\")\n excluded.push(\"172.16.0.0/12\")\n excluded.push(\"192.168.0.0/16\")\n\n if (network?.ipv6) {\n excluded.push(\"fc00::/7\")\n excluded.push(\"fe80::/10\")\n }\n }\n\n const space = createAddressSpace({ included, excluded })\n return space.subnets\n}\n\nexport function isExitNode(peer: wireguard.Peer): boolean {\n return (\n peer.allowedSubnets.some(subnet => subnetToString(subnet) === \"0.0.0.0/0\") ||\n peer.allowedSubnets.some(subnet => subnetToString(subnet) === \"::/0\")\n )\n}\n\nexport async function createPeerEntity(\n name: string,\n args: wireguard.SharedPeerArgs,\n inputs: Unwrap<SharedPeerInputs>,\n publicKey: string,\n presharedKeyPart?: string,\n): Promise<wireguard.Peer> {\n const endpoints = calculateEndpoints(args, inputs)\n const addresses = args.addresses.map(parseAddress)\n const allowedSubnets = await calculateAllowedSubnets(args, inputs, addresses)\n\n return {\n name: args.peerName ?? name,\n endpoints,\n allowedSubnets,\n dns: args.dns.map(parseAddress),\n publicKey,\n addresses,\n network: inputs.network,\n presharedKeyPart,\n listenPort: args.listenPort ?? 51820,\n persistentKeepalive: args.persistentKeepalive,\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"]}
|
package/dist/config/index.js
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
|
-
import { generateIdentityConfig } from '../chunk-
|
|
1
|
+
import { generateIdentityConfig } from '../chunk-OSJ6YUBV.js';
|
|
2
|
+
import '../chunk-I7BWSAN6.js';
|
|
2
3
|
import { text } from '@highstate/contract';
|
|
3
4
|
import { wireguard } from '@highstate/library';
|
|
4
5
|
import { forUnit, toPromise } from '@highstate/pulumi';
|
|
5
6
|
|
|
6
|
-
var { inputs, args, outputs } = forUnit(wireguard.config);
|
|
7
|
+
var { name, inputs, args, outputs } = forUnit(wireguard.config);
|
|
7
8
|
var { identity, peers } = await toPromise(inputs);
|
|
8
9
|
var configContent = generateIdentityConfig({
|
|
9
10
|
identity,
|
|
10
11
|
peers,
|
|
11
|
-
|
|
12
|
+
peerEndpointFilter: args.peerEndpointFilter
|
|
12
13
|
});
|
|
13
14
|
var config_default = outputs({
|
|
15
|
+
config: {
|
|
16
|
+
file: {
|
|
17
|
+
meta: {
|
|
18
|
+
name: `${name}.conf`
|
|
19
|
+
},
|
|
20
|
+
content: {
|
|
21
|
+
type: "embedded",
|
|
22
|
+
value: configContent
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
feedMetadata: args.feedMetadata.enabled === "true" ? {
|
|
26
|
+
id: args.feedMetadata.id,
|
|
27
|
+
name: args.feedMetadata.name,
|
|
28
|
+
displayInfo: {
|
|
29
|
+
title: args.feedMetadata.title,
|
|
30
|
+
description: args.feedMetadata.description,
|
|
31
|
+
iconUrl: args.feedMetadata.iconUrl
|
|
32
|
+
}
|
|
33
|
+
} : void 0
|
|
34
|
+
},
|
|
14
35
|
$pages: {
|
|
15
36
|
index: {
|
|
16
37
|
meta: {
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/config/index.ts"],"names":[],"mappings":";;;;;;AAKA,IAAM,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,SAAQ,GAAI,OAAA,CAAQ,UAAU,MAAM,CAAA;AAEhE,IAAM,EAAE,QAAA,EAAU,KAAA,EAAM,GAAI,MAAM,UAAU,MAAM,CAAA;AAElD,IAAM,gBAAgB,sBAAA,CAAuB;AAAA,EAC3C,QAAA;AAAA,EACA,KAAA;AAAA,EACA,oBAAoB,IAAA,CAAK;AAC3B,CAAC,CAAA;AAED,IAAO,iBAAQ,OAAA,CAAQ;AAAA,EACrB,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,GAAG,IAAI,CAAA,KAAA;AAAA,OACf;AAAA,MACA,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,UAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,YAAA,EACE,IAAA,CAAK,YAAA,CAAa,OAAA,KAAY,MAAA,GAC1B;AAAA,MACE,EAAA,EAAI,KAAK,YAAA,CAAa,EAAA;AAAA,MACtB,IAAA,EAAM,KAAK,YAAA,CAAa,IAAA;AAAA,MACxB,WAAA,EAAa;AAAA,QACX,KAAA,EAAO,KAAK,YAAA,CAAa,KAAA;AAAA,QACzB,WAAA,EAAa,KAAK,YAAA,CAAa,WAAA;AAAA,QAC/B,OAAA,EAAS,KAAK,YAAA,CAAa;AAAA;AAC7B,KACF,GACA;AAAA,GACR;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO;AAAA,MACL,IAAA,EAAM;AAAA,QACJ,KAAA,EAAO;AAAA,OACT;AAAA,MAEA,OAAA,EAAS;AAAA,QACP;AAAA,UACE,IAAA,EAAM,UAAA;AAAA,UACN,OAAA,EAAS,IAAA;AAAA;AAAA,UAAA;AAAA,SAGX;AAAA,QACA;AAAA,UACE,IAAA,EAAM,IAAA;AAAA,UACN,OAAA,EAAS,aAAA;AAAA,UACT,WAAA,EAAa,IAAA;AAAA,UACb,QAAA,EAAU;AAAA;AACZ;AACF;AACF;AAEJ,CAAC","file":"index.js","sourcesContent":["import { text } from \"@highstate/contract\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { name, inputs, args, outputs } = forUnit(wireguard.config)\n\nconst { identity, peers } = await toPromise(inputs)\n\nconst configContent = generateIdentityConfig({\n identity,\n peers,\n peerEndpointFilter: args.peerEndpointFilter,\n})\n\nexport default outputs({\n config: {\n file: {\n meta: {\n name: `${name}.conf`,\n },\n content: {\n type: \"embedded\",\n value: configContent,\n },\n },\n feedMetadata:\n args.feedMetadata.enabled === \"true\"\n ? {\n id: args.feedMetadata.id,\n name: args.feedMetadata.name,\n displayInfo: {\n title: args.feedMetadata.title,\n description: args.feedMetadata.description,\n iconUrl: args.feedMetadata.iconUrl,\n },\n }\n : undefined,\n },\n $pages: {\n index: {\n meta: {\n title: \"WireGuard Configuration\",\n },\n\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"]}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import { generateIdentityConfig } from '../chunk-
|
|
1
|
+
import { generateIdentityConfig } from '../chunk-OSJ6YUBV.js';
|
|
2
|
+
import '../chunk-I7BWSAN6.js';
|
|
2
3
|
import { text } from '@highstate/contract';
|
|
3
4
|
import { wireguard } from '@highstate/library';
|
|
4
5
|
import { forUnit, toPromise, fileFromBuffer } from '@highstate/pulumi';
|
|
5
6
|
import ZipStream from 'zip-stream';
|
|
6
7
|
|
|
7
|
-
var { name,
|
|
8
|
+
var { name, args, inputs, outputs } = forUnit(wireguard.configBundle);
|
|
8
9
|
var { identity, peers, sharedPeers } = await toPromise(inputs);
|
|
9
10
|
var blocks = [];
|
|
11
|
+
var configs = [];
|
|
10
12
|
var zipStream = new ZipStream();
|
|
11
13
|
for (const peer of peers) {
|
|
12
14
|
const configContent = generateIdentityConfig({
|
|
13
15
|
identity,
|
|
14
16
|
peers: [...sharedPeers, peer],
|
|
15
|
-
|
|
17
|
+
peerEndpointFilter: args.peerEndpointFilter
|
|
16
18
|
});
|
|
17
19
|
const unsafeConfigContent = await toPromise(configContent);
|
|
18
20
|
await new Promise((resolve, reject) => {
|
|
@@ -44,6 +46,17 @@ for (const peer of peers) {
|
|
|
44
46
|
language: "ini"
|
|
45
47
|
}
|
|
46
48
|
);
|
|
49
|
+
configs.push({
|
|
50
|
+
file: {
|
|
51
|
+
meta: {
|
|
52
|
+
name: `${peer.name}.conf`
|
|
53
|
+
},
|
|
54
|
+
content: {
|
|
55
|
+
type: "embedded",
|
|
56
|
+
value: configContent
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
47
60
|
}
|
|
48
61
|
zipStream.finish();
|
|
49
62
|
var unsafeZipFileContent = await new Promise((resolve, reject) => {
|
|
@@ -57,6 +70,7 @@ var zipFile = fileFromBuffer(`${name}.zip`, unsafeZipFileContent, {
|
|
|
57
70
|
isSecret: true
|
|
58
71
|
});
|
|
59
72
|
var config_bundle_default = outputs({
|
|
73
|
+
configs,
|
|
60
74
|
$pages: {
|
|
61
75
|
index: {
|
|
62
76
|
meta: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config-bundle/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/config-bundle/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { type PageBlock, text } from \"@highstate/contract\"\nimport { wireguard } from \"@highstate/library\"\nimport { type DeepInput, fileFromBuffer, forUnit, toPromise } from \"@highstate/pulumi\"\nimport ZipStream from \"zip-stream\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { name, args, inputs, outputs } = forUnit(wireguard.configBundle)\n\nconst { identity, peers, sharedPeers } = await toPromise(inputs)\n\nconst blocks: DeepInput<PageBlock>[] = []\nconst configs: DeepInput<wireguard.Config>[] = []\nconst zipStream = new ZipStream()\n\nfor (const peer of peers) {\n const configContent = generateIdentityConfig({\n identity,\n peers: [...sharedPeers, peer],\n peerEndpointFilter: args.peerEndpointFilter,\n })\n\n const unsafeConfigContent = await toPromise(configContent)\n\n await new Promise((resolve, reject) => {\n return zipStream.entry(\n unsafeConfigContent,\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: configContent,\n showContent: true,\n language: \"ini\",\n },\n )\n\n configs.push({\n file: {\n meta: {\n name: `${peer.name}.conf`,\n },\n content: {\n type: \"embedded\",\n value: configContent,\n },\n },\n })\n}\n\nzipStream.finish()\n\nconst unsafeZipFileContent = 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`, unsafeZipFileContent, {\n contentType: \"application/zip\",\n isSecret: true,\n})\n\nexport default outputs({\n configs,\n\n $pages: {\n index: {\n meta: {\n title: \"WireGuard Configuration Bundle\",\n },\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 file: zipFile,\n },\n ...blocks,\n ],\n },\n },\n})\n"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { __using, __callDispose } from '../chunk-I7BWSAN6.js';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { parseEndpoints, l4EndpointToString, MaterializedFile, l3EndpointToString, parseEndpoint } from '@highstate/common';
|
|
4
|
+
import { Provider, Key } from '@highstate/etcd-sdk';
|
|
5
|
+
import { wireguard } from '@highstate/library';
|
|
6
|
+
import { forUnit, toPromise, secret } from '@highstate/pulumi';
|
|
7
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
8
|
+
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
9
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
10
|
+
import { generateIdentity, identityToRecipient, Encrypter, armor } from 'age-encryption';
|
|
11
|
+
import { map, join } from 'remeda';
|
|
12
|
+
import { v5 } from 'uuid';
|
|
13
|
+
|
|
14
|
+
var { args, inputs, getSecret, outputs } = forUnit(wireguard.feed);
|
|
15
|
+
var serverEndpoints = await parseEndpoints(args.serverEndpoints, inputs.serverEndpoints, 4);
|
|
16
|
+
if (serverEndpoints.length === 0) {
|
|
17
|
+
throw new Error("At least one server endpoint must be provided args or inputs");
|
|
18
|
+
}
|
|
19
|
+
var provider = new Provider("etcd", {
|
|
20
|
+
endpoints: inputs.etcd.endpoints.apply(map(l4EndpointToString)).apply(join(", ")),
|
|
21
|
+
skipTls: true
|
|
22
|
+
});
|
|
23
|
+
var configs = await toPromise(inputs.configs);
|
|
24
|
+
var namespace = "2b5e358c-3510-48fb-b1cf-a8aee788925a";
|
|
25
|
+
var feedId = await toPromise(getSecret("feedId", createId));
|
|
26
|
+
var documentId = v5(feedId, namespace);
|
|
27
|
+
var document = await toPromise({
|
|
28
|
+
id: documentId,
|
|
29
|
+
display_info: {
|
|
30
|
+
title: args.displayInfo.title,
|
|
31
|
+
description: args.displayInfo.description,
|
|
32
|
+
icon_url: args.displayInfo.iconUrl
|
|
33
|
+
},
|
|
34
|
+
endpoints: serverEndpoints.map((endpoint) => `https://${l3EndpointToString(endpoint)}/${feedId}`),
|
|
35
|
+
tunnels: configs.map(async (config) => {
|
|
36
|
+
var _stack = [];
|
|
37
|
+
try {
|
|
38
|
+
if (!config.feedMetadata) {
|
|
39
|
+
throw new Error("Feed metadata is required for all WireGuard feed configs");
|
|
40
|
+
}
|
|
41
|
+
const file = __using(_stack, await MaterializedFile.open(config.file), true);
|
|
42
|
+
const content = await readFile(file.path, "utf-8");
|
|
43
|
+
return {
|
|
44
|
+
id: config.feedMetadata.id,
|
|
45
|
+
name: config.feedMetadata.name,
|
|
46
|
+
display_info: {
|
|
47
|
+
title: config.feedMetadata.displayInfo.title,
|
|
48
|
+
description: config.feedMetadata.displayInfo.description,
|
|
49
|
+
icon_url: config.feedMetadata.displayInfo.iconUrl
|
|
50
|
+
},
|
|
51
|
+
wg_quick_config: content
|
|
52
|
+
};
|
|
53
|
+
} catch (_) {
|
|
54
|
+
var _error = _, _hasError = true;
|
|
55
|
+
} finally {
|
|
56
|
+
var _promise = __callDispose(_stack, _error, _hasError);
|
|
57
|
+
_promise && await _promise;
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
var privateKey;
|
|
62
|
+
var publicKey;
|
|
63
|
+
if (args.publicKey) {
|
|
64
|
+
publicKey = args.publicKey;
|
|
65
|
+
} else {
|
|
66
|
+
privateKey = getSecret("privateKey", generateIdentity);
|
|
67
|
+
publicKey = await toPromise(privateKey.apply(identityToRecipient));
|
|
68
|
+
}
|
|
69
|
+
var encrypter = new Encrypter();
|
|
70
|
+
encrypter.addRecipient(publicKey);
|
|
71
|
+
var encrypted = await encrypter.encrypt(JSON.stringify(document));
|
|
72
|
+
var revision = bytesToHex(sha256(encrypted));
|
|
73
|
+
var armored = armor.encode(encrypted);
|
|
74
|
+
var entry = {
|
|
75
|
+
revision,
|
|
76
|
+
ttl_seconds: args.ttlSeconds,
|
|
77
|
+
encrypted: true,
|
|
78
|
+
encrypted_data: armored
|
|
79
|
+
};
|
|
80
|
+
new Key(
|
|
81
|
+
"feed",
|
|
82
|
+
{
|
|
83
|
+
key: `wg-feed/feeds/${feedId}`,
|
|
84
|
+
value: JSON.stringify(entry)
|
|
85
|
+
},
|
|
86
|
+
{ provider }
|
|
87
|
+
);
|
|
88
|
+
var encKey = await toPromise(
|
|
89
|
+
privateKey?.apply((key) => key.replace("AGE-SECRET-KEY-", "").toLowerCase())
|
|
90
|
+
);
|
|
91
|
+
var subscriptionUrl = encKey ? `https://${l3EndpointToString(serverEndpoints[0])}/${feedId}#${encKey}` : `https://${l3EndpointToString(serverEndpoints[0])}/${feedId}`;
|
|
92
|
+
var subscriptionEndpoint = parseEndpoint(subscriptionUrl, 7);
|
|
93
|
+
var feed_default = outputs({
|
|
94
|
+
endpoint: {
|
|
95
|
+
...subscriptionEndpoint,
|
|
96
|
+
// the feed ID + encryption key part is secret
|
|
97
|
+
path: secret(subscriptionEndpoint.path)
|
|
98
|
+
},
|
|
99
|
+
$statusFields: {
|
|
100
|
+
url: {
|
|
101
|
+
// TODO: make url secret when Highstate supports secret status fields
|
|
102
|
+
value: subscriptionUrl
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export { feed_default as default };
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
109
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/feed/index.ts"],"names":["uuidv5"],"mappings":"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","file":"index.js","sourcesContent":["import type { WgFeedDocument, WgFeedEtcdEntry, WgFeedEtcdKey } from \"./models\"\nimport { readFile } from \"node:fs/promises\"\nimport {\n l3EndpointToString,\n l4EndpointToString,\n MaterializedFile,\n parseEndpoint,\n parseEndpoints,\n} from \"@highstate/common\"\nimport { Key, Provider } from \"@highstate/etcd-sdk\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, type Output, secret, toPromise } from \"@highstate/pulumi\"\nimport { sha256 } from \"@noble/hashes/sha2.js\"\nimport { bytesToHex } from \"@noble/hashes/utils.js\"\nimport { createId } from \"@paralleldrive/cuid2\"\nimport { armor, Encrypter, generateIdentity, identityToRecipient } from \"age-encryption\"\nimport { join, map } from \"remeda\"\nimport { v5 as uuidv5 } from \"uuid\"\n\nconst { args, inputs, getSecret, outputs } = forUnit(wireguard.feed)\n\nconst serverEndpoints = await parseEndpoints(args.serverEndpoints, inputs.serverEndpoints, 4)\nif (serverEndpoints.length === 0) {\n throw new Error(\"At least one server endpoint must be provided args or inputs\")\n}\n\nconst provider = new Provider(\"etcd\", {\n endpoints: inputs.etcd.endpoints.apply(map(l4EndpointToString)).apply(join(\", \")),\n skipTls: true,\n})\n\nconst configs = await toPromise(inputs.configs)\n\nconst namespace = \"2b5e358c-3510-48fb-b1cf-a8aee788925a\"\n\n// calculate the feed ID and document ID\nconst feedId = await toPromise(getSecret(\"feedId\", createId))\nconst documentId = uuidv5(feedId, namespace)\n\n// create the feed document according to wg-feed spec\nconst document: WgFeedDocument = await toPromise({\n id: documentId,\n\n display_info: {\n title: args.displayInfo.title,\n description: args.displayInfo.description,\n icon_url: args.displayInfo.iconUrl,\n },\n\n endpoints: serverEndpoints.map(endpoint => `https://${l3EndpointToString(endpoint)}/${feedId}`),\n\n tunnels: configs.map(async config => {\n if (!config.feedMetadata) {\n throw new Error(\"Feed metadata is required for all WireGuard feed configs\")\n }\n\n // TODO: use some other API for extracting the file content without materializing it on disk\n await using file = await MaterializedFile.open(config.file)\n const content = await readFile(file.path, \"utf-8\")\n\n return {\n id: config.feedMetadata.id,\n name: config.feedMetadata.name,\n\n display_info: {\n title: config.feedMetadata.displayInfo.title,\n description: config.feedMetadata.displayInfo.description,\n icon_url: config.feedMetadata.displayInfo.iconUrl,\n },\n\n wg_quick_config: content,\n }\n }),\n})\n\nlet privateKey: Output<string> | undefined\nlet publicKey: string\n\nif (args.publicKey) {\n publicKey = args.publicKey\n} else {\n privateKey = getSecret(\"privateKey\", generateIdentity)\n publicKey = await toPromise(privateKey.apply(identityToRecipient))\n}\n\n// encrypt the document with age\nconst encrypter = new Encrypter()\nencrypter.addRecipient(publicKey)\n\nconst encrypted = await encrypter.encrypt(JSON.stringify(document))\nconst revision = bytesToHex(sha256(encrypted))\nconst armored = armor.encode(encrypted)\n\n// create the etcd entry\nconst entry: WgFeedEtcdEntry = {\n revision,\n ttl_seconds: args.ttlSeconds,\n encrypted: true,\n encrypted_data: armored,\n}\n\n// store the feed in etcd\nnew Key(\n \"feed\",\n {\n key: `wg-feed/feeds/${feedId}` satisfies WgFeedEtcdKey,\n value: JSON.stringify(entry),\n },\n { provider },\n)\n\nconst encKey = await toPromise(\n privateKey?.apply(key => key.replace(\"AGE-SECRET-KEY-\", \"\").toLowerCase()),\n)\n\n// create the subscription URL\nconst subscriptionUrl = encKey\n ? `https://${l3EndpointToString(serverEndpoints[0])}/${feedId}#${encKey}`\n : `https://${l3EndpointToString(serverEndpoints[0])}/${feedId}`\n\nconst subscriptionEndpoint = parseEndpoint(subscriptionUrl, 7)\n\nexport default outputs({\n endpoint: {\n ...subscriptionEndpoint,\n // the feed ID + encryption key part is secret\n path: secret(subscriptionEndpoint.path),\n },\n\n $statusFields: {\n url: {\n // TODO: make url secret when Highstate supports secret status fields\n value: subscriptionUrl,\n },\n },\n})\n"]}
|
|
@@ -1,12 +1,13 @@
|
|
|
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/
|
|
8
|
-
"./dist/node
|
|
9
|
-
"./dist/
|
|
10
|
-
"./dist/peer
|
|
3
|
+
"./dist/network/index.js": 4207313116,
|
|
4
|
+
"./dist/identity/index.js": 11316155,
|
|
5
|
+
"./dist/config/index.js": 2931949109,
|
|
6
|
+
"./dist/config-bundle/index.js": 943827142,
|
|
7
|
+
"./dist/feed/index.js": 3874422537,
|
|
8
|
+
"./dist/node/index.js": 2641283547,
|
|
9
|
+
"./dist/node.k8s/index.js": 232582473,
|
|
10
|
+
"./dist/peer/index.js": 3842560375,
|
|
11
|
+
"./dist/peer-patch/index.js": 2928862803
|
|
11
12
|
}
|
|
12
13
|
}
|
package/dist/identity/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { generateKey, generatePresharedKey, convertPrivateKeyToPublicKey, createPeerEntity } from '../chunk-
|
|
2
|
-
import
|
|
1
|
+
import { generateKey, generatePresharedKey, convertPrivateKeyToPublicKey, createPeerEntity } from '../chunk-OSJ6YUBV.js';
|
|
2
|
+
import '../chunk-I7BWSAN6.js';
|
|
3
|
+
import { subnetToString, l4EndpointToString } from '@highstate/common';
|
|
3
4
|
import { wireguard } from '@highstate/library';
|
|
4
5
|
import { forUnit, toPromise } from '@highstate/pulumi';
|
|
5
6
|
|
|
@@ -9,24 +10,16 @@ var presharedKeyPartOutput = getSecret("presharedKeyPart", generatePresharedKey)
|
|
|
9
10
|
var resolvedInpus = await toPromise(inputs);
|
|
10
11
|
var publicKey = await toPromise(privateKey.apply(convertPrivateKeyToPublicKey));
|
|
11
12
|
var presharedKeyPart = await toPromise(presharedKeyPartOutput);
|
|
12
|
-
var peer = createPeerEntity(name, args, resolvedInpus, publicKey, presharedKeyPart);
|
|
13
|
+
var peer = await createPeerEntity(name, args, resolvedInpus, publicKey, presharedKeyPart);
|
|
13
14
|
var identity_default = outputs({
|
|
14
15
|
identity: {
|
|
15
16
|
peer,
|
|
16
17
|
privateKey
|
|
17
18
|
},
|
|
18
|
-
peer,
|
|
19
|
-
endpoints: peer.endpoints,
|
|
20
19
|
$statusFields: {
|
|
21
20
|
publicKey,
|
|
22
|
-
endpoints:
|
|
23
|
-
|
|
24
|
-
complementaryTo: "endpoints"
|
|
25
|
-
},
|
|
26
|
-
excludedIps: {
|
|
27
|
-
value: peer.excludedIps,
|
|
28
|
-
complementaryTo: "excludedIps"
|
|
29
|
-
}
|
|
21
|
+
endpoints: peer.endpoints.map(l4EndpointToString),
|
|
22
|
+
allowedIps: peer.allowedSubnets.map(subnetToString)
|
|
30
23
|
}
|
|
31
24
|
});
|
|
32
25
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/identity/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/identity/index.ts"],"names":[],"mappings":";;;;;;AAUA,IAAM,EAAE,MAAM,IAAA,EAAM,MAAA,EAAQ,WAAW,OAAA,EAAQ,GAAI,OAAA,CAAQ,SAAA,CAAU,QAAQ,CAAA;AAE7E,IAAM,UAAA,GAAa,SAAA,CAAU,YAAA,EAAc,WAAW,CAAA;AACtD,IAAM,sBAAA,GAAyB,SAAA,CAAU,kBAAA,EAAoB,oBAAoB,CAAA;AAEjF,IAAM,aAAA,GAAgB,MAAM,SAAA,CAAU,MAAM,CAAA;AAC5C,IAAM,YAAY,MAAM,SAAA,CAAU,UAAA,CAAW,KAAA,CAAM,4BAA4B,CAAC,CAAA;AAChF,IAAM,gBAAA,GAAmB,MAAM,SAAA,CAAU,sBAAsB,CAAA;AAE/D,IAAM,OAAO,MAAM,gBAAA,CAAiB,MAAM,IAAA,EAAM,aAAA,EAAe,WAAW,gBAAgB,CAAA;AAE1F,IAAO,mBAAQ,OAAA,CAAQ;AAAA,EACrB,QAAA,EAAU;AAAA,IACR,IAAA;AAAA,IACA;AAAA,GACF;AAAA,EAEA,aAAA,EAAe;AAAA,IACb,SAAA;AAAA,IACA,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,kBAAkB,CAAA;AAAA,IAChD,UAAA,EAAY,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,cAAc;AAAA;AAEtD,CAAC","file":"index.js","sourcesContent":["import { l4EndpointToString, subnetToString } from \"@highstate/common\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport {\n convertPrivateKeyToPublicKey,\n createPeerEntity,\n generateKey,\n generatePresharedKey,\n} from \"../shared\"\n\nconst { name, args, inputs, getSecret, outputs } = forUnit(wireguard.identity)\n\nconst privateKey = getSecret(\"privateKey\", generateKey)\nconst presharedKeyPartOutput = getSecret(\"presharedKeyPart\", generatePresharedKey)\n\nconst resolvedInpus = await toPromise(inputs)\nconst publicKey = await toPromise(privateKey.apply(convertPrivateKeyToPublicKey))\nconst presharedKeyPart = await toPromise(presharedKeyPartOutput)\n\nconst peer = await createPeerEntity(name, args, resolvedInpus, publicKey, presharedKeyPart)\n\nexport default outputs({\n identity: {\n peer,\n privateKey,\n },\n\n $statusFields: {\n publicKey,\n endpoints: peer.endpoints.map(l4EndpointToString),\n allowedIps: peer.allowedSubnets.map(subnetToString),\n },\n})\n"]}
|
package/dist/network/index.js
CHANGED
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { generateIdentityConfig } from '../chunk-
|
|
1
|
+
import { generateIdentityConfig } from '../chunk-OSJ6YUBV.js';
|
|
2
|
+
import '../chunk-I7BWSAN6.js';
|
|
2
3
|
import { Command, l3EndpointToL4, l4EndpointToString } from '@highstate/common';
|
|
3
4
|
import { wireguard } from '@highstate/library';
|
|
4
5
|
import { forUnit, toPromise } from '@highstate/pulumi';
|
|
@@ -75,8 +76,7 @@ var wgConfig = generateIdentityConfig({
|
|
|
75
76
|
preUp,
|
|
76
77
|
postUp,
|
|
77
78
|
preDown,
|
|
78
|
-
postDown
|
|
79
|
-
defaultInterface: args.defaultInterface
|
|
79
|
+
postDown
|
|
80
80
|
});
|
|
81
81
|
var configFile = Command.createTextFile(
|
|
82
82
|
"wireguard-config",
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/node/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/node/index.ts"],"names":[],"mappings":";;;;;;AAKA,IAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAQ,GAAI,OAAA,CAAQ,UAAU,IAAI,CAAA;AAExD,IAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,OAAM,GAAI,MAAM,UAAU,MAAM,CAAA;AAG1D,IAAM,eAAe,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,KAAK,GAAG,CAAA;AAC3D,IAAM,aAAA,GAAgB,KAAK,aAAA,IAAiB,CAAA,GAAA,EAAM,YAAY,CAAA,CAAA,CAAG,SAAA,CAAU,GAAG,EAAE,CAAA;AAGhF,IAAM,cAAyB,EAAC;AAEhC,IAAI,KAAK,WAAA,EAAa;AACpB,EAAA,WAAA,CAAY,IAAA;AAAA,IACV,OAAA,CAAQ,eAAe,wBAAA,EAA0B;AAAA,MAC/C,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM,kBAAkB,aAAa,CAAA,UAAA,CAAA;AAAA,MACrC,OAAA,EAAS,CAAA;AAAA,EAAgB,KAAK,WAAW,CAAA;AAAA,KAC1C;AAAA,GACH;AACF;AAEA,IAAI,KAAK,YAAA,EAAc;AACrB,EAAA,WAAA,CAAY,IAAA;AAAA,IACV,OAAA,CAAQ,eAAe,yBAAA,EAA2B;AAAA,MAChD,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM,kBAAkB,aAAa,CAAA,WAAA,CAAA;AAAA,MACrC,OAAA,EAAS,CAAA;AAAA,EAAgB,KAAK,YAAY,CAAA;AAAA,KAC3C;AAAA,GACH;AACF;AAEA,IAAI,KAAK,aAAA,EAAe;AACtB,EAAA,WAAA,CAAY,IAAA;AAAA,IACV,OAAA,CAAQ,eAAe,0BAAA,EAA4B;AAAA,MACjD,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM,kBAAkB,aAAa,CAAA,YAAA,CAAA;AAAA,MACrC,OAAA,EAAS,CAAA;AAAA,EAAgB,KAAK,aAAa,CAAA;AAAA,KAC5C;AAAA,GACH;AACF;AAEA,IAAI,KAAK,cAAA,EAAgB;AACvB,EAAA,WAAA,CAAY,IAAA;AAAA,IACV,OAAA,CAAQ,eAAe,2BAAA,EAA6B;AAAA,MAClD,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM,kBAAkB,aAAa,CAAA,aAAA,CAAA;AAAA,MACrC,OAAA,EAAS,CAAA;AAAA,EAAgB,KAAK,cAAc,CAAA;AAAA,KAC7C;AAAA,GACH;AACF;AAGA,IAAM,QAAkB,EAAC;AACzB,IAAM,SAAmB,EAAC;AAC1B,IAAM,UAAoB,EAAC;AAC3B,IAAM,WAAqB,EAAC;AAG5B,IAAI,KAAK,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,aAAa,CAAA,UAAA,CAAY,CAAA;AAC5E,IAAI,KAAK,YAAA,EAAc,MAAA,CAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,aAAa,CAAA,WAAA,CAAa,CAAA;AAC/E,IAAI,KAAK,aAAA,EAAe,OAAA,CAAQ,IAAA,CAAK,CAAA,eAAA,EAAkB,aAAa,CAAA,YAAA,CAAc,CAAA;AAClF,IAAI,KAAK,cAAA,EAAgB,QAAA,CAAS,IAAA,CAAK,CAAA,eAAA,EAAkB,aAAa,CAAA,aAAA,CAAe,CAAA;AAGrF,IAAI,KAAK,gBAAA,EAAkB;AACzB,EAAA,MAAA,CAAO,KAAK,8CAA8C,CAAA;AAC1D,EAAA,MAAA,CAAO,KAAK,qCAAqC,CAAA;AACjD,EAAA,MAAA,CAAO,KAAK,qCAAqC,CAAA;AAEjD,EAAA,OAAA,CAAQ,KAAK,sDAAsD,CAAA;AACnE,EAAA,OAAA,CAAQ,KAAK,6CAA6C,CAAA;AAC1D,EAAA,OAAA,CAAQ,KAAK,6CAA6C,CAAA;AAC5D;AAGA,KAAA,MAAW,cAAA,IAAkB,KAAK,oBAAA,EAAsB;AACtD,EAAA,MAAA,CAAO,IAAA,CAAK,CAAA,uBAAA,EAA0B,cAAc,CAAA,QAAA,CAAU,CAAA;AAC9D,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,uBAAA,EAA0B,cAAc,CAAA,gBAAA,CAAkB,CAAA;AACzE;AAGA,IAAM,WAAW,sBAAA,CAAuB;AAAA,EACtC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA,EAAY,SAAS,IAAA,CAAK,UAAA;AAAA,EAC1B,KAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGD,IAAM,aAAa,OAAA,CAAQ,cAAA;AAAA,EACzB,kBAAA;AAAA,EACA;AAAA,IACE,IAAA,EAAM,MAAA;AAAA,IACN,IAAA,EAAM,kBAAkB,aAAa,CAAA,KAAA,CAAA;AAAA,IACrC,OAAA,EAAS;AAAA,GACX;AAAA,EACA,EAAE,WAAW,WAAA;AACf,CAAA;AAGA,IAAM,iBAAiB,IAAI,OAAA;AAAA,EACzB,uBAAA;AAAA,EACA;AAAA,IACE,IAAA,EAAM,MAAA;AAAA,IACN,MAAA,EAAQ;AAAA,+BAAA,EACqB,aAAa,CAAA;AAAA,MAAA,EACtC,IAAA,CAAK,WAAA,GAAc,CAAA,yBAAA,EAA4B,aAAa,eAAe,EAAE;AAAA,MAAA,EAC7E,IAAA,CAAK,YAAA,GAAe,CAAA,yBAAA,EAA4B,aAAa,gBAAgB,EAAE;AAAA,MAAA,EAC/E,IAAA,CAAK,aAAA,GAAgB,CAAA,yBAAA,EAA4B,aAAa,iBAAiB,EAAE;AAAA,MAAA,EACjF,IAAA,CAAK,cAAA,GAAiB,CAAA,yBAAA,EAA4B,aAAa,kBAAkB,EAAE;AAAA,IAAA;AAAA,GAEzF;AAAA,EACA,EAAE,SAAA,EAAW,CAAC,UAAU,CAAA;AAC1B,CAAA;AAGA,IAAI,OAAA;AAAA,EACF,mBAAA;AAAA,EACA;AAAA,IACE,IAAA,EAAM,MAAA;AAAA,IACN,MAAA,EAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAAA,EAQ4B,aAAa,CAAA;AAAA,IAAA,CAAA;AAAA,IAEjD,MAAA,EAAQ;AAAA;AAAA,iCAAA,EAEuB,aAAa,CAAA;AAAA,IAAA,CAAA;AAAA,IAE5C,MAAA,EAAQ;AAAA;AAAA,uCAAA,EAE6B,aAAa,CAAA;AAAA;AAAA;AAAA,qBAAA,EAG/B,aAAa,CAAA;AAAA,IAAA,CAAA;AAAA,IAEhC,cAAA,EAAgB,CAAC,QAAQ;AAAA,GAC3B;AAAA,EACA,EAAE,SAAA,EAAW,CAAC,cAAc,CAAA;AAC9B,CAAA;AAGA,IAAM,YAAY,QAAA,CAAS,IAAA,CAAK,UAAA,GAC3B,MAAA,CAAO,WAAW,GAAA,CAAI,CAAA,CAAA,KAAK,cAAA,CAAe,CAAA,EAAG,SAAS,IAAA,CAAK,UAAW,CAAC,CAAA,IAAK,KAC7E,EAAC;AAEL,IAAO,eAAQ,OAAA,CAAQ;AAAA,EACrB,IAAA,EAAM,QAAA,CAAS,IAAA,CAAK,UAAA,GAChB;AAAA,IACE,GAAG,QAAA,CAAS,IAAA;AAAA,IACZ;AAAA,MAEF,QAAA,CAAS,IAAA;AAAA,EAEb,SAAA;AAAA,EAEA,aAAA,EAAe;AAAA,IACb,aAAA;AAAA,IACA,GAAI,QAAA,CAAS,IAAA,CAAK,UAAA,IAAc,SAAA,CAAU,SAAS,CAAA,GAC/C;AAAA,MACE,SAAA,EAAW,SAAA,CAAU,GAAA,CAAI,kBAAkB;AAAA,QAE7C;AAAC;AAET,CAAC","file":"index.js","sourcesContent":["import { Command, l3EndpointToL4, l4EndpointToString } from \"@highstate/common\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { generateIdentityConfig } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.node)\n\nconst { identity, server, peers } = await toPromise(inputs)\n\n// generate interface name (max 15 chars for Linux)\nconst identityName = identity.peer.name.replaceAll(\".\", \"-\")\nconst interfaceName = args.interfaceName ?? `wg-${identityName}`.substring(0, 15)\n\n// create script files for user-provided scripts\nconst scriptFiles: Command[] = []\n\nif (args.preUpScript) {\n scriptFiles.push(\n Command.createTextFile(\"wireguard-preup-script\", {\n host: server,\n path: `/etc/wireguard/${interfaceName}.pre-up.sh`,\n content: `#!/bin/bash\\n${args.preUpScript}`,\n }),\n )\n}\n\nif (args.postUpScript) {\n scriptFiles.push(\n Command.createTextFile(\"wireguard-postup-script\", {\n host: server,\n path: `/etc/wireguard/${interfaceName}.post-up.sh`,\n content: `#!/bin/bash\\n${args.postUpScript}`,\n }),\n )\n}\n\nif (args.preDownScript) {\n scriptFiles.push(\n Command.createTextFile(\"wireguard-predown-script\", {\n host: server,\n path: `/etc/wireguard/${interfaceName}.pre-down.sh`,\n content: `#!/bin/bash\\n${args.preDownScript}`,\n }),\n )\n}\n\nif (args.postDownScript) {\n scriptFiles.push(\n Command.createTextFile(\"wireguard-postdown-script\", {\n host: server,\n path: `/etc/wireguard/${interfaceName}.post-down.sh`,\n content: `#!/bin/bash\\n${args.postDownScript}`,\n }),\n )\n}\n\n// build up the pre/post commands\nconst preUp: string[] = []\nconst postUp: string[] = []\nconst preDown: string[] = []\nconst postDown: string[] = []\n\n// reference script files if they exist\nif (args.preUpScript) preUp.push(`/etc/wireguard/${interfaceName}.pre-up.sh`)\nif (args.postUpScript) postUp.push(`/etc/wireguard/${interfaceName}.post-up.sh`)\nif (args.preDownScript) preDown.push(`/etc/wireguard/${interfaceName}.pre-down.sh`)\nif (args.postDownScript) postDown.push(`/etc/wireguard/${interfaceName}.post-down.sh`)\n\n// add IP masquerading if enabled\nif (args.enableMasquerade) {\n postUp.push(\"iptables -t nat -A POSTROUTING -j MASQUERADE\")\n postUp.push(\"iptables -A FORWARD -i %i -j ACCEPT\")\n postUp.push(\"iptables -A FORWARD -o %i -j ACCEPT\")\n\n preDown.push(\"iptables -t nat -D POSTROUTING -j MASQUERADE || true\")\n preDown.push(\"iptables -D FORWARD -i %i -j ACCEPT || true\")\n preDown.push(\"iptables -D FORWARD -o %i -j ACCEPT || true\")\n}\n\n// add forwarding restrictions for specified CIDRs\nfor (const restrictedCidr of args.forwardRestrictedIps) {\n postUp.push(`iptables -I FORWARD -d ${restrictedCidr} -j DROP`)\n preDown.push(`iptables -D FORWARD -d ${restrictedCidr} -j DROP || true`)\n}\n\n// generate WireGuard configuration\nconst wgConfig = generateIdentityConfig({\n identity,\n peers,\n listenPort: identity.peer.listenPort,\n preUp,\n postUp,\n preDown,\n postDown,\n})\n\n// create WireGuard configuration file\nconst configFile = Command.createTextFile(\n \"wireguard-config\",\n {\n host: server,\n path: `/etc/wireguard/${interfaceName}.conf`,\n content: wgConfig,\n },\n { dependsOn: scriptFiles },\n)\n\n// set proper permissions on the config and script files\nconst setPermissions = new Command(\n \"wireguard-permissions\",\n {\n host: server,\n create: `\n chmod 600 /etc/wireguard/${interfaceName}.conf\n ${args.preUpScript ? `chmod 755 /etc/wireguard/${interfaceName}.pre-up.sh` : \"\"}\n ${args.postUpScript ? `chmod 755 /etc/wireguard/${interfaceName}.post-up.sh` : \"\"}\n ${args.preDownScript ? `chmod 755 /etc/wireguard/${interfaceName}.pre-down.sh` : \"\"}\n ${args.postDownScript ? `chmod 755 /etc/wireguard/${interfaceName}.post-down.sh` : \"\"}\n `,\n },\n { dependsOn: [configFile] },\n)\n\n// check for wg-quick template service and enable it\nnew Command(\n \"wireguard-service\",\n {\n host: server,\n create: `\n # check if wg-quick template service exists\n if ! systemctl list-unit-files | grep -q \"^wg-quick@.service\"; then\n echo \"Error: wg-quick@.service template not found. Please install wireguard-tools.\" >&2\n exit 1\n fi\n \n # enable and start the service instance\n systemctl enable --now wg-quick@${interfaceName}.service\n `,\n update: `\n # restart the service to apply new configuration\n systemctl restart wg-quick@${interfaceName}.service\n `,\n delete: `\n # stop and disable the service instance\n systemctl disable --now wg-quick@${interfaceName}.service || true\n \n # clean up the interface if it still exists\n ip link delete ${interfaceName} 2>/dev/null || true\n `,\n updateTriggers: [wgConfig],\n },\n { dependsOn: [setPermissions] },\n)\n\n// calculate endpoints from server L3 endpoints (only if listen port is specified)\nconst endpoints = identity.peer.listenPort\n ? (server.endpoints?.map(e => l3EndpointToL4(e, identity.peer.listenPort!)) ?? [])\n : []\n\nexport default outputs({\n peer: identity.peer.listenPort\n ? {\n ...identity.peer,\n endpoints,\n }\n : identity.peer,\n\n endpoints,\n\n $statusFields: {\n interfaceName,\n ...(identity.peer.listenPort && endpoints.length > 0\n ? {\n endpoints: endpoints.map(l4EndpointToString),\n }\n : {}),\n },\n})\n"]}
|
package/dist/node.k8s/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { generateIdentityConfig, shouldExpose, isExitNode } from '../chunk-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { generateIdentityConfig, shouldExpose, isExitNode } from '../chunk-OSJ6YUBV.js';
|
|
2
|
+
import '../chunk-I7BWSAN6.js';
|
|
3
|
+
import { createAddressSpace, subnetToString, l4EndpointToString } from '@highstate/common';
|
|
4
|
+
import { Namespace, Secret, Workload, ExposableWorkload, NetworkPolicy } from '@highstate/k8s';
|
|
4
5
|
import { wireguard as wireguard$1 } from '@highstate/library';
|
|
5
|
-
import { forUnit, toPromise
|
|
6
|
+
import { forUnit, toPromise } from '@highstate/pulumi';
|
|
6
7
|
import { deepmerge } from 'deepmerge-ts';
|
|
7
8
|
|
|
8
9
|
// assets/images.json
|
|
@@ -25,10 +26,7 @@ var namespace = Namespace.createOrPatch(appName, {
|
|
|
25
26
|
}
|
|
26
27
|
});
|
|
27
28
|
var downstreamInterface = await toPromise(inputs.interface);
|
|
28
|
-
var preUp = [
|
|
29
|
-
// idk why
|
|
30
|
-
"sleep 5"
|
|
31
|
-
];
|
|
29
|
+
var preUp = [];
|
|
32
30
|
var postUp = [
|
|
33
31
|
// enable masquerading for all traffic going out of the WireGuard node
|
|
34
32
|
// TODO: consider adding more specific and restrictive rules
|
|
@@ -38,7 +36,7 @@ var preDown = [
|
|
|
38
36
|
// remove the masquerading rule
|
|
39
37
|
"iptables -t nat -D POSTROUTING -j MASQUERADE"
|
|
40
38
|
];
|
|
41
|
-
for (const restrictedCidr of args.
|
|
39
|
+
for (const restrictedCidr of args.forwardRestrictedSubnets) {
|
|
42
40
|
postUp.push(`iptables -I FORWARD -d ${restrictedCidr} -j DROP`);
|
|
43
41
|
preDown.push(`iptables -D FORWARD -d ${restrictedCidr} -j DROP`);
|
|
44
42
|
}
|
|
@@ -66,50 +64,51 @@ var configSecret = Secret.create(appName, {
|
|
|
66
64
|
preUp,
|
|
67
65
|
postUp,
|
|
68
66
|
preDown,
|
|
69
|
-
defaultInterface: "eth0",
|
|
70
67
|
cluster: await toPromise(inputs.k8sCluster)
|
|
71
68
|
})
|
|
72
69
|
}
|
|
73
70
|
});
|
|
74
|
-
var workload =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
71
|
+
var workload = await toPromise(
|
|
72
|
+
Workload.createOrPatchGeneric(appName, {
|
|
73
|
+
defaultType: "Deployment",
|
|
74
|
+
namespace,
|
|
75
|
+
existing: inputs.workload ?? inputs.interface?.workload,
|
|
76
|
+
container: deepmerge(
|
|
77
|
+
{
|
|
78
|
+
image: wireguard.image,
|
|
79
|
+
environment: {
|
|
80
|
+
PUID: "1000",
|
|
81
|
+
PGID: "1000",
|
|
82
|
+
TZ: "Etc/UTC"
|
|
83
|
+
},
|
|
84
|
+
securityContext: {
|
|
85
|
+
capabilities: {
|
|
86
|
+
add: ["NET_ADMIN"]
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
port: {
|
|
90
|
+
containerPort,
|
|
91
|
+
protocol: "UDP"
|
|
92
|
+
},
|
|
93
|
+
volumeMount: {
|
|
94
|
+
volume: configSecret,
|
|
95
|
+
mountPath: "/config/wg_confs"
|
|
89
96
|
}
|
|
90
97
|
},
|
|
98
|
+
args.containerSpec ?? {}
|
|
99
|
+
),
|
|
100
|
+
service: shouldExpose(identity, args.exposePolicy) ? {
|
|
101
|
+
external: args.external,
|
|
91
102
|
port: {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
volume: configSecret,
|
|
97
|
-
mountPath: "/config/wg_confs"
|
|
103
|
+
port: identity.peer.listenPort ?? 51820,
|
|
104
|
+
targetPort: containerPort,
|
|
105
|
+
protocol: "UDP",
|
|
106
|
+
nodePort: args.external ? identity.peer.listenPort : void 0
|
|
98
107
|
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
external: args.external,
|
|
104
|
-
port: {
|
|
105
|
-
port: identity.peer.listenPort ?? 51820,
|
|
106
|
-
targetPort: containerPort,
|
|
107
|
-
protocol: "UDP",
|
|
108
|
-
nodePort: args.external ? identity.peer.listenPort : void 0
|
|
109
|
-
}
|
|
110
|
-
} : void 0
|
|
111
|
-
});
|
|
112
|
-
if (shouldExpose(identity, args.exposePolicy)) {
|
|
108
|
+
} : void 0
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
if (shouldExpose(identity, args.exposePolicy) && workload instanceof ExposableWorkload) {
|
|
113
112
|
new NetworkPolicy("allow-wireguard-ingress", {
|
|
114
113
|
namespace,
|
|
115
114
|
selector: workload.spec.selector,
|
|
@@ -119,7 +118,7 @@ if (shouldExpose(identity, args.exposePolicy)) {
|
|
|
119
118
|
}
|
|
120
119
|
});
|
|
121
120
|
}
|
|
122
|
-
if (isExitNode(identity.peer)) {
|
|
121
|
+
if (isExitNode(identity.peer) && workload instanceof ExposableWorkload) {
|
|
123
122
|
new NetworkPolicy("allow-all-egress", {
|
|
124
123
|
namespace,
|
|
125
124
|
selector: workload.spec.selector,
|
|
@@ -129,36 +128,40 @@ if (isExitNode(identity.peer)) {
|
|
|
129
128
|
}
|
|
130
129
|
});
|
|
131
130
|
}
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
var pureAllowedSpace = createAddressSpace({
|
|
132
|
+
included: identity.peer.allowedSubnets,
|
|
133
|
+
excluded: identity.peer.addresses
|
|
134
|
+
});
|
|
135
|
+
if (pureAllowedSpace.subnets.length > 0 && workload instanceof ExposableWorkload) {
|
|
136
|
+
new NetworkPolicy("allow-egress-to-allowed-subnets", {
|
|
134
137
|
namespace,
|
|
135
138
|
selector: workload.spec.selector,
|
|
136
|
-
description:
|
|
139
|
+
description: "Allow egress traffic from the WireGuard node to its allowed subnets.",
|
|
137
140
|
egressRule: {
|
|
138
|
-
|
|
141
|
+
toCidrs: pureAllowedSpace.subnets.map(subnetToString)
|
|
139
142
|
}
|
|
140
143
|
});
|
|
141
144
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
new NetworkPolicy(`allow-egress-to-peer-${peer.name}`, {
|
|
147
|
-
namespace,
|
|
148
|
-
selector: workload.spec.selector,
|
|
149
|
-
description: `Allow egress traffic from the WireGuard node to the endpoints of the peer "${peer.name}".`,
|
|
150
|
-
egressRule: {
|
|
151
|
-
toEndpoints: peer.endpoints
|
|
145
|
+
if (workload instanceof ExposableWorkload) {
|
|
146
|
+
for (const peer of peers) {
|
|
147
|
+
if (!peer.endpoints.length) {
|
|
148
|
+
continue;
|
|
152
149
|
}
|
|
153
|
-
|
|
150
|
+
new NetworkPolicy(`allow-egress-to-peer-${peer.name}`, {
|
|
151
|
+
namespace,
|
|
152
|
+
selector: workload.spec.selector,
|
|
153
|
+
description: `Allow egress traffic from the WireGuard node to the endpoints of the peer "${peer.name}".`,
|
|
154
|
+
egressRule: {
|
|
155
|
+
toEndpoints: peer.endpoints
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
154
159
|
}
|
|
155
|
-
var endpoints = await
|
|
156
|
-
|
|
157
|
-
[],
|
|
158
|
-
output(workload.optionalService.apply((service) => service?.endpoints ?? [])),
|
|
159
|
-
"prepend"
|
|
160
|
+
var endpoints = await toPromise(
|
|
161
|
+
workload instanceof ExposableWorkload ? workload.optionalService.apply((service) => service?.endpoints) : []
|
|
160
162
|
);
|
|
161
163
|
var node_default = outputs({
|
|
164
|
+
workload: workload.entity,
|
|
162
165
|
interface: {
|
|
163
166
|
name: interfaceName,
|
|
164
167
|
workload: workload.entity
|
|
@@ -167,7 +170,6 @@ var node_default = outputs({
|
|
|
167
170
|
...identity.peer,
|
|
168
171
|
endpoints
|
|
169
172
|
},
|
|
170
|
-
endpoints,
|
|
171
173
|
$statusFields: {
|
|
172
174
|
endpoints: endpoints.map(l4EndpointToString)
|
|
173
175
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../assets/images.json","../../src/node.k8s/index.ts"],"names":["wireguard"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"wireguard\": {\n \"name\": \"docker.io/linuxserver/wireguard\",\n \"tag\": \"latest\",\n \"image\": \"docker.io/linuxserver/wireguard:latest@sha256:7792dcef56c51e6b4d499a209e980ed74309bf3bee6af12168ea02bf289eddd9\"\n }\n}\n","import { l4EndpointToString, l34EndpointToString, updateEndpoints } from \"@highstate/common\"\nimport { ExposableWorkload, Namespace, NetworkPolicy, Secret } from \"@highstate/k8s\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, output, toPromise } from \"@highstate/pulumi\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport * as images from \"../../assets/images.json\"\nimport { generateIdentityConfig, isExitNode, shouldExpose } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.nodeK8s)\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\n// Add forwarding restrictions for specified CIDRs\nfor (const restrictedCidr of args.forwardRestrictedIps) {\n // Block forwarding to restricted CIDR (prevents other peers from reaching these destinations)\n postUp.push(`iptables -I FORWARD -d ${restrictedCidr} -j DROP`)\n preDown.push(`iptables -D FORWARD -d ${restrictedCidr} -j DROP`)\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 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 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 new NetworkPolicy(\"allow-wireguard-ingress\", {\n namespace,\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 new NetworkPolicy(\"allow-all-egress\", {\n namespace,\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 new NetworkPolicy(`allow-egress-to-${l34EndpointToString(endpoint)}`, {\n namespace,\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 new NetworkPolicy(`allow-egress-to-peer-${peer.name}`, {\n namespace,\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 $statusFields: {\n endpoints: endpoints.map(l4EndpointToString),\n },\n\n $terminals: [workload.terminal],\n})\n"]}
|
|
1
|
+
{"version":3,"sources":["../../assets/images.json","../../src/node.k8s/index.ts"],"names":["wireguard"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"wireguard\": {\n \"name\": \"docker.io/linuxserver/wireguard\",\n \"tag\": \"latest\",\n \"image\": \"docker.io/linuxserver/wireguard:latest@sha256:7792dcef56c51e6b4d499a209e980ed74309bf3bee6af12168ea02bf289eddd9\"\n }\n}\n","import { createAddressSpace, l4EndpointToString, subnetToString } from \"@highstate/common\"\nimport { ExposableWorkload, Namespace, NetworkPolicy, Secret, Workload } from \"@highstate/k8s\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\nimport { deepmerge } from \"deepmerge-ts\"\nimport * as images from \"../../assets/images.json\"\nimport { generateIdentityConfig, isExitNode, shouldExpose } from \"../shared\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.nodeK8s)\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\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\n// add forwarding restrictions for specified CIDRs\nfor (const restrictedCidr of args.forwardRestrictedSubnets) {\n // block forwarding to restricted CIDR (prevents other peers from reaching these destinations)\n postUp.push(`iptables -I FORWARD -d ${restrictedCidr} -j DROP`)\n preDown.push(`iptables -D FORWARD -d ${restrictedCidr} -j DROP`)\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 namespace,\n\n stringData: {\n [`${interfaceName}.conf`]: generateIdentityConfig({\n identity,\n peers,\n listenPort: containerPort,\n preUp,\n postUp,\n preDown,\n cluster: await toPromise(inputs.k8sCluster),\n }),\n },\n})\n\nconst workload = await toPromise(\n Workload.createOrPatchGeneric(appName, {\n defaultType: \"Deployment\",\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)\n\nif (shouldExpose(identity, args.exposePolicy) && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-wireguard-ingress\", {\n namespace,\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) && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-all-egress\", {\n namespace,\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\nconst pureAllowedSpace = createAddressSpace({\n included: identity.peer.allowedSubnets,\n excluded: identity.peer.addresses,\n})\n\n// allow egress to the subnets that are not part of the peer's addresses\nif (pureAllowedSpace.subnets.length > 0 && workload instanceof ExposableWorkload) {\n new NetworkPolicy(\"allow-egress-to-allowed-subnets\", {\n namespace,\n selector: workload.spec.selector,\n\n description: \"Allow egress traffic from the WireGuard node to its allowed subnets.\",\n\n egressRule: {\n toCidrs: pureAllowedSpace.subnets.map(subnetToString),\n },\n })\n}\n\nif (workload instanceof ExposableWorkload) {\n for (const peer of peers) {\n if (!peer.endpoints.length) {\n continue\n }\n\n new NetworkPolicy(`allow-egress-to-peer-${peer.name}`, {\n namespace,\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}\n\nconst endpoints = await toPromise(\n workload instanceof ExposableWorkload\n ? workload.optionalService.apply(service => service?.endpoints!)\n : [],\n)\n\nexport default outputs({\n workload: workload.entity,\n\n interface: {\n name: interfaceName,\n workload: workload.entity,\n },\n\n peer: {\n ...identity.peer,\n endpoints,\n },\n\n $statusFields: {\n endpoints: endpoints.map(l4EndpointToString),\n },\n\n $terminals: [workload.terminal],\n})\n"]}
|
package/dist/peer/index.js
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
import { createPeerEntity } from '../chunk-
|
|
2
|
-
import
|
|
1
|
+
import { createPeerEntity } from '../chunk-OSJ6YUBV.js';
|
|
2
|
+
import '../chunk-I7BWSAN6.js';
|
|
3
|
+
import { subnetToString, l4EndpointToString } from '@highstate/common';
|
|
3
4
|
import { wireguard } from '@highstate/library';
|
|
4
5
|
import { forUnit, toPromise } from '@highstate/pulumi';
|
|
5
6
|
|
|
6
7
|
var { name, args, secrets, inputs, outputs } = forUnit(wireguard.peer);
|
|
7
8
|
var resolvedInpus = await toPromise(inputs);
|
|
8
9
|
var presharedKey = await toPromise(secrets.presharedKey);
|
|
9
|
-
var peer = createPeerEntity(name, args, resolvedInpus, args.publicKey, presharedKey);
|
|
10
|
+
var peer = await createPeerEntity(name, args, resolvedInpus, args.publicKey, presharedKey);
|
|
10
11
|
var peer_default = outputs({
|
|
11
12
|
peer,
|
|
12
|
-
endpoints: peer.endpoints,
|
|
13
13
|
$statusFields: {
|
|
14
|
-
endpoints:
|
|
15
|
-
|
|
16
|
-
complementaryTo: "endpoints"
|
|
17
|
-
},
|
|
18
|
-
allowedEndpoints: {
|
|
19
|
-
value: peer.allowedEndpoints.map(l3EndpointToString),
|
|
20
|
-
complementaryTo: "allowedEndpoints"
|
|
21
|
-
}
|
|
14
|
+
endpoints: peer.endpoints.map(l4EndpointToString),
|
|
15
|
+
allowedSubnets: peer.allowedSubnets.map(subnetToString)
|
|
22
16
|
}
|
|
23
17
|
});
|
|
24
18
|
|
package/dist/peer/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/peer/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/peer/index.ts"],"names":[],"mappings":";;;;;;AAKA,IAAM,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,QAAQ,OAAA,EAAQ,GAAI,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA;AAEvE,IAAM,aAAA,GAAgB,MAAM,SAAA,CAAU,MAAM,CAAA;AAC5C,IAAM,YAAA,GAAe,MAAM,SAAA,CAAU,OAAA,CAAQ,YAAY,CAAA;AAEzD,IAAM,IAAA,GAAO,MAAM,gBAAA,CAAiB,IAAA,EAAM,MAAM,aAAA,EAAe,IAAA,CAAK,WAAW,YAAY,CAAA;AAE3F,IAAO,eAAQ,OAAA,CAAQ;AAAA,EACrB,IAAA;AAAA,EAEA,aAAA,EAAe;AAAA,IACb,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,kBAAkB,CAAA;AAAA,IAChD,cAAA,EAAgB,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,cAAc;AAAA;AAE1D,CAAC","file":"index.js","sourcesContent":["import { l4EndpointToString, subnetToString } from \"@highstate/common\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\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 = await createPeerEntity(name, args, resolvedInpus, args.publicKey, presharedKey)\n\nexport default outputs({\n peer,\n\n $statusFields: {\n endpoints: peer.endpoints.map(l4EndpointToString),\n allowedSubnets: peer.allowedSubnets.map(subnetToString),\n },\n})\n"]}
|
package/dist/peer-patch/index.js
CHANGED
|
@@ -1,44 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import '../chunk-I7BWSAN6.js';
|
|
2
|
+
import { parseEndpoints, parseSubnets, subnetToString, l4EndpointToString } from '@highstate/common';
|
|
3
3
|
import { wireguard } from '@highstate/library';
|
|
4
4
|
import { forUnit, toPromise } from '@highstate/pulumi';
|
|
5
5
|
|
|
6
6
|
var { args, inputs, outputs } = forUnit(wireguard.peerPatch);
|
|
7
|
-
var
|
|
8
|
-
var endpoints = await
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
args.endpointsPatchMode
|
|
13
|
-
);
|
|
14
|
-
var allowedEndpoints = await updateEndpoints(
|
|
15
|
-
inputs.peer.allowedEndpoints,
|
|
16
|
-
[],
|
|
17
|
-
calculateAllowedEndpoints(args, resolvedInputs),
|
|
18
|
-
args.allowedEndpointsPatchMode
|
|
19
|
-
);
|
|
7
|
+
var peer = await toPromise(inputs.peer);
|
|
8
|
+
var endpoints = await parseEndpoints(args.endpoints, inputs.endpoints, 4);
|
|
9
|
+
var allowedSubnets = await parseSubnets(args.allowedSubnets, inputs.allowedSubnets);
|
|
10
|
+
var newEndpoints = endpoints.length > 0 ? endpoints : peer.endpoints;
|
|
11
|
+
var newAllowedSubnets = allowedSubnets.length > 0 ? allowedSubnets : peer.allowedSubnets;
|
|
20
12
|
var peer_patch_default = outputs({
|
|
21
|
-
peer: {
|
|
22
|
-
...
|
|
23
|
-
endpoints,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
allowedIps: calculateAllowedIps(
|
|
27
|
-
{ address: args.address ?? resolvedInputs.peer.address, exitNode: args.exitNode },
|
|
28
|
-
resolvedInputs,
|
|
29
|
-
allowedEndpoints
|
|
30
|
-
)
|
|
31
|
-
},
|
|
32
|
-
endpoints,
|
|
13
|
+
peer: inputs.peer.apply((peer2) => ({
|
|
14
|
+
...peer2,
|
|
15
|
+
endpoints: newEndpoints,
|
|
16
|
+
allowedSubnets: newAllowedSubnets
|
|
17
|
+
})),
|
|
33
18
|
$statusFields: {
|
|
34
|
-
endpoints:
|
|
35
|
-
|
|
36
|
-
complementaryTo: "endpoints"
|
|
37
|
-
},
|
|
38
|
-
allowedEndpoints: {
|
|
39
|
-
value: allowedEndpoints.map(l3EndpointToString),
|
|
40
|
-
complementaryTo: "allowedEndpoints"
|
|
41
|
-
}
|
|
19
|
+
endpoints: endpoints.map(l4EndpointToString),
|
|
20
|
+
allowedSubnets: allowedSubnets.map(subnetToString)
|
|
42
21
|
}
|
|
43
22
|
});
|
|
44
23
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/peer-patch/index.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"sources":["../../src/peer-patch/index.ts"],"names":["peer"],"mappings":";;;;;AAIA,IAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAQ,GAAI,OAAA,CAAQ,UAAU,SAAS,CAAA;AAE7D,IAAM,IAAA,GAAO,MAAM,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AACxC,IAAM,YAAY,MAAM,cAAA,CAAe,KAAK,SAAA,EAAW,MAAA,CAAO,WAAW,CAAC,CAAA;AAC1E,IAAM,iBAAiB,MAAM,YAAA,CAAa,IAAA,CAAK,cAAA,EAAgB,OAAO,cAAc,CAAA;AAEpF,IAAM,YAAA,GAAe,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,YAAY,IAAA,CAAK,SAAA;AAC7D,IAAM,iBAAA,GAAoB,cAAA,CAAe,MAAA,GAAS,CAAA,GAAI,iBAAiB,IAAA,CAAK,cAAA;AAE5E,IAAO,qBAAQ,OAAA,CAAQ;AAAA,EACrB,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,CAAAA,KAAAA,MAAS;AAAA,IAC/B,GAAGA,KAAAA;AAAA,IACH,SAAA,EAAW,YAAA;AAAA,IACX,cAAA,EAAgB;AAAA,GAClB,CAAE,CAAA;AAAA,EAEF,aAAA,EAAe;AAAA,IACb,SAAA,EAAW,SAAA,CAAU,GAAA,CAAI,kBAAkB,CAAA;AAAA,IAC3C,cAAA,EAAgB,cAAA,CAAe,GAAA,CAAI,cAAc;AAAA;AAErD,CAAC","file":"index.js","sourcesContent":["import { l4EndpointToString, parseEndpoints, parseSubnets, subnetToString } from \"@highstate/common\"\nimport { wireguard } from \"@highstate/library\"\nimport { forUnit, toPromise } from \"@highstate/pulumi\"\n\nconst { args, inputs, outputs } = forUnit(wireguard.peerPatch)\n\nconst peer = await toPromise(inputs.peer)\nconst endpoints = await parseEndpoints(args.endpoints, inputs.endpoints, 4)\nconst allowedSubnets = await parseSubnets(args.allowedSubnets, inputs.allowedSubnets)\n\nconst newEndpoints = endpoints.length > 0 ? endpoints : peer.endpoints\nconst newAllowedSubnets = allowedSubnets.length > 0 ? allowedSubnets : peer.allowedSubnets\n\nexport default outputs({\n peer: inputs.peer.apply(peer => ({\n ...peer,\n endpoints: newEndpoints,\n allowedSubnets: newAllowedSubnets,\n })),\n\n $statusFields: {\n endpoints: endpoints.map(l4EndpointToString),\n allowedSubnets: allowedSubnets.map(subnetToString),\n },\n})\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/wireguard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./identity": "./dist/identity/index.js",
|
|
11
11
|
"./config": "./dist/config/index.js",
|
|
12
12
|
"./config-bundle": "./dist/config-bundle/index.js",
|
|
13
|
+
"./feed": "./dist/feed/index.js",
|
|
13
14
|
"./node": "./dist/node/index.js",
|
|
14
15
|
"./node.k8s": "./dist/node.k8s/index.js",
|
|
15
16
|
"./peer": "./dist/peer/index.js",
|
|
@@ -30,17 +31,21 @@
|
|
|
30
31
|
"deepmerge-ts": "^7.1.5",
|
|
31
32
|
"remeda": "^2.32.0",
|
|
32
33
|
"zip-stream": "^7.0.2",
|
|
33
|
-
"@
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"@highstate/
|
|
37
|
-
"@highstate/k8s": "0.
|
|
34
|
+
"@paralleldrive/cuid2": "^2.2.2",
|
|
35
|
+
"uuid": "^11.1.0",
|
|
36
|
+
"age-encryption": "^0.2.4",
|
|
37
|
+
"@highstate/common": "0.16.0",
|
|
38
|
+
"@highstate/k8s": "0.16.0",
|
|
39
|
+
"@highstate/contract": "0.17.0",
|
|
40
|
+
"@highstate/library": "0.16.0",
|
|
41
|
+
"@highstate/pulumi": "0.17.0",
|
|
42
|
+
"@highstate/etcd-sdk": "0.14.2"
|
|
38
43
|
},
|
|
39
44
|
"devDependencies": {
|
|
40
45
|
"@biomejs/biome": "2.2.0",
|
|
41
46
|
"@types/zip-stream": "^7.0.0",
|
|
42
47
|
"@typescript/native-preview": "^7.0.0-dev.20250920.1",
|
|
43
|
-
"@highstate/cli": "0.
|
|
48
|
+
"@highstate/cli": "0.17.0"
|
|
44
49
|
},
|
|
45
50
|
"repository": {
|
|
46
51
|
"url": "https://github.com/highstate-io/highstate"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared.ts"],"names":[],"mappings":"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","file":"chunk-GVOR653I.js","sourcesContent":["import type { k8s, network, wireguard } from \"@highstate/library\"\nimport {\n l3EndpointToL4,\n l3EndpointToString,\n l4EndpointToString,\n l34EndpointToString,\n parseL4Endpoint,\n parseL34Endpoint,\n} from \"@highstate/common\"\nimport { getBestEndpoint } from \"@highstate/k8s\"\nimport { type Input, type Output, secret, type Unwrap } from \"@highstate/pulumi\"\nimport { x25519 } from \"@noble/curves/ed25519\"\nimport { randomBytes } from \"@noble/hashes/utils.js\"\nimport { unique, uniqueBy } from \"remeda\"\n\nexport function generateKey(): string {\n const key = x25519.utils.randomSecretKey()\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 (peer.persistentKeepalive > 0) {\n lines.push(`PersistentKeepalive = ${peer.persistentKeepalive}`)\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): Output<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 secret(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 => l3EndpointToL4(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 persistentKeepalive: args.persistentKeepalive,\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"]}
|