sync with labv2.nix + standalone flake with toDisk app
Previous history (https://git.sagar.ch/dotfiles/labv2.nix/commits/branch/master/modules/apps/vmix): - c359054 daku working! - 8de5cff fix integer overflow in vmix network lib - 9c25a66 daku on 25.05. with ollama - 385a3bf vmix enables relaxed sandbox - c363da1 restructure vmixLib into linux/windows subattrs with OS-specific customizeImage - edd4dc2 vmix: port namespace model and module improvements from conf.nix - 6666ecf vmix: add SPICE support, install virtio guest tools with SPICE agent - 46f5671 vmix: add QEMU guest agent channel for Windows VMs - e1fea34 vmix: add Win11 LTSC 2024 image, refactor VirtIO driver selection - c27ae68 vmix: make customizeImage chroot-sandboxed by default, opt-in impure - 305fbac virt customize needs chroot for now due to usr bin env things. could be fixed later - 264d30f vmix: add win10 VM on desk, disable SMB signing for guest Samba access - 9b64f51 vmix: split Windows templates into per-category files, add comprehensive debloat - ef91bf8 vmix: fix missing parent registry keys in Windows templates - f87f340 win10 VM on panda with AMD GPU + USB passthrough - 38e474f vmix: split Windows build into Audit Mode install + composable templates - a6a8db3 vmix: win11 support, remove build VNC, switch VMs to SPICE - 6cf5a21 generalize stage sets bg color, accent color and sets visual effects to performance - a84849f remove rdp template since it doesn't even work - 5245263 vmix: best performance template + generalize cleanup - ab12dd3 vmix: use CopyProfile for best performance visual effects - bce3326 vmix: CopyProfile for best performance visual effects - 2496107 vmix: add app templates (7zip, VLC, ImageGlass, Edge WebView, VC++ runtimes) - 29a6123 wip: debug default associations xml - 2a2e5f5 vmix: fix DefaultAssociations.xml cmd.exe escaping - cc6ff9d vmix: move DefaultAssociations.xml to template only - a4a78ec vmix: add removeWMP template to remove Windows Media Player - 3fe56de vmix: improved Edge removal (files, shortcuts, scheduled tasks) - a491767 vmix: fully remove Edge via post-oobe AppxPackage removal - 6ca1619 vmix: remove Edge DevToolsClient SystemApps + AppxPackage - 0c1ec35 vmix: sandboxie windows app template - 628bbd2 vmix: add Sandboxie-Plus template - f055a41 vmix: reorganize templates, add file associations, remove Paint - 34326f4 vmix: set Thorium as default browser via PS-SFTA in post-oobe - 86af258 vmix: Active Setup for default browser (all users, no post-oobe needed) - 35b8cb0 remove vnc display from thorium template - c7e0af6 vmix: fix Win11 generalize timeout + UCPD disable for URL associations - 43a1345 vmix: add Office 2024 template + Ohook activation in generalize - 03bbce0 vmix: updated office installation xml. more privacy options enabled - 790a0ee vmix: thorium installation - hide SFTA window - a0e5c18 vmix: fix office install.bat call + add privacy registry policies - 3df38ca vmix: fix Ohook activation + suppress Office theme dialog - df39ba3 vmix: remove sandboxie shortcut from desktop - 50d5972 vmix: skip Sandboxie desktop shortcut via installer flag - ee2fa0f vmix: fix win10 default browser - 938315b vmix: windows: set accent color to automatic. remove accent color from unnecessary elements - beceda8 vmix: allow ISO-only VMs without OS disk, add WinPE VM to panda Flake outputs: overlays.default, nixosModules.default, lib, apps.toDisk Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dd1fb16e1b
commit
736503d730
77 changed files with 2785 additions and 796 deletions
290
nixos/networks/config.nix
Normal file
290
nixos/networks/config.nix
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
{ config, pkgs, lib, vmixLib, ... }:
|
||||
with vmixLib.network;
|
||||
let
|
||||
vmixCfg = config.vmix;
|
||||
# creates a /30 network from available range for veth-pair wan interfaces
|
||||
mkVethIPv4Range = index: availableIPv4Range:
|
||||
let
|
||||
vethIPv4RangeLength = 30;
|
||||
in
|
||||
(calc.cidr.subnet (vethIPv4RangeLength - (calc.cidr.length availableIPv4Range)) index availableIPv4Range);
|
||||
|
||||
namespaceGlobalService = {
|
||||
"ns.net.vmix@" = {
|
||||
description = "network namespace %I for vmix";
|
||||
before = [ "network.target" ];
|
||||
path = with pkgs; [ iproute2 utillinux ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
PrivateMounts = false;
|
||||
PrivateNetwork = true;
|
||||
ExecStart = (pkgs.writeShellScript "ns.net.vmix-start" ''
|
||||
spaceName="$1.vmix"
|
||||
ip netns add $spaceName
|
||||
umount /var/run/netns/$spaceName
|
||||
mount --bind /proc/self/ns/net /var/run/netns/$spaceName
|
||||
'') + " %I";
|
||||
ExecStop = "${pkgs.iproute2}/bin/ip netns del %I.vmix";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mkLanDomainName = spaceName: lanName: lanCfg:
|
||||
if (lanCfg.domain != null) then lanCfg.domain else "${lanName}.${spaceName}.vmix";
|
||||
|
||||
mkLan = spaceName: staticRoutes: wanCfg: lanName: cfg:
|
||||
let
|
||||
lanCfg = cfg // { name = lanName; spaceName = "${spaceName}"; };
|
||||
lanInterfaceName = "brx-${lanCfg.name}";
|
||||
lanInterfaceIPAddress =
|
||||
if (lanCfg.ipv4.address != null)
|
||||
then lanCfg.ipv4.address
|
||||
else (calc.cidr.host 1 lanCfg.ipv4.range);
|
||||
netmask = calc.cidr.netmask lanCfg.ipv4.range;
|
||||
networkPrefix = builtins.elemAt (lib.splitString "/" lanCfg.ipv4.range) 1;
|
||||
|
||||
dhcpStartAddress =
|
||||
if (lanCfg.ipv4.dhcp.startAddress != null)
|
||||
then lanCfg.ipv4.dhcp.startAddress
|
||||
else (calc.cidr.host 2 lanCfg.ipv4.range);
|
||||
|
||||
dhcpEndAddress =
|
||||
if (lanCfg.ipv4.dhcp.endAddress != null)
|
||||
then lanCfg.ipv4.dhcp.endAddress
|
||||
else (calc.cidr.host ((calc.cidr.capacity lanCfg.ipv4.range) - 2) lanCfg.ipv4.range);
|
||||
|
||||
createLanInterface = ''
|
||||
ip link add ${lanInterfaceName} type bridge
|
||||
ip address add ${lanInterfaceIPAddress}/${networkPrefix} dev ${lanInterfaceName}
|
||||
ip link set ${lanInterfaceName} up
|
||||
'';
|
||||
|
||||
deleteLanInterface = ''
|
||||
ip link del ${lanInterfaceName}
|
||||
'';
|
||||
|
||||
lanDomainName = mkLanDomainName spaceName lanName lanCfg;
|
||||
|
||||
lanDnsmasqConf = ''
|
||||
# lan ${lanName}
|
||||
domain=${lanDomainName},${lanInterfaceName}
|
||||
''
|
||||
+ (lib.optionalString lanCfg.ipv4.dhcp.enable ''
|
||||
dhcp-range=${lanInterfaceName},${dhcpStartAddress},${dhcpEndAddress},${netmask},12h
|
||||
dhcp-option=${lanInterfaceName},option:classless-static-route,${lib.concatMapStringsSep "," (route: "${route},${lanInterfaceIPAddress}") ([ "0.0.0.0/0" ] ++ (builtins.filter (route: route != lanCfg.ipv4.range) staticRoutes))}
|
||||
'')
|
||||
+ (lib.optionalString (lanCfg.ipv4.dhcp.enable && (!wanCfg.dns.resolver.enable) && (lanCfg.ipv4.dhcp.dns.addresses != null) && (lanCfg.ipv4.dhcp.dns.addresses != []))
|
||||
("dhcp-option=${lanInterfaceName},option:dns-server,${(lib.concatStringsSep "," lanCfg.ipv4.dhcp.dns.addresses)}\n"));
|
||||
|
||||
staticIPsListedOnVMs = with lib; concatMapAttrs (vmName: vmCfg: optionalAttrs ((vmCfg ? networks.lans.${lanName}.ip) && (vmCfg.networks.lans.${lanName}.ip != null)) { ${vmCfg.networks.lans.${lanName}.mac} = vmCfg.networks.lans.${lanName}.ip; }) config.vmix.namespaces.${spaceName}.vms;
|
||||
in
|
||||
lanCfg // {
|
||||
createIface = createLanInterface;
|
||||
deleteIface = deleteLanInterface;
|
||||
dnsmasqConf = lanDnsmasqConf;
|
||||
staticHostsFileContents = (with lib; concatStringsSep "\n" (mapAttrsToList (mac: ipv4: "${mac},${ipv4},infinite") (lanCfg.ipv4.dhcp.statics // staticIPsListedOnVMs)));
|
||||
domain = lanDomainName;
|
||||
};
|
||||
|
||||
mkLansService = spaceName: wanCfg: lansCfg:
|
||||
let
|
||||
lansTmpDir = "/tmp/vmix/${spaceName}";
|
||||
dhcpDynamicLeaseFileForDnsmasq="${lansTmpDir}/lans.dhcp.dynamic.leases";
|
||||
dhcpStaticHostsFileForDnsmasq="${lansTmpDir}/lans.dhcp.static.hosts";
|
||||
staticRoutes = [ wanCfg.ipv4.range ] ++ (builtins.map (lanCfg: lanCfg.ipv4.range) (lib.attrValues lansCfg));
|
||||
lansList = lib.attrValues(lib.mapAttrs (mkLan spaceName staticRoutes wanCfg) lansCfg);
|
||||
dnsmasqConf = pkgs.writeText "dnsmasq-${spaceName}.conf" (''
|
||||
dhcp-host=*:*:*:*:*:*,id:*
|
||||
except-interface=lo
|
||||
dhcp-authoritative
|
||||
${lib.optionalString (!wanCfg.dns.resolver.enable) "port=0"}
|
||||
localise-queries
|
||||
no-hosts
|
||||
expand-hosts
|
||||
dhcp-leasefile=${dhcpDynamicLeaseFileForDnsmasq}
|
||||
dhcp-hostsfile=${dhcpStaticHostsFileForDnsmasq}
|
||||
filter-AAAA
|
||||
address=/host/${calc.cidr.host 1 wanCfg.ipv4.range}
|
||||
${lib.optionalString (wanCfg.dns.resolver.enable && wanCfg.dns.resolver.useHostResolvConf) "no-resolv"}
|
||||
${lib.concatMapStringsSep "\n" (nameserver: "server=${nameserver}") (lib.optionals wanCfg.dns.resolver.enable wanCfg.dns.resolver.upstream)}
|
||||
'' + (lib.concatMapStrings (lan: lan.dnsmasqConf) lansList)
|
||||
);
|
||||
|
||||
createLansInterfaces = pkgs.writeShellScript "create-lans-${spaceName}-vmix" (''
|
||||
# for dnsmasq temp files
|
||||
mkdir -m 700 -p /tmp/vmix/${spaceName}
|
||||
'' + (lib.concatMapStrings (lan: lan.createIface) lansList)
|
||||
);
|
||||
|
||||
deleteLansInterfaces = pkgs.writeShellScript "delete-lans-${spaceName}-vmix" (''
|
||||
# for dnsmasq temp files
|
||||
rm -rf /tmp/vmix/${spaceName}
|
||||
'' + lib.concatMapStrings (lan: lan.deleteIface) lansList
|
||||
);
|
||||
|
||||
staticHostsFile = pkgs.writeText "dnsmasq-${spaceName}-static-hostsfile" (lib.concatMapStringsSep "\n" (lan: lan.staticHostsFileContents) lansList);
|
||||
in
|
||||
{
|
||||
"lans.net.vmix@${spaceName}" = rec {
|
||||
bindsTo = [ "ns.net.vmix@${spaceName}.service" ];
|
||||
after = bindsTo ++ [ "lans.static-leases-hostsfile.net.vmix@${spaceName}.service" ];
|
||||
wantedBy = [ "net.vmix@${spaceName}.target" ];
|
||||
unitConfig.JoinsNamespaceOf = "ns.net.vmix@${spaceName}.service";
|
||||
path = with pkgs; [ iproute2 ];
|
||||
reloadTriggers = [ staticHostsFile ];
|
||||
serviceConfig = {
|
||||
ExecStartPre = createLansInterfaces;
|
||||
ExecStart = "${pkgs.dnsmasq}/bin/dnsmasq -d -C ${dnsmasqConf}";
|
||||
ExecReload = pkgs.writeShellScript "reload-dnsmasq" "kill -HUP $MAINPID";
|
||||
ExecStopPost = deleteLansInterfaces;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5";
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = true;
|
||||
ProtectHome = true;
|
||||
PrivateNetwork = true;
|
||||
};
|
||||
};
|
||||
|
||||
"lans.static-leases-hostsfile.net.vmix@${spaceName}" = rec {
|
||||
bindsTo = [ "ns.net.vmix@${spaceName}.service" ];
|
||||
after = bindsTo;
|
||||
requiredBy = [ "sysinit-reactivation.target" ];
|
||||
before = requiredBy;
|
||||
wantedBy = [ "net.vmix@${spaceName}.target" ];
|
||||
unitConfig.JoinsNamespaceOf = "ns.net.vmix@${spaceName}.service";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecCondition = pkgs.writeShellScript "check-if-symlink-already-present.sh" "! [ ${staticHostsFile} -ef ${dhcpStaticHostsFileForDnsmasq} ]";
|
||||
ExecStart = pkgs.writeShellScript "create-hostsfile-symlink.sh" "mkdir -m 700 -p ${lansTmpDir}; ln -sf ${staticHostsFile} ${dhcpStaticHostsFileForDnsmasq};";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5";
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = true;
|
||||
ProtectHome = true;
|
||||
PrivateNetwork = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mkWanService = spaceName: cfg:
|
||||
let
|
||||
wanCfg = cfg // { spaceName = spaceName; };
|
||||
vethInNSToHost.iface = "vhost";
|
||||
vethOnHostToNS.iface = "vn-${wanCfg.spaceName}";
|
||||
vethOnHostToNS.ipv4.address = calc.cidr.host 1 wanCfg.ipv4.range;
|
||||
vethInNSToHost.ipv4.address = calc.cidr.host 2 wanCfg.ipv4.range;
|
||||
networkPrefix = builtins.elemAt (lib.splitString "/" wanCfg.ipv4.range) 1;
|
||||
iptablesMark = builtins.toString (ipv4ToInt vethOnHostToNS.ipv4.address);
|
||||
portForwardRules = lib.concatStringsSep "\n" (lib.mapAttrsToList (hostIPnPort: nsPort: "iptables -t nat -A PREROUTING -p tcp --dport ${hostIPnPort} -j DNAT --to-destination ${vethInNSToHost.ipv4.address}:${toString nsPort}") wanCfg.forwardPorts);
|
||||
|
||||
createWanCommands = ''
|
||||
ip link add ${vethOnHostToNS.iface} type veth peer name ${vethInNSToHost.iface}
|
||||
ip link set ${vethInNSToHost.iface} netns ${wanCfg.spaceName}.vmix
|
||||
|
||||
ip address add ${vethOnHostToNS.ipv4.address}/${networkPrefix} dev ${vethOnHostToNS.iface}
|
||||
ip netns exec ${wanCfg.spaceName}.vmix ip address add ${vethInNSToHost.ipv4.address}/${networkPrefix} dev ${vethInNSToHost.iface}
|
||||
|
||||
iptables -A FORWARD -i ${vethOnHostToNS.iface} -j ACCEPT
|
||||
iptables -A FORWARD -o ${vethOnHostToNS.iface} -j ACCEPT
|
||||
${lib.optionalString (!wanCfg.host.reachable) "iptables -I INPUT 1 -i ${vethOnHostToNS.iface} -j DROP"}
|
||||
|
||||
${lib.optionalString wanCfg.masquerade "iptables -t mangle -A PREROUTING -i ${vethOnHostToNS.iface} -j MARK --set-mark ${iptablesMark}"}
|
||||
${lib.optionalString wanCfg.masquerade "iptables -t nat -A POSTROUTING -m mark --mark ${iptablesMark} -j MASQUERADE"}
|
||||
|
||||
${portForwardRules}
|
||||
|
||||
ip link set ${vethOnHostToNS.iface} up
|
||||
ip netns exec ${wanCfg.spaceName}.vmix ip link set ${vethInNSToHost.iface} up
|
||||
ip netns exec ${wanCfg.spaceName}.vmix ip r add default via ${vethOnHostToNS.ipv4.address}
|
||||
|
||||
${lib.optionalString wanCfg.host.addNSLansRoutes (lib.concatMapStrings (lanRange: "ip r add ${lanRange} via ${vethInNSToHost.ipv4.address} \n") wanCfg.lanRanges)}
|
||||
'';
|
||||
|
||||
createWan = pkgs.writeShellScript "create-wan-${wanCfg.spaceName}-vmix" createWanCommands;
|
||||
|
||||
deleteWan =
|
||||
let
|
||||
createdIptablesRules = lib.filter (line: (lib.hasPrefix "iptables" line)) (lib.splitString "\n" createWanCommands);
|
||||
delIptablesRules = builtins.map (
|
||||
rule: lib.replaceStrings [ "-I INPUT 1" "-A" ] [ "-D INPUT" "-D" ] rule
|
||||
) createdIptablesRules;
|
||||
in
|
||||
pkgs.writeShellScript "delete-wan-${wanCfg.spaceName}-vmix" (''
|
||||
ip link del ${vethOnHostToNS.iface}
|
||||
'' + (lib.concatStringsSep "\n" delIptablesRules));
|
||||
in
|
||||
{
|
||||
"wan.net.vmix@${wanCfg.spaceName}" = rec {
|
||||
bindsTo = [ "ns.net.vmix@${wanCfg.spaceName}.service" ];
|
||||
after = bindsTo;
|
||||
wantedBy = [ "net.vmix@${wanCfg.spaceName}.target" ];
|
||||
path = with pkgs; [ iproute2 iptables ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = createWan;
|
||||
ExecStop = deleteWan;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mkVmGraphicsForwardPorts = spaceName:
|
||||
let
|
||||
vms = vmixCfg.namespaces.${spaceName}.vms;
|
||||
|
||||
vmGraphicsPortMappings = lib.concatLists (lib.mapAttrsToList (vmName: vmCfg:
|
||||
(lib.optional (vmCfg.vnc.enable && vmCfg.vnc.forwardHostPort != null) {
|
||||
hostPort = toString vmCfg.vnc.forwardHostPort;
|
||||
nsPort = vmCfg.vnc.port;
|
||||
reason = "vnc";
|
||||
inherit vmName;
|
||||
})
|
||||
++ (lib.optional (vmCfg.spice.enable && vmCfg.spice.forwardHostPort != null) {
|
||||
hostPort = toString vmCfg.spice.forwardHostPort;
|
||||
nsPort = vmCfg.spice.port;
|
||||
reason = "spice";
|
||||
inherit vmName;
|
||||
})
|
||||
) vms);
|
||||
|
||||
addForwardPortMapping = acc: mapping:
|
||||
if builtins.hasAttr mapping.hostPort acc then
|
||||
throw "Duplicate vmix auto-forward host port ${mapping.hostPort} in namespace '${spaceName}' (at least '${mapping.vmName}' ${mapping.reason} conflicts with another VM mapping)."
|
||||
else
|
||||
acc // { ${mapping.hostPort} = mapping.nsPort; };
|
||||
in
|
||||
builtins.foldl' addForwardPortMapping {} vmGraphicsPortMappings;
|
||||
|
||||
mkNetworkServices = spaceName: cfg:
|
||||
let
|
||||
netCfg = cfg // { name = spaceName; };
|
||||
vethIPv4RangeForWan = mkVethIPv4Range netCfg.index vmixCfg.global.net.wan.ipv4.range;
|
||||
vmGraphicsForwardPorts = mkVmGraphicsForwardPorts spaceName;
|
||||
manualForwardPorts = netCfg.wan.forwardPorts;
|
||||
wanCfg = netCfg.wan // {
|
||||
ipv4.range = vethIPv4RangeForWan;
|
||||
lanRanges = builtins.map (lan: lan.ipv4.range) (lib.attrValues netCfg.lans);
|
||||
forwardPorts = vmGraphicsForwardPorts // manualForwardPorts;
|
||||
};
|
||||
in
|
||||
(mkLansService netCfg.name wanCfg netCfg.lans)
|
||||
// (lib.optionalAttrs wanCfg.enable (mkWanService netCfg.name wanCfg));
|
||||
|
||||
spaceNames = builtins.attrNames vmixCfg.namespaces;
|
||||
|
||||
networkServices = lib.mergeAttrsList (lib.imap0 (index: spaceName: (mkNetworkServices spaceName (vmixCfg.namespaces.${spaceName}.networks // { inherit index;}))) spaceNames);
|
||||
networkTargets = lib.mergeAttrsList (builtins.map (spaceName: {
|
||||
"net.vmix@${spaceName}" = {
|
||||
description = "Network ${spaceName} for vmix";
|
||||
bindsTo = [ "ns.net.vmix@${spaceName}.service" "lans.net.vmix@${spaceName}.service" ]
|
||||
++ lib.optionals vmixCfg.namespaces.${spaceName}.networks.wan.enable [ "wan.net.vmix@${spaceName}.service" ];
|
||||
};
|
||||
}) spaceNames);
|
||||
in
|
||||
{
|
||||
config.systemd.services = namespaceGlobalService // networkServices;
|
||||
config.systemd.targets = networkTargets;
|
||||
config.boot.kernel.sysctl."net.ipv4.ip_forward" = lib.mkDefault 1;
|
||||
}
|
||||
10
nixos/networks/default.nix
Normal file
10
nixos/networks/default.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
args@{ config, pkgs, lib, vmixLib, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.vmix.global.net.wan.ipv4.range = mkOption {
|
||||
type = types.strMatching vmixLib.network.regex.cidr4;
|
||||
default = "172.27.72.0/24"; # enough to create 64x /30 networks for veth pairs used for wan interfaces
|
||||
};
|
||||
|
||||
imports = [ (import ./config.nix args) ];
|
||||
}
|
||||
137
nixos/networks/options.nix
Normal file
137
nixos/networks/options.nix
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{ lib, vmixLib, ... }:
|
||||
with lib;
|
||||
with vmixLib.network;
|
||||
{
|
||||
macvtaps = mkOption {
|
||||
description = "Macvtap network definitions available to VMs in this namespace.";
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
uplink.iface = mkOption {
|
||||
type = types.str;
|
||||
description = "Host interface name to attach the macvtap device to.";
|
||||
};
|
||||
|
||||
uplink.namespace = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Optional network namespace where the uplink interface exists. Null means the host namespace.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
wan = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable forwarding traffic to and from the namespace to the rest of the networks on the host including the internet. (iptables FORWARD chain on the host)";
|
||||
};
|
||||
|
||||
masquerade = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Masquerade outgoing traffic using host's IP";
|
||||
};
|
||||
|
||||
host.reachable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Allow talking to the host itself from the namespace and VMs on the lan (iptables INPUT chain on the host)";
|
||||
};
|
||||
|
||||
host.addNSLansRoutes = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "add routes to the LAN on host so the vms are reachable from the host";
|
||||
};
|
||||
|
||||
# host.dns.addNSLansResolver = mkOption {
|
||||
# type = types.bool;
|
||||
# default = true;
|
||||
# };
|
||||
|
||||
dns.resolver.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Add dnsmasq's built in resolver to lan clients DHCP responses";
|
||||
};
|
||||
dns.resolver.useHostResolvConf = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Use host's resolvconf for upstreaming dns queries";
|
||||
};
|
||||
|
||||
dns.resolver.upstream = mkOption {
|
||||
type = types.listOf (types.strMatching regex.ipv4);
|
||||
default = [];
|
||||
description = "Upstream DNS servers for dnsmasq's built in resolver";
|
||||
};
|
||||
|
||||
forwardPorts = mkOption {
|
||||
type = types.attrsOf types.int;
|
||||
default = {};
|
||||
description = "Map host TCP port to namespace destination TCP port.";
|
||||
};
|
||||
};
|
||||
|
||||
lans = mkOption {
|
||||
description = "Layer-2 LAN bridge networks and DHCP settings for the namespace.";
|
||||
type = types.attrsOf (types.submodule {
|
||||
options.domain = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Domain name for the hosts of this lan.";
|
||||
};
|
||||
|
||||
options.ipv4 = {
|
||||
range = mkOption {
|
||||
type = types.strMatching regex.cidr4;
|
||||
description = "IPv4 Range in x.x.x.x/y format to be assigned to the network.";
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.nullOr (types.strMatching regex.ipv4);
|
||||
default = null;
|
||||
description = "IPv4 address to attach to the bridge interface of this Lan.";
|
||||
};
|
||||
|
||||
dhcp.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to start a DHCP server within this network.";
|
||||
};
|
||||
|
||||
dhcp.startAddress = mkOption {
|
||||
type = types.nullOr (types.strMatching regex.ipv4);
|
||||
description = "Starting IP Address for DHCP clients.";
|
||||
default = null;
|
||||
};
|
||||
|
||||
dhcp.endAddress = mkOption {
|
||||
type = types.nullOr (types.strMatching regex.ipv4);
|
||||
description = "Ending IP Address for DHCP clients.";
|
||||
default = null;
|
||||
};
|
||||
|
||||
dhcp.dns.addresses = mkOption {
|
||||
type = types.nullOr (types.listOf (types.strMatching regex.ipv4));
|
||||
description = "List of IP Addresses to pass as DNS servers in the DHCP response. These servers are only passed if dnsmasq's built in resolver is not enabled via wan.dns.resolver.enable";
|
||||
};
|
||||
|
||||
dhcp.statics = mkOption {
|
||||
description = "Static IP leases for mac addresses";
|
||||
type = types.attrsOf (types.strMatching regex.ipv4);
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# routes.internal.add = mkOption {
|
||||
# description = "Additional routes to add on the internal network";
|
||||
# };
|
||||
|
||||
# routes.host.add = mkOption {
|
||||
# description = "Addtional routes to add on the host's network namespace";
|
||||
# };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue