It appears I can get app passwords with kanidm and ldap so just going to a more stable, probably supported setup, should be good.
276 lines
7.1 KiB
Nix
276 lines
7.1 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
inputs,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.khscodes.infrastructure.hetzner-instance;
|
|
fqdn = config.khscodes.networking.fqdn;
|
|
provisioningUserData = config.khscodes.infrastructure.provisioning.instanceUserData;
|
|
firewallTcpRules = lib.lists.map (p: {
|
|
direction = "in";
|
|
protocol = "tcp";
|
|
port = p;
|
|
source_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
}) config.networking.firewall.allowedTCPPorts;
|
|
firewallUdpRules = lib.lists.map (p: {
|
|
direction = "in";
|
|
protocol = "udp";
|
|
port = p;
|
|
source_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
}) config.networking.firewall.allowedUDPPorts;
|
|
firewallIcmpRules = lib.lists.optional config.networking.firewall.allowPing {
|
|
direction = "in";
|
|
protocol = "icmp";
|
|
source_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "ping";
|
|
};
|
|
firewallRules =
|
|
firewallTcpRules
|
|
++ firewallUdpRules
|
|
++ firewallIcmpRules
|
|
++ cfg.extraFirewallRules
|
|
++ [
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 80;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "http";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 443;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "http";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "udp";
|
|
port = 443;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "quic";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "udp";
|
|
port = 53;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "dns";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 53;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "dns";
|
|
}
|
|
];
|
|
firewallEnable = config.networking.firewall.enable;
|
|
in
|
|
{
|
|
options.khscodes.infrastructure.hetzner-instance = {
|
|
enable = lib.mkEnableOption "enables generating a opentofu config";
|
|
dnsName = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = fqdn;
|
|
};
|
|
dnsAliases = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
default = lib.lists.unique (
|
|
lib.lists.filter (alias: alias != cfg.dnsName) config.khscodes.networking.aliases
|
|
);
|
|
};
|
|
bucket = {
|
|
key = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Key for use in the bucket";
|
|
default = "${fqdn}.tfstate";
|
|
};
|
|
};
|
|
datacenter = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "The Hetzner datacenter to create a server in";
|
|
default = "hel1-dc2";
|
|
};
|
|
mapRdns = lib.mkOption {
|
|
type = lib.types.bool;
|
|
description = "Sets up RDNS for the server";
|
|
default = false;
|
|
};
|
|
server_type = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
description = "The server type to create";
|
|
default = null;
|
|
};
|
|
extraFirewallRules = lib.mkOption {
|
|
type = lib.types.listOf lib.types.attrs;
|
|
description = "Extra firewall rules added to the instance";
|
|
default = [
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 80;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "http";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 443;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "https";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "udp";
|
|
port = 443;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "quic";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "icmp";
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "Ping";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
config = lib.mkIf cfg.enable (
|
|
let
|
|
labels = {
|
|
app = fqdn;
|
|
};
|
|
modules = [
|
|
(
|
|
{ config, ... }:
|
|
{
|
|
imports = [
|
|
inputs.self.terranixModules.cloudflare
|
|
inputs.self.terranixModules.hcloud
|
|
inputs.self.terranixModules.s3
|
|
];
|
|
config = {
|
|
khscodes.s3 = {
|
|
enable = true;
|
|
bucket.key = cfg.bucket.key;
|
|
};
|
|
khscodes.hcloud.data.ssh_key.khs = {
|
|
name = "ca.kaareskovgaard.net";
|
|
};
|
|
khscodes.hcloud.enable = true;
|
|
khscodes.hcloud.server.compute = {
|
|
inherit (cfg) server_type datacenter;
|
|
inherit labels;
|
|
name = fqdn;
|
|
initial_image = "debian-12";
|
|
rdns = lib.mkIf cfg.mapRdns fqdn;
|
|
ssh_keys = [ config.khscodes.hcloud.output.data.ssh_key.khs.id ];
|
|
user_data = builtins.toJSON provisioningUserData;
|
|
};
|
|
khscodes.cloudflare = {
|
|
enable = true;
|
|
dns = {
|
|
enable = true;
|
|
aRecords = [
|
|
{
|
|
fqdn = cfg.dnsName;
|
|
content = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
|
}
|
|
];
|
|
aaaaRecords = [
|
|
{
|
|
fqdn = cfg.dnsName;
|
|
content = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
|
}
|
|
];
|
|
cnameRecords = lib.lists.map (domain: {
|
|
fqdn = domain;
|
|
content = cfg.dnsName;
|
|
}) cfg.dnsAliases;
|
|
};
|
|
};
|
|
resource.hcloud_firewall.fw = lib.mkIf firewallEnable {
|
|
inherit labels;
|
|
name = fqdn;
|
|
apply_to = {
|
|
server = config.khscodes.hcloud.output.server.compute.id;
|
|
};
|
|
rule = firewallRules;
|
|
};
|
|
output.ipv4_address = {
|
|
value = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
|
sensitive = false;
|
|
};
|
|
|
|
output.ipv6_address = {
|
|
value = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
|
sensitive = false;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
];
|
|
in
|
|
{
|
|
assertions = [
|
|
{
|
|
assertion = config.khscodes.networking.fqdn != null;
|
|
message = "Must set config.khscodes.networking.fqdn when using opentofu";
|
|
}
|
|
];
|
|
khscodes.services.openssh = {
|
|
enable = true;
|
|
hostCertificate = {
|
|
enable = true;
|
|
};
|
|
};
|
|
khscodes.services.read-vault-auth-from-userdata = {
|
|
url = "http://169.254.169.254/latest/user-data";
|
|
doubleDecodeJsonData = true;
|
|
};
|
|
khscodes.infrastructure.provisioning.pre = {
|
|
modules = modules;
|
|
};
|
|
}
|
|
);
|
|
}
|