diff options
20 files changed, 552 insertions, 202 deletions
diff --git a/hosts/vidhar/default.nix b/hosts/vidhar/default.nix index 3d81b221..f9b021d3 100644 --- a/hosts/vidhar/default.nix +++ b/hosts/vidhar/default.nix | |||
@@ -1,7 +1,7 @@ | |||
1 | { hostName, flake, config, pkgs, lib, ... }: | 1 | { hostName, flake, config, pkgs, lib, ... }: |
2 | { | 2 | { |
3 | imports = with flake.nixosModules.systemProfiles; [ | 3 | imports = with flake.nixosModules.systemProfiles; [ |
4 | ./zfs.nix ./network ./samba.nix ./dns.nix ./prometheus ./borg | 4 | ./zfs.nix ./network ./samba.nix ./dns ./prometheus ./borg |
5 | initrd-all-crypto-modules default-locale openssh rebuild-machines | 5 | initrd-all-crypto-modules default-locale openssh rebuild-machines |
6 | build-server | 6 | build-server |
7 | initrd-ssh | 7 | initrd-ssh |
diff --git a/hosts/vidhar/dns.nix b/hosts/vidhar/dns.nix deleted file mode 100644 index 72e707e7..00000000 --- a/hosts/vidhar/dns.nix +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | { config, lib, pkgs, ... }: | ||
2 | { | ||
3 | config = { | ||
4 | services.unbound = { | ||
5 | enable = true; | ||
6 | resolveLocalQueries = false; | ||
7 | stateDir = "/var/lib/unbound"; | ||
8 | localControlSocketPath = "/run/unbound/unbound.ctl"; | ||
9 | settings = { | ||
10 | server = { | ||
11 | interface = ["127.0.0.1" "10.141.0.1" "::0"]; | ||
12 | access-control = ["0.0.0.0/0 allow" "::/0 allow"]; | ||
13 | root-hints = "${pkgs.dns-root-data}/root.hints"; | ||
14 | |||
15 | num-threads = 12; | ||
16 | so-reuseport = true; | ||
17 | msg-cache-slabs = 16; | ||
18 | rrset-cache-slabs = 16; | ||
19 | infra-cache-slabs = 16; | ||
20 | key-cache-slabs = 16; | ||
21 | |||
22 | rrset-cache-size = "100m"; | ||
23 | msg-cache-size = "50m"; | ||
24 | outgoing-range = 8192; | ||
25 | num-queries-per-thread = 4096; | ||
26 | |||
27 | so-rcvbuf = "4m"; | ||
28 | so-sndbuf = "4m"; | ||
29 | |||
30 | # serve-expired = true; | ||
31 | # serve-expired-ttl = 86400; | ||
32 | # serve-expired-reply-ttl = 0; | ||
33 | |||
34 | prefetch = true; | ||
35 | prefetch-key = true; | ||
36 | |||
37 | minimal-responses = false; | ||
38 | |||
39 | extended-statistics = true; | ||
40 | |||
41 | rrset-roundrobin = true; | ||
42 | use-caps-for-id = true; | ||
43 | }; | ||
44 | }; | ||
45 | }; | ||
46 | }; | ||
47 | } | ||
diff --git a/hosts/vidhar/dns/Gupfile b/hosts/vidhar/dns/Gupfile new file mode 100644 index 00000000..ac96f620 --- /dev/null +++ b/hosts/vidhar/dns/Gupfile | |||
@@ -0,0 +1,2 @@ | |||
1 | key.gup: | ||
2 | keys/*.yaml \ No newline at end of file | ||
diff --git a/hosts/vidhar/dns/default.nix b/hosts/vidhar/dns/default.nix new file mode 100644 index 00000000..19a121f6 --- /dev/null +++ b/hosts/vidhar/dns/default.nix | |||
@@ -0,0 +1,127 @@ | |||
1 | { config, lib, pkgs, ... }: | ||
2 | |||
3 | with lib; | ||
4 | |||
5 | let | ||
6 | knotKeys = let | ||
7 | dir = ./keys; | ||
8 | toKeyInfo = name: v: | ||
9 | if v == "regular" || v == "symlink" | ||
10 | then { path = dir + "/${name}"; inherit name; } | ||
11 | else null; | ||
12 | in filter (v: v != null) (mapAttrsToList toKeyInfo (builtins.readDir dir)); | ||
13 | in { | ||
14 | config = { | ||
15 | services.unbound = { | ||
16 | enable = true; | ||
17 | resolveLocalQueries = false; | ||
18 | stateDir = "/var/lib/unbound"; | ||
19 | localControlSocketPath = "/run/unbound/unbound.ctl"; | ||
20 | settings = { | ||
21 | server = { | ||
22 | interface = ["127.0.0.1" "10.141.0.1" "::0"]; | ||
23 | prefer-ip6 = true; | ||
24 | access-control = ["0.0.0.0/0 allow" "::/0 allow"]; | ||
25 | root-hints = "${pkgs.dns-root-data}/root.hints"; | ||
26 | |||
27 | num-threads = 12; | ||
28 | so-reuseport = true; | ||
29 | msg-cache-slabs = 16; | ||
30 | rrset-cache-slabs = 16; | ||
31 | infra-cache-slabs = 16; | ||
32 | key-cache-slabs = 16; | ||
33 | |||
34 | rrset-cache-size = "100m"; | ||
35 | msg-cache-size = "50m"; | ||
36 | outgoing-range = 8192; | ||
37 | num-queries-per-thread = 4096; | ||
38 | |||
39 | so-rcvbuf = "4m"; | ||
40 | so-sndbuf = "4m"; | ||
41 | |||
42 | # serve-expired = true; | ||
43 | # serve-expired-ttl = 86400; | ||
44 | # serve-expired-reply-ttl = 0; | ||
45 | |||
46 | prefetch = true; | ||
47 | prefetch-key = true; | ||
48 | |||
49 | minimal-responses = false; | ||
50 | |||
51 | extended-statistics = true; | ||
52 | |||
53 | rrset-roundrobin = true; | ||
54 | use-caps-for-id = true; | ||
55 | |||
56 | local-zone = [ | ||
57 | "141.10.in-addr.arpa transparent" | ||
58 | "yggdrasil transparent" | ||
59 | ]; | ||
60 | domain-insecure = [ | ||
61 | "141.10.in-addr.arpa" | ||
62 | "yggdrasil" | ||
63 | ]; | ||
64 | }; | ||
65 | |||
66 | stub-zone = map (name: { | ||
67 | inherit name; | ||
68 | stub-addr = "127.0.0.1@5353"; | ||
69 | stub-first = true; | ||
70 | stub-no-cache = true; | ||
71 | stub-prime = false; | ||
72 | }) ["yggdrasil" "lan.yggdrasil" "mgmt.yggdrasil" "arpa.in-addr.10.141" "arpa.in-addr.10.141.0" "arpa.in-addr.10.141.1"]; | ||
73 | }; | ||
74 | }; | ||
75 | |||
76 | services.knot = { | ||
77 | enable = true; | ||
78 | keyFiles = map ({name, ...}: config.sops.secrets.${name}.path) knotKeys; | ||
79 | extraConfig = '' | ||
80 | server: | ||
81 | listen: 127.0.0.1@5353 | ||
82 | listen: ::1@5353 | ||
83 | |||
84 | acl: | ||
85 | - id: local_acl | ||
86 | key: local_key | ||
87 | action: update | ||
88 | |||
89 | template: | ||
90 | - id: local_zone | ||
91 | storage: /var/lib/knot | ||
92 | zonefile-sync: -1 | ||
93 | zonefile-load: difference-no-serial | ||
94 | serial-policy: dateserial | ||
95 | journal-content: all | ||
96 | semantic-checks: on | ||
97 | acl: [local_acl] | ||
98 | |||
99 | zone: | ||
100 | - domain: yggdrasil | ||
101 | template: local_zone | ||
102 | file: ${./zones/yggdrasil.soa} | ||
103 | - domain: lan.yggdrasil | ||
104 | template: local_zone | ||
105 | file: ${./zones/yggdrasil.lan.soa} | ||
106 | - domain: mgmt.yggdrasil | ||
107 | template: local_zone | ||
108 | file: ${./zones/yggdrasil.mgmt.soa} | ||
109 | - domain: 141.10.in-addr.arpa | ||
110 | template: local_zone | ||
111 | file: ${./zones/arpa.in-addr.10.141.soa} | ||
112 | - domain: 0.141.10.in-addr.arpa | ||
113 | template: local_zone | ||
114 | file: ${./zones/arpa.in-addr.10.141.0.soa} | ||
115 | - domain: 1.141.10.in-addr.arpa | ||
116 | template: local_zone | ||
117 | file: ${./zones/arpa.in-addr.10.141.1.soa} | ||
118 | ''; | ||
119 | }; | ||
120 | |||
121 | sops.secrets = listToAttrs (map ({name, path}: nameValuePair name { | ||
122 | format = "binary"; | ||
123 | owner = "knot"; | ||
124 | sopsFile = path; | ||
125 | }) knotKeys); | ||
126 | }; | ||
127 | } | ||
diff --git a/hosts/vidhar/dns/key.gup b/hosts/vidhar/dns/key.gup new file mode 100644 index 00000000..83c36b0e --- /dev/null +++ b/hosts/vidhar/dns/key.gup | |||
@@ -0,0 +1,6 @@ | |||
1 | #!/usr/bin/env zsh | ||
2 | |||
3 | keyName=${${2:t}%.yaml}_key | ||
4 | |||
5 | keymgr -t ${keyName} > $1 | ||
6 | sops -p 'A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362,30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51' --input-type=binary --output-type=binary -e -i $1 | ||
diff --git a/hosts/vidhar/dns/keys/local.yaml b/hosts/vidhar/dns/keys/local.yaml new file mode 100644 index 00000000..e66f4b61 --- /dev/null +++ b/hosts/vidhar/dns/keys/local.yaml | |||
@@ -0,0 +1,26 @@ | |||
1 | { | ||
2 | "data": "ENC[AES256_GCM,data:hpWdnmsmBmO01PkTlmRLHdmXrPX6POuU/PWrOUMgH6glThzsFdk84tskUExnsl3N39ryCmgZwotIZ8zCWduPBn+nN3VTEP5Z4xltC8I82C6F283gWC3gxpTXFSwF7JetRM5uBQV0FFd9iXHUySEHdzoRqsGuZTMYdT44Bm6gGQHyt7N3/EeLHyJKa7MH+SLLznjlaTnmrAxEyGP8Talda0s/mkh4nRqQnbxX6aOTQpQ=,iv:eRQuxRNQGU2Zwudaqjr+QvLLpJ5QqrjvAN/uL6x8hUs=,tag:CYEt1K+gOGiOX9qQR/Q9jw==,type:str]", | ||
3 | "sops": { | ||
4 | "kms": null, | ||
5 | "gcp_kms": null, | ||
6 | "azure_kv": null, | ||
7 | "hc_vault": null, | ||
8 | "age": null, | ||
9 | "lastmodified": "2022-03-15T13:30:32Z", | ||
10 | "mac": "ENC[AES256_GCM,data:PG4ywF/U6ITmdRB4OU5uXu54YabYt9Yyy2oYEMx0XpMlpKWH5bmg2qQNFakxBD6wCy2H6e3LmwcUl2N692crm3n/qQRNPQ0ETHVlaPlRFG85tiz/Ngi6tasoKG+ciLAXMy05c+yY6oENN7grm1TTMZRGSIyxo27ZU+k4kmz4eVM=,iv:fluwCnXHAJ/z2oGWCLXbjooymXbViPrZdVJOnoSrn1g=,tag:QtNGIKMBDtKnb3JPuRqmiA==,type:str]", | ||
11 | "pgp": [ | ||
12 | { | ||
13 | "created_at": "2022-03-15T13:30:31Z", | ||
14 | "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DbYDvGI0HDr0SAQdAQAK54tXtgsLn6MmWQC/4irGRJd160lpAxCIT+nt/MBUw\nznjpLnbZXSft1RQI6/B95udkm0U/MBKt7wSMe9I/Po44qJrqHqb4jofz6NCeqxD3\n0l4Bl/DpnWfam9knZFQ9NIEaKYWXSmVuxVduhpYYGopXUrKol8BVTdXU6qHaPKgV\nQc72FvezgyHngZwXNEggvS1IWPq4m6pamLi77e8hNGiQx5CiaFXWwCP4gY6A80pS\n=FNi5\n-----END PGP MESSAGE-----\n", | ||
15 | "fp": "A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362" | ||
16 | }, | ||
17 | { | ||
18 | "created_at": "2022-03-15T13:30:31Z", | ||
19 | "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdA+/lLWPxgadpnWQlbAVbdzpbevoVKuaGrQmp79m4wKycw\nBeErMZugDNzHWXkTHXez5SpS94RYlGzhLcVLGfMg7C0h3wN192QaMrcH01udnjhK\n0l4BRYt9+9CCZL+Nb/ss+BIyOAFCZi2RkwzvXl9wVk+mb1As9/UYml9zqh/juU5F\nBZXqwNPA5RSNCoB0wy3A5yIB3uniMuYczTs67VHJ5cw2VVSQvXF5zue90i2F4mC4\n=IsU1\n-----END PGP MESSAGE-----\n", | ||
20 | "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51" | ||
21 | } | ||
22 | ], | ||
23 | "unencrypted_suffix": "_unencrypted", | ||
24 | "version": "3.7.1" | ||
25 | } | ||
26 | } \ No newline at end of file | ||
diff --git a/hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa new file mode 100644 index 00000000..75e6b3a8 --- /dev/null +++ b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.0.soa | |||
@@ -0,0 +1,12 @@ | |||
1 | $ORIGIN 0.141.10.in-addr.arpa. | ||
2 | $TTL 300 | ||
3 | @ IN SOA vidhar.lan.yggdrasil. root.yggdrasil.li. ( | ||
4 | 2022031504 ; serial | ||
5 | 300 ; refresh | ||
6 | 300 ; retry | ||
7 | 300 ; expire | ||
8 | 300 ; min TTL | ||
9 | ) | ||
10 | |||
11 | IN NS vidhar.lan.yggdrasil. | ||
12 | 1 IN PTR vidhar.lan.yggdrasil. | ||
diff --git a/hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa new file mode 100644 index 00000000..2d535d56 --- /dev/null +++ b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.1.soa | |||
@@ -0,0 +1,14 @@ | |||
1 | $ORIGIN 1.141.10.in-addr.arpa. | ||
2 | $TTL 300 | ||
3 | @ IN SOA vidhar.mgmt.yggdrasil. root.yggdrasil.li. ( | ||
4 | 2022031505 ; serial | ||
5 | 300 ; refresh | ||
6 | 300 ; retry | ||
7 | 300 ; expire | ||
8 | 300 ; min TTL | ||
9 | ) | ||
10 | |||
11 | IN NS vidhar.mgmt.yggdrasil. | ||
12 | 1 IN PTR vidhar.mgmt.yggdrasil. | ||
13 | 2 IN PTR switch01.mgmt.yggdrasil. | ||
14 | 4 IN PTR ap01.mgmt.yggdrasil. | ||
diff --git a/hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa new file mode 100644 index 00000000..ea5a35f3 --- /dev/null +++ b/hosts/vidhar/dns/zones/arpa.in-addr.10.141.soa | |||
@@ -0,0 +1,11 @@ | |||
1 | $ORIGIN 141.10.in-addr.arpa. | ||
2 | $TTL 300 | ||
3 | @ IN SOA vidhar.lan.yggdrasil. root.yggdrasil.li. ( | ||
4 | 2022031505 ; serial | ||
5 | 300 ; refresh | ||
6 | 300 ; retry | ||
7 | 300 ; expire | ||
8 | 300 ; min TTL | ||
9 | ) | ||
10 | |||
11 | IN NS vidhar.lan.yggdrasil. | ||
diff --git a/hosts/vidhar/dns/zones/yggdrasil.lan.soa b/hosts/vidhar/dns/zones/yggdrasil.lan.soa new file mode 100644 index 00000000..c58b9a13 --- /dev/null +++ b/hosts/vidhar/dns/zones/yggdrasil.lan.soa | |||
@@ -0,0 +1,13 @@ | |||
1 | $ORIGIN lan.yggdrasil. | ||
2 | $TTL 300 | ||
3 | @ IN SOA vidhar.lan.yggdrasil. root.yggdrasil.li. ( | ||
4 | 2022031504 ; serial | ||
5 | 300 ; refresh | ||
6 | 300 ; retry | ||
7 | 300 ; expire | ||
8 | 300 ; min TTL | ||
9 | ) | ||
10 | |||
11 | IN NS vidhar.lan.yggdrasil. | ||
12 | |||
13 | vidhar IN A 10.141.0.1 | ||
diff --git a/hosts/vidhar/dns/zones/yggdrasil.mgmt.soa b/hosts/vidhar/dns/zones/yggdrasil.mgmt.soa new file mode 100644 index 00000000..8a630a9a --- /dev/null +++ b/hosts/vidhar/dns/zones/yggdrasil.mgmt.soa | |||
@@ -0,0 +1,15 @@ | |||
1 | $ORIGIN mgmt.yggdrasil. | ||
2 | $TTL 300 | ||
3 | @ IN SOA vidhar.mgmt.yggdrasil. root.yggdrasil.li. ( | ||
4 | 2022031505 ; serial | ||
5 | 300 ; refresh | ||
6 | 300 ; retry | ||
7 | 300 ; expire | ||
8 | 300 ; min TTL | ||
9 | ) | ||
10 | |||
11 | IN NS vidhar.mgmt.yggdrasil. | ||
12 | |||
13 | vidhar IN A 10.141.1.1 | ||
14 | switch01 IN A 10.141.1.2 | ||
15 | ap01 IN A 10.141.1.4 | ||
diff --git a/hosts/vidhar/dns/zones/yggdrasil.soa b/hosts/vidhar/dns/zones/yggdrasil.soa new file mode 100644 index 00000000..6e66a063 --- /dev/null +++ b/hosts/vidhar/dns/zones/yggdrasil.soa | |||
@@ -0,0 +1,21 @@ | |||
1 | $ORIGIN yggdrasil. | ||
2 | $TTL 300 | ||
3 | @ IN SOA vidhar.yggdrasil. root.yggdrasil.li. ( | ||
4 | 2022031504 ; serial | ||
5 | 300 ; refresh | ||
6 | 300 ; retry | ||
7 | 300 ; expire | ||
8 | 300 ; min TTL | ||
9 | ) | ||
10 | |||
11 | IN NS vidhar.yggdrasil. | ||
12 | |||
13 | surtr IN AAAA 2a03:4000:52:ada:1:: | ||
14 | vidhar IN AAAA 2a03:4000:52:ada:1:1:: | ||
15 | sif IN AAAA 2a03:4000:52:ada:1:2:: | ||
16 | |||
17 | grafana.vidhar IN CNAME vidhar.yggdrasil. | ||
18 | |||
19 | |||
20 | vidhar.lan IN A 10.141.0.1 | ||
21 | vidhar.mgmt IN A 10.141.1.1 | ||
diff --git a/hosts/vidhar/network/default.nix b/hosts/vidhar/network/default.nix index 2d9a7b8f..85ddd4ef 100644 --- a/hosts/vidhar/network/default.nix +++ b/hosts/vidhar/network/default.nix | |||
@@ -1,6 +1,6 @@ | |||
1 | { flake, config, lib, pkgs, ... }: | 1 | { ... }: |
2 | { | 2 | { |
3 | imports = [ ./dsl.nix ./bifrost ]; | 3 | imports = [ ./dsl.nix ./bifrost ./dhcp ]; |
4 | 4 | ||
5 | config = { | 5 | config = { |
6 | networking = { | 6 | networking = { |
@@ -53,132 +53,6 @@ | |||
53 | llmnr = "false"; | 53 | llmnr = "false"; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | services.kea = { | ||
57 | dhcp4 = { | ||
58 | enable = true; | ||
59 | settings = { | ||
60 | valid-lifetime = 4000; | ||
61 | rebind-timer = 2000; | ||
62 | renew-timer = 1000; | ||
63 | |||
64 | interfaces-config = { | ||
65 | interfaces = [ "lan" "mgmt" ]; | ||
66 | }; | ||
67 | |||
68 | lease-database = { | ||
69 | name = "/var/lib/kea/dhcp4.leases"; | ||
70 | persist = true; | ||
71 | type = "memfile"; | ||
72 | }; | ||
73 | |||
74 | client-classes = [ | ||
75 | { name = "ipxe"; | ||
76 | test = "option[77].hex == 'iPXE'"; | ||
77 | next-server = "10.141.0.1"; | ||
78 | boot-file-name = "netboot.ipxe"; | ||
79 | only-if-required = true; | ||
80 | } | ||
81 | { name = "uefi-64"; | ||
82 | test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00007' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00008' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00009'"; | ||
83 | only-if-required = true; | ||
84 | option-data = [ | ||
85 | { name = "tftp-server-name"; data = "10.141.0.1"; } | ||
86 | ]; | ||
87 | boot-file-name = "ipxe.efi"; | ||
88 | } | ||
89 | { name = "uefi-32"; | ||
90 | test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'"; | ||
91 | only-if-required = true; | ||
92 | option-data = [ | ||
93 | { name = "tftp-server-name"; data = "10.141.0.1"; } | ||
94 | ]; | ||
95 | boot-file-name = "i386-ipxe.efi"; | ||
96 | } | ||
97 | { name = "legacy"; | ||
98 | test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'"; | ||
99 | only-if-required = true; | ||
100 | option-data = [ | ||
101 | { name = "tftp-server-name"; data = "10.141.0.1"; } | ||
102 | ]; | ||
103 | boot-file-name = "undionly.kpxe"; | ||
104 | } | ||
105 | ]; | ||
106 | |||
107 | subnet4 = [ | ||
108 | { subnet = "10.141.0.0/24"; | ||
109 | option-data = [ | ||
110 | { name = "domain-name-servers"; | ||
111 | data = "10.141.0.1"; | ||
112 | } | ||
113 | { name = "broadcast-address"; | ||
114 | data = "10.141.0.255"; | ||
115 | } | ||
116 | { name = "routers"; | ||
117 | data = "10.141.0.1"; | ||
118 | } | ||
119 | { name = "domain-name"; | ||
120 | data = "yggdrasil"; | ||
121 | } | ||
122 | ]; | ||
123 | pools = [ { pool = "10.141.0.128 - 10.141.0.254"; } ]; | ||
124 | reservations = []; | ||
125 | require-client-classes = ["ipxe" "uefi-64" "uefi-32" "legacy"]; | ||
126 | } | ||
127 | { subnet = "10.141.1.0/24"; | ||
128 | option-data = [ | ||
129 | { name = "domain-name-servers"; | ||
130 | data = "10.141.1.1"; | ||
131 | } | ||
132 | { name = "broadcast-address"; | ||
133 | data = "10.141.1.255"; | ||
134 | } | ||
135 | ]; | ||
136 | pools = [ { pool = "10.141.1.128 - 10.141.1.254"; } ]; | ||
137 | reservations = [ | ||
138 | { hostname = "switch01"; | ||
139 | hw-address = "60:a4:b7:53:94:b5"; | ||
140 | ip-address = "10.141.1.2"; | ||
141 | } | ||
142 | { hostname = "ap01"; | ||
143 | hw-address = "74:ac:b9:29:ad:9a"; | ||
144 | ip-address = "10.141.1.4"; | ||
145 | } | ||
146 | ]; | ||
147 | } | ||
148 | { subnet = "10.141.2.0/24"; | ||
149 | option-data = [ | ||
150 | { name = "domain-name-servers"; | ||
151 | data = "10.141.2.1"; | ||
152 | } | ||
153 | { name = "broadcast-address"; | ||
154 | data = "10.141.2.255"; | ||
155 | } | ||
156 | { name = "routers"; | ||
157 | data = "10.141.2.1"; | ||
158 | } | ||
159 | ]; | ||
160 | pools = [ { pool = "10.141.2.128 - 10.141.2.254"; } ]; | ||
161 | reservations = []; | ||
162 | } | ||
163 | ]; | ||
164 | }; | ||
165 | }; | ||
166 | dhcp6 = { | ||
167 | enable = true; | ||
168 | settings = { | ||
169 | interfaces-config = { | ||
170 | interfaces = [ "lan" ]; | ||
171 | }; | ||
172 | |||
173 | lease-database = { | ||
174 | name = "/var/lib/kea/dhcp6.leases"; | ||
175 | persist = true; | ||
176 | type = "memfile"; | ||
177 | }; | ||
178 | }; | ||
179 | }; | ||
180 | }; | ||
181 | |||
182 | systemd.network.networks = { | 56 | systemd.network.networks = { |
183 | "eno1" = { | 57 | "eno1" = { |
184 | matchConfig.Name = "eno1"; | 58 | matchConfig.Name = "eno1"; |
@@ -191,27 +65,5 @@ | |||
191 | networkConfig.LinkLocalAddressing = "no"; | 65 | networkConfig.LinkLocalAddressing = "no"; |
192 | }; | 66 | }; |
193 | }; | 67 | }; |
194 | |||
195 | systemd.services."installer-atftpd" = { | ||
196 | description = "TFTP Server for PXE Booting NixOS Installer"; | ||
197 | after = [ "network.target" ]; | ||
198 | wantedBy = [ "multi-user.target" ]; | ||
199 | serviceConfig.ExecStart = let | ||
200 | installerBuild = flake.nixosConfigurations.installer-x86_64-linux-netboot.config.system.build; | ||
201 | ipxe = pkgs.ipxe.override { | ||
202 | additionalTargets = { | ||
203 | "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi"; | ||
204 | }; | ||
205 | }; | ||
206 | tftpRoot = pkgs.runCommandLocal "installer-netboot" {} '' | ||
207 | mkdir -p $out | ||
208 | install -m 0444 -t $out \ | ||
209 | ${installerBuild.netbootRamdisk}/initrd \ | ||
210 | ${installerBuild.kernel}/bzImage \ | ||
211 | ${installerBuild.netbootIpxeScript}/netboot.ipxe \ | ||
212 | ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe | ||
213 | ''; | ||
214 | in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=10.141.0.1 ${tftpRoot}"; | ||
215 | }; | ||
216 | }; | 68 | }; |
217 | } | 69 | } |
diff --git a/hosts/vidhar/network/dhcp/default.nix b/hosts/vidhar/network/dhcp/default.nix new file mode 100644 index 00000000..ccc22c7f --- /dev/null +++ b/hosts/vidhar/network/dhcp/default.nix | |||
@@ -0,0 +1,264 @@ | |||
1 | { flake, config, pkgs, lib, ... }: | ||
2 | { | ||
3 | config = { | ||
4 | services.kea = { | ||
5 | dhcp4 = { | ||
6 | enable = true; | ||
7 | settings = { | ||
8 | valid-lifetime = 4000; | ||
9 | rebind-timer = 2000; | ||
10 | renew-timer = 1000; | ||
11 | |||
12 | interfaces-config = { | ||
13 | interfaces = [ "lan" "mgmt" ]; | ||
14 | }; | ||
15 | |||
16 | lease-database = { | ||
17 | name = "/var/lib/kea/dhcp4.leases"; | ||
18 | persist = true; | ||
19 | type = "memfile"; | ||
20 | }; | ||
21 | |||
22 | client-classes = [ | ||
23 | { name = "ipxe"; | ||
24 | test = "option[77].hex == 'iPXE'"; | ||
25 | next-server = "10.141.0.1"; | ||
26 | boot-file-name = "netboot.ipxe"; | ||
27 | only-if-required = true; | ||
28 | } | ||
29 | { name = "uefi-64"; | ||
30 | test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00007' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00008' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00009'"; | ||
31 | only-if-required = true; | ||
32 | option-data = [ | ||
33 | { name = "tftp-server-name"; data = "10.141.0.1"; } | ||
34 | ]; | ||
35 | boot-file-name = "ipxe.efi"; | ||
36 | } | ||
37 | { name = "uefi-32"; | ||
38 | test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00002' or substring(option[60].hex,0,20) == 'PXEClient:Arch:00006'"; | ||
39 | only-if-required = true; | ||
40 | option-data = [ | ||
41 | { name = "tftp-server-name"; data = "10.141.0.1"; } | ||
42 | ]; | ||
43 | boot-file-name = "i386-ipxe.efi"; | ||
44 | } | ||
45 | { name = "legacy"; | ||
46 | test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'"; | ||
47 | only-if-required = true; | ||
48 | option-data = [ | ||
49 | { name = "tftp-server-name"; data = "10.141.0.1"; } | ||
50 | ]; | ||
51 | boot-file-name = "undionly.kpxe"; | ||
52 | } | ||
53 | ]; | ||
54 | |||
55 | dhcp-ddns.enable-updates = true; | ||
56 | ddns-send-updates = false; | ||
57 | ddns-override-client-update = true; | ||
58 | ddns-override-no-update = true; | ||
59 | ddns-replace-client-name = "when-not-present"; | ||
60 | ddns-generated-prefix = "noname"; | ||
61 | ddns-update-on-renew = true; | ||
62 | |||
63 | subnet4 = [ | ||
64 | { subnet = "10.141.0.0/24"; | ||
65 | option-data = [ | ||
66 | { name = "domain-name-servers"; | ||
67 | data = "10.141.0.1"; | ||
68 | } | ||
69 | { name = "broadcast-address"; | ||
70 | data = "10.141.0.255"; | ||
71 | } | ||
72 | { name = "routers"; | ||
73 | data = "10.141.0.1"; | ||
74 | } | ||
75 | { name = "domain-name"; | ||
76 | data = "yggdrasil"; | ||
77 | } | ||
78 | { name = "domain-search"; | ||
79 | data = "lan.yggdrasil, yggdrasil"; | ||
80 | } | ||
81 | ]; | ||
82 | ddns-send-updates = true; | ||
83 | ddns-qualifying-suffix = "lan.yggdrasil"; | ||
84 | pools = [ { pool = "10.141.0.128 - 10.141.0.254"; } ]; | ||
85 | require-client-classes = ["ipxe" "uefi-64" "uefi-32" "legacy"]; | ||
86 | reservations = [ | ||
87 | { hostname = "sif"; | ||
88 | hw-address = "3c:e1:a1:52:24:35"; | ||
89 | } | ||
90 | { hostname = "sif"; | ||
91 | hw-address = "ee:32:68:76:83:ac"; | ||
92 | } | ||
93 | { hostname = "sif"; | ||
94 | hw-address = "48:2a:e3:64:62:97"; | ||
95 | } | ||
96 | { hostname = "eos"; | ||
97 | hw-address = "00:d8:61:79:c5:40"; | ||
98 | } | ||
99 | ]; | ||
100 | } | ||
101 | { subnet = "10.141.1.0/24"; | ||
102 | option-data = [ | ||
103 | { name = "domain-name-servers"; | ||
104 | data = "10.141.1.1"; | ||
105 | } | ||
106 | { name = "broadcast-address"; | ||
107 | data = "10.141.1.255"; | ||
108 | } | ||
109 | { name = "domain-name"; | ||
110 | data = "yggdrasil"; | ||
111 | } | ||
112 | { name = "domain-search"; | ||
113 | data = "mgmt.yggdrasil, yggdrasil"; | ||
114 | } | ||
115 | ]; | ||
116 | ddns-send-updates = true; | ||
117 | ddns-qualifying-suffix = "mgmt.yggdrasil"; | ||
118 | pools = [ { pool = "10.141.1.128 - 10.141.1.254"; } ]; | ||
119 | reservations = [ | ||
120 | { hostname = "switch01"; | ||
121 | hw-address = "60:a4:b7:53:94:b5"; | ||
122 | ip-address = "10.141.1.2"; | ||
123 | } | ||
124 | { hostname = "ap01"; | ||
125 | hw-address = "74:ac:b9:29:ad:9a"; | ||
126 | ip-address = "10.141.1.4"; | ||
127 | } | ||
128 | ]; | ||
129 | } | ||
130 | { subnet = "10.141.2.0/24"; | ||
131 | option-data = [ | ||
132 | { name = "domain-name-servers"; | ||
133 | data = "10.141.2.1"; | ||
134 | } | ||
135 | { name = "broadcast-address"; | ||
136 | data = "10.141.2.255"; | ||
137 | } | ||
138 | { name = "routers"; | ||
139 | data = "10.141.2.1"; | ||
140 | } | ||
141 | ]; | ||
142 | ddns-send-updates = false; | ||
143 | pools = [ { pool = "10.141.2.128 - 10.141.2.254"; } ]; | ||
144 | reservations = []; | ||
145 | } | ||
146 | ]; | ||
147 | }; | ||
148 | }; | ||
149 | dhcp6 = { | ||
150 | enable = true; | ||
151 | settings = { | ||
152 | interfaces-config = { | ||
153 | interfaces = [ "lan" ]; | ||
154 | }; | ||
155 | |||
156 | lease-database = { | ||
157 | name = "/var/lib/kea/dhcp6.leases"; | ||
158 | persist = true; | ||
159 | type = "memfile"; | ||
160 | }; | ||
161 | }; | ||
162 | }; | ||
163 | dhcp-ddns = { | ||
164 | enable = true; | ||
165 | settings = { | ||
166 | forward-ddns = { | ||
167 | ddns-domains = [ | ||
168 | { name = "lan.yggdrasil."; | ||
169 | dns-servers = [ | ||
170 | { ip-address = "127.0.0.1"; | ||
171 | port = 5353; | ||
172 | key-name = "local_key"; | ||
173 | } | ||
174 | ]; | ||
175 | } | ||
176 | { name = "mgmt.yggdrasil."; | ||
177 | dns-servers = [ | ||
178 | { ip-address = "127.0.0.1"; | ||
179 | port = 5353; | ||
180 | key-name = "local_key"; | ||
181 | } | ||
182 | ]; | ||
183 | } | ||
184 | ]; | ||
185 | }; | ||
186 | reverse-ddns = { | ||
187 | ddns-domains = [ | ||
188 | { name = "0.141.10.in-addr.arpa."; | ||
189 | dns-servers = [ | ||
190 | { ip-address = "127.0.0.1"; | ||
191 | port = 5353; | ||
192 | key-name = "local_key"; | ||
193 | } | ||
194 | ]; | ||
195 | } | ||
196 | { name = "1.141.10.in-addr.arpa."; | ||
197 | dns-servers = [ | ||
198 | { ip-address = "127.0.0.1"; | ||
199 | port = 5353; | ||
200 | key-name = "local_key"; | ||
201 | } | ||
202 | ]; | ||
203 | } | ||
204 | ]; | ||
205 | }; | ||
206 | }; | ||
207 | }; | ||
208 | }; | ||
209 | |||
210 | systemd.services.kea-dhcp-ddns-server = { | ||
211 | preStart = let | ||
212 | configLines = [ | ||
213 | "<?include \"\${CREDENTIALS_DIRECTORY}/knot-tsig.json.frag\"?>" | ||
214 | ] ++ lib.mapAttrsToList (k: v: | ||
215 | "\"${k}\": ${builtins.toJSON v}" | ||
216 | ) config.services.kea.dhcp-ddns.settings; | ||
217 | |||
218 | config-template = pkgs.writeText "dhcp-ddns.conf" '' | ||
219 | {"DhcpDdns": { | ||
220 | ${lib.concatStringsSep ",\n " configLines} | ||
221 | }} | ||
222 | ''; | ||
223 | in '' | ||
224 | ${pkgs.envsubst}/bin/envsubst -i "${config-template}" -o "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" | ||
225 | ''; | ||
226 | |||
227 | serviceConfig = { | ||
228 | ExecStart = lib.mkForce '' | ||
229 | ${pkgs.kea}/bin/kea-dhcp-ddns -c "''${RUNTIME_DIRECTORY}/dhcp-ddns.conf" ${lib.escapeShellArgs config.services.kea.dhcp-ddns.extraArgs} | ||
230 | ''; | ||
231 | LoadCredential = [ | ||
232 | "knot-tsig.json.frag:${config.sops.secrets."kea-knot-tsig.json.frag".path}" | ||
233 | ]; | ||
234 | }; | ||
235 | }; | ||
236 | |||
237 | sops.secrets."kea-knot-tsig.json.frag" = { | ||
238 | format = "binary"; | ||
239 | sopsFile = ./knot-tsig.json.frag; | ||
240 | }; | ||
241 | |||
242 | systemd.services."installer-atftpd" = { | ||
243 | description = "TFTP Server for PXE Booting NixOS Installer"; | ||
244 | after = [ "network.target" ]; | ||
245 | wantedBy = [ "multi-user.target" ]; | ||
246 | serviceConfig.ExecStart = let | ||
247 | installerBuild = flake.nixosConfigurations.installer-x86_64-linux-netboot.config.system.build; | ||
248 | ipxe = pkgs.ipxe.override { | ||
249 | additionalTargets = { | ||
250 | "bin-i386-efi/ipxe.efi" = "i386-ipxe.efi"; | ||
251 | }; | ||
252 | }; | ||
253 | tftpRoot = pkgs.runCommandLocal "installer-netboot" {} '' | ||
254 | mkdir -p $out | ||
255 | install -m 0444 -t $out \ | ||
256 | ${installerBuild.netbootRamdisk}/initrd \ | ||
257 | ${installerBuild.kernel}/bzImage \ | ||
258 | ${installerBuild.netbootIpxeScript}/netboot.ipxe \ | ||
259 | ${ipxe}/ipxe.efi ${ipxe}/i386-ipxe.efi ${ipxe}/undionly.kpxe | ||
260 | ''; | ||
261 | in "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address=10.141.0.1 ${tftpRoot}"; | ||
262 | }; | ||
263 | }; | ||
264 | } | ||
diff --git a/hosts/vidhar/network/dhcp/knot-tsig.json.frag b/hosts/vidhar/network/dhcp/knot-tsig.json.frag new file mode 100644 index 00000000..75deb41c --- /dev/null +++ b/hosts/vidhar/network/dhcp/knot-tsig.json.frag | |||
@@ -0,0 +1,26 @@ | |||
1 | { | ||
2 | "data": "ENC[AES256_GCM,data:cGcoqYZ341xQOFukDm4J5KDfG6+NaNbk2U2k4YGneRsAoPJZe/8KDmVr8TBWFCXXbuzeCGbiuXRVBmtYSEIqbqTN4u00RdQgpeL72cB3ZFd2c7cideEQV5z802pqFfXSlmLBC01OPG3TwAgk6xhQYSn5IcBTIL6fRF235Y9Q8k/X96rhfwPRVq84,iv:UoweWBcVuQIXeWFFl/WNUHLXG8nEri1UuTskC2I26hU=,tag:TJldVr2LDTmKA3ozZoX+cQ==,type:str]", | ||
3 | "sops": { | ||
4 | "kms": null, | ||
5 | "gcp_kms": null, | ||
6 | "azure_kv": null, | ||
7 | "hc_vault": null, | ||
8 | "age": null, | ||
9 | "lastmodified": "2022-03-15T13:52:17Z", | ||
10 | "mac": "ENC[AES256_GCM,data:rTelaGx5S2E2oYPNGfctFbgDKdyRX8tpVTqLtpcCAJ8MS5ppFTjnSwYi4yQHvTicfAPNz7hGJYAnTdyC2QDTciJgkS6KC3CCXWCimkTybBdVW4Azwz9iBZCpWu+rB1vcQhSLlLCaKmKskkqDZZ5+mfuaXc+TT2uwTA0SDtZWvnM=,iv:ANCZ1fHy6w/svEE53o7rWsp5qU15qoriqyVMzClH6J0=,tag:H92RM5GuLIl9/kslq4tzkQ==,type:str]", | ||
11 | "pgp": [ | ||
12 | { | ||
13 | "created_at": "2022-03-15T13:50:52Z", | ||
14 | "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DbYDvGI0HDr0SAQdANAtB0un04iI+foGRefRK249LhT6Mz+yzdhkWa0UYoxcw\nUGDSh6la4ijiaqdeVfJ3vckXfAqee7dLseNQ64dafdlk2hVI0ZNv6mjfwgWk698v\n0l4B4EOHfDrmFNhZFcj1/sCRnukgx7PSeybZn3miTLQgMGOydrfYuisA3we/4EUo\nU55PGINdtAu268OUHQjj3yF1S72Yeh1MXEdvajRQdqorQJ4TpsPUtJolM25Df/kK\n=etIn\n-----END PGP MESSAGE-----\n", | ||
15 | "fp": "A1C7C95E6CAF0A965CB47277BCF50A89C1B1F362" | ||
16 | }, | ||
17 | { | ||
18 | "created_at": "2022-03-15T13:50:52Z", | ||
19 | "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DXxoViZlp6dISAQdABm/Qf3pX4SxvTzq6sJKWc5o3Fzu/nH3XAH1WE2L/BUMw\nMFFmYmq3399ZcZ6JvaHdbJFUdavo/+wOg3ecWok039wbsr9qwn8YA4cR7VBsUPLa\n0l4BxuaiT3M+mTVvr5WpGFc3Xj7Mp4/z6hBUS+qTFIFZI2U5JsmZgC7VGTm+dlSJ\nexN6yr9mlQXvDIkx8w5/eaiYGViZ90SxN9BPYDqfGGigAw+xdXaafcOx8uBldAL1\n=HLRI\n-----END PGP MESSAGE-----\n", | ||
20 | "fp": "30D3453B8CD02FE2A3E7C78C0FB536FB87AE8F51" | ||
21 | } | ||
22 | ], | ||
23 | "unencrypted_suffix": "_unencrypted", | ||
24 | "version": "3.7.1" | ||
25 | } | ||
26 | } \ No newline at end of file | ||
diff --git a/system-profiles/openssh/known-hosts/Gupfile b/system-profiles/openssh/known-hosts/Gupfile index 9217f43f..7aead812 100644 --- a/system-profiles/openssh/known-hosts/Gupfile +++ b/system-profiles/openssh/known-hosts/Gupfile | |||
@@ -1,2 +1,4 @@ | |||
1 | ca-sign.gup: | 1 | ca-sign.gup: |
2 | **/*-cert.pub \ No newline at end of file | 2 | **/*-cert.pub |
3 | ca-resign-dir.gup: | ||
4 | * \ No newline at end of file | ||
diff --git a/system-profiles/openssh/known-hosts/ca-resign-dir.gup b/system-profiles/openssh/known-hosts/ca-resign-dir.gup new file mode 100644 index 00000000..ca1d08fd --- /dev/null +++ b/system-profiles/openssh/known-hosts/ca-resign-dir.gup | |||
@@ -0,0 +1,6 @@ | |||
1 | #!/usr/bin/env zsh | ||
2 | set -eu | ||
3 | |||
4 | gup --always | ||
5 | gup -u ${2}/*-cert.pub | ||
6 | touch $2 \ No newline at end of file | ||
diff --git a/system-profiles/openssh/known-hosts/sif/ed25519-cert.pub b/system-profiles/openssh/known-hosts/sif/ed25519-cert.pub index ccc8118d..3ead53f4 100644 --- a/system-profiles/openssh/known-hosts/sif/ed25519-cert.pub +++ b/system-profiles/openssh/known-hosts/sif/ed25519-cert.pub | |||
@@ -1 +1 @@ | |||
ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIMrGeBKnPV6ns7yb1/GEI44htBzL8vJMD9vGIOQi9FQFAAAAIOfiwlzGcNQjamtIwv7fmXnddjajraeovaM6gRNui1+vQAAAAGIHseIAAAACAAAAJGM1OWZlN2ZmLWRkZDUtNDMyMC1iYjA4LWIzYWJkZDM1NWE1MgAAABEAAAANc2lmLnlnZ2RyYXNpbAAAAABiBmBYAAAAAGOwzQAAAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC1t7HamptQ49VXtSZyRsaOuja5In1N0U9Ybdiu6ztziAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEBiwiSUhTAo3abyR6Vj6my+N/aLb/zazhB9mXSkXMC3YMkLuuwEk3yqVDZYaBD1pcaH03PQvj6haHaHLZdiK+sC sif/ed25519.pub | ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIJbwfRloLc7IkLWJEjleSrcc62G4Sw+XtW6+nVH5M/0yAAAAIOfiwlzGcNQjamtIwv7fmXnddjajraeovaM6gRNui1+vQAAAAGIwrR4AAAACAAAAJDgwMGU0MjRlLTIwZmMtNDM0OS1iYThjLTk4MWRkOWE5MDkzOAAAACYAAAANc2lmLnlnZ2RyYXNpbAAAABFzaWYubGFuLnlnZ2RyYXNpbAAAAABiL1uUAAAAAGOwzQAAAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIC1t7HamptQ49VXtSZyRsaOuja5In1N0U9Ybdiu6ztziAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEB147Dt1TPNzWXf2orbcvh/VQwCik7ogRKBTvLwpCvwODyc51vbjbpV96yuOs9jEnGS7ukJMSeKtdpHzD8rKrUM sif/ed25519.pub | ||
diff --git a/system-profiles/openssh/known-hosts/sif/host-principals b/system-profiles/openssh/known-hosts/sif/host-principals index 7f9156b4..d8de4a87 100644 --- a/system-profiles/openssh/known-hosts/sif/host-principals +++ b/system-profiles/openssh/known-hosts/sif/host-principals | |||
@@ -1 +1 @@ | |||
sif.yggdrasil \ No newline at end of file | sif.yggdrasil,sif.lan.yggdrasil \ No newline at end of file | ||
diff --git a/system-profiles/openssh/known-hosts/sif/rsa-cert.pub b/system-profiles/openssh/known-hosts/sif/rsa-cert.pub index 5d591209..8120d8f3 100644 --- a/system-profiles/openssh/known-hosts/sif/rsa-cert.pub +++ b/system-profiles/openssh/known-hosts/sif/rsa-cert.pub | |||
@@ -1 +1 @@ | |||
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgdlvyraQkUAx9hKBCtObbfNB85CHxTKya7FOzJa2XQUYAAAADAQABAAACAQCeFqJep1CuWakcoiAkz4bSaHbAIwM89Er46o3KUpjCWGTmDmhJyBiG38pupcctH0awwElkX09GsNx230mTtjT6qcxN+vGsGMJIqFD+/7ZobSLJDHYCo6Jx23jZUjg1SqxYjwB5ooWGI61Vh6SaOy8WRrUn0q8rJyd9SEC+3tJlKO5QqRi/Vnwzj47m+YjGz2UlqJ9a4GeRh1O5SiGx5jd4a/VoeK1XJcW94XeWpPQdUGnVYUXZn9cwYVrogmXdr18ImnPxghsQg4xwS2A6KMjUw9m56XkqIq7vTslmL9JaYcjlSCHbsSVq9+Wu1oKxoyndN7Sim7SkAZwHFUEMBNlontBitgYl6z10VdKX739os6h07uXjGEs+mPk4/CkGZhvhnErV2T9FO+65jnU3mZkeX5tfJHqJ8PnDch2JD6O7+Mjpce4zs/x3mwH36peER6iiIBYGlSF0AlUDShdqj+fPWFu6gZ9piOAZ2L3YXDA0ulM6pL69SbulrUNOwtTy6LkBfKDwpaQK1KO1VOYBaKa7s+krOJXW18k+tpfo4aKSeTuwvykMPndKMKvxcsxNymkGo2AzLw017Qgshzv9rRbLNMBFd85S3krakGyBVL0HAVrAdkjvsWqj5FnHAjgBc1AZnZPbJu3g9/wm7k8rPMV0jxKMpW+zxjVFYDhFUWYp90AAAABiB7HpAAAAAgAAACRlYzcyNzM0My05ZmJkLTRhYjYtODRhZS00ODI1NTU3YjI5YTQAAAARAAAADXNpZi55Z2dkcmFzaWwAAAAAYgZgXwAAAABjsM0AAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAtbex2pqbUOPVV7UmckbGjro2uSJ9TdFPWG3Yrus7c4gAAAFMAAAALc3NoLWVkMjU1MTkAAABAremJjy9AVSoFcDjxOGnLSGJaNhZmref8a1pXJNeqarVrjIy7lkUxv/MSXfbg/Bf9/O4k+fCKalsZ1K8NVUTvCQ== sif/rsa.pub | ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgcMQpd317uQNOua7KSZOBFXItFNKFTNrDE0276zIMmkIAAAADAQABAAACAQCeFqJep1CuWakcoiAkz4bSaHbAIwM89Er46o3KUpjCWGTmDmhJyBiG38pupcctH0awwElkX09GsNx230mTtjT6qcxN+vGsGMJIqFD+/7ZobSLJDHYCo6Jx23jZUjg1SqxYjwB5ooWGI61Vh6SaOy8WRrUn0q8rJyd9SEC+3tJlKO5QqRi/Vnwzj47m+YjGz2UlqJ9a4GeRh1O5SiGx5jd4a/VoeK1XJcW94XeWpPQdUGnVYUXZn9cwYVrogmXdr18ImnPxghsQg4xwS2A6KMjUw9m56XkqIq7vTslmL9JaYcjlSCHbsSVq9+Wu1oKxoyndN7Sim7SkAZwHFUEMBNlontBitgYl6z10VdKX739os6h07uXjGEs+mPk4/CkGZhvhnErV2T9FO+65jnU3mZkeX5tfJHqJ8PnDch2JD6O7+Mjpce4zs/x3mwH36peER6iiIBYGlSF0AlUDShdqj+fPWFu6gZ9piOAZ2L3YXDA0ulM6pL69SbulrUNOwtTy6LkBfKDwpaQK1KO1VOYBaKa7s+krOJXW18k+tpfo4aKSeTuwvykMPndKMKvxcsxNymkGo2AzLw017Qgshzv9rRbLNMBFd85S3krakGyBVL0HAVrAdkjvsWqj5FnHAjgBc1AZnZPbJu3g9/wm7k8rPMV0jxKMpW+zxjVFYDhFUWYp90AAAABiMK0fAAAAAgAAACQ2MGE0ZGNhNS0yZmU1LTRjMzgtODg2NS1iMjg3MTE5ODY5MGEAAAAmAAAADXNpZi55Z2dkcmFzaWwAAAARc2lmLmxhbi55Z2dkcmFzaWwAAAAAYi9blQAAAABjsM0AAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAtbex2pqbUOPVV7UmckbGjro2uSJ9TdFPWG3Yrus7c4gAAAFMAAAALc3NoLWVkMjU1MTkAAABAmX44QPnSlaAmqRYOArvsJMeTgqCuHKA8xNGxiL3P2WG4neENHWZn7A31ZH/wYTjxD+sg49olEMFhg9ouUa0VDQ== sif/rsa.pub | ||