commit 9ec37597b3f29aa4ab3e23f09acf37b536817f16 Author: toufic ar Date: Wed Jan 7 06:25:07 2026 +0200 initial commit, after deletion :) diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml new file mode 100644 index 0000000..1fa4707 --- /dev/null +++ b/.forgejo/workflows/deploy.yaml @@ -0,0 +1,37 @@ +on: + push: + branches: + - main +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: checkout repo + uses: actions/checkout@v6 + - name: install necessary packages + run: | + set -e + apt update + apt install rsync -y + - name: add ssh key + run: | + set -e + mkdir -p /root/.ssh + ssh-keyscan toufy.me >> /root/.ssh/known_hosts + chmod -R 600 /root/.ssh + eval $(ssh-agent -s) + echo "${{ secrets.SSH_KEY }}" | tr -d "\r" | ssh-add - + - name: copy repo to target + run: rsync -az . root@toufy.me:/tmp/deploy + - name: nixos-rebuild test + run: | + set -e + ssh root@toufy.me -C "nixos-rebuild test --flake /tmp/deploy --impure" + [ "$?" == 0 ] || exit 1 + - name: nixos-rebuild switch + run: | + set -e + ssh root@toufy.me -C "nixos-rebuild switch --flake /tmp/deploy --impure" + [ "$?" == 0 ] || exit 1 + - name: clean up + run: ssh root@toufy.me -C "rm -rf /tmp/deploy" diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..352a8c5 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,7 @@ +keys: + - &toufy age1jcl6pr27ne5qmnadh723lhlu0js5dnt050akvaxmhvapm3yz9yqqkpakxs +creation_rules: + - path_regex: secrets.yaml$ + key_groups: + - age: + - *toufy diff --git a/config/configuration.nix b/config/configuration.nix new file mode 100644 index 0000000..3673293 --- /dev/null +++ b/config/configuration.nix @@ -0,0 +1,30 @@ +{config, ...}: { + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + nix.settings.experimental-features = ["nix-command" "flakes"]; + networking.hostName = "adonis"; + networking.firewall.logRefusedPackets = true; + + customOps.owner = "toufy"; + customOps.domain = "toufy.me"; + + sops.secrets."ssh/authorizedKeys/owner" = {}; + + users.users.root.openssh.authorizedKeys.keyFiles = [ + config.sops.secrets."ssh/authorizedKeys/owner".path + ]; + + services.openssh = { + enable = true; + ports = [22]; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + AllowUsers = null; + UseDns = true; + X11Forwarding = false; + PermitRootLogin = "prohibit-password"; + }; + }; +} diff --git a/config/default.nix b/config/default.nix new file mode 100644 index 0000000..1e17346 --- /dev/null +++ b/config/default.nix @@ -0,0 +1,23 @@ +{inputs, ...}: { + imports = [ + ./disks.nix + ./hardware-configuration.nix + ./configuration.nix + ./options.nix + ./devops + ./mail + ./nvim + ./http + ./search + ]; + system.stateVersion = "25.05"; + + system.autoUpgrade = { + enable = true; + flake = inputs.self.outPath; + flags = ["--print-build-logs"]; + dates = "00:00"; + runGarbageCollection = true; + operation = "switch"; + }; +} diff --git a/config/devops/actions_runner.nix b/config/devops/actions_runner.nix new file mode 100644 index 0000000..9e9e315 --- /dev/null +++ b/config/devops/actions_runner.nix @@ -0,0 +1,31 @@ +{ + config, + pkgs, + ... +}: { + sops.secrets."actions_runner/token" = {}; + + virtualisation.docker.enable = true; + + sops.secrets."ssh/authorizedKeys/nix-deploy" = {}; + + users.users.root.openssh.authorizedKeys.keyFiles = [ + config.sops.secrets."ssh/authorizedKeys/nix-deploy".path + ]; + + services.gitea-actions-runner = { + package = pkgs.forgejo-runner; + instances.default = { + enable = true; + name = "monolith"; + url = config.services.forgejo.settings.actions.DEFAULT_ACTIONS_URL; + tokenFile = config.sops.secrets."actions_runner/token".path; + labels = [ + "debian-latest:docker://debian:latest" + "ubuntu-latest:docker://node:current-bullseye" + "alpine-latest:docker://node:current-alpine" + "nix-latest:docker://nixos/nix:latest" + ]; + }; + }; +} diff --git a/config/devops/default.nix b/config/devops/default.nix new file mode 100644 index 0000000..a259cb2 --- /dev/null +++ b/config/devops/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./forgejo.nix + ./actions_runner.nix + ]; +} diff --git a/config/devops/forgejo.nix b/config/devops/forgejo.nix new file mode 100644 index 0000000..98eceb4 --- /dev/null +++ b/config/devops/forgejo.nix @@ -0,0 +1,128 @@ +{ + config, + lib, + ... +}: let + customDomain = config.customOps.domain; + mail = "forgejo@${customDomain}"; + cfg = config.services.forgejo; + srv = cfg.settings.server; +in { + sops.secrets = { + "forgejo/mail".owner = "forgejo"; + "forgejo/admin".owner = "forgejo"; + "mailserver/forgejo".owner = "dovecot2"; + }; + + mailserver.loginAccounts.${mail} = lib.mkIf config.mailserver.enable { + hashedPasswordFile = config.sops.secrets."mailserver/forgejo".path; + sendOnly = true; + }; + + services.nginx.virtualHosts.${srv.DOMAIN} = { + forceSSL = true; + enableACME = true; + extraConfig = '' + client_max_body_size 512M; + ''; + locations."/".proxyPass = "http://localhost:${toString srv.HTTP_PORT}"; + }; + + services.forgejo = { + enable = true; + lfs.enable = true; + settings = { + DEFAULT = { + APP_NAME = "git.${customDomain}"; + APP_SLOGAN = "the git repositories of ${config.customOps.owner}'s projects"; + APP_DISPLAY_NAME_FORMAT = "${config.customOps.owner}'s forge | {APP_NAME}"; + }; + server = { + DOMAIN = "git.${customDomain}"; + ROOT_URL = "https://${srv.DOMAIN}/"; + HTTP_PORT = 3000; + SSH_PORT = lib.head config.services.openssh.ports; + LANDING_PAGE = "/${config.customOps.owner}"; + }; + actions = { + ENABLED = true; + DEFAULT_ACTIONS_URL = "https://${srv.DOMAIN}"; + }; + repository = { + DISABLE_STARS = true; + }; + ui = { + DEFAULT_THEME = "forgejo-auto"; + THEMES = "forgejo-auto,forgejo-light,forgejo-dark"; + DEFAULT_SHOW_FULL_NAME = true; + PREFERRED_TIMESTAMP_TENSE = "absolute"; + }; + "ui.meta" = { + AUTHOR = cfg.settings.DEFAULT.APP_NAME; + DESCRIPTION = cfg.settings.DEFAULT.APP_SLOGAN; + }; + admin = { + DISABLE_REGULAR_ORG_CREATION = true; + }; + security = { + INSTALL_LOCK = true; + GLOBAL_TWO_FACTOR_REQUIREMENT = "all"; + PASSWORD_COMPLEXITY = "lower,upper,digit,spec"; + DISABLE_QUERY_AUTH_TOKEN = true; + }; + service = { + DISABLE_REGISTRATION = true; + VALID_SITE_URL_SCHEMES = "https"; + }; + "service.explore" = { + DISABLE_USERS_PAGE = true; + }; + picture = { + ENABLE_FEDERATED_AVATAR = true; + AVATAR_MAX_FILE_SIZE = 10485760; + REPOSITORY_AVATAR_FALLBACK = "random"; + }; + federation = { + ENABLED = true; + }; + mailer = lib.mkIf config.mailserver.enable { + ENABLED = true; + SMTP_ADDR = config.mailserver.fqdn; + FROM = mail; + USER = mail; + }; + i18n = { + LANGS = + "en-US,zh-CN,zh-HK,zh-TW,da,de-DE,nds,fr-FR" + + ",nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR" + + ",pt-PT,pl-PL,bg,it-IT,fi-FI,fil,eo,tr-TR" + + ",cs-CZ,sl,sv-SE,ko-KR,el-GR,fa-IR,hu-HU," + + "id-ID,ar"; + NAMES = + "English,简体中文,繁體中文(香港)" + + ",繁體中文(台灣),Dansk,Deutsch,Plattdüütsch" + + ",Français,Nederlands,Latviešu,Русский,Українська" + + ",日本語,Español,Português do Brasil" + + ",Português de Portugal,Polski,Български,Italiano" + + ",Suomi,Filipino,Esperanto,Türkçe,Čeština,Slovenščina" + + ",Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv" + + ",Bahasa Indonesia,العربية"; + }; + other = { + SHOW_FOOTER_TEMPLATE_LOAD_TIME = false; + }; + }; + secrets = lib.mkIf config.mailserver.enable { + mailer.PASSWD = config.sops.secrets."forgejo/mail".path; + }; + }; + + systemd.services.forgejo.preStart = let + adminCmd = "${lib.getExe cfg.package} admin user"; + passwd = config.sops.secrets."forgejo/admin".path; + user = config.customOps.owner; + email = "root@${config.mailserver.fqdn}"; + in '' + ${adminCmd} create --admin --email "${email}" --username ${user} --password "$(tr -d '\n' < ${passwd})" || true + ''; +} diff --git a/config/disks.nix b/config/disks.nix new file mode 100644 index 0000000..6208bdc --- /dev/null +++ b/config/disks.nix @@ -0,0 +1,60 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/vda"; + content = { + type = "gpt"; + partitions = { + ESP = { + priority = 1; + name = "ESP"; + start = "1M"; + end = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = ["fmask=0022" "dmask=0022"]; + }; + }; + root = { + size = "100%"; + content = { + type = "btrfs"; + extraArgs = ["-f"]; + subvolumes = { + "/root" = { + mountOptions = ["compress=zstd"]; + mountpoint = "/"; + }; + "/home" = { + mountOptions = ["compress=zstd"]; + mountpoint = "/home"; + }; + "/nix" = { + mountOptions = [ + "compress=zstd" + "noatime" + ]; + mountpoint = "/nix"; + }; + "/swap" = { + mountpoint = "/swap"; + mountOptions = ["noatime"]; + swap.swapfile = { + size = "8G"; + path = "swapfile"; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/config/hardware-configuration.nix b/config/hardware-configuration.nix new file mode 100644 index 0000000..16db18b --- /dev/null +++ b/config/hardware-configuration.nix @@ -0,0 +1,16 @@ +{ + lib, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk"]; + boot.initrd.kernelModules = []; + boot.kernelModules = []; + boot.extraModulePackages = []; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/config/http/default.nix b/config/http/default.nix new file mode 100644 index 0000000..112eff7 --- /dev/null +++ b/config/http/default.nix @@ -0,0 +1,29 @@ +{config, ...}: let + customDomain = config.customOps.domain; +in { + networking.firewall.allowedTCPPorts = [80 443]; + + services.nginx = { + enable = true; + + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedUwsgiSettings = true; + recommendedProxySettings = true; + recommendedBrotliSettings = true; + + sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + + virtualHosts.${customDomain} = { + root = "/var/www/${customDomain}"; + forceSSL = true; + enableACME = true; + }; + }; + + security.acme = { + acceptTerms = true; + defaults.email = "security@${config.mailserver.fqdn}"; + }; +} diff --git a/config/mail/default.nix b/config/mail/default.nix new file mode 100644 index 0000000..757873a --- /dev/null +++ b/config/mail/default.nix @@ -0,0 +1,60 @@ +{config, ...}: let + mailDomain = config.customOps.domain; +in { + sops.secrets = { + "mailserver/contact".owner = "dovecot2"; + }; + + mailserver = { + enable = true; + stateVersion = 3; + fqdn = mailDomain; + domains = [mailDomain]; + + systemDomain = mailDomain; + systemName = mailDomain; + + dmarcReporting.enable = true; + fullTextSearch.enable = true; + + mailboxes = { + Archive = { + auto = "subscribe"; + specialUse = "Archive"; + }; + Drafts = { + auto = "subscribe"; + specialUse = "Drafts"; + }; + Junk = { + auto = "subscribe"; + specialUse = "Junk"; + }; + Sent = { + auto = "subscribe"; + specialUse = "Sent"; + }; + Trash = { + auto = "subscribe"; + specialUse = "Trash"; + }; + }; + + loginAccounts = { + "contact@${mailDomain}" = { + hashedPasswordFile = config.sops.secrets."mailserver/contact".path; + aliases = [ + "root@${mailDomain}" + "postmaster@${mailDomain}" + "security@${mailDomain}" + "abuse@${mailDomain}" + "webmaster@${mailDomain}" + "admin@${mailDomain}" + "info@${mailDomain}" + "support@${mailDomain}" + ]; + }; + }; + certificateScheme = "acme"; + }; +} diff --git a/config/nvim/config.lua b/config/nvim/config.lua new file mode 100644 index 0000000..7b7c4dc --- /dev/null +++ b/config/nvim/config.lua @@ -0,0 +1,27 @@ +-- global +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" + +-- opts +vim.opt.nu = true +vim.opt.relativenumber = true +vim.opt.shiftwidth = 4 +vim.opt.tabstop = 4 +vim.opt.softtabstop = 4 +vim.opt.expandtab = false +vim.opt.smartindent = true +vim.opt.wrap = false +vim.opt.hlsearch = false +vim.opt.incsearch = true +vim.opt.scrolloff = 6 +vim.opt.cursorline = true +vim.opt.cursorcolumn = true +vim.opt.mouse = nil +vim.opt.clipboard = "unnamedplus" +vim.opt.completeopt = { "menu", "menuone", "noselect" } +vim.opt.winborder = "rounded" + +-- keymap +vim.keymap.set("n", "cd", vim.cmd.Ex) +vim.keymap.set("n", "|", vim.cmd.vsplit) +vim.keymap.set("n", "_", vim.cmd.split) diff --git a/config/nvim/default.nix b/config/nvim/default.nix new file mode 100644 index 0000000..1fcefb0 --- /dev/null +++ b/config/nvim/default.nix @@ -0,0 +1,14 @@ +{ + programs.neovim = { + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + + configure = { + customRC = '' + luafile ${./config.lua} + ''; + }; + }; +} diff --git a/config/options.nix b/config/options.nix new file mode 100644 index 0000000..1db795b --- /dev/null +++ b/config/options.nix @@ -0,0 +1,21 @@ +{lib, ...}: { + options = with lib; { + customOps = mkOption { + description = "custom options"; + type = types.submodule { + options = { + owner = mkOption { + type = types.str; + default = null; + description = "machine owner username"; + }; + domain = mkOption { + type = types.str; + default = null; + description = "machine domain name"; + }; + }; + }; + }; + }; +} diff --git a/config/search/default.nix b/config/search/default.nix new file mode 100644 index 0000000..1fec4e5 --- /dev/null +++ b/config/search/default.nix @@ -0,0 +1,95 @@ +{config, ...}: let + searxDomain = "search.${config.customOps.domain}"; +in { + imports = [./engines.nix]; + + sops.secrets.searx.owner = "searx"; + + services.searx = { + enable = true; + redisCreateLocally = true; + + limiterSettings = { + real_ip = { + x_for = 1; + ipv4_prefix = 32; + ipv6_prefix = 56; + }; + + botdetection = { + ip_limit = { + filter_link_local = true; + link_token = true; + }; + }; + }; + + settings = { + general = { + debug = false; + instance_name = "${config.customOps.owner}'s search"; + donation_url = false; + contact_url = false; + privacypolicy_url = false; + enable_metrics = false; + }; + + ui = { + static_use_hash = true; + default_locale = "en"; + query_in_title = false; + infinite_scroll = true; + center_alignment = false; + default_theme = "simple"; + theme_args.simple_style = "auto"; + search_on_category_select = true; + hotkeys = "vim"; + url_formatting = "full"; + }; + + search = { + safe_search = 0; + autocomplete_min = 2; + autocomplete = "duckduckgo"; + favicon_resolver = ""; + ban_time_on_fail = 5; + max_ban_time_on_fail = 120; + }; + + server = { + base_url = "https://${searxDomain}"; + port = 8888; + bind_address = "127.0.0.1"; + secret_key = config.sops.secrets.searx.path; + limiter = true; + public_instance = true; + image_proxy = false; + method = "POST"; + }; + + outgoing = { + request_timeout = 5.0; + max_request_timeout = 15.0; + pool_connections = 100; + pool_maxsize = 15; + enable_http2 = true; + }; + + enabled_plugins = [ + "Basic Calculator" + "Hash plugin" + "Tor check plugin" + "Open Access DOI rewrite" + "Hostnames plugin" + "Unit converter plugin" + "Tracker URL remover" + ]; + }; + }; + + services.nginx.virtualHosts.${searxDomain} = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://localhost:8888"; + }; +} diff --git a/config/search/engines.nix b/config/search/engines.nix new file mode 100644 index 0000000..61f5287 --- /dev/null +++ b/config/search/engines.nix @@ -0,0 +1,163 @@ +{lib, ...}: { + services.searx.settings.engines = lib.mapAttrsToList (name: value: {inherit name;} // value) { + # unnecessary + "dictzone".disabled = true; + "lingva".disabled = true; + "mymemory translated".disabled = true; + "mozhi".disabled = true; + "presearch".disabled = true; + "presearch images".disabled = true; + "presearch videos".disabled = true; + "presearch news".disabled = true; + "seznam".disabled = true; + "goo".disabled = true; + "naver".disabled = true; + "naver videos".disabled = true; + "naver images".disabled = true; + "naver news".disabled = true; + "alexandria".disabled = true; + "ask".disabled = true; + "crowdview".disabled = true; + "mwmbl".disabled = true; + "searchmysite".disabled = true; + "stract".disabled = true; + "bpb".disabled = true; + "tagesschau".disabled = true; + "wikimini".disabled = true; + "findthatmeme".disabled = true; + "frinkiac".disabled = true; + "livespace".disabled = true; + "sepiasearch".disabled = true; + "mediathekviewweb".disabled = true; + "ina".disabled = true; + "niconio".disabled = true; + "acfun".disabled = true; + "iqiyi".disabled = true; + "wolframalpha".disabled = true; + "ansa".disabled = true; + "il post".disabled = true; + "deezer".disabled = true; + "habrahabr".disabled = true; + "btdigg".disabled = true; + "duden".disabled = true; + "woxikon.de synonyme".disabled = true; + "jisho".disabled = true; + "moviepilot".disabled = true; + "senscritique".disabled = true; + "geizhals".disabled = true; + "duckduckgo weather".disabled = true; + "openmeteo".disabled = true; + "fyyd".disabled = true; + "yummly".disabled = true; + "chefkoch".disabled = true; + "destatis".disabled = true; + # big brother + "google".disabled = true; + "google play movies".disabled = true; + "google play apps".disabled = true; + "google news".disabled = true; + "google images".disabled = true; + "google videos".disabled = true; + "google scholar".disabled = true; + "youtube".disabled = true; + "bing".disabled = true; + "bing images".disabled = true; + "bing videos".disabled = true; + "bing news".disabled = true; + "microsoft learn".disabled = true; + "material icons".disabled = true; + "apple maps".disabled = true; + "apple app store".disabled = true; + "goodreads".disabled = true; + # captcha + "mojeek".disabled = true; + "mojeek images".disabled = true; + "mojeek news".disabled = true; + "qwant".disabled = true; + "qwant images".disabled = true; + "qwant videos".disabled = true; + "qwant news".disabled = true; + "cppreference".disabled = true; + "lib.rs".disabled = true; + "sourcehut".disabled = true; + "free software directory".disabled = true; + "searchcode code".disabled = true; + "pdbe".disabled = true; + "1337x".disabled = true; + "kickass".disabled = true; + "library genesis".disabled = true; + "openrepos".disabled = true; + "tokyotoshokan".disabled = true; + "startpage".disabled = true; + "mulvaddelta".disabled = true; + "mulvaddelta brave".disabled = true; + "brave".disabled = true; + # non-free + "tineye".disabled = true; + "1x".disabled = true; + "adobe stock".disabled = true; + "adobe stock video".disabled = true; + "adobe stock audio".disabled = true; + "deviantart".disabled = true; + "flickr".disabled = true; + "imgur".disabled = true; + "library of congress".disabled = true; + "pinterest".disabled = true; + "unsplash".disabled = true; + "bilibili".disabled = true; + "dailymotion".disabled = true; + "vimeo".disabled = true; + "yahoo".disabled = true; + "yahoo news".disabled = true; + "genius".disabled = true; + "mixcloud".disabled = true; + "soundcloud".disabled = true; + "huggingface".disabled = true; + "huggingface datasets".disabled = true; + "huggingface spaces".disabled = true; + "9gag".disabled = true; + "reddit".disabled = true; + "imdb".disabled = true; + "rottentomatoes".disabled = true; + # shady + "right dao".disabled = true; + "quark".disabled = true; + "quark images".disabled = true; + "sogou".disabled = true; + "sogou images".disabled = true; + "sogou wechat".disabled = true; + "sogou videos".disabled = true; + # LLM + "cloudflareai".disabled = true; + "yacy".disabled = true; + "yacy images".disabled = true; + "yep".disabled = true; + "yep images".disabled = true; + "yep news".disabled = true; + "360search".disabled = true; + "360search videos".disabled = true; + "baidu".disabled = true; + "baidu images".disabled = true; + "baidu kaifa".disabled = true; + "seekr images".disabled = true; + "seekr news".disabled = true; + "seekr videos".disabled = true; + "github".disabled = true; + # censorship + "reuters".disabled = true; + # far-right/disinformation/misinformation + "bitchute".disabled = true; + "rumble".disabled = true; + "bandcamp".disabled = true; + # slow + "crossref".disabled = true; + "wikidata".disabled = true; + + # enabled + "wiby".disabled = false; + "duckduckgo".disabled = false; + "duckduckgo images".disabled = false; + "duckduckgo videos".disabled = false; + "duckduckgo news".disabled = false; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..cfd7238 --- /dev/null +++ b/flake.lock @@ -0,0 +1,188 @@ +{ + "nodes": { + "blobs": { + "flake": false, + "locked": { + "lastModified": 1604995301, + "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=", + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "type": "gitlab" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1766150702, + "narHash": "sha256-P0kM+5o+DKnB6raXgFEk3azw8Wqg5FL6wyl9jD+G5a4=", + "owner": "nix-community", + "repo": "disko", + "rev": "916506443ecd0d0b4a0f4cf9d40a3c22ce39b378", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "simple-nixos-mailserver", + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "simple-nixos-mailserver", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763319842, + "narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "simple-nixos-mailserver", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1766736597, + "narHash": "sha256-BASnpCLodmgiVn0M1MU2Pqyoz0aHwar/0qLkp7CjvSQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f560ccec6b1116b22e6ed15f4c510997d99d5852", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1764020296, + "narHash": "sha256-6zddwDs2n+n01l+1TG6PlyokDdXzu/oBmEejcH5L5+A=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a320ce8e6e2cc6b4397eef214d202a50a4583829", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "nixpkgs": "nixpkgs", + "simple-nixos-mailserver": "simple-nixos-mailserver", + "sops-nix": "sops-nix" + } + }, + "simple-nixos-mailserver": { + "inputs": { + "blobs": "blobs", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1766537863, + "narHash": "sha256-HEt+wbazRgJYeY+lgj65bxhPyVc4x7NEB2bs5NU6DF8=", + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "rev": "23f0a53ca6e58e61e1ea2b86791c69b79c91656d", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "ref": "nixos-25.11", + "repo": "nixos-mailserver", + "type": "gitlab" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1766894905, + "narHash": "sha256-pn8AxxfajqyR/Dmr1wnZYdUXHgM3u6z9x0Z1Ijmz2UQ=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "61b39c7b657081c2adc91b75dd3ad8a91d6f07a7", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..31247ed --- /dev/null +++ b/flake.nix @@ -0,0 +1,37 @@ +{ + description = "toufy's server config"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-25.11"; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs @ { + self, + nixpkgs, + sops-nix, + simple-nixos-mailserver, + disko, + ... + }: { + nixosConfigurations.adonis = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + specialArgs = {inherit inputs;}; + modules = [ + ./config + ./secrets.nix + disko.nixosModules.disko + sops-nix.nixosModules.sops + simple-nixos-mailserver.nixosModule + ]; + }; + }; +} diff --git a/secrets.nix b/secrets.nix new file mode 100644 index 0000000..ddad538 --- /dev/null +++ b/secrets.nix @@ -0,0 +1,5 @@ +{ + sops.defaultSopsFile = ./secrets.yaml; + sops.defaultSopsFormat = "yaml"; + sops.age.keyFile = "/root/.config/sops/age/keys.txt"; +} diff --git a/secrets.yaml b/secrets.yaml new file mode 100644 index 0000000..baeae8b --- /dev/null +++ b/secrets.yaml @@ -0,0 +1,29 @@ +ssh: + authorizedKeys: + owner: ENC[AES256_GCM,data:LqatOCIAcAvYF354I5itm/rAp5S8UdyONgtK/CEvUq66isiqp+QhV3L1WiW10R8OOm4+nD70uzu4hMnSVxGfNPd8ysE7PUoTGstNFf06uwDtbRiVkJ8=,iv:LW2LwZexi/WliJ7zsoWG0nUSjk2rk5y5++LFI80qLBQ=,tag:3MpE+WVLtMwl8XeFno5FBQ==,type:str] + nix-deploy: ENC[AES256_GCM,data:UVCAdWsy0U53uF2LXNQWI8zqI9LGWS/PpS05qhNuBekZiUXUhC0TMK9RlPhbmjTGfWiQi/bJOzUlZq7C/KRLxIGV6ulAlrsS8YHhX3Oo3r0/o30d/yPMjG+sysdV,iv:UjjFJQlt+kcYHNGI+gVXcee0lFOn2DpF0+R/HOnhWCk=,tag:zYDRE878cL6FhTsoDrI/jw==,type:str] +mailserver: + contact: ENC[AES256_GCM,data:bDC9e4GzBn6c+yT4NOOVlcqQ86ynDkTZhKKE6Ck6xlwWpPYfngP+rffzsX0bL61N0ruMUuUD1XEcdRNz,iv:wqgBzTYa3ipeuUN7YhkH87U6vKb9pGyOS89SekqojLc=,tag:lQfSZm9OVYJ9dgT2WoBYsg==,type:str] + forgejo: ENC[AES256_GCM,data:nDGMlxhJIlLr3ynR9ftRPqSdKNxxy8FVItRNLXVrbbbaIttpHUve68hz7O7s/v9qo1a14HvP5Z/NKuErRVsUzJJFRuDqwoywWg==,iv:eyf33mOOCOtEfRGLQqXFO2KEIJzWAflUXssf8qWwck4=,tag:sti3pRMbhunTsAVqQ6JJVw==,type:str] +searx: ENC[AES256_GCM,data:n451XLvOi2D2YvL0/+ko+HyXWEU7uuVlivkFsKxIzq1EWqMVEhFgEAt1k8W15AdgLY1xo455fUbL6/W1uSFO8w==,iv:QfX7s4l4QuZ8/85Q/+0OWezDGqOKXdY7B5M6wq/5tAM=,tag:ppZXewIAN0IdRMgrIIKTmg==,type:str] +actions_runner: + token: ENC[AES256_GCM,data:K3l1i8TlOh4P0m0HvI/U97weP2BzPxkiz1DYvAFL8ergFVYHsE62A92rVxIAlQ==,iv:BIITpfqKa/IA7dQfmoNTA2dhB91jn7Ay7Ihib+2Mddg=,tag:Ojk4407BhM7b4LjmnPuZjA==,type:str] +forgejo: + admin: ENC[AES256_GCM,data:yWvcNrmQJJTyUrML8ibkxLlDgp7/Ac4JD4GZ8ArwmJdZeDuedSIWZV8j/nr0Tg==,iv:AqDV5QEneIZ+KcrJF1mBEZiXZ7QxFfwxnSGxGVWAhCc=,tag:EPfeCvDAGsMLkhE4QawoDQ==,type:str] + mail: ENC[AES256_GCM,data:+pohnzkYs6RsusDhuX7s48stYRJfS66AXx05J3xi6RdL3d3eJ2iCIcwQs1wIzbVsyA==,iv:7dV2B0Tyh65iQlfemaynYJFvt0NOXWWSonwu0y7grG8=,tag:Km7cKbe9RMxtT2lJDizYpQ==,type:str] + secret: ENC[AES256_GCM,data:/c9me5lpSIX2AFjqWm+YFdP+5dIxMI+k55GA7agDiTX0A3hlbDaqSZCE9R5YtlBXTeiY1jvoksMZVoW0340RzA==,iv:/CL9L3PH7viJaVxMLv2MVJY9akD3lbk9TThJkn9g4bg=,tag:q9eChmyBd/vzY9UlGGP2gw==,type:str] +sops: + age: + - recipient: age1jcl6pr27ne5qmnadh723lhlu0js5dnt050akvaxmhvapm3yz9yqqkpakxs + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyRnQxVjFqZ1pCbzJZT2xZ + c0E2THE5TDZjeHpHUEozZk91WGJ3VkFuTWxBCk5rVFcxYTZCWndVWjZDSkJqczMx + dVR5Q1hYcWxZQjlnOVBtYXhIN1JmQUUKLS0tIEorMTJuOVNTcXhwZm82a2x2cWwx + L0NsZWFmd3UwblExc3UrVVVraHVTTm8KyUN1t1NgQG8+zHViKXT4fwnuFBVgzhYw + WbCHfzut3a55ta1B50hQGFlPcUZDPImUg4wKmkdc7vurg02vOTgwUQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-01-07T01:38:01Z" + mac: ENC[AES256_GCM,data:Rz2uGZ46LkmwoWhzNSIYTWdWAYpibmFyHvR3gwCNN8FRGKugm0IPES7ApJJW/0Ihf65BgeIbHe3rPzqDsNVsLvvJdfBP4jCD+SaIVuhVptLofDuO9UC4G69eXsjl1wceww4ZMjZJr69UUUXFe+0+c1+Mvdvah6KZWQJLoQraq3w=,iv:og9XkeYN523o8jsRKKus0/Jq7LKlLabO1Mz2Z+BYiLA=,tag:2leOjdHn83wTsfN94IGHiQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.11.0