at master 17 kB view raw
1variant: fcos 2version: 1.5.0 3 4passwd: 5 users: 6 - name: core 7 ssh_authorized_keys: 8%{ for _, ssh_key in ssh_keys ~} 9 - ${ssh_key} 10%{ endfor ~} 11 12storage: 13 directories: 14 # Config dir 15 - path: /var/home/core/.config 16 user: 17 name: core 18 group: 19 name: core 20%{ for _, path in config_dirs ~} 21 - path: /var/home/core/.config/${path} 22 user: 23 name: core 24 group: 25 name: core 26%{ endfor ~} 27 28 # Systemd user dir 29 - path: /var/home/core/.config/systemd 30 user: 31 name: core 32 group: 33 name: core 34 - path: /var/home/core/.config/systemd/user 35 user: 36 name: core 37 group: 38 name: core 39 40 # For local binaries 41 - path: /var/home/core/.local/bin 42 user: 43 name: core 44 group: 45 name: core 46 47 # Backup snapshot mounting points 48 - path: /var/mnt/snapshots/backblaze 49 - path: /var/mnt/snapshots/storj 50 51 links: 52 # Enable Podman socket for Traefik 53 - path: /var/home/core/.config/systemd/user/timers.target.wants/podman.socket 54 target: /usr/lib/systemd/user/podman.socket 55 user: 56 name: core 57 group: 58 name: core 59 60 # Enable http and https sockets for traefik 61 - path: /var/home/core/.config/systemd/user/timers.target.wants/http.socket 62 target: /var/home/core/.config/systemd/user/http.socket 63 user: 64 name: core 65 group: 66 name: core 67 - path: /var/home/core/.config/systemd/user/timers.target.wants/https.socket 68 target: /var/home/core/.config/systemd/user/https.socket 69 user: 70 name: core 71 group: 72 name: core 73 - path: /var/home/core/.config/systemd/user/timers.target.wants/imaps.socket 74 target: /var/home/core/.config/systemd/user/imaps.socket 75 user: 76 name: core 77 group: 78 name: core 79 - path: /var/home/core/.config/systemd/user/timers.target.wants/smtps.socket 80 target: /var/home/core/.config/systemd/user/smtps.socket 81 user: 82 name: core 83 group: 84 name: core 85 - path: /var/home/core/.config/systemd/user/timers.target.wants/ldaps.socket 86 target: /var/home/core/.config/systemd/user/ldaps.socket 87 user: 88 name: core 89 group: 90 name: core 91 92 # Enable Podman auto updates 93 - path: /var/home/core/.config/systemd/user/timers.target.wants/podman-auto-update.timer 94 target: /usr/lib/systemd/user/podman-auto-update.timer 95 user: 96 name: core 97 group: 98 name: core 99 100 # Hometown timezone 101 - path: /etc/localtime 102 target: ../usr/share/zoneinfo/Europe/Belgrade 103 104 # Enable systemd_exporter 105 - path: /var/home/core/.config/systemd/user/default.target.wants/systemd-exporter.service 106 target: /var/home/core/.config/systemd/user/systemd-exporter.service 107 user: 108 name: core 109 group: 110 name: core 111 112 # Enable node_exporter 113 - path: /var/home/core/.config/systemd/user/default.target.wants/node-exporter.service 114 target: /var/home/core/.config/systemd/user/node-exporter.service 115 user: 116 name: core 117 group: 118 name: core 119 120 files: 121 # http and https sockets for traefik 122 - path: /var/home/core/.config/systemd/user/http.socket 123 contents: 124 inline: | 125 [Socket] 126 ListenStream=${ip}:8080 127 FileDescriptorName=web 128 Service=traefik.service 129 130 [Install] 131 WantedBy=sockets.target 132 user: 133 name: core 134 group: 135 name: core 136 - path: /var/home/core/.config/systemd/user/https.socket 137 contents: 138 inline: | 139 [Socket] 140 ListenStream=${ip}:8443 141 ListenDatagram=${ip}:8443 142 FileDescriptorName=websecure 143 Service=traefik.service 144 145 [Install] 146 WantedBy=sockets.target 147 user: 148 name: core 149 group: 150 name: core 151 - path: /var/home/core/.config/systemd/user/imaps.socket 152 contents: 153 inline: | 154 [Socket] 155 ListenStream=${ip}:8993 156 FileDescriptorName=imaps 157 Service=traefik.service 158 159 [Install] 160 WantedBy=sockets.target 161 user: 162 name: core 163 group: 164 name: core 165 - path: /var/home/core/.config/systemd/user/smtps.socket 166 contents: 167 inline: | 168 [Socket] 169 ListenStream=${ip}:8465 170 FileDescriptorName=smtps 171 Service=traefik.service 172 173 [Install] 174 WantedBy=sockets.target 175 user: 176 name: core 177 group: 178 name: core 179 - path: /var/home/core/.config/systemd/user/ldaps.socket 180 contents: 181 inline: | 182 [Socket] 183 ListenStream=${ip}:8636 184 FileDescriptorName=ldaps 185 Service=traefik.service 186 187 [Install] 188 WantedBy=sockets.target 189 user: 190 name: core 191 group: 192 name: core 193 194 - path: /etc/containers/storage.conf 195 contents: 196 inline: | 197 [storage] 198 driver = "overlay" 199 rootless_storage_path = "/var/mnt/docker/$USER" 200 201 # Configs block 202%{ for name, content in config_files ~} 203 - path: /var/home/core/.config/${name} 204 contents: 205 inline: | 206 ${indent(10, content)} 207 user: 208 name: core 209 group: 210 name: core 211%{ endfor ~} 212 213 # Enable linger so containers can continue to run even after core user logouts 214 - path: /var/lib/systemd/linger/core 215 216 # Set machine hostname 217 - path: /etc/hostname 218 contents: 219 inline: ${hostname} 220 221 # Configure iSCSI target 222 - path: /etc/iscsi/iscsid.conf 223 overwrite: true 224 contents: 225 inline: | 226 node.startup = automatic 227 isns.address = ${truenas_ip} 228 isns.port = 3260 229 230 # Import Step CA root certificate 231 - path: /etc/pki/ca-trust/source/anchors/step-online-ca.pem 232 contents: 233 inline: | 234 ${indent(10, root_ca)} 235 236 # Enable zram swap 237 - path: /etc/systemd/zram-generator.conf 238 contents: 239 inline: | 240 [zram0] 241 242 - path: /etc/sysctl.d/90-bbr.conf 243 contents: 244 inline: | 245 net.core.default_qdisc = cake 246 net.ipv4.tcp_congestion_control = bbr 247 248 - path: /etc/sysctl.d/90-inotify.conf 249 contents: 250 inline: | 251 fs.inotify.max_user_instances = 1024 252 253 - path: /etc/ssh/sshd_config.d/20-increase-max-auth-tries.conf 254 mode: 0644 255 contents: 256 inline: | 257 # I have a lot of SSH keys, unfortunately Terraform hasn't "IdentitiesOnly yes" alternative, so it just tries 258 # all keys on machine, reaching the limit. 259 MaxAuthTries 10 260 261 # Firewall configuration 262 - path: /etc/sysconfig/nftables.conf 263 overwrite: true 264 mode: 0644 265 contents: 266 inline: | 267 include "/etc/nftables/main.nft" 268 269 - path: /etc/nftables/main.nft 270 overwrite: true 271 mode: 0644 272 contents: 273 inline: | 274 #!/usr/sbin/nft -f 275 276 flush ruleset 277 278 table inet filter { 279 chain input { 280 type filter hook input priority filter; policy drop; 281 282 # allow established/related connections 283 ct state {established, related} accept 284 285 # early drop of invalid connections 286 ct state invalid drop 287 288 # allow from loopback 289 iifname lo accept 290 291 # allow icmp 292 ip protocol icmp accept 293 ip6 nexthdr icmpv6 counter accept 294 295 # allow ssh 296 tcp dport ssh accept 297 tcp dport 2222 accept 298 299 # allow http and https 300 tcp dport 8080 accept 301 tcp dport 8443 accept 302 udp dport 8443 accept 303 tcp dport 9443 accept 304 udp dport 9443 accept 305 306 # allow imaps, smtps and ldaps 307 tcp dport 8993 accept 308 tcp dport 8465 accept 309 tcp dport 8636 accept 310 311 # allow livekit 312 udp dport 59000-60000 accept 313 udp dport 3478 accept 314 tcp dport 7881 accept 315 316 # allow plex 317 udp dport { 32410, 32412, 32413, 32414 } accept 318 319 # allow minecraft bds 320 udp dport 19132 accept 321 322 # allow truenas to report metrics using graphite 323 ip saddr 192.168.100.3 tcp dport 2003 accept 324 ip saddr 192.168.100.3 udp dport 2003 accept 325 326 # allow plugs to access mqtt broker 327 ip saddr 192.168.100.1 tcp dport 1883 accept 328 } 329 330 chain forward { 331 type filter hook forward priority filter; policy drop; 332 333 ct state {established, related} accept 334 ct state invalid drop 335 336 ct status dnat accept 337 } 338 339 chain output { 340 type filter hook output priority 0; policy accept; 341 } 342 } 343 344 # download systemd_exporter and create systemd user service 345 - path: /var/home/core/.local/bin/systemd_exporter.tar.gz 346 contents: 347 source: https://github.com/prometheus-community/systemd_exporter/releases/download/v0.7.0/systemd_exporter-0.7.0.linux-amd64.tar.gz 348 verification: 349 hash: sha256-2d995ca20249aeeac8f507173176ce5d162f17470a98ca66e289c85b388480c3 350 user: 351 name: core 352 group: 353 name: core 354 - path: /var/home/core/.config/systemd/user/systemd-exporter.service 355 contents: 356 inline: | 357 [Unit] 358 Description=Systemd Exporter 359 360 [Service] 361 Type=simple 362 WorkingDirectory=/var/home/core/.local/bin 363 ExecStartPre=/usr/bin/tar -xvf systemd_exporter.tar.gz systemd_exporter-0.7.0.linux-amd64/systemd_exporter --strip-components=1 364 ExecStart=/var/home/core/.local/bin/systemd_exporter 365 366 [Install] 367 WantedBy=default.target 368 user: 369 name: core 370 group: 371 name: core 372 373 # download node_exporter and create systemd user service 374 - path: /var/home/core/.local/bin/node_exporter.tar.gz 375 contents: 376 source: https://github.com/prometheus/node_exporter/releases/download/v1.10.2/node_exporter-1.10.2.linux-amd64.tar.gz 377 verification: 378 hash: sha256-c46e5b6f53948477ff3a19d97c58307394a29fe64a01905646f026ddc32cb65b 379 user: 380 name: core 381 group: 382 name: core 383 - path: /var/home/core/.config/systemd/user/node-exporter.service 384 contents: 385 inline: | 386 [Unit] 387 Description=Node Exporter 388 389 [Service] 390 Type=simple 391 WorkingDirectory=/var/home/core/.local/bin 392 ExecStartPre=/usr/bin/tar -xvf node_exporter.tar.gz node_exporter-1.10.2.linux-amd64/node_exporter --strip-components=1 393 ExecStart=/var/home/core/.local/bin/node_exporter --collector.systemd --collector.processes 394 395 [Install] 396 WantedBy=default.target 397 398systemd: 399 units: 400 - name: install-additional-software.service 401 enabled: true 402 contents: | 403 [Unit] 404 Description=Additional software installer 405 Wants=network-online.target 406 After=network-online.target 407 Before=zincati.service 408 ConditionPathExists=!/var/lib/%N.stamp 409 410 [Service] 411 Type=oneshot 412 RemainAfterExit=yes 413 ExecStart=/usr/bin/rpm-ostree install --allow-inactive --assumeyes --reboot qemu-guest-agent restic btop nvtop 414 ExecStart=/bin/touch /var/lib/%N.stamp 415 416 [Install] 417 WantedBy=multi-user.target 418 419 - name: iscsi.service 420 enabled: true 421 422 - name: attach-iscsi-disk.service 423 enabled: true 424 contents: | 425 [Unit] 426 Description=Attach iSCSI disk 427 ConditionFirstBoot=yes 428 Wants=network-online.target 429 After=network-online.target iscsi.service 430 431 [Service] 432 Type=oneshot 433 RemainAfterExit=yes 434 ExecStart=/usr/sbin/iscsiadm -m discovery -t sendtargets -p ${truenas_ip} 435 ExecStart=/usr/sbin/iscsiadm -m node -T ${truenas_iqn} -p ${truenas_ip} --login 436 ExecStart=/usr/sbin/lvmdevices --adddev /dev/sda 437 ExecStart=/usr/sbin/vgchange -ay 438 439 [Install] 440 WantedBy=multi-user.target 441 442 - name: var-mnt-docker.mount 443 enabled: true 444 contents: | 445 [Unit] 446 Description=Mount docker directory 447 Before=remote-fs.target 448 Wants=network-online.target iscsi.service 449 450 [Mount] 451 What=/dev/vg0/lv0 452 Where=/var/mnt/docker 453 Type=xfs 454 Options=_netdev 455 456 [Install] 457 WantedBy=remote-fs.target 458 459 - name: podman-fix-selinux-context.service 460 enabled: true 461 contents: | 462 [Unit] 463 Description=Fix SELinux context for Podman storage 464 Requires=var-mnt-docker.mount 465 After=var-mnt-docker.mount 466 ConditionPathExists=!/var/lib/%N.stamp 467 468 [Service] 469 Type=oneshot 470 RemainAfterExit=yes 471 ExecStart=/usr/bin/chcon -R -t container_file_t /var/mnt/docker/core 472 ExecStart=/bin/touch /var/lib/%N.stamp 473 474 [Install] 475 WantedBy=multi-user.target 476 477 - name: var-mnt-observability.mount 478 enabled: true 479 contents: | 480 [Unit] 481 Description=Mount observability directory 482 Before=remote-fs.target 483 484 [Mount] 485 What=${truenas_ip}:/mnt/spool/observability 486 Where=/var/mnt/observability 487 Type=nfs 488 489 [Install] 490 WantedBy=remote-fs.target 491 492 - name: var-mnt-media.mount 493 enabled: true 494 contents: | 495 [Unit] 496 Description=Mount media directory 497 Before=remote-fs.target 498 499 [Mount] 500 What=${truenas_ip}:/mnt/spool/media 501 Where=/var/mnt/media 502 Type=nfs 503 504 [Install] 505 WantedBy=remote-fs.target 506 507 - name: var-mnt-personal.mount 508 enabled: true 509 contents: | 510 [Unit] 511 Description=Mount personal directory 512 Before=remote-fs.target 513 514 [Mount] 515 What=${truenas_ip}:/mnt/spool/personal 516 Where=/var/mnt/personal 517 Type=nfs 518 519 [Install] 520 WantedBy=remote-fs.target 521 522 - name: nftables.service 523 enabled: true 524 525 - name: restic-backblaze.service 526 contents: | 527 [Unit] 528 Description=Backup Docker data to Backblaze 529 Wants=network-online.target 530 After=network-online.target iscsi.service 531 532 [Service] 533 Type=oneshot 534 LoadCredential=restic-b2-account-id 535 LoadCredential=restic-b2-account-key 536 LoadCredential=restic-password 537 Environment=RESTIC_PASSWORD_FILE=%d/restic-password 538 # Create LVM snapshot and do backup 539 ExecStart=/bin/bash -c "lvremove -y vg0/restic-backblaze || true" 540 ExecStart=/usr/sbin/lvcreate --size 1G --snapshot --name restic-backblaze vg0/lv0 541 ExecStart=/usr/bin/mount -o nouuid /dev/vg0/restic-backblaze /mnt/snapshots/backblaze 542 ExecStart=/bin/bash -c "export B2_ACCOUNT_ID=$(cat $CREDENTIALS_DIRECTORY/restic-b2-account-id); export B2_ACCOUNT_KEY=$(cat $CREDENTIALS_DIRECTORY/restic-b2-account-key); restic -r b2:krasovsky-homelab:app-data --verbose backup /var/mnt/docker/app_data" 543 ExecStart=/usr/bin/umount /mnt/snapshots/backblaze 544 ExecStart=/usr/sbin/lvremove -y vg0/restic-backblaze 545 546 [Install] 547 WantedBy=multi-user.target 548 549 - name: restic-backblaze.timer 550 enabled: true 551 contents: | 552 [Unit] 553 Description=Daily backup to Backblaze 554 555 [Timer] 556 OnCalendar=daily 557 RandomizedDelaySec=3600 558 Unit=restic-backblaze.service 559 560 [Install] 561 WantedBy=timers.target 562 563 - name: restic-storj.service 564 contents: | 565 [Unit] 566 Description=Backup Docker data to Storj 567 Wants=network-online.target 568 After=network-online.target iscsi.service 569 570 [Service] 571 Type=oneshot 572 LoadCredential=restic-aws-access-key-id 573 LoadCredential=restic-aws-secret-access-key 574 LoadCredential=restic-password 575 Environment=RESTIC_PASSWORD_FILE=%d/restic-password 576 # Create LVM snapshot and do backup 577 ExecStart=/bin/bash -c "lvremove -y vg0/restic-storj || true" 578 ExecStart=/usr/sbin/lvcreate --size 1G --snapshot --name restic-storj vg0/lv0 579 ExecStart=/usr/bin/mount -o nouuid /dev/vg0/restic-storj /mnt/snapshots/storj 580 ExecStart=/bin/bash -c "export AWS_ACCESS_KEY_ID=$(cat $CREDENTIALS_DIRECTORY/restic-aws-access-key-id); export AWS_SECRET_ACCESS_KEY=$(cat $CREDENTIALS_DIRECTORY/restic-aws-secret-access-key); restic -r s3:https://gateway.eu1.storjshare.io/homelab-backup/app-data --verbose backup /var/mnt/docker/app_data" 581 ExecStart=/usr/bin/umount /mnt/snapshots/storj 582 ExecStart=/usr/sbin/lvremove -y vg0/restic-storj 583 584 [Install] 585 WantedBy=multi-user.target 586 587 - name: restic-storj.timer 588 enabled: true 589 contents: | 590 [Unit] 591 Description=Daily backup to Storj 592 593 [Timer] 594 OnCalendar=daily 595 RandomizedDelaySec=3600 596 Unit=restic-storj.service 597 598 [Install] 599 WantedBy=timers.target 600 601kernel_arguments: 602 should_exist: 603 - pcie_aspm.policy=powersupersave ifname=infra:${mac_address} ip=${ip}::${gateway}:${mask}:${hostname}:infra:none:${nameserver}