feat(deertopia): Wireguard+Mullvad

This commit is contained in:
Madeleine Sydney
2025-03-24 22:26:13 -06:00
parent fa77a26afc
commit 8081d299c1
161 changed files with 1984 additions and 3 deletions

View File

@@ -0,0 +1,84 @@
{ config, lib, pkgs, options, ... }:
# This module provides a container whose traffic is routed through Mullvad VPN.
# Other modules may configure `containers.mullvad-vpn.config` to run their
# services through the container.
let cfg = config.sydnix.deertopia.mullvad;
in {
options.sydnix.deertopia.mullvad = {
enable = lib.mkEnableOption "Mullvad VPN";
interface = lib.mkOption {
description = ''
The network interface to use. See the output of `ip addr show`.
'';
type = lib.types.str;
default = "eno1";
};
peer = lib.mkOption {
default = "us-atl-wg-001";
type = lib.types.str;
description = ''
The name of a Wireguard configuration file in
modules/nixos/deertopia/mullvad/, without the .conf suffix. Ideally, we
would support multiple peers without rebuilding, but...
'';
};
};
config = lib.mkIf cfg.enable {
sydnix.sops.secrets.wireguard-mullvad-key = {};
networking.nat = {
enable = true;
internalInterfaces = [ "ve-mullvad-vpn" ];
externalInterface = cfg.interface;
};
containers.mullvad-vpn = {
# Impermanence-esque wiping of undeclared state.
ephemeral = true;
autoStart = true;
privateNetwork = true;
enableTun = true;
# These IP choices are arbitrary.
hostAddress = "192.168.100.10";
# Counter-intuitively (IMO), the host reaches the container at *this*
# address.
localAddress = "192.168.100.11";
# Bind these directories to their corresponding paths on the host as to
# persist them through container reboots.
bindMounts = {
"/config/wg".hostPath = toString ./mullvad;
"/run/secrets".hostPath = "/run/secrets";
};
config = { pkgs, ... }@args: lib.mkMerge [
{
systemd.services."create-wireguard-config" = {
script = ''
if [ ! -e /wg.conf ]; then
cp "/config/wg/${cfg.peer}.conf" /wg.conf
${pkgs.replace-secret}/bin/replace-secret \
'{{WG_PRIVATE_KEY}}' \
/run/secrets/wireguard-mullvad-key \
/wg.conf
chmod 777 /wg.conf
fi
'';
# requiredBy = [ "wg-quick0-wg0.service" ];
requires = [ "tmp.mount" ];
};
# HACK: Make sure wg starts *after* its config exists.
systemd.services."wg-quick-wg0".requires =
[ "create-wireguard-config.service" ];
networking.wg-quick.interfaces.wg0.configFile = "/wg.conf";
system.stateVersion = "24.11";
}
];
};
};
}