1 Commits

Author SHA1 Message Date
84a5ff6fd4 Add jupiter wireguard server
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-06-26 09:16:24 +01:00
6 changed files with 1416 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ in
(import ./traefik { inherit user home; })
(import ./vaultwarden { inherit user home; })
(import ./whoami { inherit user home; })
(import ./wireguard { inherit user home; })
];
boot.kernel.sysctl = {

View File

@@ -0,0 +1,201 @@
{
user ? throw "user argument is required",
home ? throw "home argument is required",
}:
{
config,
inputs,
system,
lib,
pkgs,
...
}:
let
selfPkgs = inputs.self.packages.${system};
inherit (config.virtualisation.quadlet) containers volumes;
wireguardPort = 51820;
in
{
networking.firewall.allowedUDPPorts = [ wireguardPort ];
boot = {
kernelModules = [ "wireguard" ];
kernel.sysctl."net.ipv4.ip_forward" = 1;
};
sops = {
secrets = {
"wireguard/server".sopsFile = ../../../../../../secrets/secrets.yaml;
"wireguard-ui/sessionSecret".sopsFile = ../../../../../../secrets/secrets.yaml;
"wireguard-ui/smtp".sopsFile = ../../../../../../secrets/secrets.yaml;
};
templates = {
wireguard-env.content = ''
SESSION_SECRET=${config.sops.placeholder."wireguard-ui/sessionSecret"}
SMTP_PASSWORD=${config.sops.placeholder."wireguard-ui/smtp"}
'';
wireguard-keypair.content = builtins.readFile (
(pkgs.formats.json { }).generate "keypair.json" {
private_key = config.sops.placeholder."wireguard/server";
public_key = "zz8jO+/rQbp2/GKuYrowcBe/LfO+zeJfEbF7/WIl+WQ=";
updated_at = "1970-01-01T00:00:00.000000000Z";
}
);
};
};
virtualisation.quadlet = {
volumes.wireguard = { };
containers.wireguard = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-wireguard-ui}";
networks = [ "host" ];
volumes = [
"${volumes.wireguard.ref}:/var/lib/wireguard-ui/db/clients"
"${config.sops.templates.wireguard-keypair.path}:/var/lib/wireguard-ui/db/server/keypair.json:ro"
];
environments =
let
publicIPs = [
"0.0.0.0/5"
"8.0.0.0/7"
"11.0.0.0/8"
"12.0.0.0/6"
"16.0.0.0/4"
"32.0.0.0/3"
"64.0.0.0/2"
"128.0.0.0/3"
"160.0.0.0/5"
"168.0.0.0/6"
"172.0.0.0/12"
"172.32.0.0/11"
"172.64.0.0/10"
"172.128.0.0/9"
"173.0.0.0/8"
"174.0.0.0/7"
"176.0.0.0/4"
"192.0.0.0/9"
"192.128.0.0/11"
"192.160.0.0/13"
"192.169.0.0/16"
"192.170.0.0/15"
"192.172.0.0/14"
"192.176.0.0/12"
"192.192.0.0/10"
"193.0.0.0/8"
"194.0.0.0/7"
"196.0.0.0/6"
"200.0.0.0/5"
"208.0.0.0/4"
"1.1.1.1/32"
];
in
{
EMAIL_FROM_ADDRESS = "jupiter@karaolidis.com";
EMAIL_FROM_NAME = "WireGuard";
SMTP_HOSTNAME = "smtp.protonmail.ch";
SMTP_PORT = "587";
SMTP_USERNAME = "jupiter@karaolidis.com";
SMTP_AUTH_TYPE = "PLAIN";
SMTP_ENCRYPTION = "STARTTLS";
DISABLE_LOGIN = "true";
WGUI_SERVER_INTERFACE_ADDRESSES = "10.252.1.1/24";
WGUI_ENDPOINT_ADDRESS = "vpn.karaolidis.com";
WGUI_CONFIG_FILE_PATH = "/etc/wireguard/wg1.conf";
WGUI_SERVER_POST_UP_SCRIPT = lib.strings.concatStringsSep "; " (
[
"ipset create wireguard-public hash:net || true"
"ipset flush wireguard-public"
]
++ builtins.map (ip: "ipset add wireguard-public ${ip}") publicIPs
++ [
"iptables -I FORWARD -i wg1 -m set --match-set wireguard-public dst -j ACCEPT"
"iptables -A FORWARD -i wg1 -j DROP"
"iptables -t nat -A POSTROUTING -s 10.252.1.0/24 -o enp2s0 -j MASQUERADE"
]
);
WGUI_SERVER_POST_DOWN_SCRIPT = lib.strings.concatStringsSep "; " [
"iptables -t nat -D POSTROUTING -s 10.252.1.0/24 -o enp2s0 -j MASQUERADE"
"iptables -D FORWARD -i wg1 -j DROP"
"iptables -D FORWARD -i wg1 -m set --match-set wireguard-public dst -j ACCEPT"
"ipset destroy wireguard-public"
];
WGUI_DEFAULT_CLIENT_ALLOWED_IPS = lib.strings.concatStringsSep "," publicIPs;
};
environmentFiles = [ config.sops.templates.wireguard-env.path ];
addCapabilities = [
"NET_RAW"
"NET_ADMIN"
];
};
serviceConfig.Sockets = [ "wireguard-ui.socket" ];
unitConfig = {
After = [
"sops-nix.service"
"wireguard-ui.socket"
];
Requires = [ "wireguard-ui.socket" ];
};
};
};
systemd.sockets.wireguard-ui = {
listenStreams = [ "/run/wireguard/wireguard-ui.sock" ];
socketConfig = {
Service = "${containers.wireguard._serviceName}.service";
SocketMode = 660;
SocketUser = "root";
SocketGroup = config.users.users.${user}.group;
};
wantedBy = [ "default.target" ];
};
home-manager.users.${user} = {
virtualisation.quadlet = {
containers = {
authelia-init.containerConfig.volumes =
let
config = (pkgs.formats.yaml { }).generate "wireguard.yaml" {
access_control.rules = [
{
domain = "vpn.karaolidis.com";
policy = "two_factor";
subject = [ "group:admins" ];
}
];
};
in
[ "${config}:/etc/authelia/conf.d/wireguard.yaml:ro" ];
traefik.containerConfig = {
volumes =
let
wireguard = (pkgs.formats.yaml { }).generate "wireguard.yaml" {
http = {
routers.wireguard = {
service = "wireguard";
rule = "Host(`vpn.karaolidis.com`)";
middlewares = "authelia@docker";
};
services.wireguard.loadBalancer.servers = [ { url = "unix:///run/wireguard/wireguard-ui.sock"; } ];
};
};
in
[
"/run/wireguard/wireguard-ui.sock:/run/wireguard/wireguard-ui.sock"
"${wireguard}:/etc/traefik/wireguard.yaml:ro"
];
exec = [ "--providers.file.filename=/etc/traefik/wireguard.yaml" ];
};
};
};
};
}

View File

@@ -35,6 +35,7 @@
docker-sish = import ./docker/sish { inherit pkgs; };
docker-traefik = import ./docker/traefik { inherit pkgs; };
docker-whoami = import ./docker/whoami { inherit pkgs; };
docker-wireguard-ui = import ./docker/wireguard-ui { inherit pkgs; };
docker-yq = import ./docker/yq { inherit pkgs; };
linux-firmware-latest = import ./linux-firmware-latest { inherit pkgs; };

View File

@@ -1,11 +1,22 @@
{ pkgs, ... }:
let
# FIXME: https://github.com/traefik/traefik/issues/4881
traefik = pkgs.traefik.overrideAttrs (oldAttrs: {
patches = oldAttrs.patches or [ ] ++ [
(builtins.fetchurl {
url = "https://github.com/traefik/traefik/commit/e877a94b2a759b93fc886cba53f5fa9bc1e973ed.patch";
sha256 = "sha256:178s4m2jnvr081slvgv48b6g4sispfwj2k7mfwskcyry1g2nbfvb";
})
];
});
in
pkgs.dockerTools.buildImage {
name = "traefik";
fromImage = import ../base { inherit pkgs; };
copyToRoot = pkgs.buildEnv {
name = "root";
paths = with pkgs; [ traefik ];
paths = [ traefik ];
pathsToLink = [ "/bin" ];
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
{ pkgs, ... }:
let
wireguard-ui = pkgs.wireguard-ui.overrideAttrs (oldAttrs: {
src = pkgs.applyPatches {
src = oldAttrs.src;
patches = [
# - Always write config on run
# - Activate with systemd sockets
# - Remove telegram
# - Automatically run wg-quick
./customization.patch
];
};
vendorHash = "sha256-ic9EUJLvU9mPmqU1mhjZozc6bQQqoR7XkhIKx1vuekA=";
});
in
pkgs.dockerTools.buildImage {
name = "wireguard-ui";
fromImage = import ../base { inherit pkgs; };
copyToRoot = pkgs.buildEnv {
name = "root";
paths =
[ wireguard-ui ]
++ (with pkgs; [
wireguard-tools
iptables
ipset
]);
pathsToLink = [ "/bin" ];
};
runAsRoot = ''
mkdir -p /etc/wireguard
'';
config = {
Entrypoint = [ "wireguard-ui" ];
ExposedPorts = {
"5000/tcp" = { };
"51820/udp" = { };
};
Volumes = {
"/var/lib/wireguard-ui/db/clients" = { };
};
WorkingDir = "/var/lib/wireguard-ui";
};
}