feat: Netbird | set up netbird vpn
This commit is contained in:
5
main.ts
5
main.ts
@@ -9,6 +9,7 @@ import { NetworkSecurity } from "./network-security";
|
|||||||
import { GamingServices } from "./gaming-services/minecraft";
|
import { GamingServices } from "./gaming-services/minecraft";
|
||||||
import { MediaServices } from "./media-services";
|
import { MediaServices } from "./media-services";
|
||||||
import { PKI } from "./pki";
|
import { PKI } from "./pki";
|
||||||
|
import { Netbird } from "./netbird";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@@ -46,6 +47,9 @@ mediaServices.node.addDependency(networkSecurity);
|
|||||||
const caches = new CacheInfrastructure(app, "cache-infrastructure");
|
const caches = new CacheInfrastructure(app, "cache-infrastructure");
|
||||||
caches.node.addDependency(utilityServices);
|
caches.node.addDependency(utilityServices);
|
||||||
|
|
||||||
|
const netbird = new Netbird(app, "netbird");
|
||||||
|
netbird.node.addDependency(utilityServices);
|
||||||
|
|
||||||
const deploy: (stack: TerraformStack, key: string) => S3Backend = (
|
const deploy: (stack: TerraformStack, key: string) => S3Backend = (
|
||||||
stack,
|
stack,
|
||||||
key,
|
key,
|
||||||
@@ -75,5 +79,6 @@ deploy(utilityServices, "utility-services");
|
|||||||
deploy(caches, "cache-infrastructure");
|
deploy(caches, "cache-infrastructure");
|
||||||
deploy(gamingServices, "gaming-services");
|
deploy(gamingServices, "gaming-services");
|
||||||
deploy(mediaServices, "media-services");
|
deploy(mediaServices, "media-services");
|
||||||
|
deploy(netbird, "netbird");
|
||||||
|
|
||||||
app.synth();
|
app.synth();
|
||||||
|
|||||||
95
netbird/index.ts
Normal file
95
netbird/index.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "path";
|
||||||
|
import { Construct } from "constructs";
|
||||||
|
import { TerraformStack } from "cdktf";
|
||||||
|
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
||||||
|
import { NamespaceV1 } from "@cdktf/provider-kubernetes/lib/namespace-v1";
|
||||||
|
import { DataKubernetesSecretV1 } from "@cdktf/provider-kubernetes/lib/data-kubernetes-secret-v1";
|
||||||
|
import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
|
||||||
|
import { SecretV1 } from "@cdktf/provider-kubernetes/lib/secret-v1";
|
||||||
|
import { Release } from "@cdktf/provider-helm/lib/release";
|
||||||
|
import { CloudflareCertificate, OnePasswordSecret } from "../utils";
|
||||||
|
|
||||||
|
export class Netbird extends TerraformStack {
|
||||||
|
constructor(scope: Construct, id: string) {
|
||||||
|
super(scope, id);
|
||||||
|
|
||||||
|
const kubernetes = new KubernetesProvider(this, "kubernetes", {
|
||||||
|
configPath: "~/.kube/config",
|
||||||
|
});
|
||||||
|
|
||||||
|
const helm = new HelmProvider(this, "helm", {
|
||||||
|
kubernetes: {
|
||||||
|
configPath: "~/.kube/config",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const namespace = "netbird";
|
||||||
|
|
||||||
|
// Create namespace
|
||||||
|
new NamespaceV1(this, "namespace", {
|
||||||
|
metadata: {
|
||||||
|
name: namespace,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
new OnePasswordSecret(this, "netbird-secret", {
|
||||||
|
name: "netbird",
|
||||||
|
namespace,
|
||||||
|
provider: kubernetes,
|
||||||
|
itemPath: "vaults/Lab/items/Netbird",
|
||||||
|
});
|
||||||
|
|
||||||
|
const pgClientCert = new DataKubernetesSecretV1(
|
||||||
|
this,
|
||||||
|
"netbird-client-cert",
|
||||||
|
{
|
||||||
|
provider: kubernetes,
|
||||||
|
metadata: {
|
||||||
|
name: "netbird-client-cert",
|
||||||
|
namespace: "homelab",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const pgCaCert = new DataKubernetesSecretV1(this, "postgres-ca-cert", {
|
||||||
|
provider: kubernetes,
|
||||||
|
metadata: {
|
||||||
|
name: "postgres-server-cert",
|
||||||
|
namespace: "homelab",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const pgSslBundle = new SecretV1(this, "netbird-postgres-ssl", {
|
||||||
|
provider: kubernetes,
|
||||||
|
metadata: {
|
||||||
|
name: "netbird-postgres-ssl-bundle",
|
||||||
|
namespace,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
"tls.crt": pgClientCert.data.lookup("tls.crt"),
|
||||||
|
"tls.key": pgClientCert.data.lookup("tls.key"),
|
||||||
|
"ca.crt": pgCaCert.data.lookup("ca.crt"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
new CloudflareCertificate(this, "netbird-cloudflare-cert", {
|
||||||
|
provider: kubernetes,
|
||||||
|
name: "netbird",
|
||||||
|
namespace,
|
||||||
|
dnsNames: ["vpn.dogar.dev"],
|
||||||
|
secretName: "netbird-tls",
|
||||||
|
});
|
||||||
|
|
||||||
|
new Release(this, "netbird", {
|
||||||
|
dependsOn: [pgSslBundle],
|
||||||
|
provider: helm,
|
||||||
|
namespace,
|
||||||
|
createNamespace: true,
|
||||||
|
name: "netbird",
|
||||||
|
repository: "https://netbirdio.github.io/helms",
|
||||||
|
chart: "netbird",
|
||||||
|
values: [fs.readFileSync(path.join(__dirname, "values.yaml"), "utf8")],
|
||||||
|
}).importFrom("netbird/netbird");
|
||||||
|
}
|
||||||
|
}
|
||||||
218
netbird/values.yaml
Normal file
218
netbird/values.yaml
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
fullnameOverride: netbird
|
||||||
|
management:
|
||||||
|
configmap: |-
|
||||||
|
{
|
||||||
|
"Stuns": [
|
||||||
|
{
|
||||||
|
"Proto": "udp",
|
||||||
|
"URI": "{{ .STUN_SERVER }}",
|
||||||
|
"Username": "",
|
||||||
|
"Password": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TURNConfig": {
|
||||||
|
"TimeBasedCredentials": false,
|
||||||
|
"CredentialsTTL": "12h0m0s",
|
||||||
|
"Secret": "secret",
|
||||||
|
"Turns": [
|
||||||
|
{
|
||||||
|
"Proto": "udp",
|
||||||
|
"URI": "{{ .TURN_SERVER }}",
|
||||||
|
"Username": "{{ .TURN_SERVER_USER }}",
|
||||||
|
"Password": "{{ .TURN_SERVER_PASSWORD }}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Relay": {
|
||||||
|
"Addresses": ["rels://vpn.dogar.dev:443/relay"],
|
||||||
|
"CredentialsTTL": "24h",
|
||||||
|
"Secret": "{{ .RELAY_PASSWORD }}"
|
||||||
|
},
|
||||||
|
"Signal": {
|
||||||
|
"Proto": "https",
|
||||||
|
"URI": "vpn.dogar.dev:443",
|
||||||
|
"Username": "",
|
||||||
|
"Password": ""
|
||||||
|
},
|
||||||
|
"Datadir": "/var/lib/netbird/",
|
||||||
|
"DataStoreEncryptionKey": "{{ .DATASTORE_ENCRYPTION_KEY }}",
|
||||||
|
"HttpConfig": {
|
||||||
|
"LetsEncryptDomain": "",
|
||||||
|
"CertFile": "",
|
||||||
|
"CertKey": "",
|
||||||
|
"AuthAudience": "{{ .IDP_CLIENT_ID }}",
|
||||||
|
"AuthIssuer": "https://auth.dogar.dev/application/o/netbird/",
|
||||||
|
"AuthUserIDClaim": "",
|
||||||
|
"AuthKeysLocation": "https://auth.dogar.dev/application/o/netbird/jwks/",
|
||||||
|
"OIDCConfigEndpoint": "https://auth.dogar.dev/application/o/netbird/.well-known/openid-configuration",
|
||||||
|
"IdpSignKeyRefreshEnabled": false
|
||||||
|
},
|
||||||
|
"IdpManagerConfig": {
|
||||||
|
"ManagerType": "authentik",
|
||||||
|
"ClientConfig": {
|
||||||
|
"Issuer": "https://auth.dogar.dev/application/o/netbird",
|
||||||
|
"TokenEndpoint": "https://auth.dogar.dev/application/o/token/",
|
||||||
|
"ClientID": "{{ .IDP_CLIENT_ID }}",
|
||||||
|
"ClientSecret": "",
|
||||||
|
"GrantType": "client_credentials"
|
||||||
|
},
|
||||||
|
"ExtraConfig": {
|
||||||
|
"Password": "{{ .IDP_SERVICE_ACCOUNT_PASSWORD }}",
|
||||||
|
"Username": "{{ .IDP_SERVICE_ACCOUNT_USER }}"
|
||||||
|
},
|
||||||
|
"Auth0ClientCredentials": null,
|
||||||
|
"AzureClientCredentials": null,
|
||||||
|
"KeycloakClientCredentials": null,
|
||||||
|
"ZitadelClientCredentials": null
|
||||||
|
},
|
||||||
|
"DeviceAuthorizationFlow": {
|
||||||
|
"Provider": "hosted",
|
||||||
|
"ProviderConfig": {
|
||||||
|
"ClientID": "{{ .IDP_CLIENT_ID }}",
|
||||||
|
"ClientSecret": "",
|
||||||
|
"Domain": "auth.dogar.dev",
|
||||||
|
"Audience": "{{ .IDP_CLIENT_ID }}",
|
||||||
|
"TokenEndpoint": "https://auth.dogar.dev/application/o/token/",
|
||||||
|
"DeviceAuthEndpoint": "https://auth.dogar.dev/application/o/device/",
|
||||||
|
"AuthorizationEndpoint": "",
|
||||||
|
"Scope": "openid",
|
||||||
|
"UseIDToken": false,
|
||||||
|
"RedirectURLs": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PKCEAuthorizationFlow": {
|
||||||
|
"ProviderConfig": {
|
||||||
|
"ClientID": "{{ .IDP_CLIENT_ID }}",
|
||||||
|
"ClientSecret": "",
|
||||||
|
"Domain": "",
|
||||||
|
"Audience": "{{ .IDP_CLIENT_ID }}",
|
||||||
|
"TokenEndpoint": "https://auth.dogar.dev/application/o/token/",
|
||||||
|
"DeviceAuthEndpoint": "",
|
||||||
|
"AuthorizationEndpoint": "https://auth.dogar.dev/application/o/authorize/",
|
||||||
|
"Scope": "openid profile email offline_access api",
|
||||||
|
"UseIDToken": false,
|
||||||
|
"RedirectURLs": ["http://localhost:53000"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StoreConfig": {
|
||||||
|
"Engine": "postgres"
|
||||||
|
},
|
||||||
|
"ReverseProxy": {
|
||||||
|
"TrustedHTTPProxies": null,
|
||||||
|
"TrustedHTTPProxiesCount": 0,
|
||||||
|
"TrustedPeers": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
persistentVolume:
|
||||||
|
enabled: true
|
||||||
|
storageClass: longhorn
|
||||||
|
size: 1Gi
|
||||||
|
envFromSecret:
|
||||||
|
NETBIRD_STORE_ENGINE_POSTGRES_DSN: netbird/postgresDSN
|
||||||
|
STUN_SERVER: netbird/stunServer
|
||||||
|
TURN_SERVER: netbird/turnServer
|
||||||
|
TURN_SERVER_USER: netbird/turnServerUser
|
||||||
|
TURN_SERVER_PASSWORD: netbird/turnServerPassword
|
||||||
|
RELAY_PASSWORD: netbird/relayPassword
|
||||||
|
IDP_CLIENT_ID: netbird/idpClientID
|
||||||
|
IDP_SERVICE_ACCOUNT_USER: netbird/idpServiceAccountUser
|
||||||
|
IDP_SERVICE_ACCOUNT_PASSWORD: netbird/idpServiceAccountPassword
|
||||||
|
DATASTORE_ENCRYPTION_KEY: netbird/datastoreEncryptionKey
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 3
|
||||||
|
initialDelaySeconds: 180
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
|
tcpSocket:
|
||||||
|
port: http
|
||||||
|
volumes:
|
||||||
|
- name: postgres-ssl-bundle
|
||||||
|
secret:
|
||||||
|
secretName: netbird-postgres-ssl-bundle
|
||||||
|
volumeMounts:
|
||||||
|
- name: postgres-ssl-bundle
|
||||||
|
mountPath: /etc/ssl/certs/postgres-ssl-bundle
|
||||||
|
readOnly: true
|
||||||
|
|
||||||
|
signal:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
relay:
|
||||||
|
envFromSecret:
|
||||||
|
NB_AUTH_SECRET: netbird/relayPassword
|
||||||
|
env:
|
||||||
|
NB_LOG_LEVEL: info
|
||||||
|
NB_LISTEN_ADDRESS: ":33080"
|
||||||
|
NB_EXPOSED_ADDRESS: rels://vpn.dogar.dev:443/relay
|
||||||
|
|
||||||
|
dashboard:
|
||||||
|
enabled: true
|
||||||
|
env:
|
||||||
|
# Endpoints
|
||||||
|
NETBIRD_MGMT_API_ENDPOINT: https://vpn.dogar.dev:443
|
||||||
|
NETBIRD_MGMT_GRPC_API_ENDPOINT: https://vpn.dogar.dev:443
|
||||||
|
# OIDC
|
||||||
|
AUTH_CLIENT_SECRET:
|
||||||
|
AUTH_AUTHORITY: https://auth.dogar.dev/application/o/netbird/
|
||||||
|
USE_AUTH0: false
|
||||||
|
AUTH_SUPPORTED_SCOPES: openid profile email offline_access api
|
||||||
|
AUTH_REDIRECT_URI:
|
||||||
|
AUTH_SILENT_REDIRECT_URI:
|
||||||
|
NETBIRD_TOKEN_SOURCE: accessToken
|
||||||
|
NGINX_SSL_PORT:
|
||||||
|
LETSENCRYPT_DOMAIN:
|
||||||
|
LETSENCRYPT_EMAIL:
|
||||||
|
envFromSecret:
|
||||||
|
AUTH_CLIENT_ID: netbird/idpClientID
|
||||||
|
AUTH_AUDIENCE: netbird/idpClientID
|
||||||
|
|
||||||
|
extraManifests:
|
||||||
|
- apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: netbird
|
||||||
|
namespace: netbird
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- kind: Rule
|
||||||
|
match: Host(`vpn.dogar.dev`) && !PathPrefix(`/api`) && !PathPrefix(`/management`) && !PathPrefix(`/signalexchange`) && !PathPrefix(`/relay`)
|
||||||
|
services:
|
||||||
|
- name: netbird-dashboard
|
||||||
|
namespace: netbird
|
||||||
|
passHostHeader: true
|
||||||
|
port: 80
|
||||||
|
- kind: Rule
|
||||||
|
match: Host(`vpn.dogar.dev`) && PathPrefix(`/api`)
|
||||||
|
services:
|
||||||
|
- name: netbird-management
|
||||||
|
namespace: netbird
|
||||||
|
passHostHeader: true
|
||||||
|
port: 80
|
||||||
|
- kind: Rule
|
||||||
|
match: Host(`vpn.dogar.dev`) && PathPrefix(`/relay`)
|
||||||
|
services:
|
||||||
|
- name: netbird-relay
|
||||||
|
namespace: netbird
|
||||||
|
passHostHeader: true
|
||||||
|
port: 33080
|
||||||
|
- kind: Rule
|
||||||
|
match: Host(`vpn.dogar.dev`) && PathPrefix(`/management`)
|
||||||
|
services:
|
||||||
|
- name: netbird-management
|
||||||
|
namespace: netbird
|
||||||
|
passHostHeader: true
|
||||||
|
port: 80
|
||||||
|
scheme: h2c
|
||||||
|
- kind: Rule
|
||||||
|
match: Host(`vpn.dogar.dev`) && PathPrefix(`/signalexchange`)
|
||||||
|
services:
|
||||||
|
- name: netbird-signal
|
||||||
|
namespace: netbird
|
||||||
|
passHostHeader: true
|
||||||
|
port: 80
|
||||||
|
scheme: h2c
|
||||||
|
tls:
|
||||||
|
secretName: netbird-tls
|
||||||
@@ -78,7 +78,7 @@ export class UtilityServices extends TerraformStack {
|
|||||||
name: "postgres-cluster",
|
name: "postgres-cluster",
|
||||||
namespace,
|
namespace,
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
users: ["shahab", "budget-tracker", "authentik", "gitea"],
|
users: ["shahab", "budget-tracker", "authentik", "gitea", "netbird"],
|
||||||
primaryUser: "shahab",
|
primaryUser: "shahab",
|
||||||
initSecretName: "postgres-password",
|
initSecretName: "postgres-password",
|
||||||
backupR2EndpointURL: `https://${r2Endpoint}`,
|
backupR2EndpointURL: `https://${r2Endpoint}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user