使用sops-nix在NixOS上管理机密
摘要
使用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">&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">&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 与密钥管理
教程介绍 NixOS 的密钥管理选项,比较 sops-nix、agenix 和 ragenix 工具,并提供使用 sops-nix 进行加密密钥管理的实际示例。
我喜欢的 NixOS 声明式安装方式
一份关于使用 nixos-anywhere 等工具通过网络声明式安装 NixOS 的指南,重点强调在版本控制下管理配置文件。
在 NixOS 上使用 microvm.nix 的编码代理虚拟机
一篇技术指南,介绍如何在 NixOS 上使用 microvm.nix 创建临时虚拟机,以便在无法访问个人文件的情况下安全运行编码代理。
将我的 NAS 从 CoreOS/Flatcar Linux 迁移到 NixOS
Michael Stapelberg 详细介绍了他将一台 NAS 从 CoreOS/Flatcar Linux 迁移到 NixOS 的过程,涵盖了从 Docker 容器逐步过渡到原生 NixOS 模块的步骤,并附有实际示例。
部分密钥管理应交给 HTTP 代理
博客文章建议将 API 密钥注入工作卸载到内部 HTTP 代理,使应用和代理程序永远接触不到密钥,从而简化轮换并降低外泄风险。