diff options
Diffstat (limited to 'nix')
29 files changed, 1230 insertions, 747 deletions
diff --git a/nix/hosts/caladan/darwin-configuration.nix b/nix/hosts/caladan/darwin-configuration.nix index ef18642..6fdbdaa 100644 --- a/nix/hosts/caladan/darwin-configuration.nix +++ b/nix/hosts/caladan/darwin-configuration.nix @@ -85,10 +85,10 @@ { hostName = "corrino.emile.space"; system = "x86_64-linux"; - maxJobs = 16; + maxJobs = 10; speedFactor = 2; - # Feature | Derivations requiring it + # Feature | Derivations requiring it # ----------------|----------------------------------------------------- # kvm | Everything which builds inside a vm, like NixOS tests # nixos-test | Machine can run NixOS tests @@ -110,8 +110,9 @@ ]; }; - nixpkgs = { - config.allowUnfree = true; + nixpkgs.config = { + allowUnfree = true; + allowUnsupportedSystem = true; }; services.nix-daemon.enable = true; diff --git a/nix/hosts/caladan/emacs_config.el b/nix/hosts/caladan/emacs_config.el index 0ed5786..01cf5bd 100644 --- a/nix/hosts/caladan/emacs_config.el +++ b/nix/hosts/caladan/emacs_config.el @@ -17,10 +17,7 @@ (unless (package-installed-p package) (package-install package))) -(when (display-graphic-p) - (tool-bar-mode 0) - (scroll-bar-mode 'left)) - +(scroll-bar-mode -1) (load-theme 'leuven) ;; light theme (setq pixel-scroll-precision-mode 1) (xterm-mouse-mode 1) @@ -42,9 +39,6 @@ (display-buffer-no-window) (allow-no-window . t))) -(when (not (display-graphic-p)) - (menu-bar-mode -1)) - ;; general purpose emacs settings (use-package emacs :init @@ -148,7 +142,6 @@ completion-category-overrides '((file (styles partial-completion))))) - ;; markdown mode ;; https://jblevins.org/projects/markdown-mode/ (defvar markdown-command) @@ -181,7 +174,7 @@ :ensure nil ; no need to install it as it is built-in, but needs to be activated :hook (after-init . delete-selection-mode)) -;; Configure the Lisp program for SLIME +;; Configure the Lisp program for SLY (add-to-list 'exec-path "/Users/emile/.nix-profile/bin") (defvar inferior-lisp-program "sbcl") @@ -206,14 +199,5 @@ (use-package breadcrumb :ensure t) -;(setq circe-network-options -; '(("Libera Chat" -; :tls t -; :tls-keylist (("/Users/emile/libera.crt" -; "/Users/emile/libera.key")) -; :sasl-external t -; :nick "hanemile" -; :channels ("#test")))) - (provide '.emacs) ;;; emacs_config.el ends here diff --git a/nix/hosts/caladan/home_emile.nix b/nix/hosts/caladan/home_emile.nix index 86d6965..545c4d5 100644 --- a/nix/hosts/caladan/home_emile.nix +++ b/nix/hosts/caladan/home_emile.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ lib, pkgs, ... }: { home = { @@ -60,6 +60,18 @@ ''; }; + neovim = let + custom_plugins = pkgs.callPackage ./nvim_plugins.nix { }; + in { + enable = true; + plugins = with pkgs.vimPlugins // custom_plugins; [ + neovim-ayu + lisp.vlime + ]; + extraConfig = '' + ''; + }; + emacs = { enable = true; package = pkgs.emacs; @@ -174,7 +186,7 @@ nixos-rebuild # editor - unstable.helix + unstable-darwin.helix ## formatter nixfmt-rfc-style # official formatter for nix code @@ -200,6 +212,7 @@ # go foo go delve + gotools # c foo cmake @@ -249,6 +262,10 @@ drawio + # cargo rustup + cargo + + # custom libc-database # blender diff --git a/nix/hosts/caladan/nvim_plugins.nix b/nix/hosts/caladan/nvim_plugins.nix new file mode 100644 index 0000000..7f07816 --- /dev/null +++ b/nix/hosts/caladan/nvim_plugins.nix @@ -0,0 +1,21 @@ +{ vimUtils, fetchgit, ... }: + +let + build = ({name, owner, rev, sha256}: vimUtils.buildVimPlugin { + inherit name; + src = fetchgit { + inherit rev sha256; + url = "https://github.com/${owner}/${name}"; + }; + dependencies = []; + }); +in { + lisp = { + vlime = build { + name = "vlime"; + owner = "l04m33"; + rev = "065b95f3ac7a455314c2bdefeb2b792f290034df"; + sha256 = "1bmmskdwvbl6lvbnjp9lls86rz0vzmk73y644bjb9ix9ygmjbia4"; + }; + }; +} diff --git a/nix/hosts/caladan/overlay.nix b/nix/hosts/caladan/overlay.nix index c9bdd79..8f3b810 100644 --- a/nix/hosts/caladan/overlay.nix +++ b/nix/hosts/caladan/overlay.nix @@ -33,11 +33,6 @@ rm tools/utils/passwd_test.go ''; }); - - # helix-2303 = self.callPackage ../../pkgs/helix-2303 { }; - # r2 = self.callPackage ../../pkgs/radare2-5.8.4 { }; - # ansel = self.callPackage ../../pkgs/ansel { }; - # typst = self.callPackage ../pkgs/radare2-5.8.4 { }; }) ]; config = { diff --git a/nix/hosts/corrino/configuration.nix b/nix/hosts/corrino/configuration.nix index 52e9ecf..2f8954b 100644 --- a/nix/hosts/corrino/configuration.nix +++ b/nix/hosts/corrino/configuration.nix @@ -46,6 +46,7 @@ in ./www/tickets.emile.space.nix # ./www/talks.emile.space.nix + ./www/miniflux.emile.space.nix # ./www/stream.emile.space.nix ./www/md.emile.space.nix ./www/social.emile.space.nix @@ -556,13 +557,25 @@ in }; "/mnt/storagebox-bx11" = { - device = "//u331921.your-storagebox.de/backup"; - fsType = "cifs"; - options = - let - automount_opts = "_netdev,x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"; - in - [ "${automount_opts},credentials=${config.age.secrets.storage_box_bx11_password.path}" ]; + device = "u331921@u331921.your-storagebox.de:/home/backup"; + fsType = "sshfs"; + options = [ # Filesystem options + "allow_other" # for non-root access + "_netdev" # this is a network fs + + # We don't mount on demand, as that will cause services like navidrome to fail + # as the share doesn't yet exist. + #"x-systemd.automount" # mount on demand, rather than boot + + #"debug" # print debug logging + # warning: this causes the one-shot service to never exit + + # SSH options + "StrictHostKeyChecking=no" # prevent the connection from failing if the host's key hasn't been trusted yet + "ServerAliveInterval=15" # keep connections alive + "Port=23" + "IdentityFile=/root/.ssh/id_ed25519" + ]; }; }; diff --git a/nix/hosts/corrino/secrets/garage_admin_metrics_secret.age b/nix/hosts/corrino/secrets/garage_admin_metrics_secret.age new file mode 100644 index 0000000..e1af7da --- /dev/null +++ b/nix/hosts/corrino/secrets/garage_admin_metrics_secret.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 gvwQ2Q 7QkcpYGeeMsbW0GcXzNGPTc0jUf4ydpMiTO6ZxEIKGY +OOxq2hMORsmUzBuoqOIPNJeLqJB0seve9PhorS6PKNs +-> ssh-ed25519 m8VklA pF7mWG6tviFC6qD88dxoQRnXGfR0AuanVyY+bh8XgV0 +mrk4HgEs3i8y5P+BSGM1psweXpY/xO+8vK/DsXyhyiY +--- zqEl/ZN/3jEgMZ/IbPbyTHGZJDDENLOnoQezaACeoSs +l,±W`\6yh. oV(?Em,;(@0dVA=4v \ No newline at end of file diff --git a/nix/hosts/corrino/secrets/garage_admin_token_secret.age b/nix/hosts/corrino/secrets/garage_admin_token_secret.age new file mode 100644 index 0000000..2a18a6b --- /dev/null +++ b/nix/hosts/corrino/secrets/garage_admin_token_secret.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 gvwQ2Q hcMMVkZSsObrOFjetml2z4eH+EfnuSsna+GaXEeMUA4 +y6lFBj49cMhOGuJBpILHsykpBMpKDHZpFXR4E4zZEbg +-> ssh-ed25519 m8VklA Z6zLilTWlGWG17Q6jBx13m3KYs3gE93TPLq0CidHeTA +eqMN5mDMasi/Nw2y5Kgwy2COna+3zbbFTTUrD/O26ls +--- QdVyqrTLmEcGSB37Ft3Ur0Ry9Jk9DyHFI6fo88tnsgI +X`wY,<A$XeDGe ;െ>1nsNr_Y\`)F#{< \ No newline at end of file diff --git a/nix/hosts/corrino/secrets/garage_env.age b/nix/hosts/corrino/secrets/garage_env.age new file mode 100644 index 0000000..becb511 --- /dev/null +++ b/nix/hosts/corrino/secrets/garage_env.age Binary files differdiff --git a/nix/hosts/corrino/secrets/garage_rpc_secret.age b/nix/hosts/corrino/secrets/garage_rpc_secret.age index e228d0d..ce8a65a 100644 --- a/nix/hosts/corrino/secrets/garage_rpc_secret.age +++ b/nix/hosts/corrino/secrets/garage_rpc_secret.age Binary files differdiff --git a/nix/hosts/corrino/secrets/miniflux_admin_file.age b/nix/hosts/corrino/secrets/miniflux_admin_file.age new file mode 100644 index 0000000..3e00b9b --- /dev/null +++ b/nix/hosts/corrino/secrets/miniflux_admin_file.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 gvwQ2Q OGds4NLmRiMmVjPTORP3jLe3iEkqrDyTqW4V7ceFfRk +FFdZcsT9ZruNhpY5cb674qpQpK0qzHNwRPCfHvYaKcE +-> ssh-ed25519 m8VklA 84XSPja8dzJEUVR5olwNONVzNn5QrsX+R+WeBHqxXDo +5CVpnTDcO0EG3NsHdFsSABWNBIe3Xe16me13JIOlfos +--- rlIUU/0gYwxIXmpRI5/3mmZXJ+JrG/tE/3IBtpo4uT4 +-9JNVG.l.e?&r;V#ahSJWjhvѳt;3ϫk(^QU *czFbwPZuqĉ \ No newline at end of file diff --git a/nix/hosts/corrino/secrets/miniflux_oidc_secret.age b/nix/hosts/corrino/secrets/miniflux_oidc_secret.age new file mode 100644 index 0000000..c16754e --- /dev/null +++ b/nix/hosts/corrino/secrets/miniflux_oidc_secret.age Binary files differdiff --git a/nix/hosts/corrino/secrets/tailscale-corrino-cert.age b/nix/hosts/corrino/secrets/tailscale-corrino-cert.age new file mode 100644 index 0000000..07252cc --- /dev/null +++ b/nix/hosts/corrino/secrets/tailscale-corrino-cert.age Binary files differdiff --git a/nix/hosts/corrino/secrets/tailscale-corrino-key.age b/nix/hosts/corrino/secrets/tailscale-corrino-key.age new file mode 100644 index 0000000..36c132e --- /dev/null +++ b/nix/hosts/corrino/secrets/tailscale-corrino-key.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 gvwQ2Q P6b4m51AxFbXT3OOkgMe/BPZi3240e/Gii3weyMtPxI +fRVIno8tPqh4F6e6TOj6YiW2uL9T3uqkro6EZ1mPXOc +-> ssh-ed25519 m8VklA lRMfdLzmoVybkJJvTlY1lZgkMt1R0wyjA/NFcdRFKDM +CLyqRXYetMUbsGhL8NRQ333WIy/TnJwhWX8UpxyLmbw +--- zTjX+CIXtDurBc+TaT7zQ0xn/5Xx3mIrKkAviqMgn4c +:$+D\[Q.pS<HQWMTLTGxZV'^pNDGF*ڢ:6`ˉ`aMdbN\ȣ ClH7>i_! %neUVI4sA6_kP4-=.dxqt+)4`+E2R&0__$V}Hojܾ}aB|//@L#IK3Dt +C?4?u}7! \ No newline at end of file diff --git a/nix/hosts/corrino/www/grafana.emile.space.nix b/nix/hosts/corrino/www/grafana.emile.space.nix index 22b444f..f8674a2 100644 --- a/nix/hosts/corrino/www/grafana.emile.space.nix +++ b/nix/hosts/corrino/www/grafana.emile.space.nix @@ -91,19 +91,30 @@ provision = { dashboards.settings = { }; datasources.settings = { + deleteDatasources = [ + { name = "Prometheus"; orgId = 1; } + { name = "Lampadas"; orgId = 1; } + ]; datasources = [ { url = "http://localhost:${toString config.services.prometheus.port}"; type = "prometheus"; - name = "Prometheus"; + name = "Prometheus Corrino"; editable = false; access = "proxy"; # server = "proxy", browser = "direct" } { - name = "loki"; - url = "http://${config.services.loki.configuration.common.instance_addr}:${toString config.services.loki.configuration.server.http_listen_port}"; - type = "loki"; + url = "http://lampadas:9009"; + type = "prometheus"; + name = "Prometheus Lampadas"; + editable = false; + access = "proxy"; # server = "proxy", browser = "direct" } + # { + # name = "loki"; + # url = "http://${config.services.loki.configuration.common.instance_addr}:${toString config.services.loki.configuration.server.http_listen_port}"; + # type = "loki"; + # } ]; }; diff --git a/nix/hosts/corrino/www/mc.emile.space.nix b/nix/hosts/corrino/www/mc.emile.space.nix new file mode 100644 index 0000000..8250a1d --- /dev/null +++ b/nix/hosts/corrino/www/mc.emile.space.nix @@ -0,0 +1,150 @@ +{ config, pkgs, ... }: + +{ + services.minecraft-server = { + package = pkgs.minecraft-server; + serverProperties = { + server-port = 43000; + + # 0 peaceful + # 1 easy + # 2 normal + # 3 hard + difficulty = 1; + + # 0 survival + # 1 creative + # 2 adventure + # 5 default + # "spectator" spectator + # gamemode = "survival"; + gamemode = 0; + + max-players = 10; + motd = "Neurodivergenter Hexenzirkel"; + enable-rcon = true; + "rcon.password" = "hunter2"; + enable-command-block = false; + enable-query = false; + spawn-protection = 0; + + white-list = true; + }; + openFirewall = true; + + whitelist = { + "emileemail" = "a7614a53-b8b8-47b7-91cf-860e7c7f325f"; + "dodonator23" = "f93506b6-76e8-437d-927d-dceeb833a33f"; + "ChaosAyumi" = "223040ec-ca30-4238-8b58-c81597c30426"; + "xerunala" = "962e41c8-1da8-4592-9a2f-e36cdb20d5a6"; + "rappet" = "588377a5-362f-4ea1-8195-9cf97dd7a884"; + }; + + jvmOpts = "-Xms4092M -Xmx4092M"; + eula = true; + enable = true; + declarative = true; + dataDir = "/var/lib/minecraft"; + }; + + services.nginx.virtualHosts."mc.emile.space" = { + forceSSL = true; + enableACME = true; + }; + + services.bluemap = { + enable = true; + + enableNginx = true; + host = "mc.emile.space"; + + webappSettings = { + enabled = true; + webroot = config.services.bluemap.webRoot; + }; + + # webserverSettings = {}; + webserverSettings.enabled = false; # using nginx; + webRoot = "/var/lib/bluemap/web"; + + # coreSettings = {}; + coreSettings.data = "/var/lib/bluemap"; + coreSettings.metrics = false; # don't send data to the devs + + storage = { + "file" = { + root = "${config.services.bluemap.webRoot}/maps"; + }; + }; + # storage.<name>.storage-type + + maps = let + worldpath = "/var/lib/minecraft/world"; + in { + "overworld" = { + world = "${worldpath}"; + ambient-light = 0.1; + cave-detection-ocean-floor = -5; + dimension = "minecraft:overworld"; + }; + + "nether" = { + world = "${worldpath}/DIM-1"; + sorting = 100; + sky-color = "#290000"; + void-color = "#150000"; + ambient-light = 0.6; + world-sky-light = 0; + remove-caves-below-y = -10000; + cave-detection-ocean-floor = -5; + cave-detection-uses-block-light = true; + max-y = 90; + dimension = "minecraft:the_nether"; + }; + + "end" = { + world = "${worldpath}/DIM1"; + sorting = 200; + sky-color = "#080010"; + void-color = "#080010"; + ambient-light = 0.6; + world-sky-light = 0; + remove-caves-below-y = -10000; + cave-detection-ocean-floor = -5; + dimension = "minecraft:the_end"; + }; + }; + + # A set of resourcepacks, datapacks, and mods to extract resources from, loaded in alphabetical order. + packs = {}; + + # How often to trigger rendering the map, in the format of a systemd timer onCalendar configuration. See systemd.timer(5). + # + # This one means "every three hours": + # *-*-* */3:00:00 + onCalendar = "*-*-* *:00:00"; + + eula = true; + + enableRender = true; + + # The world used by the default map ruleset. If you configure your own maps you do not need to set this. + # defaultWorld = "${config.services.minecraft.dataDir}/world"; + + addons = {}; + }; + + services.restic.backups."minecraft" = { + repository = "/mnt/storagebox-bx11/minecraft"; + paths = [ "/var/lib/minecraft" ]; + timerConfig = null; + passwordFile = config.age.secrets.restic_password.path; + initialize = true; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + "--keep-yearly 75" + ]; + }; +} diff --git a/nix/hosts/corrino/www/md.emile.space.nix b/nix/hosts/corrino/www/md.emile.space.nix index 6088ea0..d94c06c 100644 --- a/nix/hosts/corrino/www/md.emile.space.nix +++ b/nix/hosts/corrino/www/md.emile.space.nix @@ -6,7 +6,7 @@ enableACME = true; locations = { "/" = { - proxyPass = "http://127.0.0.1:${toString config.services.hedgedoc.settings.port}"; + proxyPass = "http://[${config.services.hedgedoc.settings.host}]:${toString config.services.hedgedoc.settings.port}"; }; }; }; @@ -14,10 +14,10 @@ # auth via authelia services.authelia.instances.main.settings.identity_providers.oidc.clients = [ { - id = "HedgeDoc"; + client_id = "HedgeDoc"; # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986 - secret = "$pbkdf2-sha512$310000$l4Kyec7Q9oY2GAhWA/xMig$P/MYFmulfgsDNyyiclUzd6le0oSiOvqCIvl4op5DkXtVTxLWlMA3ZwhJ6Z7u.OfIREuEM2htH6asxWPhBhkpNQ"; + client_secret = "$pbkdf2-sha512$310000$l4Kyec7Q9oY2GAhWA/xMig$P/MYFmulfgsDNyyiclUzd6le0oSiOvqCIvl4op5DkXtVTxLWlMA3ZwhJ6Z7u.OfIREuEM2htH6asxWPhBhkpNQ"; public = false; authorization_policy = "two_factor"; redirect_uris = [ "https://md.emile.space/auth/oauth2/callback" ]; @@ -47,7 +47,7 @@ environmentFile = config.age.secrets.hedgedoc_environment_variables.path; settings = { - host = "127.0.0.1"; + host = "::1"; port = config.emile.ports.md; domain = "md.emile.space"; @@ -85,6 +85,20 @@ }; }; + services.restic.backups."hedgedoc" = { + repository = "/mnt/storagebox-bx11/hedgedoc"; + paths = [ "/var/lib/hedgedoc" ]; + timerConfig = null; + passwordFile = config.age.secrets.restic_password.path; + initialize = true; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + "--keep-yearly 75" + ]; + }; + # backups # services.restic.backups."hedgedoc" = { # user = "u331921"; diff --git a/nix/hosts/corrino/www/miniflux.emile.space.nix b/nix/hosts/corrino/www/miniflux.emile.space.nix new file mode 100644 index 0000000..f5b9817 --- /dev/null +++ b/nix/hosts/corrino/www/miniflux.emile.space.nix @@ -0,0 +1,73 @@ +{ config, pkgs, ... }: + +{ + services.nginx.virtualHosts."miniflux.emile.space" = { + forceSSL = true; + enableACME = true; + locations = { + "/" = { + proxyPass = "http://${config.services.miniflux.config.LISTEN_ADDR}"; + }; + }; + }; + + # auth via authelia + services.authelia.instances.main.settings.identity_providers.oidc.clients = [ + { + id = "miniflux"; + + # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986 + secret = "$pbkdf2-sha512$310000$rlOuqUDGc/kl3bw7JgcSpg$4COyNudsu/7L8qhnxfcQld5Fy.ru/JUp7RCI7dCHZMtzxRnhckW8A7uz3Xeuc7.BjCIwc4GdWusPt6.TiH6Kpw"; + public = false; + authorization_policy = "two_factor"; + redirect_uris = [ "https://miniflux.emile.space/oauth2/oidc/callback" ]; + scopes = [ + "openid" + "email" + "profile" + ]; + grant_types = [ + "refresh_token" + "authorization_code" + ]; + response_types = [ "code" ]; + response_modes = [ + "form_post" + "query" + "fragment" + ]; + token_endpoint_auth_method = "client_secret_post"; + } + ]; + + services.miniflux = { + enable = true; + package = pkgs.miniflux; + config = { + BASE_URL = "https://miniflux.emile.space"; + + # Cleanup job frequency to remove old sessions and archive entries. + CLEANUP_FREQUENCY = 48; + + # Set to 1 to enable maintenance mode. Maintenance mode disables the web ui and show a text message to the users. + # MAINTENANCE_MODE = 1; + # MAINTENANCE_MESSAGE = "updating foo"; + + OAUTH2_CLIENT_ID = "miniflux"; + OAUTH2_CLIENT_SECRET_FILE = config.age.secrets.miniflux_oidc_secret.path; + OAUTH2_OIDC_DISCOVERY_ENDPOINT = "sso.emile.space"; + OAUTH2_OIDC_PROVIDER_NAME = "authelia"; + OAUTH2_PROVIDER = "oidc"; + OAUTH2_REDIRECT_URL = "https://miniflux.emile.space/oauth2/oidc/callback"; + + LISTEN_ADDR = "[::1]:${toString config.emile.ports.miniflux}"; + }; + createDatabaseLocally = true; + + # File containing the ADMIN_USERNAME and ADMIN_PASSWORD (length >= 6) in the format of an EnvironmentFile=, as described by systemd.exec(5). + adminCredentialsFile = config.age.secrets.miniflux_admin_file.path; + }; + + + +} diff --git a/nix/hosts/corrino/www/sb.emile.space.nix b/nix/hosts/corrino/www/sb.emile.space.nix index 1854f0e..0522e25 100644 --- a/nix/hosts/corrino/www/sb.emile.space.nix +++ b/nix/hosts/corrino/www/sb.emile.space.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { services.nginx.virtualHosts."sb.emile.space" = { @@ -6,7 +6,7 @@ enableACME = true; locations = { "/" = { - proxyPass = "http://${config.services.silverbullet.listenSddress}:${toString config.services.silverbullet.listenPort}"; + proxyPass = "http://${config.services.silverbullet.listenAddress}:${toString config.services.silverbullet.listenPort}"; extraConfig = '' ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. auth_request /internal/authelia/authz; @@ -73,7 +73,7 @@ proxy_connect_timeout 240; ''; }; - + }; }; # auth via authelia diff --git a/nix/hosts/corrino/www/sso.emile.space.nix b/nix/hosts/corrino/www/sso.emile.space.nix index 44e30bb..6ffff80 100644 --- a/nix/hosts/corrino/www/sso.emile.space.nix +++ b/nix/hosts/corrino/www/sso.emile.space.nix @@ -141,9 +141,22 @@ in storage.local.path = "/var/lib/authelia-main/db.sqlite"; session = { - domain = "sso.emile.space"; - expiration = 3600; # 1 hour - inactivity = 300; # 5 minutes + # domain = "sso.emile.space"; + # expiration = 3600; # 1 hour + # inactivity = 300; # 5 minutes + + cookies = [ + { + domain = "emile.space"; + authelia_url = "https://sso.emile.space"; + # The period of time the user can be inactive for until the session is destroyed. Useful if you want long session timers but don’t want unused devices to be vulnerable. + inactivity = "1h"; + # The period of time before the cookie expires and the session is destroyed. This is overridden by remember_me when the remember me box is checked. + expiration = "1d"; + # The period of time before the cookie expires and the session is destroyed when the remember me box is checked. Setting this to -1 disables this feature entirely for this session cookie domain + remember_me = "3M"; + } + ]; }; notifier = { @@ -196,6 +209,16 @@ in default_policy = "deny"; rules = [ { + # silverbullet needs access to these without auth + domain = "sb.emile.space"; + policy = "bypass"; + resources = [ + "/.client/manifest.json$" + "/.client/[a-zA-Z0-9_-]+.png$" + "/service_worker.js$" + ]; + } + { domain = "*.emile.space"; policy = "two_factor"; } diff --git a/nix/hosts/lampadas/configuration.nix b/nix/hosts/lampadas/configuration.nix index cc829d8..007f8a1 100644 --- a/nix/hosts/lampadas/configuration.nix +++ b/nix/hosts/lampadas/configuration.nix @@ -2,7 +2,7 @@ # your system. Help is available in the configuration.nix(5) man page, on # https://search.nixos.org/options and in the NixOS manual (`nixos-help`). -{ pkgs, lib, ... }: +{ config, pkgs, lib, ... }: let emile_keys = [ @@ -17,12 +17,34 @@ in ./hardware-configuration.nix ]; + hardware.fancontrol = { + enable = true; + config = '' + # Configuration file generated by pwmconfig, changes will be lost + INTERVAL=10 + DEVPATH=hwmon0=devices/platform/coretemp.0 hwmon1=devices/platform/nct6775.672 + DEVNAME=hwmon0=coretemp hwmon1=nct6798 + FCTEMPS=hwmon1/pwm3=hwmon0/temp2_input hwmon1/pwm2=hwmon1/temp2_input + FCFANS=hwmon1/pwm3=hwmon1/fan3_input hwmon1/pwm2=hwmon1/fan2_input + MINTEMP=hwmon1/pwm3=35 hwmon1/pwm2=35 + MAXTEMP=hwmon1/pwm3=75 hwmon1/pwm2=75 + MINSTART=hwmon1/pwm3=255 hwmon1/pwm2=255 + MINSTOP=hwmon1/pwm3=30 hwmon1/pwm2=30 + MINPWM=hwmon1/pwm3=30 hwmon1/pwm2=30 + MAXPWM=hwmon1/pwm3=255 hwmon1/pwm2=255 + ''; + }; + boot = { loader = { systemd-boot.enable = true; efi.canTouchEfiVariables = true; }; kernelParams = [ "ip=dhcp" ]; + kernelModules = [ + # fan speed modules, detected using `sensors-detect` + "coretemp" "nct6775" + ]; initrd = { availableKernelModules = [ "r8169" ]; systemd.users.root.shell = "/bin/cryptsetup-askpass"; @@ -159,10 +181,41 @@ in }; # metric exporters - prometheus.exporters = { - node.enable = true; # port 9100 - systemd.enable = true; # port 9558 - smartctl.enable = true; # port 9633 + prometheus = { + enable = true; + port = 9090; + listenAddress = "100.87.209.97"; + scrapeConfigs = [ + { + job_name = "node"; + static_configs = [{ + targets = [ + "localhost:${toString config.services.prometheus.exporters.node.port}" + ]; + }]; + } + { + job_name = "systemd"; + static_configs = [{ + targets = [ + "localhost:${toString config.services.prometheus.exporters.systemd.port}" + ]; + }]; + } + { + job_name = "smartctl"; + static_configs = [{ + targets = [ + "localhost:${toString config.services.prometheus.exporters.smartctl.port}" + ]; + }]; + } + ]; + exporters = { + node.enable = true; # port 9100 + systemd.enable = true; # port 9558 + smartctl.enable = true; # port 9633 + }; }; # shares diff --git a/nix/modules/libvirtnix/config.nix b/nix/modules/libvirtnix/config.nix new file mode 100644 index 0000000..e1a8d28 --- /dev/null +++ b/nix/modules/libvirtnix/config.nix @@ -0,0 +1,59 @@ +{ + services.emile.libvirtnix = { + enable = true; + vm = { + "alan" = { + vm_type = "kvm"; + id = "1337"; + name = "blub"; + uuid = "cafebabe-d474-452b-80f4-c951c39bcf74"; + + metadata.libosinfo = "https://libosinfo.org/xmlns/libvirt/domain/1.0"; + metadata.libosinfo_os = "https://nixos.org/nixos/unknown"; + + memory.unit = "KiB"; + memory.value = 2097152; + + currentMemory.unit = "KiB"; + currentMemory.value = 2097152; + + vcpu.placement = "static"; + vcpu.count = 3; + + resource.partition = "/machine"; + + os = { + type = { + arch = "x86_64"; + machine = "pc-q35-3.1"; + value = "hvm"; + }; + + loader = { + readonly = "yes"; + type = "pflash"; + value = "/usr/share/OVMF/OVMF_CODE.fd"; + }; + + nvram.value = "/var/lib/libvirt/qemu/nvram/fileserver2_VARS.fd"; + + boot.dev = "hd"; + }; + + features = { + acpi = true; + apic = true; + vmport = { + state = "off"; + }; + }; + + cpu = { + mode = "host-passthrough"; + check = "none"; + migratable = "on"; + }; + }; + }; + }; +} diff --git a/nix/modules/libvirtnix/domain.nix b/nix/modules/libvirtnix/domain.nix index a028c7d..22cd891 100644 --- a/nix/modules/libvirtnix/domain.nix +++ b/nix/modules/libvirtnix/domain.nix @@ -1,701 +1,483 @@ -{ pkgs, lib, ... }: - +{ config, lib, ... }: + +let + mkTag = import ./xml.nix { inherit lib; }; + pkgs = import <nixpkgs> { }; + + stringOption = + { + default ? "", + }: + lib.mkOption { + type = lib.types.str; + default = "${default}"; + }; +in { - options = with lib; { - - # meta, this allows defining the package used for each vm individually, defaults should be sane - packages = mkOption { - type = types.submodule { - options = { - libvirt = mkPackageOption pkgs "libvirt" { }; - qemu = mkPackageOption pkgs "qemu" { }; + options = { + services.emile.libvirtnix = + let + cpu = lib.mkOption { + type = lib.types.submodule { + options = { + mode = lib.mkOption { + type = lib.types.str; + example = "host-passthrough"; + default = ""; + }; + check = lib.mkOption { + type = lib.types.str; + example = "none"; + default = ""; + }; + migratable = lib.mkOption { + type = lib.types.str; + example = "on"; + default = ""; + }; + }; + }; }; - }; - }; - - # attributs for the root `<domain ...>` node - type = mkOption { - type = types.enum [ - "xen" - "hvm" - "kvm" - "qemu" - "lxc" - ]; - default = "kvm"; - example = "qemu"; - description = '' - hypervisor used for running the domain - allowed values are driver specific, if missing, plz send PR - - hvm since since 8.1.0 and QEMU 2.12 - ''; - }; - - id = mkOption { - type = types.int; - default = 0; - example = 42; - }; + features = lib.mkOption { + type = lib.types.submodule { + options = { + acpi = lib.mkEnableOption "enable acpi"; + apic = lib.mkEnableOption "enable apic"; + + vmport = lib.mkOption { + type = lib.types.submodule { + options = { + state = lib.mkOption { + type = lib.types.str; + example = "off"; + default = ""; + }; + }; + }; + }; + }; + }; + }; + + os_boot = lib.mkOption { + type = lib.types.submodule { + options = { + dev = lib.mkOption { + type = lib.types.str; + example = "hd"; + default = ""; + }; + }; + }; + }; + + os_nvram = lib.mkOption { + type = lib.types.submodule { + options = { + value = lib.mkOption { + type = lib.types.str; + example = "/var/lib/libvirt/qemu/nvram/fileserver2_VARS.fd"; + default = ""; + }; + }; + }; + }; + + os_loader = lib.mkOption { + type = lib.types.submodule { + options = { + readonly = lib.mkOption { + type = lib.types.str; + example = "yes"; + default = ""; + }; + type = lib.mkOption { + type = lib.types.str; + example = "pflash"; + default = ""; + }; + value = lib.mkOption { + type = lib.types.str; + example = "/usr/share/OVMF/OVMF_CODE.fd"; + default = ""; + }; + }; + }; + }; + + os_type = lib.mkOption { + type = lib.types.submodule { + options = { + arch = lib.mkOption { + type = lib.types.str; + example = "x86_64"; + default = ""; + }; + machine = lib.mkOption { + type = lib.types.str; + example = "pc-q35-3.1"; + default = ""; + }; + value = lib.mkOption { + type = lib.types.str; + example = "hvm"; + default = ""; + }; + }; + }; + }; - # General metadata - name = mkOption { - type = types.str; - example = "MyGuest"; - }; + os = lib.mkOption { + description = "os"; + type = lib.types.submodule { + options = { + type = os_type; + loader = os_loader; + nvram = os_nvram; + boot = os_boot; + }; + }; + }; - uuid = mkOption { - type = types.str; - example = "3e3fce45-4f53-4fa7-bb32-11f34168b82b"; - }; + resource = lib.mkOption { + description = "resource"; + type = lib.types.submodule { + options = { + partition = lib.mkOption { + type = lib.types.str; + example = "/machine"; + default = ""; + }; + }; + }; + }; - genid = mkOption { - type = types.str; - example = "43dc0cf8-809b-4adb-9bea-a9abb5f3d90e"; - }; + vcpu = lib.mkOption { + description = "vcpu"; + type = lib.types.submodule { + options = { + placement = lib.mkOption { + # TODO(emile): fill up + type = lib.types.enum [ "static" ]; + example = "static"; + default = "static"; + }; + count = lib.mkOption { + type = lib.types.int; + example = 4; + default = 1; + }; + }; + }; + }; - title = mkOption { - type = types.str; - example = "A short description - title - of the domain"; - }; + mem = lib.mkOption { + description = "memory"; + type = lib.types.submodule { + options = { + unit = lib.mkOption { + # TODO(emile): fill up + type = lib.types.enum [ + "KiB" + "MiB" + "GiB" + "TiB" + ]; + example = "KiB"; + default = "KiB"; + }; + value = lib.mkOption { + type = lib.types.int; + example = 2097152; + default = 1000; + }; + }; + }; + }; - description = mkOption { - type = types.str; - example = "Some human readable description"; - }; + memory = mem; + currentMemory = mem; + + metadata = lib.mkOption { + description = "metadata submodule"; + type = lib.types.submodule { + options = { + libosinfo = lib.mkOption { + type = lib.types.str; + example = "https://libosinfo.org/xmlns/libvirt/domain/1.0"; + default = ""; + }; + libosinfo_os = lib.mkOption { + type = lib.types.str; + example = "https://nixos.org/nixos/unknown"; + default = ""; + }; + }; + }; + }; - metadata = mkOption { - type = types.str; - default = ""; - example = '' - <metadata> - <app1:foo xmlns:app1="http://app1.org/app1/">..</app1:foo> - <app2:bar xmlns:app2="http://app1.org/app2/">..</app2:bar> - </metadata> - ''; - }; + vm = lib.types.submodule { + options = { + vm_type = stringOption { default = "kvm"; }; + id = stringOption { }; + name = stringOption { }; + uuid = stringOption { }; + + inherit + metadata + memory + currentMemory + vcpu + resource + os + features + cpu + ; + }; + }; + in + { + enable = lib.mkEnableOption "Enable r2wars-web"; + + + # Temporary output we write the domain to, in order to inspect the correctness of + # the generated xml + output.domain = lib.mkOption { type = lib.types.path; }; + + # An attrset of VMs + vm = lib.mkOption { + description = "VMs to define"; + type = lib.types.attrsOf vm; + }; + }; + }; - os = mkOption { - type = types.submodule { - options = { - firmware = mkOption { - type = types.enum [ - "bios" - "efi" + config = lib.mkIf config.services.emile.libvirtnix.enable { + services.emile.libvirtnix = + let + vm = config.services.emile.libvirtnix.vm; + + cpu = + vm_name: + mkTag { + name = "cpu"; + args = let + mode = vm.${vm_name}.cpu.mode; + check = vm.${vm_name}.cpu.check; + migratable= vm.${vm_name}.cpu.migratable; + in [ + (if (mode != null) + then {key = "mode"; val = mode;} + else "") + (if (check != null) + then {key = "check"; val = check;} + else "") + (if (migratable != null) + then {key = "migratable"; val = migratable;} + else "") ]; - default = "efi"; - example = "bios"; + closing = false; }; - type = mkOption { - type = types.enum [ - "hvm" - "linux" + + features = + vm_name: + mkTag { + name = "features"; + children = let + acpi = vm_name: mkTag { + name = "acpi"; + closing = false; + }; + apic = vm_name: mkTag { + name = "apic"; + closing = false; + }; + vmport = vm_name: mkTag { + name = "vmport"; + args = [ + { key = "state"; val = vm.${vm_name}.features.vmport.state; } + ]; + closing = false; + }; + in [ + (if (vm.${vm_name}.features.acpi != false) then (acpi vm_name) else "") + (if (vm.${vm_name}.features.apic != false) then (apic vm_name) else "") + (if (vm.${vm_name}.features.vmport != null) then (vmport vm_name) else "") ]; - default = "hvm"; - example = "linux"; }; - arch = mkOption { type = types.str; }; - machine = mkOption { type = types.str; }; - - # TODO(emile): features - # Search for the following... - # > When using firmware auto-selection there are different features enabled in the firmwares - # ... here: https://libvirt.org/formatdomain.html - # can't bother to implement this now - # features = mkOption { - # type = types.submodule { - # options = { - # enabled = { - # type = types.enum [ "yes" "no" ]; - # }; - # name = {}; - # }; - # }; - # }; - - # such as: - # <loader readonly='yes' secure='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader> - loader = mkOption { - type = types.submodule { - options = { - readonly = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - type = mkOption { - type = types.enum [ - "rom" - "pflash" - ]; - }; - secure = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - stateless = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - format = mkOption { - type = types.enum [ - "raw" - "qcow2" - ]; - }; - value = mkOption { - type = types.str; - example = "/usr/share/OVMF/OVMF_CODE.fd"; - }; + os = + vm_name: + mkTag { + name = "os"; + children = let + os_type = vm_name: mkTag { + name = "type"; + args = [ + { key = "arch"; val = vm.${vm_name}.os.type.arch; } + { key = "machine"; val = vm.${vm_name}.os.type.machine; } + ]; + value = vm.${vm_name}.os.type.value; }; - }; + os_loader = vm_name: mkTag { + name = "loader"; + args = [ + { key = "readonly"; val = vm.${vm_name}.os.loader.readonly; } + { key = "pflash"; val = vm.${vm_name}.os.loader.type; } + ]; + value = vm.${vm_name}.os.loader.value; + }; + os_nvram = vm_name: mkTag { + name = "nvram"; + value = vm.${vm_name}.os.nvram.value; + }; + os_boot = vm_name: mkTag { + name = "type"; + args = [ + { key = "dev"; val = vm.${vm_name}.os.boot.dev; } + ]; + closing = false; + }; + in [ + (os_type vm_name) + (os_loader vm_name) + (os_nvram vm_name) + (os_boot vm_name) + ]; }; - # <nvram type='network'> - # <source protocol='iscsi' name='iqn.2013-07.com.example:iscsi-nopool/0'> - # <host name='example.com' port='6000'/> - # <auth username='myname'> - # <secret type='iscsi' usage='mycluster_myname'/> - # </auth> - # </source> - # </nvram> - - # nvram = { - # type = "network"; - # source = { - # protocol = "iscsi"; - # name = "iqn.2013-07.com.example:iscsi-nopool/0"; - # }; - # }; - - nvram = mkOption { - type = types.submodule { - options = { - type = mkOption { - type = types.enum [ - "file" - "block" - "dir" - "network" - "volume" - "nvme" - "vhostuser" - "vhostvdpa" - ]; - default = ""; - }; - - source = mkOption { - type = types.submodule { - options = { - # TODO(emile): figure out how to conditionally allow setting the options below - # if the type defined above has been set - - # if type == file - file = mkOption { type = types.str; }; - fdgroup = mkOption { type = types.str; }; - - # if type == block - dev = mkOption { type = types.str; }; - - # if type == dir - dir = mkOption { type = types.str; }; - - # if type == network - protocol = mkOption { - type = types.enum [ - "nbd" - "iscsi" - "rbd" - "sheepdog" - "gluster" - "vxhs" - "nfs" - "http" - "https" - "ftp" - "ftps" - "tftp" - "ssh" - ]; - }; - name = mkOption { type = types.str; }; - tls = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - tlsHostname = mkOption { type = types.str; }; - query = mkOption { type = types.str; }; - - # if type == volume - pool = mkOption { type = types.str; }; - volume = mkOption { type = types.str; }; - mode = mkOption { - type = types.enum [ - "direct" - "host" - ]; - default = "host"; - }; - - # if type == nvme - type = mkOption { - type = types.enum [ "pci" ]; - default = "pci"; - description = '' - When the type is `nvme`, only `pci` is supported - When the type is `vhostuser`, only `unix` is supported - - (I've got not clue how to model this is nix, it's essentially an attribute that is overloaded based on another value) - ''; - }; - managed = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - namespace = mkOption { - type = types.int; - default = 0; - }; - - # if type == vhostuser - # type = see the type in the nvme section above - path = mkOption { type = types.str; }; - - # if type == vhostvdpa - # dev = (defined above in the "type == block" section) - - # if type == file - # if type == block - # if type == volume - seclabel = mkOption { type = types.str; }; - - index = mkOption { - type = types.int; - default = 0; - }; - - # TODO(emile): implement checks here - # start here and scroll down a bit to the table - # https://libvirt.org/formatdomain.html#hard-drives-floppy-disks-cdroms - # if type == network - host = mkOption { - type = types.submodule { - options = { - name = mkOption { type = types.str; }; - port = mkOption { - type = types.int; - default = 0; - }; - transport = mkOption { type = types.str; }; - socket = mkOption { type = types.str; }; - - }; - }; - }; - - snapshot = mkOption { - type = types.submodule { - options = { - name = mkOption { type = types.str; }; - }; - }; - }; - - config = mkOption { - type = types.submodule { - options = { - file = mkOption { type = types.str; }; - }; - }; - }; - - # Since 3.9.0, the auth element is supported for a disk type "network" that is using a source element with the protocol attributes "rbd", "iscsi", or "ssh". - auth = mkOption { - type = types.submodule { - options = { - type = mkOption { - # type = types.enum [ "chap" ]; - # freeform, yet "chap" is one of the allowed options, I don't know others (yet) - type = types.str; - }; - username = mkOption { type = types.str; }; - - # https://libvirt.org/formatsecret.html - secret = mkOption { - type = types.submodule { - options = { - ephemeral = mkOption { - type = types.enum [ - "yes" - "no" - ]; - default = "no"; - }; - private = mkOption { - type = types.enum [ - "yes" - "no" - ]; - default = "no"; - }; - - uuid = types.submodule { - options = { - value = mkOption { - type = types.str; - default = ""; - }; - }; - }; - description = types.submodule { - options = { - value = mkOption { - type = types.str; - default = ""; - }; - }; - }; - - usage = types.submodule { - options = { - type = mkOption { - type = types.enum [ - "volume" - "ceph" - "iscsi" - "tls" - "vtpm" - ]; - default = ""; - }; - value = mkOption { - type = types.str; - default = ""; - }; - - name = mkOption { - type = types.submodule { - options = { - value = mkOption { type = types.str; }; - }; - }; - }; - - volume = mkOption { - type = types.submodule { - options = { - value = mkOption { type = types.str; }; - }; - }; - }; - - # when using the "iscsi" type - target = mkOption { - type = types.submodule { - options = { - value = mkOption { type = types.str; }; - }; - }; - }; - - }; - }; - - }; - }; - }; # end of secret - - }; - }; - }; # end of auth - - # https://libvirt.org/formatstorageencryption.html - encryption = mkOption { - type = types.submodule { - options = { - type = mkOption { type = types.str; }; - - # mandatory - format = mkOption { - type = types.enum [ - "default" - "qcow" - "luks" - "luks2" - "luks-any" - ]; - }; - - engine = mkOption { - type = types.enum [ - "qemu" - "librbd" - ]; - }; - - secrets = mkOption { - type = types.listOf (mkOption { - type = types.submodule { - options = { - - # mandatory - type = mkOption { type = types.enum [ "volume" ]; }; - - # uuid or usage - uuid = mkOption { type = types.str; }; - usage = mkOption { type = types.str; }; - - }; - }; - }); - }; # end of secrets - - cipher = mkOption { - type = types.submodule { - options = { - name = mkOption { - type = types.str; - example = "'aes', 'des', 'cast5', 'serpent', 'twofish', etc."; - }; - size = mkOption { - type = types.str; - example = "'256', '192', '128', etc."; - }; - mode = mkOption { - type = types.str; - example = "'cbc', 'xts', 'ecb', etc."; - }; - hash = mkOption { - type = types.str; - example = "'md5', 'sha1', 'sha256', etc."; - }; - }; - }; - }; # end of cipher - - ivgen = mkOption { - type = types.submodule { - options = { - name = mkOption { - type = types.str; - example = "'plain', 'plain64', 'essiv', etc."; - }; - hash = mkOption { - type = types.str; - example = "'md5', 'sha1', 'sha256'"; - }; - }; - }; - }; # end of ivygen - }; - }; - }; # end of encryption - - # TODO(emile): reservations - # Looking at the following, it seems like this can use the source element recursively - # Haven't looked into how to define recursive nix options yet... - # https://github.com/virt-manager/virt-manager/blob/5ddd3456a0ca9836a98fc6ca4f0b2eaab268bf47/tests/data/cli/compare/virt-install-many-devices.xml#L398-L400 - - # TODO(emile): initiator - - # Based on this here: - # https://github.com/virt-manager/virt-manager/blob/5ddd3456a0ca9836a98fc6ca4f0b2eaab268bf47/tests/data/cli/compare/virt-install-many-devices.xml#L440 - address = mkOption { - type = types.submodule { - options = { - domain = mkOption { type = types.int; }; - bus = mkOption { type = types.int; }; - slot = mkOption { type = types.int; }; - function = mkOption { type = types.int; }; - }; - }; - }; # end of address - - # TODO(emile): slices - # Didn't find any usage of it, why is there documentation for it then? - - ssl = mkOption { - type = types.submodule { - options = { - verify = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - }; - }; - }; # end of ssl - - # TODO(emile): cookies for http and https - - readahead = mkOption { - type = types.submodule { - options = { - size = mkOption { type = types.int; }; - }; - }; - }; # end of readahead - - timeout = mkOption { - type = types.submodule { - options = { - seconds = mkOption { type = types.int; }; - }; - }; - }; # end of timeout - - identity = mkOption { - type = types.submodule { - options = { - user = mkOption { type = types.str; }; - group = mkOption { type = types.str; }; - - # if ssh - # required - username = mkOption { type = types.str; }; - - # one of these: - agentsock = mkOption { type = types.str; }; - keyfile = mkOption { type = types.str; }; - }; - }; - }; # end of identity - - # disk type "vhostuser" - reconnect = mkOption { - type = types.submodule { - options = { - # mandatory - enabled = mkOption { - type = types.enum [ - "yes" - "no" - ]; - }; - timeout = mkOption { - type = types.int; - description = "seconds"; - }; - - # optional for disk type network and protocol nbd - delay = mkOption { - type = types.int; - default = 0; - description = "seconds"; - }; - }; - }; - }; # end of reconnect - - # disk type "ssh" - knownHosts = mkOption { - type = types.submodule { - options = { - path = mkOption { type = types.str; }; - }; - }; - }; # end of knownHosts - - dataStore = mkOption { - type = types.submodule { - options = { - # TODO(emile): can accept the same types as a `source` element - type = mkOption { type = types.str; }; - - # TODO(emile): can accept format and source subelements - # this is (once again) recursive for the source, stil need to figure - # out how to handle this, just not now - }; - }; - }; # end of dataStore + resource = + vm_name: + mkTag { + name = "resource"; + children = [ + (mkTag { + name = "partition"; + value = "${toString vm.${vm_name}.resource.partition}"; + }) + ]; + }; - startupPolicy = mkOption { - type = types.enum [ - "mandatory" - "requisite" - "optional" - ]; - default = "mandatory"; - }; # end of startupPolicy + vcpu = + vm_name: + mkTag { + name = "vcpu"; + args = [ + { + key = "placement"; + val = vm.${vm_name}.vcpu.placement; + } + ]; + value = "${toString vm.${vm_name}.vcpu.count}"; + }; - backingStore = mkOption { - type = types.submodule { - options = { - type = mkOption { - # TODO(emile): can accept the same types as a `source` element - type = types.str; - }; + currentMemory = + vm_name: + mkTag { + name = "currentMemory"; + args = [ + { + key = "unit"; + val = vm.${vm_name}.currentMemory.unit; + } + ]; + value = "${toString vm.${vm_name}.currentMemory.value}"; + }; + memory = + vm_name: + mkTag { + name = "memory"; + args = [ + { + key = "unit"; + val = vm.${vm_name}.memory.unit; + } + ]; + value = "${toString vm.${vm_name}.memory.value}"; + }; - index = mkOption { - # TODO(emile): figure out if this can just be an int - type = types.str; - }; + libosinfo_os = + vm_name: + mkTag { + name = "libosinfo:os"; + args = [ + { + key = "id"; + val = vm.${vm_name}.metadata.libosinfo_os; + } + ]; + closing = false; + }; - # TODO(emile): can use the following sub elements: - # - format - # - source - # - backingStore - }; - }; - }; # end of backingStore + libosinfo_libosinfo = + vm_name: + mkTag { + name = "libosinfo:libosinfo"; + args = [ + { + key = "xmlns:libosinfo"; + val = vm.${vm_name}.metadata.libosinfo; + } + ]; + children = [ + (libosinfo_os vm_name) + ]; + }; - mirror = mkOption { - type = types.submodule { - options = { - api = mkOption { - type = types.enum [ - "copy" - "active-commit" - ]; - }; - ready = mkOption { - type = types.enum [ - "yes" - "abort" - "pivot" - ]; - }; - # TODO(emile): can use the following sub elements: - # - type (disk types) - # - format - # - source - # - file - }; - }; - }; # end of mirror + metadata = + vm_name: + mkTag { + name = "metadata"; + children = [ (libosinfo_libosinfo vm_name) ]; + }; - }; - }; - }; # end of source + uuid = + vm_name: + mkTag { + name = "uuid"; + value = vm.${vm_name}.uuid; + }; - }; - }; - }; # end of nvram + name = + vm_name: + mkTag { + name = "name"; + value = vm.${vm_name}.name; + }; - }; + # the vm_name has to be passed in, as we want to accesses the value for the given vm when + # generating the config + domain = + vm_name: + mkTag { + name = "domain"; + args = [ + { + key = "type"; + val = vm.${vm_name}.vm_type; + } + { + key = "id"; + val = vm.${vm_name}.id; + } + ]; + children = [ + (name vm_name) + (uuid vm_name) + (metadata vm_name) + (memory vm_name) + (currentMemory vm_name) + (vcpu vm_name) + (resource vm_name) + (os vm_name) + (features vm_name) + (cpu vm_name) + ]; + }; + in + { + output.domain = pkgs.writeText "libvirt-domain-config.xml" (domain "alan"); }; - }; - - memory = lib.mkOption { - type = lib.types.int; - default = 1024; - example = 2048; - description = '' - The amount of memory to provide to the VM - ''; - }; }; } diff --git a/nix/modules/libvirtnix/test.nix b/nix/modules/libvirtnix/test.nix new file mode 100644 index 0000000..8542b7e --- /dev/null +++ b/nix/modules/libvirtnix/test.nix @@ -0,0 +1,10 @@ +let + pkgs = import <nixpkgs> {}; +in + pkgs.lib.evalModules { + modules = [ + # ./secret.nix + ./domain.nix + ./config.nix + ]; + } diff --git a/nix/modules/libvirtnix/xml.nix b/nix/modules/libvirtnix/xml.nix new file mode 100644 index 0000000..134a878 --- /dev/null +++ b/nix/modules/libvirtnix/xml.nix @@ -0,0 +1,45 @@ +{ lib, ... }: + +# takes a few args and creats a valid xml tag pair out of it +# +# testTag = mkTag { +# name = "name"; +# args = [ +# { +# key = "arg1"; +# val = "arg1val"; +# } +# { +# key = "arg2"; +# val = "arg2val"; +# } +# ]; +# value = "qwe"; +# children = [ +# (mkTag { name = "nested"; args = []; value = "qwe"; children = [];}) +# ]; +# }; +# +# <name arg1=arg1val arg2=arg2val> +# value +# {children} +# </name> +{ + name, # name of the tag to be used, such as `secret`, `description`, ... + args ? [ ], # args, [ { key="a"; val="b"; } { key="c"; val="d"; } ] + value ? "", # the value to place in the middle + children ? [ ], # the child elements + closing ? true, # add a closing tag +}: +let + args_str = + " " + lib.strings.concatStrings (lib.strings.intersperse " " (map (x: "${x.key}='${x.val}'") args)); + child_evaled = lib.strings.concatStrings children; + + cond = condition: value: if condition then value else ""; + + closingTag = if closing == true then "</${name}>" else ""; +in +"<${name}${ + lib.optionalString (args != [ ]) args_str +}${cond (closing == false) "/"}>${value}${child_evaled}${lib.optionalString (closing) closingTag}" diff --git a/nix/pkgs/glibc-all-in-one/default.nix b/nix/pkgs/glibc-all-in-one/default.nix new file mode 100644 index 0000000..bbb0824 --- /dev/null +++ b/nix/pkgs/glibc-all-in-one/default.nix @@ -0,0 +1,25 @@ +{ pkgs ? import <nixpkgs> {}, lib, fetchFromGitHub }: + +pkgs.stdenv.mkDerivation rec { + name = "glibc-all-in-one"; + version = "master"; + + src = fetchFromGitHub { + owner = "fr0ster"; + repo = "glibc-all-in-one"; + rev = version; + sha256 = "Zysjhr76TenMarnoKo+M8DrTNbsnaXSoFZO1puPVoxU="; + }; + + buildPhase = ''''; + + installPhase = '' + ''; + + meta = { + description = ""; + homepage = "https://github.com/fr0ster/glibc-all-in-one"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ hanemile ]; + }; + } diff --git a/nix/templates/ctf/flake.lock b/nix/templates/ctf/flake.lock new file mode 100644 index 0000000..b756d8d --- /dev/null +++ b/nix/templates/ctf/flake.lock @@ -0,0 +1,141 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1740603184, + "narHash": "sha256-t+VaahjQAWyA+Ctn2idyo1yxRIYpaDxMgHkgCNiMJa4=", + "ref": "nixos-24.11", + "rev": "f44bd8ca21e026135061a0a57dcf3d0775b67a49", + "shallow": true, + "type": "git", + "url": "ssh://git@github.com/nixos/nixpkgs.git" + }, + "original": { + "ref": "nixos-24.11", + "shallow": true, + "type": "git", + "url": "ssh://git@github.com/nixos/nixpkgs.git" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1736241350, + "narHash": "sha256-CHd7yhaDigUuJyDeX0SADbTM9FXfiWaeNyY34FL1wQU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "8c9fd3e564728e90829ee7dbac6edc972971cd0f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pwndbg": { + "inputs": { + "nixpkgs": "nixpkgs_2", + "pyproject-build-systems": "pyproject-build-systems", + "pyproject-nix": "pyproject-nix", + "uv2nix": "uv2nix" + }, + "locked": { + "lastModified": 1740333626, + "narHash": "sha256-OcwULIZcWOC1FNGa0SNGtyMyfbwTsBj17LBPpGOZL78=", + "ref": "refs/heads/dev", + "rev": "ef090ebf5eb75713b1f97c3d9aa3d7be636b0c3a", + "revCount": 2284, + "type": "git", + "url": "ssh://git@github.com/pwndbg/pwndbg" + }, + "original": { + "type": "git", + "url": "ssh://git@github.com/pwndbg/pwndbg" + } + }, + "pyproject-build-systems": { + "inputs": { + "nixpkgs": [ + "pwndbg", + "nixpkgs" + ], + "pyproject-nix": [ + "pwndbg", + "pyproject-nix" + ], + "uv2nix": [ + "pwndbg", + "uv2nix" + ] + }, + "locked": { + "lastModified": 1737338290, + "narHash": "sha256-gnXlfFEHA+/jMH7R+7y3JxrI3WfOjgBhzzJNuFW70UU=", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "rev": "e1487e5cefda0c7990bdd2e660bee20971680e45", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "pwndbg", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1738204167, + "narHash": "sha256-J5M2sj3x4ocM93shScT/3Z4XWHZhwwW1NyQK+C+8Mys=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "0d9f4b90cee1b5c5d6c142ef22de1e246e003ccc", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "pwndbg": "pwndbg" + } + }, + "uv2nix": { + "inputs": { + "nixpkgs": [ + "pwndbg", + "nixpkgs" + ], + "pyproject-nix": [ + "pwndbg", + "pyproject-nix" + ] + }, + "locked": { + "lastModified": 1738653454, + "narHash": "sha256-tAFX8mPZtZ+zVE/+bwPC3U+u5MxjpNP0gG24DG26jVs=", + "owner": "pyproject-nix", + "repo": "uv2nix", + "rev": "05b0c148bc53aebc6a906b6d0ac41dde5954cd47", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "uv2nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/nix/templates/ctf/flake.nix b/nix/templates/ctf/flake.nix index da21034..f185bb7 100644 --- a/nix/templates/ctf/flake.nix +++ b/nix/templates/ctf/flake.nix @@ -1,14 +1,20 @@ { - description = "ctf"; + description = '' + One Flake to rule them all^W^Wcommon CTF problems, namely broken infa. + + Usage: + ; nix flake init -t git+https://github.com/hanemile/hefe\#ctf + ''; nixConfig.bash-prompt = "\[ctf\]; "; inputs = { - nixpkgs.url = "git+https://github.com/NixOS/nixpkgs"; + nixpkgs.url = "git+ssh://git@github.com/nixos/nixpkgs.git?shallow=1&ref=nixos-24.11"; + pwndbg.url = "git+ssh://git@github.com/pwndbg/pwndbg"; }; # Flake outputs outputs = - { nixpkgs, ... }: + { nixpkgs, pwndbg, ... }@inputs: let # Systems supported allSystems = [ @@ -21,30 +27,46 @@ # Helper to provide system-specific attributes nameValuePair = name: value: { inherit name value; }; genAttrs = names: f: builtins.listToAttrs (map (n: nameValuePair n (f n)) names); - forAllSystems = f: genAttrs allSystems (system: f { pkgs = import nixpkgs { inherit system; }; }); + forAllSystems = f: genAttrs allSystems (system: f { + pkgs = import nixpkgs { inherit system; }; + pwndbg = inputs.pwndbg.packages.${system}.default; + }); in { # Development environment output devShells = forAllSystems ( - { pkgs }: + { pkgs, pwndbg }: { default = - let - python = pkgs.python311; # Use Python 3.11 - in pkgs.mkShell { - packages = - with pkgs; - [ qemu ] - ++ [ - # Python plus helper tools - (python.withPackages ( - ps: with ps; [ - pwntools - pycryptodome - ] - )) - ]; + shellHook = '' + cat << EOF > solve.py + from pwn import * + + context.gdbinit="${pwndbg}/share/pwndbg/gdbinit.py" + + # exe = ELF("./a.out") + + p = remote("138.199.213.51", 31335) + #p = gdb.debug(exe.path, gdbscript='''' + # break main + # c + # '''') + + p.sendlineafter(b"> ", b"asd") + + p.interactive() + EOF + ''; + packages = [ + pkgs.gcc + pwndbg + (pkgs.python311.withPackages ( ps: with ps; [ + pwntools + pwndbg + pycryptodome + ])) + ]; }; } ); diff --git a/nix/templates/ctf/solve.py b/nix/templates/ctf/solve.py new file mode 100644 index 0000000..acc4a75 --- /dev/null +++ b/nix/templates/ctf/solve.py @@ -0,0 +1,15 @@ +from pwn import * + +context.gdbinit="/nix/store/jhvjf5drzzqq54xghzz94h0a6wsn1fs1-pwndbg/share/pwndbg/gdbinit.py" + +# exe = ELF("./a.out") + +p = remote("138.199.213.51", 31335) +#p = gdb.debug(exe.path, gdbscript=''' +# break main +# c +# ''') + +p.sendlineafter(b"> ", b"asd") + +p.interactive() |