demiurge.scm (16605B)
1 (define-module (epistemia systems demiurge) 2 #:use-module (gnu) 3 #:use-module (gnu packages bash) 4 #:use-module (gnu packages emacs) 5 #:use-module (gnu packages golang-crypto) 6 #:use-module (gnu packages linux) 7 #:use-module (gnu packages music) 8 #:use-module (gnu packages version-control) 9 #:use-module (gnu packages vpn) 10 #:use-module (gnu services dbus) ; temp 11 #:use-module (gnu services desktop) 12 #:use-module (gnu services dns) 13 #:use-module (gnu services containers) ; temp 14 #:use-module (gnu services linux) 15 #:use-module (gnu services networking) 16 #:use-module (gnu services shepherd) 17 #:use-module (gnu services sound) 18 #:use-module (gnu services ssh) 19 #:use-module (gnu services sysctl) 20 #:use-module (gnu services vpn) 21 #:use-module (gnu services web) 22 #:use-module (gnu system accounts) 23 #:use-module (guix) 24 #:use-module (guix gexp) 25 #:use-module (guix transformations) 26 #:use-module (guix utils) 27 #:use-module (nongnu packages linux) 28 #:use-module (nongnu system linux-initrd) 29 #:use-module (epistemia bootloader) 30 #:use-module (epistemia systems base-system) 31 #:use-module (epistemia systems linux-initrd) 32 #:use-module (epistemia services age-secret) 33 #:use-module (epistemia services machine-learning) 34 #:use-module (epistemia services zfs) 35 #:use-module (epistemia packages machine-learning) 36 #:use-module (epistemia packages zfs)) 37 38 (define (nginx-reverse-proxy domain proxy-port) 39 (nginx-server-configuration 40 (server-name (list domain)) 41 (listen '("10.0.13.2:443" "[fd00:b0ba:cafe:babe::2]:443" "10.0.13.2:80" "[fd00:b0ba:cafe:babe::2]:80")) 42 (ssl-certificate "/var/demiurge.epistemia.crt") 43 (ssl-certificate-key "/var/demiurge.epistemia.key") 44 (locations 45 (list 46 (nginx-location-configuration 47 (uri "/") 48 (body `(,(string-append "proxy_pass http://127.0.0.1:" (number->string proxy-port) ";") 49 "proxy_set_header Upgrade $http_upgrade;" 50 "proxy_set_header Connection \"upgrade\";" 51 "proxy_read_timeout 3600s;" 52 "proxy_send_timeout 3600s;" 53 "client_max_body_size 10M;"))))))) 54 55 (operating-system 56 (inherit base-system) 57 (host-name "demiurge.epistemia") 58 59 (users (cons (user-account 60 (name "vin") 61 (comment "Vineet") 62 (shell (file-append bash "/bin/bash")) 63 (group "users") 64 (supplementary-groups '("wheel" "audio" "video" "input" "seat" "tty" "cgroup" "kvm"))) ;; TODO remove docker 65 %base-user-accounts)) 66 67 (kernel linux-6.18) 68 (kernel-arguments '("net.ifnames=0" 69 "modprobe.blacklist=snd_hda_intel" 70 "amdgpu.gfxoff=0" 71 "amdgpu.aspm=0" 72 "amdgpu.runpm=0")) 73 (kernel-loadable-modules (list (list zfs-linux "module"))) 74 75 (initrd (lambda (file-systems . args) 76 (apply microcode-initrd file-systems 77 #:initrd epistemia-zfs-initrd 78 #:zfs-package zfs-linux 79 args))) 80 (firmware (cons* amdgpu-firmware %base-firmware)) 81 82 (bootloader (bootloader-configuration 83 (bootloader grub-zfs) 84 (targets '("/boot/efi")))) 85 86 (file-systems (append 87 (list (file-system 88 (device "zroot/root") 89 (mount-point "/") 90 (type "zfs") 91 (check? #f) 92 (needed-for-boot? #t)) 93 (file-system 94 (device "zroot/gnu") 95 (mount-point "/gnu") 96 (type "zfs") 97 (check? #f) 98 (needed-for-boot? #t)) 99 (file-system 100 (device "zroot/var") 101 (mount-point "/var") 102 (type "zfs") 103 (check? #f) 104 (needed-for-boot? #t)) 105 (file-system 106 (device "zroot/home") 107 (mount-point "/home") 108 (type "zfs") 109 (check? #f) 110 (needed-for-boot? #t)) 111 (file-system 112 (device (uuid "F618-FA9F" 'fat)) 113 (mount-point "/boot/efi") 114 (type "vfat")) 115 (file-system 116 (device "none") 117 (mount-point "/home/vin/.local/state/runtime") 118 (type "tmpfs") 119 (options "uid=1000"))) 120 %base-file-systems)) 121 122 (packages (append (list emacs-no-x 123 git 124 zfs-linux) 125 %base-packages)) 126 127 (services (modify-services (append (list (service age-secret-service-type 128 (age-secret-configuration 129 (secrets (list 130 (age-secret 131 (name "wg0_demiurge") 132 (file (local-file "../secrets/wg0_demiurge.age"))) 133 (age-secret 134 (name "wg1_demiurge") 135 (file (local-file "../secrets/wg1_demiurge.age"))))))) 136 (simple-service 'zfs-loader 137 kernel-module-loader-service-type 138 '("zfs")) 139 (simple-service 'zfs-shepherd-services 140 shepherd-root-service-type 141 zfs-shepherd-services) 142 (simple-service 'zfs-shepherd-services-user-processes 143 user-processes-service-type 144 '(zfs-automount)) 145 (simple-service 'gpu-power-cap 146 shepherd-root-service-type 147 (list (shepherd-service 148 (provision '(gpu-power-cap)) 149 (requirement '(udev)) 150 (one-shot? #t) 151 (documentation "Set GPU power cap on boot") 152 (start #~(make-forkexec-constructor 153 (list #$(file-append bash "/bin/bash") "-c" 154 (string-append 155 "echo 294000000 > /sys/class/drm/card0/device/hwmon/hwmon*/power1_cap; " 156 "echo 294000000 > /sys/class/drm/card1/device/hwmon/hwmon*/power1_cap")))) 157 (stop #~(make-kill-destructor))))) 158 (service seatd-service-type) 159 (service iptables-service-type) 160 (service static-networking-service-type 161 (list (static-networking 162 (addresses 163 (list (network-address 164 (device "eth0") 165 (value "192.168.1.2/24")))) 166 (routes 167 (list (network-route 168 (destination "default") 169 (gateway "192.168.1.1"))))))) 170 (simple-service 'resolv-configuration 171 etc-service-type 172 `(("resolv.conf" 173 ,(plain-file "epistemia_resolv.conf" 174 (string-append 175 "nameserver ::1\n" 176 "search epistemia\n"))))) 177 (service openssh-service-type 178 (openssh-configuration 179 (permit-root-login #f) 180 (authorized-keys 181 `(("vin" ,(local-file "/data/ssh/id_ed25519.pub")) 182 ("root" ,(local-file "/data/ssh/id_ed25519.pub")))))) 183 (service unbound-service-type 184 (unbound-configuration 185 (server 186 (unbound-server 187 (interface '("::1")) 188 (hide-version #t) 189 (hide-identity #t) 190 (extra-options '((ip-freebind . "yes" ) 191 (aggressive-nsec . "no"))))) 192 (forward-zone 193 (list 194 (unbound-zone 195 (name ".") 196 (forward-addr '("10.0.13.1"))))))) 197 (service wireguard-service-type 198 (wireguard-configuration 199 (interface "wg0") 200 (addresses '("172.26.55.213/32" "fd00:0000:1337:cafe:1111:1111:4975:4c1d/128")) 201 (port 51821) 202 (bootstrap-private-key? #f) 203 (private-key "/run/secrets/wg0_demiurge") 204 (pre-up '("while [ ! -f /run/secrets/wg0_demiurge ]; do sleep 1; done" 205 "ip route replace 185.157.162.7 via 192.168.1.1 dev eth0")) 206 (post-up 207 `("ip rule add fwmark 0x1 table 100 priority 100" 208 "ip rule add fwmark 51820 table 100 priority 100" 209 "ip route replace default via 192.168.1.1 dev eth0 table 100" 210 ,#~(string-append #$(file-append iptables "/sbin/iptables") " -t mangle -A PREROUTING -i eth0 -d 192.168.1.2 -m conntrack --ctstate NEW -j CONNMARK --set-mark 0x1") 211 ,#~(string-append #$(file-append iptables "/sbin/iptables") " -t mangle -A PREROUTING -i eth0 -j CONNMARK --restore-mark") 212 ,#~(string-append #$(file-append iptables "/sbin/iptables") " -t mangle -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark"))) 213 (post-down 214 `("ip route del 185.157.162.7 via 192.168.1.1 dev eth0" 215 "ip rule del fwmark 0x1 table 100" 216 "ip rule del fwmark 51820 table 100" 217 "ip route flush table 100" 218 ,#~(string-append #$(file-append iptables "/sbin/iptables") " -t mangle -D PREROUTING -i eth0 -d 192.168.1.2 -m conntrack --ctstate NEW -j CONNMARK --set-mark 0x1") 219 ,#~(string-append #$(file-append iptables "/sbin/iptables") " -t mangle -D PREROUTING -i eth0 -j CONNMARK --restore-mark") 220 ,#~(string-append #$(file-append iptables "/sbin/iptables") " -t mangle -D OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark"))) 221 (peers 222 (list 223 (wireguard-peer 224 (name "ovpn-ams-29") 225 (public-key "wTlz3u1egzUrx4Ho02cL7Ht1BBa/C8bULzXStn5f+zk=") 226 (allowed-ips '("0.0.0.0/0" "::0/0")) 227 (endpoint "185.157.162.7:9929")))))) 228 (service wireguard-service-type 229 (wireguard-configuration 230 (interface "wg1") 231 (addresses '("10.0.13.2/24" "fd00:b0ba:cafe:babe::2/64 ")) 232 (port 51820) 233 (bootstrap-private-key? #f) 234 (private-key "/run/secrets/wg1_demiurge") 235 (table #f) 236 (shepherd-requirement '(age-secret 237 ;; to prevent iptables lock issues 238 wireguard-wg0)) 239 (pre-up '("while [ ! -f /run/secrets/wg1_demiurge ]; do sleep 1; done")) 240 (post-up 241 ;; IPv4 and IPv6 NAT 242 (list #~(string-append #$(file-append iptables "/sbin/iptables") " -t nat -I POSTROUTING 1 -s 10.0.13.4/32 -o wg0 -j MASQUERADE") 243 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -t nat -I POSTROUTING 1 -s fd00:b0ba:cafe:babe::4/128 -o wg0 -j MASQUERADE") 244 #~(string-append #$(file-append iptables "/sbin/iptables") " -N WG1-FWD") 245 246 ;; IPv4 Forwarding Chain 247 #~(string-append #$(file-append iptables "/sbin/iptables") " -I FORWARD 1 -j WG1-FWD") 248 #~(string-append #$(file-append iptables "/sbin/iptables") " -A WG1-FWD -i wg1 -o wg1 -j ACCEPT") 249 #~(string-append #$(file-append iptables "/sbin/iptables") " -A WG1-FWD -i wg1 -o wg0 -j ACCEPT") 250 #~(string-append #$(file-append iptables "/sbin/iptables") " -A WG1-FWD -i wg0 -o wg1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") 251 252 ;; IPv6 Forwarding Chain 253 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -N WG1-FWD") 254 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -I FORWARD 1 -j WG1-FWD") 255 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -A WG1-FWD -i wg1 -o wg1 -j ACCEPT") 256 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -A WG1-FWD -i wg1 -o wg0 -j ACCEPT") 257 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -A WG1-FWD -i wg0 -o wg1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"))) 258 (pre-down 259 ;; IPv4 and IPv6 NAT 260 (list #~(string-append #$(file-append iptables "/sbin/iptables") " -t nat -D POSTROUTING -s 10.0.13.4/32 -o wg0 -j MASQUERADE") 261 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -t nat -D POSTROUTING -s fd00:b0ba:cafe:babe::4/128 -o wg0 -j MASQUERADE") 262 263 ;; IPv4 Forwarding Chain 264 #~(string-append #$(file-append iptables "/sbin/iptables") " -D FORWARD -j WG1-FWD") 265 #~(string-append #$(file-append iptables "/sbin/iptables") " -F WG1-FWD") 266 #~(string-append #$(file-append iptables "/sbin/iptables") " -X WG1-FWD") 267 268 ;; IPv6 Forwarding Chain 269 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -D FORWARD -j WG1-FWD") 270 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -F WG1-FWD") 271 #~(string-append #$(file-append iptables "/sbin/ip6tables") " -X WG1-FWD"))) 272 (peers 273 (list 274 (wireguard-peer 275 (name "saklas.epistemia") 276 (public-key "XvRailvccuc7LJIF4aaYM/MLkU4upiprwFlCfBllhl0=") 277 (allowed-ips '("10.0.13.1/32" "fd00:b0ba:cafe:babe::1/128")) 278 (endpoint "141.95.52.111:51820") 279 (keep-alive 25)) 280 (wireguard-peer 281 (name "hastur.epistemia") 282 (public-key "1ketYziRhoUmpbrj/60O5DYbcPacvmEoFQqa/NntSnc=") 283 (allowed-ips '("10.0.13.3/32" "fd00:b0ba:cafe:babe::3/128")) 284 (keep-alive 25)) 285 (wireguard-peer 286 (name "iphonebob.epistemia") 287 (public-key "Xn0EmeRZdpMejBgzr98mYtb/2f5O58GAzQLNZV/SS30=") 288 (allowed-ips '("10.0.13.4/32" "fd00:b0ba:cafe:babe::4/128")) 289 (keep-alive 25)) 290 (wireguard-peer 291 (name "lab.epistemia") 292 (public-key "iMDEwvXjPAlQH8ZCmP63FM5ICYIFIX5XIyGxjnXoNVE=") 293 (allowed-ips '("10.0.13.5/32" "fd00:b0ba:cafe:babe::5/128")) 294 (keep-alive 25)))))) 295 (simple-service 'wireguard-route-timer 296 shepherd-root-service-type 297 (list (shepherd-timer 298 '(wg1-route-updater) 299 "* * * * *" 300 #~("/data_hdd/wireguard-endpoint-route") 301 #:requirement '(wireguard-wg1) 302 #:documentation "Update Wireguard routes every minute."))) 303 (service nginx-service-type 304 (nginx-configuration 305 (server-blocks 306 (list 307 (nginx-reverse-proxy "llm.demiurge.epistemia" 8080) 308 (nginx-reverse-proxy "searx.demiurge.epistemia" 8081) 309 (nginx-reverse-proxy "redlib.demiurge.epistemia" 8085) 310 (nginx-reverse-proxy "navidrome.demiurge.epistemia" 4533) 311 (nginx-reverse-proxy "sdui.demiurge.epistemia" 5000) 312 (nginx-reverse-proxy "home.demiurge.epistemia" 8123))))) 313 (service pam-limits-service-type 314 (list (pam-limits-entry "@audio" 'both 'rtprio 99) 315 (pam-limits-entry "@audio" 'both 'memlock 'unlimited))) 316 (simple-service 'llm-router 317 shepherd-root-service-type 318 (list (shepherd-service 319 (provision '(llm-router)) 320 (requirement '(user-processes networking guix-daemon)) 321 (documentation "llm-router service") 322 (start #~(make-forkexec-constructor 323 '("/home/vin/.config/guix/current/bin/guix" "shell" 324 "-m" "/data/src/public/llm-router/manifest.scm" 325 "--" "python3" "app.py") 326 #:user "vin" 327 #:directory "/data/src/public/llm-router" 328 #:log-file "/var/log/llm-router.log" 329 #:environment-variables (append (default-environment-variables) 330 ;; for vulkan 331 (list "XDG_DATA_DIRS=/home/vin/.guix-home/profile/share")))) 332 (stop #~(make-kill-destructor))))) 333 (simple-service 'sdui 334 shepherd-root-service-type 335 (list (shepherd-service 336 (provision '(sdui)) 337 (requirement '(user-processes networking guix-daemon)) 338 (documentation "sdui service") 339 (start #~(make-forkexec-constructor 340 '("/home/vin/.config/guix/current/bin/guix" "shell" 341 "-m" "/data/src/public/sdui/manifest.scm" 342 "--" "python3" "app.py") 343 #:user "vin" 344 #:directory "/data/src/public/sdui" 345 #:log-file "/var/log/sdui.log")) 346 (stop #~(make-kill-destructor))))) 347 ;; netx three temporary 348 (service dbus-root-service-type) 349 (service rootless-podman-service-type 350 (rootless-podman-configuration 351 (subgids 352 (list (subid-range (name "vin")))) 353 (subuids 354 (list (subid-range (name "vin")))))) 355 (service oci-service-type 356 (oci-configuration 357 (runtime 'podman) 358 (containers 359 (list 360 (oci-container-configuration 361 (image "deluan/navidrome:latest") 362 (user "vin") 363 (ports '(("4533" . "4533"))) 364 (environment '("ND_ENABLEINSIGHTCOLLECTOR=false")) 365 (volumes '("/data_hdd/music_navidrome:/data" 366 "/data_hdd/music:/music:ro")))))))) 367 %base-services) 368 (sysctl-service-type config => 369 (sysctl-configuration 370 (settings 371 (append 372 '(("net.ipv4.ip_forward" . "1") 373 ("net.ipv6.conf.all.forwarding" . "1") 374 ;; for nginx since shepherd-requirement cannot be set 375 ("net.ipv4.ip_nonlocal_bind" . "1") 376 ("net.ipv6.ip_nonlocal_bind" . "1")) 377 %default-sysctl-settings)))))))