使用sops-nix在NixOS上管理机密

Michael Stapelberg 工具

摘要

使用sops-nix在NixOS配置中管理机密的指南,涵盖设置、加密以及与Samba等服务的集成。

<p>密码和机密文件(如加密密钥文件)在计算中无处不在。配置Linux系统时,迟早你需要在某个地方输入密码——例如,当我在<a href="/posts/2025-07-13-nixos-nas-network-storage-config/">将现有的Linux网络存储(NAS)设置迁移到NixOS</a>时,我需要在NixOS配置中指定所需的Samba密码(或者在NixOS外部手动管理)。对于个人计算机,这没问题,但如果目标是共享系统配置(例如在Git仓库中),我们需要一个不同的解决方案:机密管理。</p> <h2 id="what-is-secret-management">什么是机密管理?</h2> <p>机密管理系统的基本思想是<em>加密</em>静态存储的机密,这意味着如果有人克隆了包含NixOS系统配置的Git仓库,他们无法访问(因此也无法部署)加密的机密。</p> <p>从概念上讲,我们需要:</p> <ol> <li>加密机密,使目标系统能够解密它们。</li> <li>加密机密,使其他参与此配置的人员能够解密它们。</li> <li>让目标系统在运行时解密机密。</li> <li>告诉我们的软件在哪里访问解密的机密。</li> </ol> <h2 id="sops-nix-setup">sops-nix设置</h2> <p>在本文中,我将展示如何使用sops-nix完成上述任务。下面是我们将使用的三个不同构建块的快速概览:</p> <ul> <li><a href="https://getsops.io/">sops</a>是一个用于在Git中对机密进行版本控制的工具,以加密形式存储。 <ul> <li>sops使得在添加/删除授权密钥时重新加密这些机密变得容易。</li> <li>sops非常灵活,可以与许多其他工具/提供者一起使用。</li> </ul> </li> <li><a href="https://github.com/Mic92/sops-nix">sops-nix</a>提供了一种将sops与Nix/NixOS集成的方式。</li> <li>将sops与<a href="https://manpages.debian.org/age.1"><code>age(1)</code></a>一起使用,我们可以利用现有的SSH私钥(人类)或SSH主机私钥(机器),而无需管理一组单独的密钥文件。</li> </ul> <p>你可能想知道为什么我选择sops-nix而不是另一个竞争者<a href="https://github.com/ryantm/agenix">agenix</a>?我第一次查看时,sops-nix的设置说明对我来说更有意义,而且我希望能够以其他方式使用sops,而不仅仅是与age一起使用。如果你对agenix感兴趣,<a href="https://www.splitbrain.org/blog/2025-07/27-agenix">请查看Andreas Gohr关于agenix的博客文章</a>。</p> <h3 id="step-1-preparation">步骤1. 准备工作</h3> <p>我在一台<a href="/posts/2025-07-27-dev-shells-with-nix-4-quick-examples/#setup">安装了Nix工具并启用了Nix Flakes的Arch Linux机器</a>上运行了以下指令。点击链接也可查看其他系统(如Debian或Fedora)的说明。</p> <h3 id="step-2-obtain-an-age-identity-from-your-personal-ssh-key">步骤2. 从个人SSH密钥获取age身份</h3> <p>我不希望管理额外的密钥文件,所以我会使用<code>ssh-to-age</code>从我的SSH私钥文件派生一个密钥,我已经很好地备份了这个私钥:</p> <pre tabindex="0"><code>midna % mkdir -p $HOME/.config/sops/age/ midna % read -s SSH_TO_AGE_PASSPHRASE; export SSH_TO_AGE_PASSPHRASE midna % nix run nixpkgs#ssh-to-age -- \ -private-key \ -i $HOME/.ssh/id_ed25519 \ -o $HOME/.config/sops/age/keys.txt </code></pre><p>(<code>SSH_TO_AGE_PASSPHRASE</code>选项在<a href="https://github.com/Mic92/ssh-to-age/blob/main/README.md#usage">ssh-to-age README</a>中有文档说明。)</p> <p>要显示此age身份(私钥)的age接收者(公钥),我使用了:</p> <pre tabindex="0"><code>midna % nix shell nixpkgs#age midna 2 % age-keygen -y $HOME/.config/sops/age/keys.txt age10e9tt2qwq90y5hvl35dau0sm5cm4qvegtw2a70v7sz5fy99de42s9d5nkf </code></pre><h3 id="step-3-obtain-an-age-recipient-for-the-remote-machine">步骤3. 为远程机器获取age接收者</h3> <p>类似地,我将从远程系统的SSH主机密钥派生一个age接收者:</p> <pre tabindex="0"><code>batchn % cat /etc/ssh/ssh_host_ed25519_key.pub | nix run nixpkgs#ssh-to-age age1wnwfnrqhewjh39pmtyc8zhqw606znskt4h5p9s3pve4apd67gapqj6tr0k </code></pre><h3 id="step-4-configure-sops-for-your-git-repository">步骤4. 为Git仓库配置sops</h3> <p>在我的Git仓库(nix-configs)中,每个NixOS系统都有一个子目录,即<a href="https://manpages.debian.org/tree.1"><code>tree(1)</code></a>显示:</p> <pre tabindex="0"><code>├── batchn │ ├── configuration.nix │ ├── disk-config.nix │ ├── flake.lock │ ├── flake.nix │ ├── hardware-configuration.nix │ ├── Makefile │ ├── secrets │ │ └── example.yaml ├── wiki │ ├── configuration.nix │ ├── disk-config.nix │ ├── flake.lock │ ├── flake.nix │ ├── hardware-configuration.nix │ ├── Makefile … </code></pre><p>在Git仓库的根目录(与<code>batchn</code>目录同级),我创建了<code>.sops.yaml</code>,内容如下:</p> <div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#062873;font-weight:bold">keys</span>:<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>- <span style="color:#007020">&amp;admin_michael</span><span style="color:#bbb"> </span>age10e9tt2qwq90y5hvl35dau0sm5cm4qvegtw2a70v7sz5fy99de42s9d5nkf<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>- <span style="color:#007020">&amp;server_batchn</span><span style="color:#bbb"> </span>age1wnwfnrqhewjh39pmtyc8zhqw606znskt4h5p9s3pve4apd67gapqj6tr0k<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#60a0b0;font-style:italic"># …更多服务器密钥在此处…</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="color:#062873;font-weight:bold">creation_rules</span>:<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>- <span style="color:#062873;font-weight:bold">path_regex</span>:<span style="color:#bbb"> </span>batchn/secrets/[^/]+\.(yaml|json|env|ini)$<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span><span style="color:#062873;font-weight:bold">key_groups</span>:<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>- <span style="color:#062873;font-weight:bold">age</span>:<span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>- <span style="color:#007020">*admin_michael</span><span style="color:#bbb"> </span></span></span><span style="display:flex;"><span><span style="color:#bbb"> </span>- <span style="color:#007020">*server_batchn</span><span style="color:#bbb"> </span></span></span></code></pre></div><p>我管理的系统越多,需要配置的<code>keys</code>和<code>creation_rules</code>就越多。</p> <p>创建规则告诉sops在加密文件时使用哪些密钥。在我的设置中,通常每个系统只使用一个文件,但可以想象,如果我想在系统的某个方面与某人合作,我可以将一些机密拆分到单独的文件中。</p> <h3 id="step-5-manage-some-secrets-with-sops">步骤5. 使用sops管理一些机密</h3> <p>现在我们已经告诉sops要为哪些接收者加密,我们可以通过运行以下命令在配置的编辑器中解密并编辑<code>secrets/example.yaml</code>:</p> <pre tabindex="0"><code>midna ~/nix-configs/batchn % nix run nixpkgs#sops -- secrets/example.yaml</code></pre>
查看原文
查看缓存全文

缓存时间: 2026/05/16 03:33

# NixOS 上的秘密管理(使用 sops-nix) 来源:https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/ 目录- 什么是秘密管理? (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#what-is-secret-management) - sops\-nix 设置 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#sops-nix-setup)- 步骤 1\. 准备工作 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#step-1-preparation) - 步骤 2\. 从个人 SSH 密钥获取 age 身份 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#step-2-obtain-an-age-identity-from-your-personal-ssh-key) - 步骤 3\. 获取远程机器的 age 接收者 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#step-3-obtain-an-age-recipient-for-the-remote-machine) - 步骤 4\. 为你的 Git 仓库配置 sops (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#step-4-configure-sops-for-your-git-repository) - 步骤 5\. 用 sops 管理一些秘密 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#step-5-manage-some-secrets-with-sops) - 步骤 6\. 在 NixOS 中配置 sops (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#step-6-configure-sops-in-nixos) - 使用示例 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#usage-examples)- 使用示例:命令行标志(ExecStart 包装器) (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#usage-example-command-line-flags-execstart-wrapper) - 使用示例:环境变量文件 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#usage-example-environment-variable-files) - 使用示例:systemd 凭证 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#usage-example-systemd-credentials) - 使用示例:Samba 用户/密码 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#usage-example-samba-userspasswords) - 结论 (https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/#conclusion) 密码和密钥文件之类的秘密在计算中无处不在。在配置 Linux 系统时,迟早需要把密码放在某个地方——例如,当我把现有的 Linux 网络存储(NAS)配置迁移到 NixOS (https://michael.stapelberg.ch/posts/2025-07-13-nixos-nas-network-storage-config/) 时,我需要在 NixOS 配置中指定所需的 Samba 密码(或者手动管理它们,而不在 NixOS 内部管理)。对于个人电脑来说,这没问题,但如果目标是共享系统配置(例如在 Git 仓库中),我们需要一个不同的解决方案:秘密管理。 ## 什么是秘密管理? 秘密管理系统的基本思想是对静态秘密进行*加密*,这意味着如果有人克隆了包含你 NixOS 系统配置的 Git 仓库,他们无法访问(因此也无法部署)加密的秘密。 从概念上讲,我们需要: 1. 加密秘密,以便目标系统可以解密它们。 2. 加密秘密,以便处理此配置的其他人员可以解密它们。 3. 让目标系统在运行时解密秘密。 4. 告知我们的软件在哪里访问解密后的秘密。 ## sops\-nix 设置 在本文中,我将展示如何使用 sops-nix 完成上述操作。以下是我们将使用的三个不同构建块的简要概述: - sops (https://getsops.io/) 是一个工具,用于以加密形式管理 Git 中的秘密版本控制。- sops 使得在添加/删除授权密钥时重新加密这些秘密变得容易。 - sops 非常灵活,可以与大量其他工具/提供商配合使用。 - sops\-nix (https://github.com/Mic92/sops-nix) 提供了将 sops 与 Nix/NixOS 集成的方法。 - 将 sops 与 `age\(1\)` (https://manpages.debian.org/age.1) 结合使用,允许我们使用现有的 SSH 私钥(人类)或 SSH 主机私钥(机器),而无需管理单独的一组密钥文件。 你可能想知道为什么我选择 sops-nix 而不是另一竞争者 agenix (https://github.com/ryantm/agenix)?当我第一次查看时,sops-nix 的设置说明对我来说更有意义,而且我希望能够以其他方式使用 sops,而不仅仅是通过 age。如果你对 agenix 感到好奇,请查看 Andreas Gohr 关于 agenix 的博客文章 (https://www.splitbrain.org/blog/2025-07/27-agenix)。 ### 步骤 1\. 准备工作 我在一台 Arch Linux 机器上运行了以下说明,这台机器上安装了 Nix 工具并启用了 Nix Flakes (https://michael.stapelberg.ch/posts/2025-07-27-dev-shells-with-nix-4-quick-examples/#setup)。通过链接可以找到其他系统(如 Debian 或 Fedora)的说明。 ### 步骤 2\. 从个人 SSH 密钥获取 age 身份 我不想管理额外的密钥文件,因此我将使用 `ssh\-to\-age` 从我的 SSH 私钥文件中派生一个密钥,这个私钥文件我已经好好备份了: `` midna % mkdir -p $HOME/.config/sops/age/ midna % read -s SSH_TO_AGE_PASSPHRASE; export SSH_TO_AGE_PASSPHRASE midna % nix run nixpkgs#ssh-to-age -- \ -private-key \ -i $HOME/.ssh/id_ed25519 \ -o $HOME/.config/sops/age/keys.txt `` (`SSH\_TO\_AGE\_PASSPHRASE` 选项在 ssh\-to\-age README (https://github.com/Mic92/ssh-to-age/blob/main/README.md#usage) 中有文档说明。) 为了显示此 age 身份(私钥)的 age 接收者(公钥),我使用了: `` midna % nix shell nixpkgs#age midna 2 % age-keygen -y $HOME/.config/sops/age/keys.txt age10e9tt2qwq90y5hvl35dau0sm5cm4qvegtw2a70v7sz5fy99de42s9d5nkf `` ### 步骤 3\. 获取远程机器的 age 接收者 类似地,我将从远程系统的 SSH 主机密钥中派生一个 age 接收者: `` batchn % cat /etc/ssh/ssh_host_ed25519_key.pub | nix run nixpkgs#ssh-to-age age1wnwfnrqhewjh39pmtyc8zhqw606znskt4h5p9s3pve4apd67gapqj6tr0k `` ### 步骤 4\. 为你的 Git 仓库配置 sops 在我的 Git 仓库(nix\-configs)中,每个 NixOS 系统有一个子目录,也就是说 `tree\(1\)` (https://manpages.debian.org/tree.1) 显示为: `` ├── batchn │ ├── configuration.nix │ ├── disk-config.nix │ ├── flake.lock │ ├── flake.nix │ ├── hardware-configuration.nix │ ├── Makefile │ ├── secrets │ │ └── example.yaml ├── wiki │ ├── configuration.nix │ ├── disk-config.nix │ ├── flake.lock │ ├── flake.nix │ ├── hardware-configuration.nix │ ├── Makefile ... `` 在 Git 仓库的根目录(`batchn` 目录旁边),我创建 `\.sops\.yaml`,内容如下: `` keys: - &admin_michael age10e9tt2qwq90y5hvl35dau0sm5cm4qvegtw2a70v7sz5fy99de42s9d5nkf - &server_batchn age1wnwfnrqhewjh39pmtyc8zhqw606znskt4h5p9s3pve4apd67gapqj6tr0k # ...更多服务器密钥放在这里... creation_rules: - path_regex: batchn/secrets/[^/]+\.(yaml|json|env|ini)$ key_groups: - age: - *admin_michael - *server_batchn `` 我管理的系统越多,就需要配置更多的 `keys` 和 `creation\_rules`。 创建规则告诉 sops 在加密文件时使用哪些密钥。在我的设置中,我通常每个系统只使用一个文件,但可以想象,如果我只想与某个系统的一个方面合作,我会将一些秘密拆分成单独的文件。 ### 步骤 5\. 用 sops 管理一些秘密 现在我们已经告诉 sops 要为哪些接收者加密,我们可以通过运行以下命令在我们配置的编辑器中解密和编辑 `secrets/example\.yaml`: `` midna ~/nix-configs/batchn % nix run nixpkgs#sops secrets/example.yaml `` 最简单的密钥文件只包含一个密钥,例如: 保存并退出编辑器后,sops 将更新加密的 secrets/example\.yaml。 ### 步骤 6\. 在 NixOS 中配置 sops 现在,我们需要在 NixOS 中引用加密的文件,并启用 `sops\-nix` 集成,以便让解密后的秘密在系统上可用。 在 `flake\.nix` 中,我将 `sops\-nix` 添加到了 `inputs` 部分,并添加了 NixOS 模块。我展示了整个差异,因为行的位置与行内容同样重要: `` --- c/batchn/flake.nix +++ i/batchn/flake.nix @@ -1,85 +1,93 @@ { inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; disko.url = "github:nix-community/disko"; # Use the same version as nixpkgs disko.inputs.nixpkgs.follows = "nixpkgs"; stapelbergnix.url = "github:stapelberg/nix"; zkjnastools.url = "github:stapelberg/zkj-nas-tools"; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; outputs = { nixpkgs, disko, stapelbergnix, zkjnastools, + sops-nix, ... }: let system = "x86_64-linux"; pkgs = import nixpkgs { inherit system; config.allowUnfree = false; }; in { nixosConfigurations.batchn = nixpkgs.lib.nixosSystem { inherit system; inherit pkgs; modules = [ disko.nixosModules.disko ./configuration.nix stapelbergnix.lib.userSettings # Use systemd for network configuration stapelbergnix.lib.systemdNetwork # Use systemd-boot as bootloader stapelbergnix.lib.systemdBoot # Run prometheus node exporter in tailnet stapelbergnix.lib.prometheusNode zkjnastools.nixosModules.zkjbackup + sops-nix.nixosModules.sops ]; }; formatter.${system} = pkgs.nixfmt-tree; }; } `` 然后,在 `configuration\.nix` 中,我们告诉 `sops\-nix` 使用 SSH 主机密钥作为身份,sops 将在哪里找到我们的秘密,以及 `sops\-nix` 应该在远程系统上实现哪些秘密: `` sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.defaultSopsFile = ./secrets/example.yaml; sops.secrets."api-key" = { }; `` 部署后,我们可以在正在运行的系统上访问秘密: `` batchn ~ % sudo cat /run/secrets/api-key hello world :)% batchn ~ % `` 当然,即使在机器重启后,秘密仍然可用,无需重新部署: `` batchn ~ % uptime 22:09:23 up 0:00, 1 user, load average: 0,32, 0,08, 0,03 batchn ~ % sudo cat /run/secrets/api-key hello world :)% batchn ~ % `` ## 使用示例 现在我们已经将秘密存储在 `/run/secrets` 下的文件中,如何使用这些秘密? 以下部分展示了几种常见的方法。 ### 使用示例:命令行标志(ExecStart 包装器) 假设你已将自定义 Go 服务器作为 systemd 服务部署在 NixOS 上,如下所示,并且你希望开始管理通过 `\-securecookie\_hash\_key` 和 `\-securecookie\_block\_key` 命令行标志传递的明文秘密: `` { users.groups.fortuneserver = { }; users.users.fortuneserver = { isSystemUser = true; group = "fortuneserver"; }; systemd.services.fortuneserver = { description = "fortuneserver"; documentation = [ "https://michael.stapelberg.ch" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "fortuneserver"; Group = "fortuneserver"; ExecStart = '' "${pkgs.fortuneserver}/bin/fortuneserver" \ -securecookie_hash_key="some-secret-key" \ -securecookie_block_key="a-different-secret-key" ''; }; }; } `` 使用以下 sops 秘密: `` fortuneserver: securecookie_hash_key: some-secret-key securecookie_block_key: a-different-secret-key `` ……我们需要调整 NixOS 配置,以便在运行时读取这些秘密文件。因为 `ExecStart` 指令由 systemd 解释,不通过 shell,所以我们使用 `writeShellScript` 辅助函数 (https://nixos.org/manual/nixpkgs/stable/#trivial-builder-writeShellScript),然后只需 `cat` 文件: `` { sops.secrets."fortuneserver/securecookie_hash_key" = { owner = "fortuneserver"; restartUnits = [ "fortuneserver.service" ]; }; sops.secrets."fortuneserver/securecookie_block_key" = { owner = "fortuneserver"; restartUnits = [ "fortuneserver.service" ]; }; users.groups.fortuneserver = { }; users.users.fortuneserver = { isSystemUser = true; group = "fortuneserver"; }; systemd.services.fortuneserver = { description = "fortuneserver"; documentation = [ "https://michael.stapelberg.ch" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "fortuneserver"; Group = "fortuneserver"; ExecStart = pkgs.writeShellScript "fortuneserver-execstart" '' "${pkgs.fortuneserver}/bin/fortuneserver" \ -securecookie_hash_key="$(cat /run/secrets/fortuneserver/securecookie_hash_key)" \ -securecookie_block_key="$(cat /run/secrets/fortuneserver/securecookie_block_key)" ''; }; }; } `` ### 使用示例:环境变量文件 如果相关服务不使用命令行标志,而是使用环境变量来配置秘密呢?我们可以将环境变量文件放入由 sops 管理的秘密中: `` translate-fe: env: | DEEPL_AUTH_KEY=my-deepl-key `` ……然后我们让 systemd 从秘密文件中应用这些环境变量: `` { sops.secrets."translate-fe/env" = { owner = "translatefe"; restartUnits = [ "translate-fe.service" ]; }; systemd.services.translate-fe = { documentation = [ "https://michael.stapelberg.ch" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "translatefe"; EnvironmentFile = [ config.sops.secrets."translate-fe/env".path ]; ExecStart = "${translatefeExecstart}/bin/translate-fe"; }; }; } `` 如果你正在配置 NixOS 模块(而不是声明自定义服务),那么选项可能并不总是叫 `EnvironmentFile`。例如,对于 oauth2\-proxy 服务,你需要配置 `services\.oauth2\-proxy\.keyFile` 选项 (https://search.nixos.org/options?channel=25.05&show=services.oauth2-proxy.keyFile&from=0&size=50&sort=relevance&type=packages&query=oauth2-proxy): `` services.oauth2-proxy = { keyFile = config.sops.secrets."oauth2-proxy/env".path; enable = true; # ... }; `` ### 使用示例:systemd 凭证 在前面的示例中,我们将每个秘密的 `owner` 配置为服务运行的用户帐户。但如果因为服务使用 systemd 的 `DynamicUser` 特性而不存在这样的用户帐户呢? 我们可以使用 systemd 的 `LoadCredential` 功能!例如,我通过以下方式向 Prometheus Alertmanager 提供 SMTP 密码: `` { sops.secrets."alertmanager/smtp_pw" = { restartUnits = [ "alertmanager.service" ]; }; systemd.services.alertmanager.serviceConfig.LoadCredential = [ "smtp_pw:${config.sops.secrets."alertmanager/smtp_pw".path}" ]; services.prometheus.alertmanager = { enable = true; configuration = { global = { smtp_smarthost = "smtp.gmail.com:587"; smtp_from = "[email protected]"; smtp_auth_username = "[email protected]"; smtp_auth_password_file = "/run/credentials/alertmanager.service/smtp_pw"; }; # ...其余配置放在这里... }; }; } `` ### 使用示例:Samba 用户/密码 在我的博客文章“将我的 NAS 从 CoreOS/Flatcar Linux 迁移到 NixOS” (https://michael.stapelberg.ch/posts/2025-07-13-nixos-nas-network-storage-config/#samba-nixos) 中,我描述了如何使用一个 `ExecStartPre` shell 脚本(与已经解释的技术非常相似)来配置 Samba 用户和密码(来自 sops 管理的秘密)。 ## 结论 将秘密作为单独加密的文件存放在配置仓库中对我来说很有意义! age 能够与 SSH 密钥协同工作,在我看来使得设置非常方便。加密密钥

相似文章

NixOS 与密钥管理

Lobsters Hottest

教程介绍 NixOS 的密钥管理选项,比较 sops-nix、agenix 和 ragenix 工具,并提供使用 sops-nix 进行加密密钥管理的实际示例。

我喜欢的 NixOS 声明式安装方式

Michael Stapelberg

一份关于使用 nixos-anywhere 等工具通过网络声明式安装 NixOS 的指南,重点强调在版本控制下管理配置文件。

将我的 NAS 从 CoreOS/Flatcar Linux 迁移到 NixOS

Michael Stapelberg

Michael Stapelberg 详细介绍了他将一台 NAS 从 CoreOS/Flatcar Linux 迁移到 NixOS 的过程,涵盖了从 Docker 容器逐步过渡到原生 NixOS 模块的步骤,并附有实际示例。

部分密钥管理应交给 HTTP 代理

Hacker News Top

博客文章建议将 API 密钥注入工作卸载到内部 HTTP 代理,使应用和代理程序永远接触不到密钥,从而简化轮换并降低外泄风险。