mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
feat: abstractions rework
This commit is contained in:
parent
ec7571171b
commit
0a6085cb49
48 changed files with 798 additions and 1219 deletions
10
hardware/local.nix
Normal file
10
hardware/local.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{ config, lib, ... }: {
|
||||||
|
deploy.tf.resources.${config.networking.hostName} = {
|
||||||
|
provider = "null";
|
||||||
|
type = "resource";
|
||||||
|
connection = {
|
||||||
|
port = lib.head config.services.openssh.ports;
|
||||||
|
host = config.networks.gensokyo.ipv4 or config.networks.chitei.ipv4;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
12
hardware/manual.nix
Normal file
12
hardware/manual.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, lib, ... }: {
|
||||||
|
deploy.tf = {
|
||||||
|
resources.${config.networking.hostName} = {
|
||||||
|
provider = "null";
|
||||||
|
type = "resource";
|
||||||
|
connection = {
|
||||||
|
port = lib.head config.services.openssh.ports;
|
||||||
|
host = config.networks.internet.ipv4;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -68,8 +68,8 @@ in
|
||||||
${interface} = {
|
${interface} = {
|
||||||
useDHCP = true;
|
useDHCP = true;
|
||||||
ipv6 = {
|
ipv6 = {
|
||||||
addresses = lib.mkIf (config.network.addresses.public.nixos.ipv6.enable) [{
|
addresses = lib.mkIf (config.networks.internet.ipv6_defined) [{
|
||||||
address = config.network.addresses.public.nixos.ipv6.address;
|
address = config.networks.internet.ipv6;
|
||||||
prefixLength = 64;
|
prefixLength = 64;
|
||||||
}];
|
}];
|
||||||
routes = [{
|
routes = [{
|
||||||
|
|
@ -80,29 +80,29 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
networks = {
|
||||||
addresses = {
|
internet = {
|
||||||
public =
|
interfaces = lib.singleton interface;
|
||||||
let
|
ipv4 = lib.mkOrder 1000 (tf.resources.${config.networking.hostName}.getAttr "public_ip");
|
||||||
addr_ipv6_nix =
|
ipv6 = let
|
||||||
let
|
prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block"));
|
||||||
|
in assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6;
|
||||||
|
ip = hostname: class: if hostname != config.networking.hostName then
|
||||||
|
if class == 6 then let
|
||||||
prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block"));
|
prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block"));
|
||||||
in
|
in assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6
|
||||||
assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6;
|
else if class == 4 then
|
||||||
in
|
tf.resources.${config.networking.hostName}.importAttr "public_ip"
|
||||||
{
|
else throw "${config.networking.hostName}: IP for ${hostname} of ${toString class} is invalid."
|
||||||
enable = true;
|
else
|
||||||
nixos.ipv6.address = lib.mkIf tf.state.enable addr_ipv6_nix;
|
if class == 6 then let
|
||||||
nixos.ipv6.selfaddress = lib.mkIf tf.state.enable addr_ipv6_nix;
|
prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block"));
|
||||||
tf.ipv6.address = tf.resources."${config.networking.hostName}_ipv6".refAttr "ip_address";
|
in assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6
|
||||||
};
|
else if class == 4 then
|
||||||
|
tf.resources.${config.networking.hostName}.getAttr "public_ip"
|
||||||
|
else throw "${config.networking.hostName}: IP for ${hostname} of ${toString class} is invalid.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
firewall.public.interfaces = lib.singleton interface;
|
|
||||||
tf = {
|
|
||||||
enable = true;
|
|
||||||
ipv4_attr = "public_ip";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
deploy.tf =
|
deploy.tf =
|
||||||
let
|
let
|
||||||
|
|
@ -116,7 +116,6 @@ in
|
||||||
connection = tf.resources."${config.networking.hostName}".connection.set;
|
connection = tf.resources."${config.networking.hostName}".connection.set;
|
||||||
};
|
};
|
||||||
connection = {
|
connection = {
|
||||||
|
|
||||||
port = lib.head config.services.openssh.ports;
|
port = lib.head config.services.openssh.ports;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
controlPersist = "10m";
|
controlPersist = "10m";
|
||||||
hashKnownHosts = true;
|
hashKnownHosts = true;
|
||||||
compression = true;
|
compression = true;
|
||||||
|
/*TODO: revisit this
|
||||||
matchBlocks =
|
matchBlocks =
|
||||||
let
|
let
|
||||||
common = {
|
common = {
|
||||||
|
|
@ -21,6 +22,6 @@
|
||||||
(lib.foldAttrList (map
|
(lib.foldAttrList (map
|
||||||
(network:
|
(network:
|
||||||
lib.mapAttrs (_: v: { hostname = v.domain; } // common) (lib.filterAttrs (_: v: v.enable) (lib.mapAttrs (_: v: v.network.addresses.${network}) meta.network.nodes.nixos))
|
lib.mapAttrs (_: v: { hostname = v.domain; } // common) (lib.filterAttrs (_: v: v.enable) (lib.mapAttrs (_: v: v.network.addresses.${network}) meta.network.nodes.nixos))
|
||||||
) [ "private" "public" ]));
|
) [ "private" "public" ]));*/
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
meta.nix
56
meta.nix
|
|
@ -2,19 +2,38 @@
|
||||||
home = config.deploy.targets.home.tf;
|
home = config.deploy.targets.home.tf;
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
|
networks = let
|
||||||
|
meta = config;
|
||||||
|
in mkOption{
|
||||||
|
type = with types; attrsOf (submodule ({ name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
member_configs = mkOption {
|
||||||
|
type = unspecified;
|
||||||
|
};
|
||||||
|
members = mkOption {
|
||||||
|
type = unspecified;
|
||||||
|
};
|
||||||
|
};}));
|
||||||
|
};
|
||||||
tailnet_uri = mkOption {
|
tailnet_uri = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
tailnet = mkOption {
|
tailnet = mkOption {
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||||
options = {
|
options = {
|
||||||
addresses = {
|
ipv4 = mkOption {
|
||||||
ipv4 = mkOption {
|
type = types.str;
|
||||||
type = types.str;
|
};
|
||||||
};
|
ipv6 = mkOption {
|
||||||
ipv6 = mkOption {
|
type = types.str;
|
||||||
type = types.str;
|
};
|
||||||
};
|
pp = mkOption {
|
||||||
|
type = types.unspecified;
|
||||||
|
default = family: port: "http://${config."ipv${toString family}"}:${toString port}";
|
||||||
|
};
|
||||||
|
ppp = mkOption {
|
||||||
|
type = types.unspecified;
|
||||||
|
default = family: port: path: "http://${config."ipv${toString family}"}/${path}:${toString port}";
|
||||||
};
|
};
|
||||||
tags = mkOption {
|
tags = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
|
|
@ -25,20 +44,23 @@ in {
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
|
networks = let
|
||||||
|
names = [ "gensokyo" "chitei" "internet" "tailscale" ];
|
||||||
|
network_filter = network: rec {
|
||||||
|
member_configs = filterAttrs (_: nodeConfig: nodeConfig.networks.${network}.interfaces != []) config.network.nodes.nixos;
|
||||||
|
members = mapAttrs (_: nodeConfig: nodeConfig.networks.${network}) member_configs;
|
||||||
|
};
|
||||||
|
networks' = genAttrs names network_filter;
|
||||||
|
in networks';
|
||||||
|
|
||||||
tailnet_uri = "inskip.me";
|
tailnet_uri = "inskip.me";
|
||||||
tailnet = let
|
tailnet = let
|
||||||
raw = home.resources.tailnet_devices.importAttr "devices";
|
raw = home.resources.tailnet_devices.importAttr "devices";
|
||||||
devices = mapListToAttrs (elet: nameValuePair (removeSuffix ".${config.tailnet_uri}" elet.name) {
|
in mapListToAttrs (elet: nameValuePair (removeSuffix ".${config.tailnet_uri}" elet.name) {
|
||||||
tags = elet.tags;
|
tags = elet.tags;
|
||||||
addresses = let
|
ipv4 = head (filter (e: hasInfix "." e) elet.addresses);
|
||||||
addresses = elet.addresses;
|
ipv6 = head (filter (e: hasInfix ":" e) elet.addresses);
|
||||||
ipv4 = head (filter (e: hasInfix "." e) addresses);
|
|
||||||
ipv6 = head (filter (e: hasInfix ":" e) addresses);
|
|
||||||
in {
|
|
||||||
inherit ipv4 ipv6;
|
|
||||||
};
|
|
||||||
}) raw;
|
}) raw;
|
||||||
in devices;
|
|
||||||
|
|
||||||
runners = {
|
runners = {
|
||||||
lazy = {
|
lazy = {
|
||||||
|
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
{ config, nixos, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
|
||||||
options.network = {
|
|
||||||
enable = mkEnableOption "Use kat's network module?";
|
|
||||||
addresses = mkOption {
|
|
||||||
type = with types; attrsOf (submodule ({ name, ... }: {
|
|
||||||
options = {
|
|
||||||
enable = mkEnableOption "Is the system a part of the ${name} network?";
|
|
||||||
ipv4 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ipv6 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
prefix = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
out = {
|
|
||||||
identifierList = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = if config.enable then singleton config.domain ++ config.out.addressList else [ ];
|
|
||||||
};
|
|
||||||
addressList = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = if config.enable then concatMap (i: optional i.enable i.address) [ config.ipv4 config.ipv6 ] else [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
tf = {
|
|
||||||
enable = mkEnableOption "Was the system provisioned by terraform?";
|
|
||||||
ipv4_attr = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
ipv6_attr = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
dns = {
|
|
||||||
enable = mkEnableOption "Do you want DNS to be semi-managed through this module?";
|
|
||||||
isRoot = mkEnableOption "Is this system supposed to be the @ for the domain?";
|
|
||||||
email = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
zone = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
dynamic = mkEnableOption "Enable Glauca Dynamic DNS Updater";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
network.addresses = nixos.network.addresses or {};
|
|
||||||
network.tf = nixos.network.tf or {};
|
|
||||||
network.dns = nixos.network.dns or {};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -135,6 +135,7 @@ with lib;
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
meta.modules.nixos
|
meta.modules.nixos
|
||||||
meta.modules.system
|
meta.modules.system
|
||||||
|
meta.nixos.network
|
||||||
meta.system
|
meta.system
|
||||||
];
|
];
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.network.firewall;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.network.firewall = {
|
|
||||||
public.tcp.ports = mkOption {
|
|
||||||
type = types.listOf types.port;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
public.udp.ports = mkOption {
|
|
||||||
type = types.listOf types.port;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
private.tcp.ports = mkOption {
|
|
||||||
type = types.listOf types.port;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
private.udp.ports = mkOption {
|
|
||||||
type = types.listOf types.port;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
public.tcp.ranges = mkOption {
|
|
||||||
type = types.listOf (types.attrsOf types.port);
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
public.udp.ranges = mkOption {
|
|
||||||
type = types.listOf (types.attrsOf types.port);
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
private.tcp.ranges = mkOption {
|
|
||||||
type = types.listOf (types.attrsOf types.port);
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
private.udp.ranges = mkOption {
|
|
||||||
type = types.listOf (types.attrsOf types.port);
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
public.interfaces = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "Public firewall interfaces";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
private.interfaces = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "Private firewall interfaces";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
network.firewall = mkMerge (mapAttrsToList (_: user: user.network.firewall) config.home-manager.users);
|
|
||||||
networking.firewall.interfaces =
|
|
||||||
let
|
|
||||||
fwTypes = {
|
|
||||||
ports = "Ports";
|
|
||||||
ranges = "PortRanges";
|
|
||||||
};
|
|
||||||
|
|
||||||
interfaceDef = visibility:
|
|
||||||
listToAttrs (flatten (mapAttrsToList
|
|
||||||
(type: typeString:
|
|
||||||
map
|
|
||||||
(proto: {
|
|
||||||
name = "allowed${toUpper proto}${typeString}";
|
|
||||||
value = cfg.${visibility}.${proto}.${type};
|
|
||||||
}) [ "tcp" "udp" ])
|
|
||||||
fwTypes));
|
|
||||||
|
|
||||||
interfaces = visibility:
|
|
||||||
listToAttrs
|
|
||||||
(map (interface: nameValuePair interface (interfaceDef visibility))
|
|
||||||
cfg.${visibility}.interfaces);
|
|
||||||
in
|
|
||||||
mkMerge (map (visibility: interfaces visibility) [ "public" "private" ]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,257 +0,0 @@
|
||||||
{ config, lib, tf, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.network;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.network = {
|
|
||||||
enable = mkEnableOption "Use kat's network module?";
|
|
||||||
addresses = mkOption {
|
|
||||||
type = with types; attrsOf (submodule ({ name, options, config, ... }: {
|
|
||||||
options = {
|
|
||||||
enable = mkEnableOption "Is it a member of the ${name} network?";
|
|
||||||
nixos = {
|
|
||||||
ipv4 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = options.nixos.ipv4.address.isDefined;
|
|
||||||
};
|
|
||||||
selfaddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ipv6 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = options.nixos.ipv6.address.isDefined;
|
|
||||||
};
|
|
||||||
selfaddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
tf = {
|
|
||||||
ipv4 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = options.tf.ipv4.address.isDefined;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ipv6 = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = options.tf.ipv6.address.isDefined;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
prefix = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
subdomain = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "${config.subdomain}.${cfg.dns.domain}";
|
|
||||||
};
|
|
||||||
target = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "${config.domain}.";
|
|
||||||
};
|
|
||||||
out = {
|
|
||||||
identifierList = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = optionals config.enable (singleton config.domain ++ config.out.addressList);
|
|
||||||
};
|
|
||||||
addressList = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = optionals config.enable (concatMap (i: optional i.enable i.address) [ config.nixos.ipv4 config.nixos.ipv6 ]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
extraCerts = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
tf = {
|
|
||||||
enable = mkEnableOption "Was the system provisioned by terraform?";
|
|
||||||
ipv4_attr = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
ipv6_attr = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
dns = {
|
|
||||||
enable = mkEnableOption "Do you want DNS to be semi-managed through this module?";
|
|
||||||
isRoot = mkEnableOption "Is this system supposed to be the @ for the domain?";
|
|
||||||
email = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
zone = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config =
|
|
||||||
let
|
|
||||||
networks = cfg.addresses;
|
|
||||||
networksWithDomains = filterAttrs (_: v: v.enable) networks;
|
|
||||||
in
|
|
||||||
mkIf cfg.enable {
|
|
||||||
network = {
|
|
||||||
dns = {
|
|
||||||
domain = builtins.substring 0 ((builtins.stringLength cfg.dns.zone) - 1) cfg.dns.zone;
|
|
||||||
};
|
|
||||||
addresses = lib.mkMerge [
|
|
||||||
(mkIf (!cfg.tf.enable) (genAttrs [ "private" "public" "yggdrasil" ] (network: {
|
|
||||||
tf = {
|
|
||||||
ipv4.address = mkIf (cfg.addresses.${network}.nixos.ipv4.enable) cfg.addresses.${network}.nixos.ipv4.address;
|
|
||||||
ipv6.address = mkIf (cfg.addresses.${network}.nixos.ipv6.enable) cfg.addresses.${network}.nixos.ipv6.address;
|
|
||||||
};
|
|
||||||
})))
|
|
||||||
(mkIf cfg.tf.enable (genAttrs ["yggdrasil" ] (network: {
|
|
||||||
tf = {
|
|
||||||
ipv4.address = mkIf (cfg.addresses.${network}.nixos.ipv4.enable) cfg.addresses.${network}.nixos.ipv4.address;
|
|
||||||
ipv6.address = mkIf (cfg.addresses.${network}.nixos.ipv6.enable) cfg.addresses.${network}.nixos.ipv6.address;
|
|
||||||
};
|
|
||||||
})))
|
|
||||||
(mkIf cfg.tf.enable {
|
|
||||||
public = {
|
|
||||||
tf = {
|
|
||||||
ipv4.address = mkIf (cfg.tf.ipv4_attr != null) (tf.resources.${config.networking.hostName}.refAttr cfg.tf.ipv4_attr);
|
|
||||||
ipv6.address = mkIf (cfg.tf.ipv6_attr != null) (tf.resources.${config.networking.hostName}.refAttr cfg.tf.ipv6_attr);
|
|
||||||
};
|
|
||||||
nixos = {
|
|
||||||
ipv4.selfaddress = mkIf (tf.state.enable && cfg.tf.ipv4_attr != null) (tf.resources.${config.networking.hostName}.getAttr cfg.tf.ipv4_attr);
|
|
||||||
ipv6.selfaddress = mkIf (tf.state.enable && cfg.tf.ipv6_attr != null) (tf.resources.${config.networking.hostName}.getAttr cfg.tf.ipv6_attr);
|
|
||||||
ipv4.address = mkIf (tf.state.resources ? ${tf.resources.${config.networking.hostName}.out.reference} && cfg.tf.ipv4_attr != null) (tf.resources.${config.networking.hostName}.importAttr cfg.tf.ipv4_attr);
|
|
||||||
ipv6.address = mkIf (tf.state.resources ? ${tf.resources.${config.networking.hostName}.out.reference} && cfg.tf.ipv6_attr != null) (tf.resources.${config.networking.hostName}.importAttr cfg.tf.ipv6_attr);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
({
|
|
||||||
private = {
|
|
||||||
prefix = "int";
|
|
||||||
subdomain = "${config.networking.hostName}.${cfg.addresses.private.prefix}";
|
|
||||||
};
|
|
||||||
yggdrasil = {
|
|
||||||
enable = cfg.yggdrasil.enable;
|
|
||||||
prefix = "ygg";
|
|
||||||
subdomain = "${config.networking.hostName}.${cfg.addresses.yggdrasil.prefix}";
|
|
||||||
};
|
|
||||||
public = {
|
|
||||||
subdomain = config.networking.hostName;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(mkIf cfg.yggdrasil.enable {
|
|
||||||
yggdrasil.nixos.ipv6.address = cfg.yggdrasil.address;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
networking.domain = mkDefault (if cfg.addresses.public.enable then cfg.dns.domain
|
|
||||||
else if cfg.addresses.private.enable then "${cfg.addresses.private.prefix}.${cfg.dns.domain}" else "");
|
|
||||||
|
|
||||||
deploy.tf.dns.records =
|
|
||||||
let
|
|
||||||
recordsV4 = mapAttrs'
|
|
||||||
(n: v:
|
|
||||||
nameValuePair "node_${n}_${config.networking.hostName}_v4" {
|
|
||||||
inherit (v.tf.ipv4) enable;
|
|
||||||
inherit (cfg.dns) zone;
|
|
||||||
domain = v.subdomain;
|
|
||||||
a = { inherit (v.tf.ipv4) address; };
|
|
||||||
})
|
|
||||||
networksWithDomains;
|
|
||||||
recordsV6 = mapAttrs'
|
|
||||||
(n: v:
|
|
||||||
nameValuePair "node_${n}_${config.networking.hostName}_v6" {
|
|
||||||
inherit (v.tf.ipv6) enable;
|
|
||||||
inherit (cfg.dns) zone;
|
|
||||||
domain = v.subdomain;
|
|
||||||
aaaa = { inherit (v.tf.ipv6) address; };
|
|
||||||
})
|
|
||||||
networksWithDomains;
|
|
||||||
in
|
|
||||||
mkMerge (map (record: mkIf cfg.dns.enable record) [
|
|
||||||
recordsV4
|
|
||||||
recordsV6
|
|
||||||
(mkIf cfg.dns.isRoot {
|
|
||||||
"node_root_${config.networking.hostName}_v4" = {
|
|
||||||
inherit (cfg.addresses.public) enable;
|
|
||||||
inherit (cfg.dns) zone;
|
|
||||||
a = { inherit (cfg.addresses.public.tf.ipv4) address; };
|
|
||||||
};
|
|
||||||
"node_root_${config.networking.hostName}_v6" = {
|
|
||||||
inherit (cfg.addresses.public) enable;
|
|
||||||
inherit (cfg.dns) zone;
|
|
||||||
aaaa = { inherit (cfg.addresses.public.tf.ipv6) address; };
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
|
|
||||||
security.acme.certs = mkMerge (map (cert: mkIf cfg.dns.enable cert) [
|
|
||||||
(mkIf config.services.nginx.enable (mapAttrs'
|
|
||||||
(n: v:
|
|
||||||
nameValuePair "${n}_${config.networking.hostName}" {
|
|
||||||
inherit (v) domain;
|
|
||||||
dnsProvider = "rfc2136";
|
|
||||||
credentialsFile = config.secrets.files.dns_creds.path;
|
|
||||||
group = mkDefault "nginx";
|
|
||||||
})
|
|
||||||
networksWithDomains))
|
|
||||||
(mapAttrs'
|
|
||||||
(n: v:
|
|
||||||
nameValuePair "${n}" {
|
|
||||||
domain = v;
|
|
||||||
dnsProvider = "rfc2136";
|
|
||||||
credentialsFile = config.secrets.files.dns_creds.path;
|
|
||||||
group = mkDefault "nginx";
|
|
||||||
})
|
|
||||||
cfg.extraCerts)
|
|
||||||
]);
|
|
||||||
|
|
||||||
services.nginx.virtualHosts = mkMerge (map (host: mkIf cfg.dns.enable host) [
|
|
||||||
(mkIf config.services.nginx.enable (mapAttrs'
|
|
||||||
(n: v:
|
|
||||||
nameValuePair v.domain {
|
|
||||||
useACMEHost = "${n}_${config.networking.hostName}";
|
|
||||||
forceSSL = true;
|
|
||||||
})
|
|
||||||
networksWithDomains))
|
|
||||||
(mapAttrs'
|
|
||||||
(n: v:
|
|
||||||
nameValuePair v {
|
|
||||||
useACMEHost = "${n}";
|
|
||||||
forceSSL = true;
|
|
||||||
})
|
|
||||||
cfg.extraCerts)
|
|
||||||
]);
|
|
||||||
|
|
||||||
_module.args = { inherit (config.lib) kw; };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
||||||
{ config, meta, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.network.yggdrasil;
|
|
||||||
calcAddr = pubkey: lib.readFile (pkgs.runCommandNoCC "calcaddr-${pubkey}" { } ''
|
|
||||||
echo '{ SigningPublicKey: "${pubkey}" }' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -address | tr -d '\n' > $out
|
|
||||||
'').outPath;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.network.yggdrasil = {
|
|
||||||
enable = mkEnableOption "Enable the yggdrasil-based private hexnet";
|
|
||||||
pubkey = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Public key of this node";
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
#description = "Main Yggdrasil address. Set automatically";
|
|
||||||
#default = calcAddr cfg.signingPubkey;
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
trust = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = "Open Firewall completely for the network";
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
listen = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = "Allow other hosts in the network to connect directly";
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
endpoints = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "Endpoints to listen on";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
tunnel = {
|
|
||||||
localV6 = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "v6 subnets to expose";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
localV4 = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "v4 subnets to expose";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
remoteV6 = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
description = "Extra v6 subnets to route";
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
remoteV4 = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
description = "Extra v4 subnets to route";
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
extra = {
|
|
||||||
pubkeys = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
description = "Additional hosts to allow into the network. Keys won't be added to definition host.";
|
|
||||||
default = { };
|
|
||||||
example = { host = "0000000000000000000000000000000000000000000000000000000000000000"; };
|
|
||||||
};
|
|
||||||
addresses = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
internal = true;
|
|
||||||
default = mapAttrs (_: c: calcAddr c) cfg.extra.pubkeys;
|
|
||||||
};
|
|
||||||
localV6 = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "v6 subnets to expose, but not route";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
localV4 = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "v4 subnets to expose, but not route";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
extern = {
|
|
||||||
pubkeys = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
description = "Additional hosts to allow into the network. Keys won't be added to definition host.";
|
|
||||||
default = { };
|
|
||||||
example = { host = "0000000000000000000000000000000000000000000000000000000000000000"; };
|
|
||||||
};
|
|
||||||
endpoints = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "Endpoints to listen on";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
|
||||||
let
|
|
||||||
yggConfigs = filter
|
|
||||||
(
|
|
||||||
c: c.enable && (cfg.pubkey != c.pubkey)
|
|
||||||
)
|
|
||||||
(
|
|
||||||
mapAttrsToList (_: node: node.network.yggdrasil or { enable = false; pubkey = null; }) meta.network.nodes.nixos
|
|
||||||
);
|
|
||||||
pubkeys = flatten ((filter (n: n != "0000000000000000000000000000000000000000000000000000000000000000") (attrValues cfg.extern.pubkeys)) ++ (map (c: [ c.pubkey ] ++ (attrValues c.extra.pubkeys)) yggConfigs));
|
|
||||||
in
|
|
||||||
{
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = !(cfg.listen.enable && (cfg.listen.endpoints == [ ]));
|
|
||||||
message = "Specify network.yggdrasil.listen.endpoints";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.trustedInterfaces = mkIf cfg.trust [ "yggdrasil" ];
|
|
||||||
|
|
||||||
services.yggdrasil = {
|
|
||||||
enable = true;
|
|
||||||
persistentKeys = true;
|
|
||||||
config = {
|
|
||||||
AllowedPublicKeys = pubkeys;
|
|
||||||
IfName = "yggdrasil";
|
|
||||||
Listen = cfg.listen.endpoints;
|
|
||||||
Peers = lib.flatten (cfg.extern.endpoints ++ (map (c: c.listen.endpoints) (filter (c: c.listen.enable) yggConfigs)));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
system.build.yggdrasilTemplate =
|
|
||||||
let
|
|
||||||
json = builtins.toJSON {
|
|
||||||
inherit (config.services.yggdrasil.config) Peers SessionFirewall TunnelRouting;
|
|
||||||
PublicKey = "";
|
|
||||||
PrivateKey = "";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
pkgs.runCommandNoCC "yggdrasil-template.json" { }
|
|
||||||
"echo '${json}' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -normaliseconf > $out";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -2,13 +2,4 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
networking.nftables.enable = true;
|
networking.nftables.enable = true;
|
||||||
|
|
||||||
network = {
|
|
||||||
enable = true;
|
|
||||||
dns = {
|
|
||||||
enable = mkDefault true;
|
|
||||||
email = "acme@kittywit.ch";
|
|
||||||
zone = "kittywit.ch.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,11 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
network.firewall = {
|
networks = genAttrs [ "chitei" "gensokyo" ] (_: {
|
||||||
public = {
|
# Mosh
|
||||||
tcp.ports = singleton 62954;
|
tcp = [62954];
|
||||||
udp.ranges = [{
|
udp = [ [60000 61000] ];
|
||||||
from = 60000;
|
});
|
||||||
to = 61000;
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
private = {
|
|
||||||
tcp.ports = singleton 62954;
|
|
||||||
udp.ranges = [{
|
|
||||||
from = 60000;
|
|
||||||
to = 61000;
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
security.pam.services.sshd.text = mkDefault (mkAfter ''
|
security.pam.services.sshd.text = mkDefault (mkAfter ''
|
||||||
|
|
@ -39,5 +28,6 @@ with lib;
|
||||||
LogLevel VERBOSE
|
LogLevel VERBOSE
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.mosh.enable = true;
|
programs.mosh.enable = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,96 +1,334 @@
|
||||||
{ config, lib, tf, pkgs, meta, ... }: with lib; let
|
{ config, lib, tf, pkgs, meta, ... }: with lib; {
|
||||||
in {
|
options = let
|
||||||
options = with lib; {
|
nixos = config;
|
||||||
network = {
|
in {
|
||||||
routeDefault = mkOption {
|
domains = mkOption {
|
||||||
default = true;
|
default = {};
|
||||||
type = types.bool;
|
type = with types; attrsOf (submodule ({ name, config, ... }: {
|
||||||
};
|
options = {
|
||||||
|
host = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = nixos.networking.hostName;
|
||||||
|
};
|
||||||
|
network = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = "internet";
|
||||||
|
};
|
||||||
|
type = mkOption {
|
||||||
|
type = types.enum [
|
||||||
|
"ipv4"
|
||||||
|
"ipv6"
|
||||||
|
"both"
|
||||||
|
"cname"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
domain = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}";
|
||||||
|
};
|
||||||
|
dn = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = lib.removeSuffix "." config.domain;
|
||||||
|
};
|
||||||
|
prefix = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
zone = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = "kittywit.ch.";
|
||||||
|
};
|
||||||
|
target = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = if (config.type == "cname" && config.host != nixos.networking.hostName) then
|
||||||
|
meta.network.nodes.nixos.${config.host}.networks.${config.network}.target
|
||||||
|
else "${config.domain}.${config.zone}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
networks = let
|
||||||
|
nixos = config;
|
||||||
|
in mkOption {
|
||||||
|
default = { };
|
||||||
|
type = with types; attrsOf (submodule ({ name, config, options, ... }: let
|
||||||
|
portRangeModule = { config, ... }: {
|
||||||
|
options = {
|
||||||
|
from = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
};
|
||||||
|
to = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = config.from;
|
||||||
|
};
|
||||||
|
/*isRange = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = assert config.to >= config.from; config.from != config.to;
|
||||||
|
readOnly = true;
|
||||||
|
};*/
|
||||||
|
};
|
||||||
|
};
|
||||||
|
portRangeType = types.submodule portRangeModule;
|
||||||
|
convToPort = value: if isInt value
|
||||||
|
then { from = value; }
|
||||||
|
else assert length value == 2; { from = elemAt value 0; to = elemAt value 1; };
|
||||||
|
portType = coercedTo (oneOf [ int (listOf int) ]) convToPort portRangeType;
|
||||||
|
in {
|
||||||
|
options = with types; {
|
||||||
|
interfaces = mkOption {
|
||||||
|
description = "Interfaces this network operates upon.";
|
||||||
|
type = listOf str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
tcp = mkOption {
|
||||||
|
description = "Port numbers or ranges to allow TCP traffic outbound.";
|
||||||
|
type = listOf portType;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
udp = mkOption {
|
||||||
|
description = "Port numbers or ranges to allow UDP traffic outbound.";
|
||||||
|
type = listOf portType;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
ip = mkOption {
|
||||||
|
description = "The machine's IPv4 address on the network, if it has one.";
|
||||||
|
type = unspecified;
|
||||||
|
default = hostname: class: if hostname != nixos.networking.hostName then
|
||||||
|
if class == 6 then
|
||||||
|
config.ipv6
|
||||||
|
else if class == 4 then
|
||||||
|
config.ipv4
|
||||||
|
else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid."
|
||||||
|
else
|
||||||
|
if class == 6 then
|
||||||
|
config.ipv6
|
||||||
|
else if class == 4 then
|
||||||
|
config.ipv4
|
||||||
|
else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid.";
|
||||||
|
};
|
||||||
|
ipv4 = mkOption {
|
||||||
|
description = "The machine's IPv4 address on the network, if it has one.";
|
||||||
|
type = nullOr str;
|
||||||
|
};
|
||||||
|
ipv6 = mkOption {
|
||||||
|
description = "The machine's IPv6 address on the network, if it has one.";
|
||||||
|
type = nullOr str;
|
||||||
|
};
|
||||||
|
ipv4_defined = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = options.ipv4.isDefined;
|
||||||
|
};
|
||||||
|
ipv6_defined = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = options.ipv6.isDefined;
|
||||||
|
};
|
||||||
|
create_domain = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
domain = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}";
|
||||||
|
};
|
||||||
|
prefix = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
zone = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = "kittywit.ch.";
|
||||||
|
};
|
||||||
|
target = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = "${config.domain}.${config.zone}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
network.yggdrasil.extern = let
|
networks = {
|
||||||
in {
|
internet = {
|
||||||
pubkeys = {
|
create_domain = true;
|
||||||
satorin =
|
};
|
||||||
"cbadeaa973b051cf66e23dcb014ab5be59e55a1c98ef541345520868e3bcf9f7";
|
chitei = {
|
||||||
shanghai =
|
create_domain = true;
|
||||||
"5aba9ba2ac7a54ffef19dea9e39881bd977f76032db81a2c82c4674ed475c95b";
|
};
|
||||||
grimoire =
|
gensokyo = {
|
||||||
"2a1567a2848540070328c9e938c58d40f2b1a3f08982c15c7edc5dcabfde3330";
|
zone = mkDefault "gensokyo.zone.";
|
||||||
boline =
|
create_domain = true;
|
||||||
"89684441745467da0d1bf7f47dc74ec3ca65e05c72f752298ef3c22a22024d43";
|
};
|
||||||
okami =
|
tailscale = {
|
||||||
"f8fd12c6ed924048e93a7bd7dd63c2464813c9edddfef7415c4574518ecd4757";
|
interfaces = singleton "tailscale0";
|
||||||
amaterasu =
|
ipv4 = meta.tailnet.${config.networking.hostName}.ipv4 or null;
|
||||||
"ab9a4a78df124a8413c3a6576332d7739a44c036e14b7b0b4ea4558373ddda97";
|
ipv6 = meta.tailnet.${config.networking.hostName}.ipv6 or null;
|
||||||
duck-powerduck =
|
zone = "inskip.me.";
|
||||||
"9475274dcd43f0f3f397d56168efd436b0db58e58f4c068f75ab93ba3f51e405";
|
create_domain = true;
|
||||||
duck-nagoya =
|
};
|
||||||
"0000001a24b38f4341e356e7efc98dd31e259669242e0a82ba86971317b94954";
|
};
|
||||||
|
|
||||||
|
networking.domain = "inskip.me";
|
||||||
|
|
||||||
|
deploy.tf = {
|
||||||
|
dns.records = let
|
||||||
|
# Families of address to create domains for
|
||||||
|
address_families = [ "ipv4" "ipv6" ];
|
||||||
|
domains = config.domains;
|
||||||
|
# Merge the result of a map upon address_families to mapAttrs'
|
||||||
|
domains' = map (family: mapAttrs' (name: settings: let
|
||||||
|
network = if settings.host != config.networking.hostName then
|
||||||
|
meta.network.nodes.nixos.${settings.host}.networks.${settings.network}
|
||||||
|
else config.networks.${settings.network};
|
||||||
|
in nameValuePair "${settings.network}-${if settings.type == "both" || settings.type == family then family else settings.type}-${settings.domain}-${settings.zone}" ({
|
||||||
|
inherit (settings) domain zone;
|
||||||
|
enable = mkDefault false;
|
||||||
|
} // (optionalAttrs (settings.type == "cname" && family == "ipv4") {
|
||||||
|
cname = { inherit (network) target; };
|
||||||
|
enable = mkForce true;
|
||||||
|
}) // (optionalAttrs (network.ipv6_defined && family == "ipv6" && (settings.type == "both" || settings.type == family)) {
|
||||||
|
aaaa.address = network.ipv6;
|
||||||
|
enable = mkForce network.ipv6_defined;
|
||||||
|
})
|
||||||
|
// (optionalAttrs (!network.ipv4_defined && !network.ipv6_defined) {
|
||||||
|
a.address = "127.0.0.1";
|
||||||
|
enable = mkForce false;
|
||||||
|
}) // (optionalAttrs (network.ipv4_defined && family == "ipv4" && (settings.type == "both" || settings.type == family)) {
|
||||||
|
a.address = network.ipv4;
|
||||||
|
enable = mkForce network.ipv4_defined;
|
||||||
|
}))) domains) address_families;
|
||||||
|
networks = config.networks;
|
||||||
|
# Networks to actually create domains for
|
||||||
|
networks' = filterAttrs (_: settings: settings.create_domain) networks;
|
||||||
|
# Merge the result of a map upon address_families to mapAttrs'
|
||||||
|
networks'' = map (family: mapAttrs' (network: settings:
|
||||||
|
nameValuePair "${network}-${family}-${settings.domain}-${settings.zone}" ({
|
||||||
|
inherit (settings) domain zone;
|
||||||
|
} // (if family == "ipv6" then {
|
||||||
|
aaaa.address = settings.ipv6;
|
||||||
|
enable = mkForce settings.ipv6_defined;
|
||||||
|
} else {
|
||||||
|
enable = mkForce settings.ipv4_defined;
|
||||||
|
#a.address = if settings.ipv4_defined then settings.ipv4 else "127.0.0.1";
|
||||||
|
a.address = settings.ipv4;
|
||||||
|
})
|
||||||
|
)) networks') address_families;
|
||||||
|
in mkMerge (networks'' ++ domains');
|
||||||
|
|
||||||
|
acme = let
|
||||||
|
home = meta.deploy.targets.home.tf;
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
account = {
|
||||||
|
emailAddress = "kat@inskip.me";
|
||||||
|
accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem";
|
||||||
|
};
|
||||||
|
challenge = {
|
||||||
|
defaultProvider = "rfc2136";
|
||||||
|
configs.rfc2136 = {
|
||||||
|
RFC2136_NAMESERVER = tf.variables.katdns-address.ref;
|
||||||
|
RFC2136_TSIG_KEY = tf.variables.katdns-name.ref;
|
||||||
|
RFC2136_TSIG_SECRET = tf.variables.katdns-key.ref;
|
||||||
|
RFC2136_TSIG_ALGORITHM = "hmac-sha512";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
certs = let
|
||||||
|
hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks))
|
||||||
|
++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains));
|
||||||
|
in listToAttrs (map (hostname:
|
||||||
|
nameValuePair hostname {
|
||||||
|
keyType = "4096";
|
||||||
|
dnsNames = singleton hostname;
|
||||||
|
}) hostnames);
|
||||||
|
};
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
tailscale-authkey.export = true;
|
||||||
|
tailscale-apikey = {
|
||||||
|
value.shellCommand = "${meta.kw.secrets.command} secrets/tailscale -f api_key";
|
||||||
|
sensitive = true;
|
||||||
|
export = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
providers.tailscale = {
|
||||||
|
inputs = {
|
||||||
|
api_key = tf.variables.tailscale-apikey.ref;
|
||||||
|
tailnet = "inskip.me";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
resources.tailnet_key = {
|
||||||
|
provider = "tailscale";
|
||||||
|
type = "tailnet_key";
|
||||||
|
inputs = {
|
||||||
|
reusable = false;
|
||||||
|
ephemeral = false;
|
||||||
|
preauthorized = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
deploy.tf = {
|
secrets.files = let
|
||||||
variables.tailscale-apikey = {
|
hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks))
|
||||||
value.shellCommand = "${meta.kw.secrets.command} secrets/tailscale -f api_key";
|
++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains));
|
||||||
sensitive = true;
|
in listToAttrs (map (hostname:
|
||||||
export = true;
|
nameValuePair "${hostname}-cert" {
|
||||||
};
|
text = tf.acme.certs.${hostname}.out.refFullchainPem;
|
||||||
providers.tailscale = {
|
owner = "nginx";
|
||||||
inputs = {
|
group = "nginx";
|
||||||
api_key = tf.variables.tailscale-apikey.ref;
|
}) hostnames) // listToAttrs (map (hostname:
|
||||||
tailnet = "inskip.me";
|
nameValuePair "${hostname}-key" {
|
||||||
};
|
text = tf.acme.certs.${hostname}.out.refPrivateKeyPem;
|
||||||
|
owner = "nginx";
|
||||||
|
group = "nginx";
|
||||||
|
}) hostnames);
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = let
|
||||||
|
hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks))
|
||||||
|
++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains));
|
||||||
|
in listToAttrs (map (hostname:
|
||||||
|
nameValuePair hostname {
|
||||||
|
forceSSL = true;
|
||||||
|
sslCertificate = config.secrets.files."${hostname}-cert".path;
|
||||||
|
sslCertificateKey = config.secrets.files."${hostname}-key".path;
|
||||||
|
}) hostnames);
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
interfaces = mkMerge (mapAttrsToList (network: settings:
|
||||||
|
genAttrs settings.interfaces (_: { allowedTCPPortRanges = settings.tcp; allowedUDPPortRanges = settings.udp; })
|
||||||
|
) (removeAttrs config.networks ["tailscale"]));
|
||||||
|
trustedInterfaces = [ "tailscale0" ];
|
||||||
|
allowedTCPPorts = [ 5200 ];
|
||||||
|
allowedUDPPorts = [ config.services.tailscale.port ];
|
||||||
};
|
};
|
||||||
variables.tailscale-authkey.export = true;
|
|
||||||
resources.tailnet_key = {
|
|
||||||
provider = "tailscale";
|
services.tailscale.enable = true;
|
||||||
type = "tailnet_key";
|
|
||||||
inputs = {
|
systemd.services.tailscale-autoconnect = mkIf (builtins.getEnv "TF_IN_AUTOMATION" != "" || tf.state.enable) {
|
||||||
reusable = false;
|
description = "Automatic connection to Tailscale";
|
||||||
ephemeral = false;
|
|
||||||
preauthorized = true;
|
# make sure tailscale is running before trying to connect to tailscale
|
||||||
};
|
after = [ "network-pre.target" "tailscale.service" ];
|
||||||
|
wants = [ "network-pre.target" "tailscale.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
# set this service as a oneshot job
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
|
||||||
|
# have the job run this shell script
|
||||||
|
script = with pkgs; ''
|
||||||
|
# wait for tailscaled to settle
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# check if we are already authenticated to tailscale
|
||||||
|
status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)"
|
||||||
|
if [ $status = "Running" ]; then # if so, then do nothing
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# otherwise authenticate with tailscale
|
||||||
|
# to-do: --advertise-exit-node
|
||||||
|
${tailscale}/bin/tailscale up -authkey ${tf.resources.tailnet_key.getAttr "key"}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = {
|
|
||||||
trustedInterfaces = [ "tailscale0" ];
|
|
||||||
|
|
||||||
# allow the Tailscale UDP port through the firewall
|
|
||||||
allowedTCPPorts = [ 5200 ];
|
|
||||||
allowedUDPPorts = [ config.services.tailscale.port ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.tailscale.enable = true;
|
|
||||||
|
|
||||||
systemd.services.tailscale-autoconnect = mkIf (builtins.getEnv "TF_IN_AUTOMATION" != "" || tf.state.enable) {
|
|
||||||
description = "Automatic connection to Tailscale";
|
|
||||||
|
|
||||||
# make sure tailscale is running before trying to connect to tailscale
|
|
||||||
after = [ "network-pre.target" "tailscale.service" ];
|
|
||||||
wants = [ "network-pre.target" "tailscale.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
# set this service as a oneshot job
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
|
|
||||||
# have the job run this shell script
|
|
||||||
script = with pkgs; ''
|
|
||||||
# wait for tailscaled to settle
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# check if we are already authenticated to tailscale
|
|
||||||
status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)"
|
|
||||||
if [ $status = "Running" ]; then # if so, then do nothing
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# otherwise authenticate with tailscale
|
|
||||||
${tailscale}/bin/tailscale up -authkey ${tf.resources.tailnet_key.getAttr "key"}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,23 +73,9 @@ with lib;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
networks.chitei = {
|
||||||
addresses = {
|
interfaces = [ "enp0s20u1" "wlp1s0" ];
|
||||||
private = {
|
ipv4 = "192.168.1.196";
|
||||||
enable = true;
|
|
||||||
nixos = {
|
|
||||||
ipv4.address = "192.168.1.196";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Firewall
|
|
||||||
|
|
||||||
network.firewall = {
|
|
||||||
public = {
|
|
||||||
interfaces = singleton "enp0s20u1";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# State
|
# State
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,5 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network.yggdrasil = {
|
|
||||||
enable = true;
|
|
||||||
pubkey = "edb7de263e6924b8c9446123979782420e5196317bffc75e9a6ca546551252da";
|
|
||||||
address = "206:d807:a98:309f:3bc0:de7a:411d:9d95";
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "21.11";
|
system.stateVersion = "21.11";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.ssh.extraConfig = ''
|
programs.ssh.extraConfig = ''
|
||||||
Host daiyousei-build
|
Host daiyousei-build
|
||||||
HostName daiyousei.kittywit.ch
|
HostName daiyousei.kittywit.ch
|
||||||
Port 62954
|
Port 62954
|
||||||
User root
|
User root
|
||||||
|
|
@ -51,42 +51,36 @@ Host daiyousei-build
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices =
|
swapDevices = [
|
||||||
[ { device = "/dev/disk/by-uuid/0d846453-95b4-46e1-8eaf-b910b4321ef0"; }
|
{ device = "/dev/disk/by-uuid/0d846453-95b4-46e1-8eaf-b910b4321ef0"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
supportedFilesystems = [ "xfs" "zfs" ];
|
supportedFilesystems = [ "xfs" "zfs" ];
|
||||||
initrd.luks.devices."cryptroot".device = "/dev/disk/by-uuid/f0ea08b4-6af7-4d90-a2ad-edd5672a2105";
|
initrd.luks.devices."cryptroot".device = "/dev/disk/by-uuid/f0ea08b4-6af7-4d90-a2ad-edd5672a2105";
|
||||||
loader = {
|
loader = {
|
||||||
efi = {
|
efi = {
|
||||||
canTouchEfiVariables = true;
|
canTouchEfiVariables = true;
|
||||||
# assuming /boot is the mount point of the EFI partition in NixOS (as the installation section recommends).
|
efiSysMountPoint = "/boot";
|
||||||
efiSysMountPoint = "/boot";
|
};
|
||||||
};
|
grub = {
|
||||||
grub = {
|
devices = [ "nodev" ];
|
||||||
# despite what the configuration.nix manpage seems to indicate,
|
efiSupport = true;
|
||||||
# as of release 17.09, setting device to "nodev" will still call
|
enable = true;
|
||||||
# `grub-install` if efiSupport is true
|
extraEntries = ''
|
||||||
# (the devices list is not used by the EFI grub install,
|
menuentry "Windows" {
|
||||||
# but must be set to some value in order to pass an assert in grub.nix)
|
insmod part_gpt
|
||||||
devices = [ "nodev" ];
|
insmod fat
|
||||||
efiSupport = true;
|
insmod search_fs_uuid
|
||||||
enable = true;
|
insmod chain
|
||||||
# set $FS_UUID to the UUID of the EFI partition
|
search --fs-uuid --set=root DEBC-8F03
|
||||||
extraEntries = ''
|
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
|
||||||
menuentry "Windows" {
|
}
|
||||||
insmod part_gpt
|
'';
|
||||||
insmod fat
|
version = 2;
|
||||||
insmod search_fs_uuid
|
};
|
||||||
insmod chain
|
|
||||||
search --fs-uuid --set=root DEBC-8F03
|
|
||||||
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
version = 2;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -100,40 +94,14 @@ Host daiyousei-build
|
||||||
networking = {
|
networking = {
|
||||||
hostId = "dddbb888";
|
hostId = "dddbb888";
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
/* wireless = {
|
|
||||||
enable = true;
|
|
||||||
userControlled.enable = true;
|
|
||||||
interfaces = singleton "wlp3s0";
|
|
||||||
};
|
|
||||||
interfaces = {
|
|
||||||
wlp3s0.ipv4.addresses = singleton {
|
|
||||||
inherit (config.network.addresses.private.nixos.ipv4) address;
|
|
||||||
prefixLength = 24;
|
|
||||||
};
|
|
||||||
}; */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.fstrim.enable = true;
|
services.fstrim.enable = true;
|
||||||
|
|
||||||
network = {
|
networks = {
|
||||||
addresses = {
|
gensokyo = {
|
||||||
private = {
|
interfaces = [ "enp1s0" "wlp3s0" ];
|
||||||
enable = true;
|
ipv4 = "10.1.1.65";
|
||||||
nixos = {
|
|
||||||
ipv4.address = "192.168.1.121";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
yggdrasil = {
|
|
||||||
enable = true;
|
|
||||||
pubkey = "f94d49458822a73d70306b249a39d4de8a292b13e12339b21010001133417be7";
|
|
||||||
address = "200:d65:6d74:efba:b185:1f9f:29b6:cb8c";
|
|
||||||
listen.enable = false;
|
|
||||||
listen.endpoints = [ "tcp://0.0.0.0:0" ];
|
|
||||||
};
|
|
||||||
firewall = {
|
|
||||||
public.interfaces = [ "enp1s0" "wlp3s0" ];
|
|
||||||
private.interfaces = singleton "yggdrasil";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,13 @@
|
||||||
{ config, lib, pkgs, modulesPath, tf, meta, ... }: with lib; {
|
{ config, lib, pkgs, modulesPath, tf, meta, ... }: with lib; {
|
||||||
imports = with meta; [
|
imports = with meta; [
|
||||||
(modulesPath + "/profiles/qemu-guest.nix")
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
hardware.manual
|
||||||
nixos.network
|
nixos.network
|
||||||
services.nginx
|
services.nginx
|
||||||
services.access
|
services.access
|
||||||
services.irlsite
|
services.irlsite
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
deploy.tf = {
|
|
||||||
resources.marisa = {
|
|
||||||
provider = "null";
|
|
||||||
type = "resource";
|
|
||||||
connection = {
|
|
||||||
port = head config.services.openssh.ports;
|
|
||||||
host = config.network.addresses.public.nixos.ipv4.address;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
loader.grub = {
|
loader.grub = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
@ -45,43 +34,29 @@
|
||||||
interfaces.ens3 = {
|
interfaces.ens3 = {
|
||||||
ipv4.addresses = [
|
ipv4.addresses = [
|
||||||
{
|
{
|
||||||
inherit (config.network.addresses.public.nixos.ipv4) address;
|
address = config.networks.internet.ipv4;
|
||||||
prefixLength = 24;
|
prefixLength = 24;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
ipv6.addresses = [
|
ipv6.addresses = [
|
||||||
{
|
{
|
||||||
inherit (config.network.addresses.public.nixos.ipv6) address;
|
address = config.networks.internet.ipv6;
|
||||||
prefixLength = 48;
|
prefixLength = 48;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
networks = {
|
||||||
addresses.public = {
|
internet = {
|
||||||
enable = true;
|
ipv4 = "104.244.72.5";
|
||||||
nixos.ipv4.address = "104.244.72.5";
|
ipv6 = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0";
|
||||||
nixos.ipv6.address = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0";
|
interfaces = singleton "ens3";
|
||||||
};
|
tcp = [ 1935 52969 ];
|
||||||
yggdrasil = {
|
|
||||||
enable = true;
|
|
||||||
pubkey = "2134779f3e19e7df46113a814e9a87097839b9d557ebe3856423e148abcfe582";
|
|
||||||
address = "202:f65c:4306:f30:c105:cf76:2bf5:8b2b";
|
|
||||||
listen.enable = true;
|
|
||||||
listen.endpoints = [ "tcp://${config.network.addresses.public.nixos.ipv4.address}:52969" "tcp://[${config.network.addresses.public.nixos.ipv6.address}]:52969" ];
|
|
||||||
};
|
|
||||||
firewall = {
|
|
||||||
public = {
|
|
||||||
interfaces = singleton "ens3";
|
|
||||||
tcp.ports = [ 1935 52969 ];
|
|
||||||
};
|
|
||||||
private.interfaces = singleton "yggdrasil";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
fileSystems."/" ={
|
|
||||||
device = "/dev/disk/by-uuid/6ed3e886-d390-433f-90ac-2b37aed9f15f";
|
device = "/dev/disk/by-uuid/6ed3e886-d390-433f-90ac-2b37aed9f15f";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,13 @@ with lib;
|
||||||
|
|
||||||
imports = with meta; [
|
imports = with meta; [
|
||||||
hardware.eeepc-1015pem
|
hardware.eeepc-1015pem
|
||||||
|
hardware.local
|
||||||
nixos.network
|
nixos.network
|
||||||
nixos.arc
|
nixos.arc
|
||||||
services.kattv
|
services.kattv
|
||||||
services.dnscrypt-proxy
|
services.dnscrypt-proxy
|
||||||
];
|
];
|
||||||
|
|
||||||
# Terraform
|
|
||||||
|
|
||||||
deploy.tf = {
|
|
||||||
resources.ran = {
|
|
||||||
provider = "null";
|
|
||||||
type = "resource";
|
|
||||||
connection = {
|
|
||||||
port = head config.services.openssh.ports;
|
|
||||||
host = config.network.addresses.private.nixos.ipv4.address;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# File Systems and Swap
|
# File Systems and Swap
|
||||||
|
|
||||||
fileSystems = {
|
fileSystems = {
|
||||||
|
|
@ -57,23 +45,9 @@ with lib;
|
||||||
interfaces.enp1s0.useDHCP = true;
|
interfaces.enp1s0.useDHCP = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
networks.chitei = {
|
||||||
addresses = {
|
interfaces = [ "enp1s0" ];
|
||||||
private = {
|
ipv4 = "192.168.1.215";
|
||||||
enable = true;
|
|
||||||
nixos = {
|
|
||||||
ipv4.address = "192.168.1.215";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Firewall
|
|
||||||
|
|
||||||
network.firewall = {
|
|
||||||
public = {
|
|
||||||
interfaces = singleton "enp1s0";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# State
|
# State
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,5 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
|
||||||
yggdrasil = {
|
|
||||||
enable = true;
|
|
||||||
pubkey = "fc64ee574072ef7420ff98bc53856f881025de252081e661a78e04ebcf7c6b35";
|
|
||||||
address = "200:736:2351:7f1a:2117:be00:ce87:58f5";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "21.11";
|
system.stateVersion = "21.11";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,22 @@
|
||||||
{ config, lib, tf, ... }: {
|
{ config, lib, tf, ... }: {
|
||||||
|
# MDNS
|
||||||
|
services.avahi.enable = true;
|
||||||
|
|
||||||
|
networks.gensokyo = {
|
||||||
|
tcp = [
|
||||||
|
# Home Assistant
|
||||||
|
8123
|
||||||
|
# Tewi Homekit
|
||||||
|
21063
|
||||||
|
];
|
||||||
|
udp = [
|
||||||
|
# Chromecast
|
||||||
|
[ 32768 60999 ]
|
||||||
|
# MDNS
|
||||||
|
5353
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
kw.secrets.variables.ha-integration = {
|
kw.secrets.variables.ha-integration = {
|
||||||
path = "secrets/home-assistant";
|
path = "secrets/home-assistant";
|
||||||
field = "notes";
|
field = "notes";
|
||||||
|
|
@ -14,31 +32,12 @@
|
||||||
preStart = lib.mkBefore ''
|
preStart = lib.mkBefore ''
|
||||||
rm ${config.services.home-assistant.configDir}/integration.json
|
rm ${config.services.home-assistant.configDir}/integration.json
|
||||||
cp --no-preserve=mode ${config.secrets.files.ha-integration.path} ${config.services.home-assistant.configDir}/integration.json
|
cp --no-preserve=mode ${config.secrets.files.ha-integration.path} ${config.services.home-assistant.configDir}/integration.json
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
services.home-assistant = {
|
services.home-assistant = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
default_config = {};
|
|
||||||
google_assistant = {
|
|
||||||
project_id = "gensokyo-5cfaf";
|
|
||||||
service_account = "!include integration.json";
|
|
||||||
};
|
|
||||||
http = {
|
|
||||||
cors_allowed_origins = [
|
|
||||||
"https://google.com"
|
|
||||||
"https://www.home-assistant.io"
|
|
||||||
];
|
|
||||||
use_x_forwarded_for = "true";
|
|
||||||
trusted_proxies = [
|
|
||||||
"127.0.0.0/24"
|
|
||||||
"200::/7"
|
|
||||||
"100.64.0.0/10"
|
|
||||||
"fd7a:115c:a1e0:ab12::/64"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
homeassistant = {
|
homeassistant = {
|
||||||
name = "Gensokyo";
|
name = "Gensokyo";
|
||||||
unit_system = "metric";
|
unit_system = "metric";
|
||||||
|
|
@ -47,18 +46,94 @@
|
||||||
logger = {
|
logger = {
|
||||||
default = "info";
|
default = "info";
|
||||||
};
|
};
|
||||||
|
http = {
|
||||||
|
cors_allowed_origins = [
|
||||||
|
"https://google.com"
|
||||||
|
"https://www.home-assistant.io"
|
||||||
|
];
|
||||||
|
use_x_forwarded_for = "true";
|
||||||
|
trusted_proxies = [
|
||||||
|
"127.0.0.0/24"
|
||||||
|
"200::/7"
|
||||||
|
"100.64.0.0/10"
|
||||||
|
"fd7a:115c:a1e0:ab12::/64"
|
||||||
|
];
|
||||||
|
};
|
||||||
recorder = {
|
recorder = {
|
||||||
db_url = "postgresql://@/hass";
|
db_url = "postgresql://@/hass";
|
||||||
|
auto_purge = true;
|
||||||
|
purge_keep_days = 14;
|
||||||
|
commit_interval = 1;
|
||||||
|
exclude = {
|
||||||
|
domains = [
|
||||||
|
"automation"
|
||||||
|
"updater"
|
||||||
|
];
|
||||||
|
entity_globs = [
|
||||||
|
"sensor.weather_*"
|
||||||
|
"sensor.date_*"
|
||||||
|
];
|
||||||
|
entities = [
|
||||||
|
"sun.sun"
|
||||||
|
"sensor.last_boot"
|
||||||
|
"sensor.date"
|
||||||
|
"sensor.time"
|
||||||
|
];
|
||||||
|
event_types = [
|
||||||
|
"call_service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
google_assistant = {
|
||||||
|
project_id = "gensokyo-5cfaf";
|
||||||
|
service_account = "!include integration.json";
|
||||||
};
|
};
|
||||||
homekit = {
|
homekit = {
|
||||||
name = "Tewi";
|
name = "Tewi";
|
||||||
port = 21063;
|
port = 21063;
|
||||||
ip_address = "10.1.1.38";
|
ip_address = "10.1.1.38";
|
||||||
};
|
};
|
||||||
|
tts = [{
|
||||||
|
platform = "google_translate";
|
||||||
|
service_name = "google_say";
|
||||||
|
}];
|
||||||
|
automation = {};
|
||||||
|
counter = {};
|
||||||
|
device_tracker = {};
|
||||||
|
energy = {};
|
||||||
|
frontend = {};
|
||||||
|
group = {};
|
||||||
|
history = {};
|
||||||
|
image = {};
|
||||||
|
input_boolean = {};
|
||||||
|
input_datetime = {};
|
||||||
|
input_number = {};
|
||||||
|
input_select = {};
|
||||||
|
input_text = {};
|
||||||
|
logbook = {};
|
||||||
|
map = {};
|
||||||
|
media_source = {};
|
||||||
|
mobile_app = {};
|
||||||
|
my = {};
|
||||||
|
person = {};
|
||||||
|
scene = {};
|
||||||
|
script = {};
|
||||||
|
ssdp = {};
|
||||||
|
switch = {};
|
||||||
|
stream = {};
|
||||||
|
sun = {};
|
||||||
|
system_health = {};
|
||||||
|
tag = {};
|
||||||
|
template = {};
|
||||||
|
timer = {};
|
||||||
|
webhook = {};
|
||||||
|
wake_on_lan = {};
|
||||||
|
zeroconf = {};
|
||||||
|
zone = {};
|
||||||
};
|
};
|
||||||
extraPackages = python3Packages: with python3Packages; [
|
extraPackages = python3Packages: with python3Packages; [
|
||||||
psycopg2
|
psycopg2
|
||||||
|
aiohomekit
|
||||||
securetar
|
securetar
|
||||||
];
|
];
|
||||||
extraComponents = [
|
extraComponents = [
|
||||||
|
|
@ -80,4 +155,4 @@
|
||||||
"zeroconf"
|
"zeroconf"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
{ config, lib, tf, ... }: {
|
{ config, lib, tf, ... }: {
|
||||||
|
networks.gensokyo = {
|
||||||
|
tcp = [
|
||||||
|
# Mosquitto
|
||||||
|
1883
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
kw.secrets.variables.z2m-pass = {
|
kw.secrets.variables.z2m-pass = {
|
||||||
path = "secrets/mosquitto";
|
path = "secrets/mosquitto";
|
||||||
field = "z2m";
|
field = "z2m";
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
network.firewall = {
|
networks.gensokyo = {
|
||||||
public.tcp.ports = [ 443 80 ];
|
tcp = [
|
||||||
private.tcp.ports = [ 443 80 ];
|
443
|
||||||
|
80
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
|
|
@ -36,34 +38,12 @@ with lib;
|
||||||
#proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
#proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||||
'';
|
'';
|
||||||
clientMaxBodySize = "512m";
|
clientMaxBodySize = "512m";
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"gensokyo.zone" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations."/" = {
|
|
||||||
root = pkgs.gensokyoZone;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"home.${config.network.dns.domain}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:8123";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
security.acme = {
|
security.acme = {
|
||||||
defaults.email = config.network.dns.email;
|
defaults.email = config.network.dns.email;
|
||||||
#email = config.network.dns.email;
|
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,21 @@
|
||||||
{
|
{
|
||||||
imports = with meta; [
|
imports = with meta; [
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
hardware.local
|
||||||
nixos.network
|
nixos.network
|
||||||
./home-assistant.nix
|
./home-assistant.nix
|
||||||
./zigbee2mqtt.nix
|
./zigbee2mqtt.nix
|
||||||
./mosquitto.nix
|
./mosquitto.nix
|
||||||
./postgres.nix
|
./postgres.nix
|
||||||
|
./nginx.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
deploy.tf = {
|
networks = {
|
||||||
resources.tewi = {
|
gensokyo = {
|
||||||
provider = "null";
|
interfaces = [
|
||||||
type = "resource";
|
"eno1"
|
||||||
connection = {
|
];
|
||||||
port = lib.head config.services.openssh.ports;
|
ipv4 = "10.1.1.38";
|
||||||
host = config.network.addresses.private.nixos.ipv4.address;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -30,20 +30,6 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
|
||||||
firewall = {
|
|
||||||
public.interfaces = lib.singleton "eno1";
|
|
||||||
};
|
|
||||||
addresses = {
|
|
||||||
private = {
|
|
||||||
enable = true;
|
|
||||||
nixos = {
|
|
||||||
ipv4.address = "10.1.1.38";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
loader = {
|
loader = {
|
||||||
systemd-boot = {
|
systemd-boot = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,33 @@
|
||||||
{ config, lib, tf, ... }: {
|
{ config, lib, tf, ... }: {
|
||||||
|
networks.gensokyo = {
|
||||||
|
tcp = [
|
||||||
|
# Zigbee2MQTT Frontend
|
||||||
|
8072
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
kw.secrets.variables.z2m-mqtt-password = {
|
||||||
|
path = "secrets/mosquitto";
|
||||||
|
field = "z2m";
|
||||||
|
};
|
||||||
|
|
||||||
|
kw.secrets.variables.z2m-network-key = {
|
||||||
|
path = "secrets/zigbee2mqtt";
|
||||||
|
field = "password";
|
||||||
|
};
|
||||||
|
|
||||||
|
secrets.files.zigbee2mqtt-config = {
|
||||||
|
text = builtins.toJSON config.services.zigbee2mqtt.settings;
|
||||||
|
owner = "zigbee2mqtt";
|
||||||
|
group = "zigbee2mqtt";
|
||||||
|
};
|
||||||
|
|
||||||
|
secrets.files.zigbee2mqtt-secret = {
|
||||||
|
text = "network_key: ${tf.variables.z2m-network-key.ref}";
|
||||||
|
owner = "zigbee2mqtt";
|
||||||
|
group = "zigbee2mqtt";
|
||||||
|
};
|
||||||
|
|
||||||
services.zigbee2mqtt = {
|
services.zigbee2mqtt = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
|
|
@ -23,33 +52,8 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
kw.secrets.variables.z2m-mqtt-password = {
|
|
||||||
path = "secrets/mosquitto";
|
|
||||||
field = "z2m";
|
|
||||||
};
|
|
||||||
|
|
||||||
kw.secrets.variables.z2m-network-key = {
|
|
||||||
path = "secrets/zigbee2mqtt";
|
|
||||||
field = "password";
|
|
||||||
};
|
|
||||||
|
|
||||||
secrets.files.zigbee2mqtt-config = {
|
|
||||||
text = builtins.toJSON config.services.zigbee2mqtt.settings;
|
|
||||||
owner = "zigbee2mqtt";
|
|
||||||
group = "zigbee2mqtt";
|
|
||||||
};
|
|
||||||
|
|
||||||
secrets.files.zigbee2mqtt-secret = {
|
|
||||||
text = "network_key: ${tf.variables.z2m-network-key.ref}";
|
|
||||||
owner = "zigbee2mqtt";
|
|
||||||
group = "zigbee2mqtt";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.zigbee2mqtt.preStart = let cfg = config.services.zigbee2mqtt; in lib.mkForce ''
|
systemd.services.zigbee2mqtt.preStart = let cfg = config.services.zigbee2mqtt; in lib.mkForce ''
|
||||||
cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-config.path} "${cfg.dataDir}/configuration.yaml"
|
cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-config.path} "${cfg.dataDir}/configuration.yaml"
|
||||||
cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-secret.path} "${cfg.dataDir}/secret.yaml"
|
cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-secret.path} "${cfg.dataDir}/secret.yaml"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
network.firewall.public.tcp.ports = [ 8123 8072 1883 21064 21063 ];
|
|
||||||
network.firewall.private.tcp.ports = [ 8123 ];
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,26 +93,9 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
networks.chitei = {
|
||||||
addresses = {
|
interfaces = [ "eno1" ];
|
||||||
private = {
|
ipv4 = "100.98.152.108";
|
||||||
enable = true;
|
|
||||||
nixos = {
|
|
||||||
ipv4.address = "100.98.152.108";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
yggdrasil = {
|
|
||||||
enable = true;
|
|
||||||
pubkey = "4f8fb0817afcd6211fb6a2cac2893df7d3f12c5c99eed106718d7223468473b2";
|
|
||||||
address = "201:c1c1:3dfa:140c:a77b:8125:74d4:f5db";
|
|
||||||
listen.enable = false;
|
|
||||||
listen.endpoints = [ "tcp://0.0.0.0:0" ];
|
|
||||||
};
|
|
||||||
firewall = {
|
|
||||||
private.interfaces = singleton "yggdrasil";
|
|
||||||
public.interfaces = singleton "eno1";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = "21.05";
|
system.stateVersion = "21.05";
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@
|
||||||
pulseaudio
|
pulseaudio
|
||||||
wireplumber
|
wireplumber
|
||||||
alsa
|
alsa
|
||||||
yggdrasil
|
|
||||||
bindings
|
bindings
|
||||||
matrix-appservices
|
matrix-appservices
|
||||||
matrix-synapse-appservices
|
matrix-synapse-appservices
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,50 @@
|
||||||
{ config, lib, meta, pkgs, ... }: with lib; {
|
{ config, lib, meta, pkgs, ... }: with lib; {
|
||||||
deploy.tf.dns.records.services_plex = {
|
domains = {
|
||||||
inherit (config.network.dns) zone;
|
kittywitch-plex = {
|
||||||
domain = "plex";
|
network = "internet";
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
type = "cname";
|
||||||
};
|
domain = "plex";
|
||||||
|
};
|
||||||
deploy.tf.dns.records.services_cloud = {
|
kittywitch-home = {
|
||||||
inherit (config.network.dns) zone;
|
network = "internet";
|
||||||
domain = "cloud";
|
type = "cname";
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
domain = "home";
|
||||||
};
|
};
|
||||||
|
kittywitch-cloud = {
|
||||||
deploy.tf.dns.records.services_home = {
|
network = "internet";
|
||||||
inherit (config.network.dns) zone;
|
type = "cname";
|
||||||
domain = "home";
|
domain = "cloud";
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
};
|
||||||
};
|
gensokyo-root = {
|
||||||
|
network = "internet";
|
||||||
deploy.tf.dns.records.gensokyo_home = {
|
type = "both";
|
||||||
zone = "gensokyo.zone.";
|
zone = "gensokyo.zone.";
|
||||||
domain = "home";
|
};
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
gensokyo-home = {
|
||||||
};
|
network = "internet";
|
||||||
|
type = "cname";
|
||||||
deploy.tf.dns.records.gensokyo_root_v4 = {
|
domain = "home";
|
||||||
zone = "gensokyo.zone.";
|
zone = "gensokyo.zone.";
|
||||||
a = { inherit (config.network.addresses.public.tf.ipv4) address; };
|
};
|
||||||
};
|
gensokyo-z2m = {
|
||||||
|
network = "internet";
|
||||||
deploy.tf.dns.records.gensokyo_root_v6 = {
|
type = "cname";
|
||||||
zone = "gensokyo.zone.";
|
domain = "z2m";
|
||||||
aaaa = { inherit (config.network.addresses.public.tf.ipv6) address; };
|
zone = "gensokyo.zone.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts = mkMerge [
|
services.nginx.virtualHosts = mkMerge [
|
||||||
{
|
{
|
||||||
"gensokyo.zone" = {
|
"gensokyo.zone" = {
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
root = pkgs.gensokyoZone;
|
root = pkgs.gensokyoZone;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"home.gensokyo.zone" = {
|
"home.gensokyo.zone" = {
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://${meta.tailnet.tewi.addresses.ipv4}:8123";
|
proxyPass = meta.tailnet.tewi.pp 4 8123;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
@ -56,52 +53,46 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"home.${config.network.dns.domain}" = {
|
"home.${config.networking.domain}" = {
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://yukari.ygg.kittywit.ch:8123";
|
proxyPass = meta.tailnet.yukari.pp 4 8123;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"cloud.${config.network.dns.domain}" = {
|
"cloud.${config.networking.domain}" = {
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
locations = {
|
||||||
"/".proxyPass = "http://cloud.int.kittywit.ch/";
|
"/".proxyPass = meta.tailnet.yukari.ppp 4 80 "nextcloud/";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"plex.${config.network.dns.domain}" = {
|
"plex.${config.networking.domain}" = {
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://[${meta.network.nodes.nixos.yukari.network.addresses.yggdrasil.nixos.ipv6.address}]";
|
proxyPass = meta.tailnet.yukari.pp 4 32400;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
|
proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
|
||||||
proxy_set_header X-Plex-Device $http_x_plex_device;
|
proxy_set_header X-Plex-Device $http_x_plex_device;
|
||||||
proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
|
proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
|
||||||
proxy_set_header X-Plex-Platform $http_x_plex_platform;
|
proxy_set_header X-Plex-Platform $http_x_plex_platform;
|
||||||
proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
|
proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
|
||||||
proxy_set_header X-Plex-Product $http_x_plex_product;
|
proxy_set_header X-Plex-Product $http_x_plex_product;
|
||||||
proxy_set_header X-Plex-Token $http_x_plex_token;
|
proxy_set_header X-Plex-Token $http_x_plex_token;
|
||||||
proxy_set_header X-Plex-Version $http_x_plex_version;
|
proxy_set_header X-Plex-Version $http_x_plex_version;
|
||||||
proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
|
proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
|
||||||
proxy_set_header X-Plex-Provides $http_x_plex_provides;
|
proxy_set_header X-Plex-Provides $http_x_plex_provides;
|
||||||
proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
|
proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
|
||||||
proxy_set_header X-Plex-Model $http_x_plex_model;
|
proxy_set_header X-Plex-Model $http_x_plex_model;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,5 @@
|
||||||
cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-secret.path} "${cfg.dataDir}/secret.yaml"
|
cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-secret.path} "${cfg.dataDir}/secret.yaml"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
network.firewall.public.tcp.ports = [ 8123 8072 1883 ];
|
networks.chitei.tcp = [ 8123 8072 1883 ];
|
||||||
network.firewall.private.tcp.ports = [ 8123 ];
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
{ config, tf, meta, lib, ... }: with lib; {
|
{ config, tf, meta, lib, ... }: with lib; {
|
||||||
dns.zones."inskip.me." = {
|
|
||||||
provider = "dns.katdns";
|
|
||||||
};
|
|
||||||
|
|
||||||
resources.gmail-mx = let
|
resources.gmail-mx = let
|
||||||
zone = config.dns.zones."inskip.me.";
|
zone = config.dns.zones."inskip.me.";
|
||||||
in with zone; {
|
in with zone; {
|
||||||
|
|
@ -25,11 +21,11 @@
|
||||||
dns.records = {
|
dns.records = {
|
||||||
services_inskip_a = {
|
services_inskip_a = {
|
||||||
zone = "inskip.me.";
|
zone = "inskip.me.";
|
||||||
a.address = meta.network.nodes.nixos.marisa.network.addresses.public.nixos.ipv4.address;
|
a.address = meta.networks.internet.members.marisa.ipv4;
|
||||||
};
|
};
|
||||||
services_inskip_aaaa = {
|
services_inskip_aaaa = {
|
||||||
zone = "inskip.me.";
|
zone = "inskip.me.";
|
||||||
aaaa.address = meta.network.nodes.nixos.marisa.network.addresses.public.nixos.ipv6.address;
|
aaaa.address = meta.networks.internet.members.marisa.ipv6;
|
||||||
};
|
};
|
||||||
services_gmail_spf = {
|
services_gmail_spf = {
|
||||||
zone = "inskip.me.";
|
zone = "inskip.me.";
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ let
|
||||||
{
|
{
|
||||||
element.tcpserversink = {
|
element.tcpserversink = {
|
||||||
port = 8989;
|
port = 8989;
|
||||||
host = config.network.addresses.yggdrasil.nixos.ipv6.address;
|
host = config.networks.tailscale.ipv4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ let
|
||||||
{
|
{
|
||||||
element.tcpserversink = {
|
element.tcpserversink = {
|
||||||
port = 8990;
|
port = 8990;
|
||||||
host = config.network.addresses.yggdrasil.nixos.ipv6.address;
|
host = config.networks.tailscale.ipv4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,15 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
network.extraCerts.domain-auth = "auth.${config.network.dns.domain}";
|
|
||||||
users.groups.domain-auth.members = [ "nginx" "openldap" "keycloak" ];
|
users.groups.domain-auth.members = [ "nginx" "openldap" "keycloak" ];
|
||||||
security.acme.certs.domain-auth = {
|
/* security.acme.certs.domain-auth = {
|
||||||
group = "domain-auth";
|
group = "domain-auth";
|
||||||
postRun = ''
|
postRun = ''
|
||||||
${pkgs.adoptopenjdk-jre-bin}/bin/keytool -delete -alias auth.kittywit.ch -keypass ${keystore-pass} -storepass ${keystore-pass} -keystore ./trust-store.jks
|
${pkgs.adoptopenjdk-jre-bin}/bin/keytool -delete -alias auth.kittywit.ch -keypass ${keystore-pass} -storepass ${keystore-pass} -keystore ./trust-store.jks
|
||||||
${pkgs.adoptopenjdk-jre-bin}/bin/keytool -import -alias auth.${config.network.dns.domain} -noprompt -keystore trust-store.jks -keypass ${keystore-pass} -storepass ${keystore-pass} -file cert.pem
|
${pkgs.adoptopenjdk-jre-bin}/bin/keytool -import -alias auth.${config.network.dns.domain} -noprompt -keystore trust-store.jks -keypass ${keystore-pass} -storepass ${keystore-pass} -file cert.pem
|
||||||
chown acme:domain-auth ./trust-store.jks
|
chown acme:domain-auth ./trust-store.jks
|
||||||
'';
|
'';
|
||||||
};
|
}; */
|
||||||
|
|
||||||
users.groups.keycloak = { };
|
users.groups.keycloak = { };
|
||||||
users.users.keycloak = {
|
users.users.keycloak = {
|
||||||
|
|
@ -63,9 +62,9 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
deploy.tf.dns.records.services_keycloak = {
|
domains.kittywitch-keycloak = {
|
||||||
inherit (config.network.dns) zone;
|
network = "internet";
|
||||||
|
type = "cname";
|
||||||
domain = "auth";
|
domain = "auth";
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
{ config, lib, tf, pkgs, ... }:
|
{ config, lib, tf, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
network.dns.enable = false;
|
|
||||||
|
|
||||||
kw.secrets.variables = {
|
kw.secrets.variables = {
|
||||||
katdns-key-config = {
|
katdns-key-config = {
|
||||||
path = "secrets/katdns";
|
path = "secrets/katdns";
|
||||||
|
|
@ -10,9 +8,9 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network.firewall.public = {
|
networks.internet = {
|
||||||
tcp.ports = [ 53 ];
|
tcp = [ 53 ];
|
||||||
udp.ports = [ 53 ];
|
udp = [ 53 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* environment.etc."katdns/zones/gensokyo.zone.zone".text = let
|
/* environment.etc."katdns/zones/gensokyo.zone.zone".text = let
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ remote:
|
||||||
- id: benjojo-1
|
- id: benjojo-1
|
||||||
address: [ 185.230.223.84, 2a0c:2f07:4896:666:216:3eff:fedb:c742 ]
|
address: [ 185.230.223.84, 2a0c:2f07:4896:666:216:3eff:fedb:c742 ]
|
||||||
- id: benjojo-2
|
- id: benjojo-2
|
||||||
address: 185.236.240.26
|
|
||||||
- id: benjojo-3
|
|
||||||
address: 185.230.223.7
|
address: 185.230.223.7
|
||||||
|
|
||||||
acl:
|
acl:
|
||||||
|
|
@ -14,7 +12,7 @@ acl:
|
||||||
key: dnsupdate.kittywit.ch.
|
key: dnsupdate.kittywit.ch.
|
||||||
action: update
|
action: update
|
||||||
- id: benjojo
|
- id: benjojo
|
||||||
remote: [ benjojo-1, benjojo-2, benjojo-3 ]
|
remote: [ benjojo-1, benjojo-2 ]
|
||||||
action: transfer
|
action: transfer
|
||||||
|
|
||||||
zone:
|
zone:
|
||||||
|
|
@ -24,7 +22,7 @@ zone:
|
||||||
file: kittywit.ch.zone
|
file: kittywit.ch.zone
|
||||||
dnssec-signing: on
|
dnssec-signing: on
|
||||||
module: mod-stats
|
module: mod-stats
|
||||||
notify: [ benjojo-1, benjojo-2, benjojo-3 ]
|
notify: [ benjojo-1, benjojo-2 ]
|
||||||
zonefile-load: difference
|
zonefile-load: difference
|
||||||
acl: [ benjojo, dnsupdate ]
|
acl: [ benjojo, dnsupdate ]
|
||||||
- domain: dork.dev
|
- domain: dork.dev
|
||||||
|
|
@ -33,7 +31,7 @@ zone:
|
||||||
file: dork.dev.zone
|
file: dork.dev.zone
|
||||||
dnssec-signing: on
|
dnssec-signing: on
|
||||||
module: mod-stats
|
module: mod-stats
|
||||||
notify: [ benjojo-1, benjojo-2, benjojo-3 ]
|
notify: [ benjojo-1, benjojo-2 ]
|
||||||
zonefile-load: difference
|
zonefile-load: difference
|
||||||
acl: [ benjojo, dnsupdate ]
|
acl: [ benjojo, dnsupdate ]
|
||||||
- domain: inskip.me
|
- domain: inskip.me
|
||||||
|
|
@ -42,7 +40,7 @@ zone:
|
||||||
file: inskip.me.zone
|
file: inskip.me.zone
|
||||||
dnssec-signing: on
|
dnssec-signing: on
|
||||||
module: mod-stats
|
module: mod-stats
|
||||||
notify: [ benjojo-1, benjojo-2, benjojo-3 ]
|
notify: [ benjojo-1, benjojo-2 ]
|
||||||
zonefile-load: difference
|
zonefile-load: difference
|
||||||
acl: [ benjojo, dnsupdate ]
|
acl: [ benjojo, dnsupdate ]
|
||||||
- domain: gensokyo.zone
|
- domain: gensokyo.zone
|
||||||
|
|
@ -51,7 +49,7 @@ zone:
|
||||||
file: gensokyo.zone.zone
|
file: gensokyo.zone.zone
|
||||||
dnssec-signing: on
|
dnssec-signing: on
|
||||||
module: mod-stats
|
module: mod-stats
|
||||||
notify: [ benjojo-1, benjojo-2, benjojo-3 ]
|
notify: [ benjojo-1, benjojo-2 ]
|
||||||
zonefile-load: difference
|
zonefile-load: difference
|
||||||
acl: [ benjojo, dnsupdate ]
|
acl: [ benjojo, dnsupdate ]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,9 @@ let
|
||||||
forking = (cfg.logFile != null);
|
forking = (cfg.logFile != null);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
network.firewall = {
|
networks.internet = {
|
||||||
public = {
|
tcp = singleton 64738;
|
||||||
tcp.ports = singleton 64738;
|
udp = singleton 64738;
|
||||||
udp.ports = singleton 64738;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
kw.secrets.variables = {
|
kw.secrets.variables = {
|
||||||
|
|
@ -107,26 +105,24 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# Certs
|
# Certs
|
||||||
|
/*
|
||||||
network.extraCerts.services_murmur = "voice.${config.network.dns.domain}";
|
network.extraCerts.services_murmur = "voice.${config.net";
|
||||||
users.groups."voice-cert".members = [ "nginx" "murmur" ];
|
users.groups."voice-cert".members = [ "nginx" "murmur" ];
|
||||||
security.acme.certs.services_murmur = {
|
security.acme.certs.services_murmur = {
|
||||||
group = "voice-cert";
|
group = "voice-cert";
|
||||||
postRun = "systemctl restart murmur";
|
postRun = "systemctl restart murmur";
|
||||||
extraDomainNames = [ config.network.dns.domain ];
|
extraDomainNames = [ config.networks.internet.dn ];
|
||||||
|
};*/
|
||||||
|
|
||||||
|
domains.kittywitch-murmur = {
|
||||||
|
network = "internet";
|
||||||
|
type = "cname";
|
||||||
|
domain = "voice";
|
||||||
};
|
};
|
||||||
|
|
||||||
# DNS
|
|
||||||
|
|
||||||
deploy.tf.dns.records = {
|
deploy.tf.dns.records = {
|
||||||
services_murmur = {
|
|
||||||
inherit (config.network.dns) zone;
|
|
||||||
domain = "voice";
|
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
|
||||||
};
|
|
||||||
|
|
||||||
services_murmur_tcp_srv = {
|
services_murmur_tcp_srv = {
|
||||||
inherit (config.network.dns) zone;
|
inherit (config.networks.internet) zone;
|
||||||
domain = "@";
|
domain = "@";
|
||||||
srv = {
|
srv = {
|
||||||
service = "mumble";
|
service = "mumble";
|
||||||
|
|
@ -134,12 +130,12 @@ in
|
||||||
priority = 0;
|
priority = 0;
|
||||||
weight = 5;
|
weight = 5;
|
||||||
port = 64738;
|
port = 64738;
|
||||||
target = "voice.${config.network.dns.zone}";
|
target = kittywitch-murmur.target;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services_murmur_udp_srv = {
|
services_murmur_udp_srv = {
|
||||||
inherit (config.network.dns) zone;
|
inherit (config.networks.internet) zone;
|
||||||
domain = "@";
|
domain = "@";
|
||||||
srv = {
|
srv = {
|
||||||
service = "mumble";
|
service = "mumble";
|
||||||
|
|
@ -147,7 +143,7 @@ in
|
||||||
priority = 0;
|
priority = 0;
|
||||||
weight = 5;
|
weight = 5;
|
||||||
port = 64738;
|
port = 64738;
|
||||||
target = "voice.${config.network.dns.zone}";
|
target = kittywitch-murmur.target;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
{ config, pkgs, lib, tf, kw, ... }: with lib; let
|
{ config, pkgs, lib, tf, kw, ... }: with lib; let
|
||||||
cfg = config.services.nextcloud;
|
cfg = config.services.nextcloud;
|
||||||
in {
|
in {
|
||||||
deploy.tf.dns.records.services_internal_cloud = {
|
|
||||||
inherit (config.network.dns) zone;
|
|
||||||
domain = "cloud.int";
|
|
||||||
cname = { inherit (config.network.addresses.yggdrasil) target; };
|
|
||||||
};
|
|
||||||
|
|
||||||
kw.secrets.variables =
|
kw.secrets.variables =
|
||||||
mapListToAttrs
|
mapListToAttrs
|
||||||
(field:
|
(field:
|
||||||
|
|
@ -53,27 +47,27 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."cloud.kittywit.ch".extraConfig = mkForce ''
|
services.nginx.virtualHosts."${config.networks.tailscale.ipv4}".locations."/nextcloud".extraConfig = mkForce ''
|
||||||
index index.php index.html /index.php$request_uri;
|
index index.php index.html /index.php$request_uri;
|
||||||
add_header X-Content-Type-Options nosniff;
|
add_header X-Content-Type-Options nosniff;
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
add_header X-Robots-Tag none;
|
add_header X-Robots-Tag none;
|
||||||
add_header X-Download-Options noopen;
|
add_header X-Download-Options noopen;
|
||||||
add_header X-Permitted-Cross-Domain-Policies none;
|
add_header X-Permitted-Cross-Domain-Policies none;
|
||||||
add_header X-Frame-Options sameorigin;
|
add_header X-Frame-Options sameorigin;
|
||||||
add_header Referrer-Policy no-referrer;
|
add_header Referrer-Policy no-referrer;
|
||||||
client_max_body_size ${cfg.maxUploadSize};
|
client_max_body_size ${cfg.maxUploadSize};
|
||||||
fastcgi_buffers 64 4K;
|
fastcgi_buffers 64 4K;
|
||||||
fastcgi_hide_header X-Powered-By;
|
fastcgi_hide_header X-Powered-By;
|
||||||
gzip on;
|
gzip on;
|
||||||
gzip_vary on;
|
gzip_vary on;
|
||||||
gzip_comp_level 4;
|
gzip_comp_level 4;
|
||||||
gzip_min_length 256;
|
gzip_min_length 256;
|
||||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||||
${optionalString cfg.webfinger ''
|
${optionalString cfg.webfinger ''
|
||||||
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
|
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
|
||||||
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
|
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
network.firewall = {
|
networks.chitei = {
|
||||||
private.tcp.ports = [ 111 2049 ];
|
tcp = [ 111 2049 ];
|
||||||
public.tcp.ports = [ 111 2049 ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nfs.server.enable = true;
|
services.nfs.server.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,11 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
network.firewall = {
|
networks = genAttrs [ "chitei" "gensokyo" "internet" "tailscale" ] (_: {
|
||||||
public.tcp.ports = [ 443 80 ];
|
# NGINX
|
||||||
private.tcp.ports = [ 443 80 ];
|
tcp = [ 80 443 ];
|
||||||
};
|
udp = [ 80 443 ];
|
||||||
|
});
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
@ -39,8 +40,7 @@ with lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
security.acme = {
|
security.acme = {
|
||||||
defaults.email = config.network.dns.email;
|
defaults.email = "kat@inskip.me";
|
||||||
#email = config.network.dns.email;
|
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{ config, pkgs, tf, lib, ... }: with lib; {
|
{ config, pkgs, tf, lib, ... }: with lib; {
|
||||||
network.firewall.public.tcp.ports = [ 636 ];
|
networks.internet.tcp = [ 636 ];
|
||||||
|
|
||||||
services.openldap = {
|
services.openldap = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{ config, kw, pkgs, lib, ... }: {
|
{ config, kw, pkgs, lib, ... }: {
|
||||||
network.firewall.public.tcp.ports = [ 32400 ];
|
networks.chitei.tcp = [ 32400 ];
|
||||||
services = {
|
services = {
|
||||||
plex = {
|
plex = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.plex.overrideAttrs (x: let
|
package = pkgs.plex.overrideAttrs (x: let
|
||||||
|
|
@ -16,28 +16,5 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
nginx.virtualHosts."plex.kittywit.ch".locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:32400";
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_redirect off;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
|
|
||||||
proxy_set_header X-Plex-Device $http_x_plex_device;
|
|
||||||
proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
|
|
||||||
proxy_set_header X-Plex-Platform $http_x_plex_platform;
|
|
||||||
proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
|
|
||||||
proxy_set_header X-Plex-Product $http_x_plex_product;
|
|
||||||
proxy_set_header X-Plex-Token $http_x_plex_token;
|
|
||||||
proxy_set_header X-Plex-Version $http_x_plex_version;
|
|
||||||
proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
|
|
||||||
proxy_set_header X-Plex-Provides $http_x_plex_provides;
|
|
||||||
proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
|
|
||||||
proxy_set_header X-Plex-Model $http_x_plex_model;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
network.firewall.public.tcp.ports = [
|
networks.internet.tcp = [
|
||||||
5000
|
5000
|
||||||
5222
|
5222
|
||||||
5223
|
5223
|
||||||
|
|
@ -65,33 +65,29 @@ with lib;
|
||||||
[ config.network.dns.domain "upload.${config.network.dns.domain}" "conference.${config.network.dns.domain}" ];
|
[ config.network.dns.domain "upload.${config.network.dns.domain}" "conference.${config.network.dns.domain}" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
domains = rec {
|
||||||
|
kittywitch-prosody = {
|
||||||
|
network = "internet";
|
||||||
|
type = "both";
|
||||||
|
domain = "xmpp";
|
||||||
|
};
|
||||||
|
kittywitch-prosody-upload = {
|
||||||
|
network = "internet";
|
||||||
|
type = "cname";
|
||||||
|
domain = "upload";
|
||||||
|
cname.target = kittywitch-prosody.target;
|
||||||
|
};
|
||||||
|
kittywitch-prosody-conference = {
|
||||||
|
network = "internet";
|
||||||
|
type = "cname";
|
||||||
|
domain = "conference";
|
||||||
|
cname.target = kittywitch-prosody.target;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
deploy.tf.dns.records = {
|
deploy.tf.dns.records = {
|
||||||
services_prosody_xmpp = {
|
|
||||||
inherit (config.network.dns) zone;
|
|
||||||
domain = "xmpp";
|
|
||||||
a.address = config.network.addresses.public.nixos.ipv4.selfaddress;
|
|
||||||
};
|
|
||||||
|
|
||||||
services_prosody_xmpp_v6 = {
|
|
||||||
inherit (config.network.dns) zone;
|
|
||||||
domain = "xmpp";
|
|
||||||
aaaa.address = config.network.addresses.public.nixos.ipv6.selfaddress;
|
|
||||||
};
|
|
||||||
|
|
||||||
services_prosody_upload = {
|
|
||||||
inherit (config.network.dns) zone;
|
|
||||||
domain = "upload";
|
|
||||||
cname.target = "xmpp.${config.network.dns.zone}";
|
|
||||||
};
|
|
||||||
|
|
||||||
services_prosody_conference = {
|
|
||||||
inherit (config.network.dns) zone;
|
|
||||||
domain = "conference";
|
|
||||||
cname.target = "xmpp.${config.network.dns.zone}";
|
|
||||||
};
|
|
||||||
|
|
||||||
services_prosody_muc = {
|
services_prosody_muc = {
|
||||||
inherit (config.network.dns) zone;
|
inherit (config.domains.kittywitch-prosody) zone;
|
||||||
domain = "conference";
|
domain = "conference";
|
||||||
srv = {
|
srv = {
|
||||||
service = "xmpp-server";
|
service = "xmpp-server";
|
||||||
|
|
@ -99,12 +95,12 @@ with lib;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
weight = 5;
|
weight = 5;
|
||||||
port = 5269;
|
port = 5269;
|
||||||
target = "xmpp.${config.network.dns.zone}";
|
target = config.domains.kittywitch-prosody.target;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services_prosody_client_srv = {
|
services_prosody_client_srv = {
|
||||||
inherit (config.network.dns) zone;
|
inherit (config.domains.kittywitch-prosody) zone;
|
||||||
domain = "@";
|
domain = "@";
|
||||||
srv = {
|
srv = {
|
||||||
service = "xmpp-client";
|
service = "xmpp-client";
|
||||||
|
|
@ -112,12 +108,12 @@ with lib;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
weight = 5;
|
weight = 5;
|
||||||
port = 5222;
|
port = 5222;
|
||||||
target = "xmpp.${config.network.dns.zone}";
|
target = config.domains.kittywitch-prosody.target;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services_prosody_secure_client_srv = {
|
services_prosody_secure_client_srv = {
|
||||||
inherit (config.network.dns) zone;
|
inherit (config.domains.kittywitch-prosody) zone;
|
||||||
domain = "@";
|
domain = "@";
|
||||||
srv = {
|
srv = {
|
||||||
service = "xmpps-client";
|
service = "xmpps-client";
|
||||||
|
|
@ -125,12 +121,12 @@ with lib;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
weight = 5;
|
weight = 5;
|
||||||
port = 5223;
|
port = 5223;
|
||||||
target = "xmpp.${config.network.dns.zone}";
|
target = config.domains.kittywitch-prosody.target;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services_prosody_server_srv = {
|
services_prosody_server_srv = {
|
||||||
inherit (config.network.dns) zone;
|
inherit (config.domains.kittywitch-prosody) zone;
|
||||||
domain = "@";
|
domain = "@";
|
||||||
srv = {
|
srv = {
|
||||||
service = "xmpp-server";
|
service = "xmpp-server";
|
||||||
|
|
@ -138,7 +134,7 @@ with lib;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
weight = 5;
|
weight = 5;
|
||||||
port = 5269;
|
port = 5269;
|
||||||
target = "xmpp.${config.network.dns.zone}";
|
target = config.domains.kittywitch-prosody.target;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -28,17 +28,17 @@ with lib;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network.firewall.public.tcp.ports = singleton 8999;
|
networks.internet.tcp = [ 8999 ];
|
||||||
|
|
||||||
services.nginx.virtualHosts."sync.${config.network.dns.domain}" = {
|
services.nginx.virtualHosts."sync.${config.network.dns.domain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
deploy.tf.dns.records.services_syncplay = {
|
domains.kittywitch-syncplay = {
|
||||||
inherit (config.network.dns) zone;
|
network = "internet";
|
||||||
|
type = "cname";
|
||||||
domain = "sync";
|
domain = "sync";
|
||||||
cname = { inherit (config.network.addresses.public) target; };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
secrets.files.syncplay-env = {
|
secrets.files.syncplay-env = {
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,13 @@
|
||||||
users.users.tvheadend.group = "tvheadend";
|
users.users.tvheadend.group = "tvheadend";
|
||||||
users.groups.tvheadend = {};
|
users.groups.tvheadend = {};
|
||||||
|
|
||||||
network.firewall = {
|
networks.internet = {
|
||||||
private = {
|
tcp = [
|
||||||
tcp.ports = [ 9981 9982 ];
|
9981
|
||||||
};
|
9982
|
||||||
public = {
|
5009
|
||||||
tcp.ports = [ 9981 9982 ];
|
];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.antennas = {
|
systemd.services.antennas = {
|
||||||
wantedBy = [ "plex.service" ];
|
wantedBy = [ "plex.service" ];
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
network.dns.isRoot = true;
|
|
||||||
|
|
||||||
services.nginx.virtualHosts = {
|
services.nginx.virtualHosts = {
|
||||||
"${config.network.dns.domain}" = {
|
"${config.network.dns.domain}" = {
|
||||||
root = pkgs.gensokyoZone;
|
root = pkgs.gensokyoZone;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ let
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
network.firewall.public.tcp.ports = singleton 5001;
|
# ZNC
|
||||||
|
networks.internet.tcp = singleton 5001;
|
||||||
|
|
||||||
kw.secrets.variables =
|
kw.secrets.variables =
|
||||||
let
|
let
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,11 @@
|
||||||
sensitive = true;
|
sensitive = true;
|
||||||
export = true;
|
export = true;
|
||||||
};
|
};
|
||||||
|
acme.account = {
|
||||||
|
register = false;
|
||||||
|
emailAddress = "kat@inskip.me";
|
||||||
|
accountKeyPem = config.resources.acme_private_key.refAttr "private_key_pem";
|
||||||
|
};
|
||||||
providers.tailscale = {
|
providers.tailscale = {
|
||||||
inputs = {
|
inputs = {
|
||||||
api_key = config.variables.tailscale-apikey.ref;
|
api_key = config.variables.tailscale-apikey.ref;
|
||||||
|
|
@ -18,6 +22,14 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
resources = {
|
resources = {
|
||||||
|
acme_private_key = {
|
||||||
|
provider = "tls";
|
||||||
|
type = "private_key";
|
||||||
|
inputs = {
|
||||||
|
algorithm = "RSA";
|
||||||
|
rsa_bits = 4096;
|
||||||
|
};
|
||||||
|
};
|
||||||
tailnet_devices = {
|
tailnet_devices = {
|
||||||
type = "devices";
|
type = "devices";
|
||||||
provider = "tailscale";
|
provider = "tailscale";
|
||||||
|
|
|
||||||
2
tf
2
tf
|
|
@ -1 +1 @@
|
||||||
Subproject commit 58d25138fdd294512a311a0fe3c92007f8d55f7a
|
Subproject commit e4898b63141b7be8bd96c0f91fecc807d732aa58
|
||||||
2
tf.nix
2
tf.nix
|
|
@ -29,7 +29,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
dns.zones = genAttrs [ "kittywit.ch." "dork.dev." "gensokyo.zone." ] (_: {
|
dns.zones = genAttrs [ "inskip.me." "kittywit.ch." "dork.dev." "gensokyo.zone." ] (_: {
|
||||||
provider = "dns.katdns";
|
provider = "dns.katdns";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue