212 lines
5.4 KiB
Nix
212 lines
5.4 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
...
|
|
}: let
|
|
# Define the Pangolin configuration as a Nix attribute set
|
|
pangolinConfig = {
|
|
app = {
|
|
dashboard_url = "https://vpn.m3tam3re.com";
|
|
log_level = "info";
|
|
save_logs = false;
|
|
};
|
|
|
|
domains = {
|
|
vpn = {
|
|
base_domain = "m3tam3re.com";
|
|
cert_resolver = "godaddy";
|
|
prefer_wildcard_cert = false;
|
|
};
|
|
};
|
|
|
|
server = {
|
|
external_port = 3000;
|
|
internal_port = 3001;
|
|
next_port = 3002;
|
|
internal_hostname = "pangolin";
|
|
session_cookie_name = "p_session_token";
|
|
resource_access_token_param = "p_token";
|
|
resource_session_request_param = "p_session_request";
|
|
};
|
|
|
|
traefik = {
|
|
cert_resolver = "godaddy";
|
|
http_entrypoint = "web";
|
|
https_entrypoint = "websecure";
|
|
};
|
|
|
|
gerbil = {
|
|
start_port = 51820;
|
|
base_endpoint = "vpn.m3tam3re.com";
|
|
use_subdomain = false;
|
|
block_size = 24;
|
|
site_block_size = 30;
|
|
subnet_group = "100.89.137.0/20";
|
|
};
|
|
|
|
rate_limits = {
|
|
global = {
|
|
window_minutes = 1;
|
|
max_requests = 100;
|
|
};
|
|
};
|
|
|
|
email = {
|
|
smtp_host = config.age.secrets.smtp-host.path;
|
|
smtp_port = 587;
|
|
smtp_user = config.age.secrets.smtp-user.path;
|
|
smtp_pass = config.age.secrets.smtp-pass.path;
|
|
no_reply = config.age.secrets.smtp-user.path;
|
|
};
|
|
|
|
users = {
|
|
server_admin = {
|
|
email = "admin@m3tam3re.com";
|
|
password = config.age.secrets.pangolin-admin-password.path;
|
|
};
|
|
};
|
|
|
|
flags = {
|
|
require_email_verification = true;
|
|
disable_signup_without_invite = true;
|
|
disable_user_create_org = true;
|
|
allow_raw_resources = true;
|
|
allow_base_domain_resources = true;
|
|
};
|
|
};
|
|
|
|
# Convert Nix attribute set to YAML using a simpler approach
|
|
pangolinConfigYaml = pkgs.writeTextFile {
|
|
name = "config.yml";
|
|
text = lib.generators.toYAML {} pangolinConfig;
|
|
};
|
|
in {
|
|
# Define the containers
|
|
virtualisation.oci-containers.containers = {
|
|
"pangolin" = {
|
|
image = "fosrl/pangolin:1.1.0";
|
|
autoStart = true;
|
|
volumes = [
|
|
"${pangolinConfigYaml}:/app/config/config.yml:ro" # Mount the config file directly
|
|
"pangolin_config:/app/config/data" # Volume for persistent data
|
|
];
|
|
ports = [
|
|
"127.0.0.1:3020:3001" # API server
|
|
"127.0.0.1:3021:3002" # Next.js server
|
|
"127.0.0.1:3022:3000" # API/WebSocket server
|
|
];
|
|
extraOptions = ["--ip=10.89.0.20" "--network=web"];
|
|
};
|
|
|
|
"gerbil" = {
|
|
image = "fosrl/gerbil:1.0.0";
|
|
autoStart = true;
|
|
volumes = [
|
|
"pangolin_config:/var/config" # Share the volume for persistent data
|
|
];
|
|
cmd = [
|
|
"--reachableAt=http://gerbil:3003"
|
|
"--generateAndSaveKeyTo=/var/config/key"
|
|
"--remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config"
|
|
"--reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth"
|
|
];
|
|
ports = [
|
|
"51820:51820/udp" # WireGuard port
|
|
];
|
|
extraOptions = [
|
|
"--ip=10.89.0.21"
|
|
"--network=web"
|
|
"--cap-add=NET_ADMIN"
|
|
"--cap-add=SYS_MODULE"
|
|
];
|
|
};
|
|
};
|
|
|
|
# Secrets for Pangolin
|
|
# age.secrets = {
|
|
# "smtp-host" = {
|
|
# file = ../secrets/smtp-host.age;
|
|
# owner = "root";
|
|
# group = "root";
|
|
# mode = "0400";
|
|
# };
|
|
# "smtp-user" = {
|
|
# file = ../secrets/smtp-user.age;
|
|
# owner = "root";
|
|
# group = "root";
|
|
# mode = "0400";
|
|
# };
|
|
# "smtp-pass" = {
|
|
# file = ../secrets/smtp-pass.age;
|
|
# owner = "root";
|
|
# group = "root";
|
|
# mode = "0400";
|
|
# };
|
|
# "pangolin-admin-password" = {
|
|
# file = ../secrets/pangolin-admin-password.age;
|
|
# owner = "root";
|
|
# group = "root";
|
|
# mode = "0400";
|
|
# };
|
|
# };
|
|
|
|
# Traefik configuration for Pangolin
|
|
services.traefik.dynamicConfigOptions = {
|
|
http = {
|
|
# Next.js service (front-end)
|
|
services.pangolin-next-service.loadBalancer.servers = [
|
|
{url = "http://localhost:3021";}
|
|
];
|
|
|
|
# API service
|
|
services.pangolin-api-service.loadBalancer.servers = [
|
|
{url = "http://localhost:3022";}
|
|
];
|
|
|
|
# Routers
|
|
routers = {
|
|
# Next.js router (handles everything except API paths)
|
|
"pangolin-next" = {
|
|
rule = "Host(`vpn.m3tam3re.com`) && !PathPrefix(`/api/v1`)";
|
|
service = "pangolin-next-service";
|
|
entrypoints = ["websecure"];
|
|
tls = {
|
|
certResolver = "godaddy";
|
|
};
|
|
};
|
|
|
|
# API router
|
|
"pangolin-api" = {
|
|
rule = "Host(`vpn.m3tam3re.com`) && PathPrefix(`/api/v1`)";
|
|
service = "pangolin-api-service";
|
|
entrypoints = ["websecure"];
|
|
tls = {
|
|
certResolver = "godaddy";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
# Add HTTP provider to Traefik for dynamic configuration from Pangolin
|
|
services.traefik.staticConfigOptions.providers.http = {
|
|
endpoint = "http://localhost:3020/api/v1/traefik-config";
|
|
pollInterval = "5s";
|
|
};
|
|
|
|
# Add experimental section for Badger plugin
|
|
services.traefik.staticConfigOptions.experimental = {
|
|
plugins = {
|
|
#TODO create an overlay for the plugin
|
|
badger = {
|
|
moduleName = "github.com/fosrl/badger";
|
|
version = "v1.0.0";
|
|
};
|
|
};
|
|
};
|
|
|
|
# Firewall configuration for WireGuard
|
|
networking.firewall.allowedUDPPorts = [51820]; # WireGuard port
|
|
}
|