yep, more dotfiles
1{ self
2, config
3, pkgs
4, upkgs
5, ...
6}:
7
8let
9 inherit (self.inputs) srvos agenix tangled;
10
11 all-secrets = import ../../secrets;
12
13 ext-if = "eth0";
14 external-ip = "91.99.55.74";
15 external-netmask = 27;
16 external-gw = "144.x.x.255";
17 external-ip6 = "2a01:4f8:c2c:76d2::1";
18 external-netmask6 = 64;
19 external-gw6 = "fe80::1";
20
21 pds-port = 3001;
22 pds-hostname = "pds.wiro.world";
23
24 tangled-owner = "did:plc:xhgrjm4mcx3p5h3y6eino6ti";
25 tangled-knot-port = 3002;
26 tangled-knot-hostname = "knot.wiro.world";
27 tangled-spindle-port = 3003;
28 tangled-spindle-hostname = "spindle.wiro.world";
29
30 grafana-port = 9000;
31 grafana-hostname = "console.wiro.world";
32 prometheus-port = 9001;
33 prometheus-node-exporter-port = 9002;
34
35 thelounge-port = 3004;
36 thelounge-hostname = "lounge.wiro.world";
37in
38{
39 imports = [
40 srvos.nixosModules.server
41 srvos.nixosModules.hardware-hetzner-cloud
42 srvos.nixosModules.mixins-terminfo
43
44 agenix.nixosModules.default
45
46 tangled.nixosModules.knot
47 tangled.nixosModules.spindle
48 ];
49
50 config = {
51 age.secrets = all-secrets.deploy;
52
53 boot.loader.grub.enable = true;
54 boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" "ext4" ];
55
56 # Single network card is `eth0`
57 networking.usePredictableInterfaceNames = false;
58
59 networking.nameservers = [ "2001:4860:4860::8888" "2001:4860:4860::8844" ];
60
61 networking = {
62 interfaces.${ext-if} = {
63 ipv4.addresses = [{ address = external-ip; prefixLength = external-netmask; }];
64 ipv6.addresses = [{ address = external-ip6; prefixLength = external-netmask6; }];
65 };
66 defaultGateway = { interface = ext-if; address = external-gw; };
67 defaultGateway6 = { interface = ext-if; address = external-gw6; };
68
69 # TODO: rely on Hetzner firewall instead?
70 # firewall.enable = false;
71 firewall.allowedTCPPorts = [ 22 80 443 ];
72 };
73
74 services.openssh.enable = true;
75
76 services.qemuGuest.enable = true;
77
78 services.fail2ban = {
79 enable = true;
80
81 maxretry = 5;
82 ignoreIP = [ ];
83
84 bantime = "24h";
85 bantime-increment = {
86 enable = true;
87 multipliers = "1 2 4 8 16 32 64";
88 maxtime = "168h";
89 overalljails = true;
90 };
91
92 jails = { };
93 };
94
95 services.tailscale.enable = true;
96
97 services.pds = {
98 enable = true;
99 package = upkgs.bluesky-pds;
100
101 settings = {
102 PDS_HOSTNAME = "pds.wiro.world";
103 PDS_PORT = pds-port;
104 # is in systemd /tmp subfolder
105 LOG_DESTINATION = "/tmp/pds.log";
106 };
107
108 environmentFiles = [
109 config.age.secrets.pds-config.path
110 ];
111 };
112
113 services.caddy = {
114 enable = true;
115 package = pkgs.caddy;
116
117 globalConfig = ''
118 metrics { per_host }
119
120 on_demand_tls {
121 ask http://localhost:${toString pds-port}/tls-check
122 }
123 '';
124
125 # Grafana has its own auth
126 virtualHosts.${grafana-hostname}.extraConfig = ''
127 reverse_proxy http://localhost:${toString grafana-port}
128 '';
129
130 virtualHosts.${pds-hostname} = {
131 serverAliases = [ "*.${pds-hostname}" ];
132 extraConfig = ''
133 tls { on_demand }
134 reverse_proxy http://localhost:${toString pds-port}
135 '';
136 };
137
138 virtualHosts.${tangled-knot-hostname}.extraConfig = ''
139 reverse_proxy http://localhost:${toString tangled-knot-port}
140 '';
141
142 virtualHosts.${tangled-spindle-hostname}.extraConfig = ''
143 reverse_proxy http://localhost:${toString tangled-spindle-port}
144 '';
145
146 virtualHosts.${thelounge-hostname}.extraConfig = ''
147 reverse_proxy http://localhost:${toString thelounge-port}
148 '';
149 };
150
151 security.sudo.wheelNeedsPassword = false;
152
153 local.fragment.nix.enable = true;
154
155 programs.fish.enable = true;
156
157 services.tangled-knot = {
158 enable = true;
159 openFirewall = true;
160
161 motd = "Welcome to @wiro.world's knot!\n";
162 server = {
163 listenAddr = "localhost:${toString tangled-knot-port}";
164 hostname = tangled-knot-hostname;
165 owner = tangled-owner;
166 };
167 };
168
169
170 services.tangled-spindle = {
171 enable = true;
172
173 server = {
174 listenAddr = "localhost:${toString tangled-spindle-port}";
175 hostname = tangled-spindle-hostname;
176 owner = tangled-owner;
177 };
178 };
179
180 services.grafana = {
181 enable = true;
182
183 settings.server = {
184 http_port = grafana-port;
185 domain = grafana-hostname;
186 };
187 };
188
189 services.prometheus = {
190 enable = true;
191 port = prometheus-port;
192
193 scrapeConfigs = [
194 {
195 job_name = "caddy";
196 static_configs = [{ targets = [ "localhost:${toString 2019}" ]; }];
197 }
198 {
199 job_name = "node";
200 static_configs = [{ targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; }];
201 }
202 ];
203
204 exporters.node = {
205 enable = true;
206 port = prometheus-node-exporter-port;
207 };
208 };
209
210 services.thelounge = {
211 enable = true;
212 port = thelounge-port;
213 public = false;
214 extraConfig = {
215 host = "127.0.0.1";
216 reverseProxy = true;
217 };
218 };
219 };
220}