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
|
|
@ -2,13 +2,4 @@
|
|||
|
||||
{
|
||||
networking.nftables.enable = true;
|
||||
|
||||
network = {
|
||||
enable = true;
|
||||
dns = {
|
||||
enable = mkDefault true;
|
||||
email = "acme@kittywit.ch";
|
||||
zone = "kittywit.ch.";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,11 @@
|
|||
with lib;
|
||||
|
||||
{
|
||||
network.firewall = {
|
||||
public = {
|
||||
tcp.ports = singleton 62954;
|
||||
udp.ranges = [{
|
||||
from = 60000;
|
||||
to = 61000;
|
||||
}];
|
||||
};
|
||||
private = {
|
||||
tcp.ports = singleton 62954;
|
||||
udp.ranges = [{
|
||||
from = 60000;
|
||||
to = 61000;
|
||||
}];
|
||||
};
|
||||
};
|
||||
networks = genAttrs [ "chitei" "gensokyo" ] (_: {
|
||||
# Mosh
|
||||
tcp = [62954];
|
||||
udp = [ [60000 61000] ];
|
||||
});
|
||||
|
||||
/*
|
||||
security.pam.services.sshd.text = mkDefault (mkAfter ''
|
||||
|
|
@ -39,5 +28,6 @@ with lib;
|
|||
LogLevel VERBOSE
|
||||
'';
|
||||
};
|
||||
|
||||
programs.mosh.enable = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,96 +1,334 @@
|
|||
{ config, lib, tf, pkgs, meta, ... }: with lib; let
|
||||
in {
|
||||
options = with lib; {
|
||||
network = {
|
||||
routeDefault = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
};
|
||||
{ config, lib, tf, pkgs, meta, ... }: with lib; {
|
||||
options = let
|
||||
nixos = config;
|
||||
in {
|
||||
domains = mkOption {
|
||||
default = {};
|
||||
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 = {
|
||||
network.yggdrasil.extern = let
|
||||
in {
|
||||
pubkeys = {
|
||||
satorin =
|
||||
"cbadeaa973b051cf66e23dcb014ab5be59e55a1c98ef541345520868e3bcf9f7";
|
||||
shanghai =
|
||||
"5aba9ba2ac7a54ffef19dea9e39881bd977f76032db81a2c82c4674ed475c95b";
|
||||
grimoire =
|
||||
"2a1567a2848540070328c9e938c58d40f2b1a3f08982c15c7edc5dcabfde3330";
|
||||
boline =
|
||||
"89684441745467da0d1bf7f47dc74ec3ca65e05c72f752298ef3c22a22024d43";
|
||||
okami =
|
||||
"f8fd12c6ed924048e93a7bd7dd63c2464813c9edddfef7415c4574518ecd4757";
|
||||
amaterasu =
|
||||
"ab9a4a78df124a8413c3a6576332d7739a44c036e14b7b0b4ea4558373ddda97";
|
||||
duck-powerduck =
|
||||
"9475274dcd43f0f3f397d56168efd436b0db58e58f4c068f75ab93ba3f51e405";
|
||||
duck-nagoya =
|
||||
"0000001a24b38f4341e356e7efc98dd31e259669242e0a82ba86971317b94954";
|
||||
networks = {
|
||||
internet = {
|
||||
create_domain = true;
|
||||
};
|
||||
chitei = {
|
||||
create_domain = true;
|
||||
};
|
||||
gensokyo = {
|
||||
zone = mkDefault "gensokyo.zone.";
|
||||
create_domain = true;
|
||||
};
|
||||
tailscale = {
|
||||
interfaces = singleton "tailscale0";
|
||||
ipv4 = meta.tailnet.${config.networking.hostName}.ipv4 or null;
|
||||
ipv6 = meta.tailnet.${config.networking.hostName}.ipv6 or null;
|
||||
zone = "inskip.me.";
|
||||
create_domain = true;
|
||||
};
|
||||
};
|
||||
|
||||
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 = {
|
||||
variables.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";
|
||||
};
|
||||
secrets.files = 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}-cert" {
|
||||
text = tf.acme.certs.${hostname}.out.refFullchainPem;
|
||||
owner = "nginx";
|
||||
group = "nginx";
|
||||
}) hostnames) // listToAttrs (map (hostname:
|
||||
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";
|
||||
type = "tailnet_key";
|
||||
inputs = {
|
||||
reusable = false;
|
||||
ephemeral = false;
|
||||
preauthorized = true;
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
# 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 = {
|
||||
addresses = {
|
||||
private = {
|
||||
enable = true;
|
||||
nixos = {
|
||||
ipv4.address = "192.168.1.196";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
public = {
|
||||
interfaces = singleton "enp0s20u1";
|
||||
};
|
||||
networks.chitei = {
|
||||
interfaces = [ "enp0s20u1" "wlp1s0" ];
|
||||
ipv4 = "192.168.1.196";
|
||||
};
|
||||
|
||||
# State
|
||||
|
|
|
|||
|
|
@ -37,11 +37,5 @@
|
|||
};
|
||||
};
|
||||
|
||||
network.yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "edb7de263e6924b8c9446123979782420e5196317bffc75e9a6ca546551252da";
|
||||
address = "206:d807:a98:309f:3bc0:de7a:411d:9d95";
|
||||
};
|
||||
|
||||
system.stateVersion = "21.11";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
};
|
||||
};
|
||||
|
||||
programs.ssh.extraConfig = ''
|
||||
Host daiyousei-build
|
||||
programs.ssh.extraConfig = ''
|
||||
Host daiyousei-build
|
||||
HostName daiyousei.kittywit.ch
|
||||
Port 62954
|
||||
User root
|
||||
|
|
@ -51,42 +51,36 @@ Host daiyousei-build
|
|||
};
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/0d846453-95b4-46e1-8eaf-b910b4321ef0"; }
|
||||
swapDevices = [
|
||||
{ device = "/dev/disk/by-uuid/0d846453-95b4-46e1-8eaf-b910b4321ef0"; }
|
||||
];
|
||||
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
|
||||
boot = {
|
||||
supportedFilesystems = [ "xfs" "zfs" ];
|
||||
initrd.luks.devices."cryptroot".device = "/dev/disk/by-uuid/f0ea08b4-6af7-4d90-a2ad-edd5672a2105";
|
||||
loader = {
|
||||
efi = {
|
||||
canTouchEfiVariables = true;
|
||||
# assuming /boot is the mount point of the EFI partition in NixOS (as the installation section recommends).
|
||||
efiSysMountPoint = "/boot";
|
||||
};
|
||||
grub = {
|
||||
# despite what the configuration.nix manpage seems to indicate,
|
||||
# as of release 17.09, setting device to "nodev" will still call
|
||||
# `grub-install` if efiSupport is true
|
||||
# (the devices list is not used by the EFI grub install,
|
||||
# but must be set to some value in order to pass an assert in grub.nix)
|
||||
devices = [ "nodev" ];
|
||||
efiSupport = true;
|
||||
enable = true;
|
||||
# set $FS_UUID to the UUID of the EFI partition
|
||||
extraEntries = ''
|
||||
menuentry "Windows" {
|
||||
insmod part_gpt
|
||||
insmod fat
|
||||
insmod search_fs_uuid
|
||||
insmod chain
|
||||
search --fs-uuid --set=root DEBC-8F03
|
||||
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
|
||||
}
|
||||
'';
|
||||
version = 2;
|
||||
};
|
||||
efi = {
|
||||
canTouchEfiVariables = true;
|
||||
efiSysMountPoint = "/boot";
|
||||
};
|
||||
grub = {
|
||||
devices = [ "nodev" ];
|
||||
efiSupport = true;
|
||||
enable = true;
|
||||
extraEntries = ''
|
||||
menuentry "Windows" {
|
||||
insmod part_gpt
|
||||
insmod fat
|
||||
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 = {
|
||||
hostId = "dddbb888";
|
||||
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;
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
private = {
|
||||
enable = true;
|
||||
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";
|
||||
networks = {
|
||||
gensokyo = {
|
||||
interfaces = [ "enp1s0" "wlp3s0" ];
|
||||
ipv4 = "10.1.1.65";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,13 @@
|
|||
{ config, lib, pkgs, modulesPath, tf, meta, ... }: with lib; {
|
||||
imports = with meta; [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
hardware.manual
|
||||
nixos.network
|
||||
services.nginx
|
||||
services.access
|
||||
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 = {
|
||||
loader.grub = {
|
||||
enable = true;
|
||||
|
|
@ -45,43 +34,29 @@
|
|||
interfaces.ens3 = {
|
||||
ipv4.addresses = [
|
||||
{
|
||||
inherit (config.network.addresses.public.nixos.ipv4) address;
|
||||
address = config.networks.internet.ipv4;
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [
|
||||
{
|
||||
inherit (config.network.addresses.public.nixos.ipv6) address;
|
||||
address = config.networks.internet.ipv6;
|
||||
prefixLength = 48;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
network = {
|
||||
addresses.public = {
|
||||
enable = true;
|
||||
nixos.ipv4.address = "104.244.72.5";
|
||||
nixos.ipv6.address = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0";
|
||||
};
|
||||
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";
|
||||
networks = {
|
||||
internet = {
|
||||
ipv4 = "104.244.72.5";
|
||||
ipv6 = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0";
|
||||
interfaces = singleton "ens3";
|
||||
tcp = [ 1935 52969 ];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
fileSystems."/" ={
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/6ed3e886-d390-433f-90ac-2b37aed9f15f";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,25 +7,13 @@ with lib;
|
|||
|
||||
imports = with meta; [
|
||||
hardware.eeepc-1015pem
|
||||
hardware.local
|
||||
nixos.network
|
||||
nixos.arc
|
||||
services.kattv
|
||||
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
|
||||
|
||||
fileSystems = {
|
||||
|
|
@ -57,23 +45,9 @@ with lib;
|
|||
interfaces.enp1s0.useDHCP = true;
|
||||
};
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
private = {
|
||||
enable = true;
|
||||
nixos = {
|
||||
ipv4.address = "192.168.1.215";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
public = {
|
||||
interfaces = singleton "enp1s0";
|
||||
};
|
||||
networks.chitei = {
|
||||
interfaces = [ "enp1s0" ];
|
||||
ipv4 = "192.168.1.215";
|
||||
};
|
||||
|
||||
# State
|
||||
|
|
|
|||
|
|
@ -20,13 +20,5 @@
|
|||
};
|
||||
};
|
||||
|
||||
network = {
|
||||
yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "fc64ee574072ef7420ff98bc53856f881025de252081e661a78e04ebcf7c6b35";
|
||||
address = "200:736:2351:7f1a:2117:be00:ce87:58f5";
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "21.11";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
{ 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 = {
|
||||
path = "secrets/home-assistant";
|
||||
field = "notes";
|
||||
|
|
@ -14,31 +32,12 @@
|
|||
preStart = lib.mkBefore ''
|
||||
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
|
||||
'';
|
||||
'';
|
||||
};
|
||||
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
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 = {
|
||||
name = "Gensokyo";
|
||||
unit_system = "metric";
|
||||
|
|
@ -47,18 +46,94 @@
|
|||
logger = {
|
||||
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 = {
|
||||
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 = {
|
||||
name = "Tewi";
|
||||
port = 21063;
|
||||
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; [
|
||||
psycopg2
|
||||
aiohomekit
|
||||
securetar
|
||||
];
|
||||
extraComponents = [
|
||||
|
|
@ -80,4 +155,4 @@
|
|||
"zeroconf"
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
{ config, lib, tf, ... }: {
|
||||
networks.gensokyo = {
|
||||
tcp = [
|
||||
# Mosquitto
|
||||
1883
|
||||
];
|
||||
};
|
||||
|
||||
kw.secrets.variables.z2m-pass = {
|
||||
path = "secrets/mosquitto";
|
||||
field = "z2m";
|
||||
|
|
|
|||
|
|
@ -12,9 +12,11 @@ with lib;
|
|||
'';
|
||||
};
|
||||
|
||||
network.firewall = {
|
||||
public.tcp.ports = [ 443 80 ];
|
||||
private.tcp.ports = [ 443 80 ];
|
||||
networks.gensokyo = {
|
||||
tcp = [
|
||||
443
|
||||
80
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
|
|
@ -36,34 +38,12 @@ with lib;
|
|||
#proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
clientMaxBodySize = "512m";
|
||||
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;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
};
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
defaults.email = config.network.dns.email;
|
||||
#email = config.network.dns.email;
|
||||
acceptTerms = true;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,21 +3,21 @@
|
|||
{
|
||||
imports = with meta; [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
hardware.local
|
||||
nixos.network
|
||||
./home-assistant.nix
|
||||
./zigbee2mqtt.nix
|
||||
./mosquitto.nix
|
||||
./postgres.nix
|
||||
./nginx.nix
|
||||
];
|
||||
|
||||
deploy.tf = {
|
||||
resources.tewi = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = lib.head config.services.openssh.ports;
|
||||
host = config.network.addresses.private.nixos.ipv4.address;
|
||||
};
|
||||
networks = {
|
||||
gensokyo = {
|
||||
interfaces = [
|
||||
"eno1"
|
||||
];
|
||||
ipv4 = "10.1.1.38";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -30,20 +30,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
network = {
|
||||
firewall = {
|
||||
public.interfaces = lib.singleton "eno1";
|
||||
};
|
||||
addresses = {
|
||||
private = {
|
||||
enable = true;
|
||||
nixos = {
|
||||
ipv4.address = "10.1.1.38";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
systemd-boot = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,33 @@
|
|||
{ 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 = {
|
||||
enable = true;
|
||||
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 ''
|
||||
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"
|
||||
'';
|
||||
|
||||
network.firewall.public.tcp.ports = [ 8123 8072 1883 21064 21063 ];
|
||||
network.firewall.private.tcp.ports = [ 8123 ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,26 +93,9 @@
|
|||
};
|
||||
};
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
private = {
|
||||
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";
|
||||
};
|
||||
networks.chitei = {
|
||||
interfaces = [ "eno1" ];
|
||||
ipv4 = "100.98.152.108";
|
||||
};
|
||||
|
||||
system.stateVersion = "21.05";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue