@highstate/wireguard 0.7.0 → 0.7.1
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/config/index.js +1 -1
- package/dist/identity/index.js +9 -5
- package/dist/node/index.js +112 -75
- package/dist/peer/index.js +22 -0
- package/dist/{shared-BVOzbQ3O.js → shared-D24icZbJ.js} +13 -4
- package/package.json +6 -5
package/dist/config/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { wireguard } from '@highstate/library';
|
|
2
2
|
import { forUnit, output } from '@highstate/pulumi';
|
|
3
|
-
import { b as generateIdentityConfig } from '../shared-
|
|
3
|
+
import { b as generateIdentityConfig } from '../shared-D24icZbJ.js';
|
|
4
4
|
import '@noble/curves/ed25519';
|
|
5
5
|
|
|
6
6
|
function text(array, ...values) {
|
package/dist/identity/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { wireguard } from '@highstate/library';
|
|
2
2
|
import { forUnit, getOrCreateSecret, toPromise } from '@highstate/pulumi';
|
|
3
|
-
import { g as generateKey, a as generatePresharedKey, c as convertPrivateKeyToPublicKey } from '../shared-
|
|
3
|
+
import { g as generateKey, a as generatePresharedKey, c as convertPrivateKeyToPublicKey } from '../shared-D24icZbJ.js';
|
|
4
4
|
import '@noble/curves/ed25519';
|
|
5
5
|
|
|
6
6
|
const { name, args, inputs, secrets, outputs } = forUnit(wireguard.identity);
|
|
@@ -10,10 +10,12 @@ const presharedKeyPart = getOrCreateSecret(secrets, "presharedKeyPart", () => {
|
|
|
10
10
|
return network?.presharedKeyMode === "secure" ? generatePresharedKey() : void 0;
|
|
11
11
|
});
|
|
12
12
|
});
|
|
13
|
-
const
|
|
13
|
+
const defaultAllowedIps = args.address ? [args.address] : [];
|
|
14
|
+
const allowedIps = await toPromise(addK8sServiceIps(args.allowedIps ?? defaultAllowedIps));
|
|
14
15
|
const argsAllowedIpsString = args.allowedIps?.join(", ");
|
|
15
16
|
const calculatedAllowedIpsString = allowedIps.join(", ");
|
|
16
17
|
const calculatedEndpoint = args.externalIp && args.listenPort ? ` ${args.externalIp}:${args.listenPort}` : void 0;
|
|
18
|
+
const publicKey = privateKey.apply(convertPrivateKeyToPublicKey);
|
|
17
19
|
var index = outputs({
|
|
18
20
|
identity: {
|
|
19
21
|
name: args.peerName ?? name,
|
|
@@ -24,25 +26,27 @@ var index = outputs({
|
|
|
24
26
|
k8sServices: inputs.k8sServices,
|
|
25
27
|
exitNode: args.exitNode ?? false,
|
|
26
28
|
listenPort: args.listenPort,
|
|
27
|
-
externalIp: args.externalIp
|
|
29
|
+
externalIp: args.externalIp,
|
|
30
|
+
endpoint: args.endpoint ?? calculatedEndpoint
|
|
28
31
|
},
|
|
29
32
|
peer: {
|
|
30
33
|
name: args.peerName ?? name,
|
|
31
34
|
network: inputs.network,
|
|
32
35
|
address: args.address,
|
|
33
|
-
publicKey
|
|
36
|
+
publicKey,
|
|
34
37
|
allowedIps,
|
|
35
38
|
endpoint: args.endpoint ?? calculatedEndpoint,
|
|
36
39
|
presharedKeyPart
|
|
37
40
|
},
|
|
38
41
|
$status: {
|
|
42
|
+
publicKey,
|
|
39
43
|
allowedIps: calculatedAllowedIpsString !== argsAllowedIpsString ? calculatedAllowedIpsString : void 0,
|
|
40
44
|
endpoint: calculatedEndpoint !== args.endpoint ? calculatedEndpoint : void 0
|
|
41
45
|
}
|
|
42
46
|
});
|
|
43
47
|
function addK8sServiceIps(allowedIps2) {
|
|
44
48
|
return inputs.k8sServices.apply((k8sServices) => {
|
|
45
|
-
const ips = k8sServices.map((service) => service.
|
|
49
|
+
const ips = k8sServices.map((service) => service.spec.clusterIP).filter((ip) => ip !== void 0);
|
|
46
50
|
return allowedIps2.concat(ips);
|
|
47
51
|
});
|
|
48
52
|
}
|
package/dist/node/index.js
CHANGED
|
@@ -1,30 +1,39 @@
|
|
|
1
|
-
import { createProvider, createNamespace, mapMetadata, Deployment, NetworkPolicy } from '@highstate/k8s';
|
|
1
|
+
import { createProvider, getNamespace, createNamespace, mapMetadata, Deployment, StatefulSet, NetworkPolicy, getAppDisplayName, getAppName } from '@highstate/k8s';
|
|
2
2
|
import { wireguard } from '@highstate/library';
|
|
3
3
|
import { forUnit, toPromise, output } from '@highstate/pulumi';
|
|
4
4
|
import { core } from '@pulumi/kubernetes';
|
|
5
|
-
import { b as generateIdentityConfig } from '../shared-
|
|
5
|
+
import { b as generateIdentityConfig } from '../shared-D24icZbJ.js';
|
|
6
6
|
import '@noble/curves/ed25519';
|
|
7
7
|
|
|
8
|
-
const { name, args, inputs } = forUnit(wireguard.node);
|
|
8
|
+
const { name, args, inputs, outputs } = forUnit(wireguard.node);
|
|
9
9
|
const identity = await toPromise(inputs.identity);
|
|
10
10
|
const appName = args.appName ?? `wg-${name}`;
|
|
11
11
|
const containerPort = 51820;
|
|
12
12
|
const serviceType = args.serviceType ?? "ClusterIP";
|
|
13
13
|
const provider = await createProvider(inputs.k8sCluster);
|
|
14
|
-
const
|
|
15
|
-
metadata
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const existingNamespace = await toPromise(
|
|
15
|
+
inputs.deployment?.metadata?.namespace ?? inputs.statefulSet?.metadata?.namespace
|
|
16
|
+
);
|
|
17
|
+
const namespace = existingNamespace ? getNamespace(existingNamespace, provider) : createNamespace(appName, provider);
|
|
18
|
+
new core.v1.NamespacePatch(
|
|
19
|
+
"allow-privileged",
|
|
20
|
+
{
|
|
21
|
+
metadata: {
|
|
22
|
+
name: namespace.metadata.name,
|
|
23
|
+
labels: {
|
|
24
|
+
"pod-security.kubernetes.io/enforce": "privileged"
|
|
25
|
+
}
|
|
18
26
|
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
27
|
+
},
|
|
28
|
+
{ provider }
|
|
29
|
+
);
|
|
21
30
|
const configSecret = new core.v1.Secret(
|
|
22
31
|
appName,
|
|
23
32
|
{
|
|
24
33
|
metadata: mapMetadata({ name: appName, namespace }),
|
|
25
34
|
stringData: {
|
|
26
|
-
"wg0.conf": output(inputs).apply(({ identity: identity2, peers }) => {
|
|
27
|
-
return generateIdentityConfig(identity2,
|
|
35
|
+
"wg0.conf": output(inputs).apply(({ identity: identity2, peers: peers2 }) => {
|
|
36
|
+
return generateIdentityConfig(identity2, peers2, containerPort, args.dns, [
|
|
28
37
|
"iptables -t nat -A POSTROUTING -j MASQUERADE"
|
|
29
38
|
]);
|
|
30
39
|
})
|
|
@@ -32,66 +41,65 @@ const configSecret = new core.v1.Secret(
|
|
|
32
41
|
},
|
|
33
42
|
{ provider }
|
|
34
43
|
);
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
TZ: "Etc/UTC"
|
|
45
|
-
},
|
|
46
|
-
securityContext: {
|
|
47
|
-
capabilities: {
|
|
48
|
-
add: ["NET_ADMIN"]
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
port: {
|
|
52
|
-
containerPort,
|
|
53
|
-
protocol: "UDP"
|
|
54
|
-
},
|
|
55
|
-
volume: configSecret,
|
|
56
|
-
volumeMount: {
|
|
57
|
-
volume: configSecret,
|
|
58
|
-
mountPath: "/config/wg_confs"
|
|
59
|
-
}
|
|
44
|
+
const workloadOptions = {
|
|
45
|
+
namespace,
|
|
46
|
+
cluster: inputs.k8sCluster,
|
|
47
|
+
container: {
|
|
48
|
+
image: "linuxserver/wireguard:latest",
|
|
49
|
+
environment: {
|
|
50
|
+
PUID: "1000",
|
|
51
|
+
PGID: "1000",
|
|
52
|
+
TZ: "Etc/UTC"
|
|
60
53
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
port: {
|
|
65
|
-
port: containerPort,
|
|
66
|
-
protocol: "UDP",
|
|
67
|
-
nodePort: serviceType === "NodePort" ? identity.listenPort : void 0
|
|
54
|
+
securityContext: {
|
|
55
|
+
capabilities: {
|
|
56
|
+
add: ["NET_ADMIN"]
|
|
68
57
|
}
|
|
58
|
+
},
|
|
59
|
+
port: identity.endpoint ? { containerPort, protocol: "UDP" } : void 0,
|
|
60
|
+
volumeMount: {
|
|
61
|
+
volume: configSecret,
|
|
62
|
+
mountPath: "/config/wg_confs"
|
|
69
63
|
}
|
|
70
64
|
},
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
65
|
+
service: {
|
|
66
|
+
type: serviceType,
|
|
67
|
+
externalIPs: identity.externalIp ? [identity.externalIp] : void 0,
|
|
68
|
+
port: identity.endpoint ? {
|
|
69
|
+
port: containerPort,
|
|
70
|
+
protocol: "UDP",
|
|
71
|
+
nodePort: identity.listenPort
|
|
72
|
+
} : void 0
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const deployment = !inputs.statefulSet ? Deployment.create(appName, { ...workloadOptions, patch: inputs.deployment }, { provider }) : void 0;
|
|
76
|
+
const statefulSet = inputs.statefulSet ? StatefulSet.create(appName, { ...workloadOptions, patch: inputs.statefulSet }, { provider }) : void 0;
|
|
77
|
+
const selector = deployment?.spec.selector ?? statefulSet?.spec.selector;
|
|
78
|
+
const service = deployment?.service ?? statefulSet?.service;
|
|
79
|
+
if (identity.listenPort) {
|
|
80
|
+
NetworkPolicy.create(
|
|
81
|
+
"allow-wireguard-ingress",
|
|
82
|
+
{
|
|
83
|
+
cni: inputs.k8sCluster.info.cni,
|
|
84
|
+
namespace,
|
|
85
|
+
selector,
|
|
86
|
+
description: "Allow encapsulated WireGuard traffic to the node from anywhere.",
|
|
87
|
+
ingressRule: {
|
|
88
|
+
fromAll: true,
|
|
89
|
+
toPort: { port: containerPort, protocol: "UDP" }
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{ provider }
|
|
93
|
+
);
|
|
94
|
+
}
|
|
87
95
|
if (identity.exitNode) {
|
|
88
96
|
NetworkPolicy.create(
|
|
89
97
|
"allow-all-egress",
|
|
90
98
|
{
|
|
91
|
-
cni: inputs.k8sCluster.cni,
|
|
99
|
+
cni: inputs.k8sCluster.info.cni,
|
|
92
100
|
namespace,
|
|
101
|
+
selector,
|
|
93
102
|
description: "Allow all egress traffic from the WireGuard node.",
|
|
94
|
-
selector: deployment.deployment.spec.selector,
|
|
95
103
|
egressRule: {
|
|
96
104
|
toAll: true
|
|
97
105
|
}
|
|
@@ -99,37 +107,66 @@ if (identity.exitNode) {
|
|
|
99
107
|
{ provider }
|
|
100
108
|
);
|
|
101
109
|
}
|
|
102
|
-
for (const
|
|
110
|
+
for (const service2 of identity.k8sServices) {
|
|
111
|
+
const displayName = getAppDisplayName(service2.metadata);
|
|
103
112
|
NetworkPolicy.create(
|
|
104
|
-
`allow-egress-to-${
|
|
113
|
+
`allow-egress-to-${getAppName(service2.metadata)}`,
|
|
105
114
|
{
|
|
106
|
-
cni: inputs.k8sCluster.cni,
|
|
115
|
+
cni: inputs.k8sCluster.info.cni,
|
|
107
116
|
namespace,
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
selector,
|
|
118
|
+
description: `Allow egress traffic from the WireGuard node to the service "${displayName}".`,
|
|
110
119
|
egressRules: [
|
|
111
120
|
{
|
|
112
|
-
toNamespace:
|
|
113
|
-
toSelector:
|
|
121
|
+
toNamespace: service2.metadata.namespace,
|
|
122
|
+
toSelector: service2.spec.selector
|
|
114
123
|
},
|
|
115
124
|
// for compatibility with Cilium which cannot correctly detect the destination endpoint when the packet is redirected by the WireGuard node
|
|
116
|
-
...
|
|
125
|
+
...service2.spec.clusterIP ? [{ toCidr: `${service2.spec.clusterIP}/32` }] : []
|
|
117
126
|
]
|
|
118
127
|
},
|
|
119
128
|
{ provider }
|
|
120
129
|
);
|
|
121
130
|
NetworkPolicy.create(
|
|
122
|
-
`allow-ingress-
|
|
131
|
+
`allow-ingress-to-${getAppName(service2.metadata)}`,
|
|
123
132
|
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
selector:
|
|
133
|
+
name: `allow-ingress-from-${appName}`,
|
|
134
|
+
cni: inputs.k8sCluster.info.cni,
|
|
135
|
+
namespace: service2.metadata.namespace,
|
|
136
|
+
selector: service2.spec.selector,
|
|
137
|
+
description: `Allow ingress traffic from the WireGuard node "${appName}" to the service "${displayName}".`,
|
|
128
138
|
ingressRule: {
|
|
129
139
|
fromNamespace: namespace,
|
|
130
|
-
fromSelector:
|
|
140
|
+
fromSelector: selector
|
|
131
141
|
}
|
|
132
142
|
},
|
|
133
143
|
{ provider }
|
|
134
144
|
);
|
|
135
145
|
}
|
|
146
|
+
const peers = await toPromise(inputs.peers);
|
|
147
|
+
for (const peer of peers) {
|
|
148
|
+
if (!peer.endpoint) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const [endpoint, port] = peer.endpoint.split(":");
|
|
152
|
+
NetworkPolicy.create(
|
|
153
|
+
`allow-egress-to-peer-${peer.name}`,
|
|
154
|
+
{
|
|
155
|
+
cni: inputs.k8sCluster.info.cni,
|
|
156
|
+
namespace,
|
|
157
|
+
selector,
|
|
158
|
+
description: `Allow egress traffic from the WireGuard node to the endpoint of the peer "${peer.name}".`,
|
|
159
|
+
egressRule: {
|
|
160
|
+
toEndpoint: endpoint,
|
|
161
|
+
toPort: { port: port ? parseInt(port) : containerPort, protocol: "UDP" }
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
{ provider }
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
var index = outputs({
|
|
168
|
+
deployment: deployment?.entity,
|
|
169
|
+
service: service?.entity
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
export { index as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { wireguard } from '@highstate/library';
|
|
2
|
+
import { forUnit } from '@highstate/pulumi';
|
|
3
|
+
|
|
4
|
+
const { name, args, inputs, outputs } = forUnit(wireguard.peer);
|
|
5
|
+
const calculatedAllowedIpds = args.address ? [args.address] : [];
|
|
6
|
+
const argsAllowedIpsString = args.allowedIps?.join(", ");
|
|
7
|
+
const calculatedAllowedIpsString = calculatedAllowedIpds.join(", ");
|
|
8
|
+
var index = outputs({
|
|
9
|
+
peer: {
|
|
10
|
+
name: args.peerName ?? name,
|
|
11
|
+
network: inputs.network,
|
|
12
|
+
address: args.address,
|
|
13
|
+
publicKey: args.publicKey,
|
|
14
|
+
allowedIps: args.allowedIps ?? calculatedAllowedIpds,
|
|
15
|
+
endpoint: args.endpoint
|
|
16
|
+
},
|
|
17
|
+
$status: {
|
|
18
|
+
allowedIps: calculatedAllowedIpsString !== argsAllowedIpsString ? calculatedAllowedIpsString : void 0
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export { index as default };
|
|
@@ -54,14 +54,23 @@ function generatePeerConfig(identity, peer) {
|
|
|
54
54
|
}
|
|
55
55
|
return lines.join("\n");
|
|
56
56
|
}
|
|
57
|
-
function generateIdentityConfig(identity, peers, listenPort, postUp) {
|
|
57
|
+
function generateIdentityConfig(identity, peers, listenPort, dns, postUp) {
|
|
58
58
|
const lines = [
|
|
59
|
+
//
|
|
59
60
|
"[Interface]",
|
|
60
|
-
`# ${identity.name}
|
|
61
|
-
|
|
61
|
+
`# ${identity.name}`
|
|
62
|
+
];
|
|
63
|
+
if (identity.address) {
|
|
64
|
+
lines.push(`Address = ${identity.address}`);
|
|
65
|
+
}
|
|
66
|
+
lines.push(
|
|
67
|
+
//
|
|
62
68
|
`PrivateKey = ${identity.privateKey}`,
|
|
63
69
|
"MTU = 1280"
|
|
64
|
-
|
|
70
|
+
);
|
|
71
|
+
if (dns) {
|
|
72
|
+
lines.push(`DNS = ${dns.join(", ")}`);
|
|
73
|
+
}
|
|
65
74
|
if (listenPort) {
|
|
66
75
|
lines.push(`ListenPort = ${listenPort}`);
|
|
67
76
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/wireguard",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"./network": "./dist/network/index.js",
|
|
10
10
|
"./identity": "./dist/identity/index.js",
|
|
11
11
|
"./config": "./dist/config/index.js",
|
|
12
|
-
"./node": "./dist/node/index.js"
|
|
12
|
+
"./node": "./dist/node/index.js",
|
|
13
|
+
"./peer": "./dist/peer/index.js"
|
|
13
14
|
},
|
|
14
15
|
"publishConfig": {
|
|
15
16
|
"access": "public"
|
|
@@ -18,8 +19,8 @@
|
|
|
18
19
|
"build": "pkgroll --tsconfig=tsconfig.build.json"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@highstate/k8s": "^0.7.
|
|
22
|
-
"@highstate/pulumi": "^0.7.
|
|
22
|
+
"@highstate/k8s": "^0.7.1",
|
|
23
|
+
"@highstate/pulumi": "^0.7.1",
|
|
23
24
|
"@noble/curves": "^1.8.0",
|
|
24
25
|
"@pulumi/kubernetes": "^4.18.0"
|
|
25
26
|
},
|
|
@@ -29,5 +30,5 @@
|
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"pkgroll": "^2.5.1"
|
|
31
32
|
},
|
|
32
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "76c38ce5dbf7a710cf0e6339f52e86358537a99a"
|
|
33
34
|
}
|