mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-04-25 10:18:37 +02:00
feat: harden my private secrets
This commit is contained in:
18
flake.lock
generated
18
flake.lock
generated
@@ -239,6 +239,23 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mysecrets": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689326736,
|
||||||
|
"narHash": "sha256-wVfvr9bEDkuivJbdtbLC6l82QZnc2dW4Nl3ExY6/oaA=",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"rev": "cd37f1a4f8543b6e272809c75f84ed674ac0e4d3",
|
||||||
|
"shallow": true,
|
||||||
|
"type": "git",
|
||||||
|
"url": "ssh://git@github.com/ryan4yin/nix-secrets.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"shallow": true,
|
||||||
|
"type": "git",
|
||||||
|
"url": "ssh://git@github.com/ryan4yin/nix-secrets.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nix-eval-jobs": {
|
"nix-eval-jobs": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
@@ -449,6 +466,7 @@
|
|||||||
"darwin": "darwin_2",
|
"darwin": "darwin_2",
|
||||||
"home-manager": "home-manager_2",
|
"home-manager": "home-manager_2",
|
||||||
"hyprland": "hyprland",
|
"hyprland": "hyprland",
|
||||||
|
"mysecrets": "mysecrets",
|
||||||
"nixos-generators": "nixos-generators",
|
"nixos-generators": "nixos-generators",
|
||||||
"nixpkgs": "nixpkgs_3",
|
"nixpkgs": "nixpkgs_3",
|
||||||
"nixpkgs-darwin": "nixpkgs-darwin",
|
"nixpkgs-darwin": "nixpkgs-darwin",
|
||||||
|
|||||||
@@ -74,6 +74,10 @@
|
|||||||
|
|
||||||
# AstroNvim is an aesthetic and feature-rich neovim config.
|
# AstroNvim is an aesthetic and feature-rich neovim config.
|
||||||
astronvim = { url = "github:AstroNvim/AstroNvim/v3.32.0"; flake = false; };
|
astronvim = { url = "github:AstroNvim/AstroNvim/v3.32.0"; flake = false; };
|
||||||
|
|
||||||
|
# my private secrets, it's a private repository, you need to replace it with your own.
|
||||||
|
# use ssh protocol to authenticate via ssh-agent/ssh-key, and shallow clone to save time
|
||||||
|
mysecrets = { url = "git+ssh://git@github.com/ryan4yin/nix-secrets.git?shallow=1"; flake = false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
# The `outputs` function will return all the build results of the flake.
|
# The `outputs` function will return all the build results of the flake.
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
{ ... }: {
|
{ config, builtins, ... }: {
|
||||||
programs.bash = {
|
programs.bash = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableCompletion = true;
|
enableCompletion = true;
|
||||||
bashrcExtra = ''
|
bashrcExtra = ''
|
||||||
export PATH="$PATH:$HOME/bin:$HOME/.local/bin:$HOME/go/bin"
|
export PATH="$PATH:$HOME/bin:$HOME/.local/bin:$HOME/go/bin"
|
||||||
'';
|
'';
|
||||||
|
# ++ (builtins.readFile config.age.secrets."alias-for-work.bash".path);
|
||||||
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
k = "kubectl";
|
k = "kubectl";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ ... }: {
|
{ config, builtins, ... }: {
|
||||||
programs.nushell = {
|
programs.nushell = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configFile.source = ./config.nu;
|
configFile.source = ./config.nu;
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
# envFile.source = ./env.nu;
|
# envFile.source = ./env.nu;
|
||||||
# environmentVariables = { FOO="bar"; };
|
# environmentVariables = { FOO="bar"; };
|
||||||
|
|
||||||
|
# extraConfig = builtins.readFile config.age.secrets."alias-for-work.nushell".path;
|
||||||
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
k = "kubectl";
|
k = "kubectl";
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,7 @@
|
|||||||
imports = [
|
imports = [
|
||||||
../../modules/darwin/core.nix
|
../../modules/darwin/core.nix
|
||||||
../../modules/darwin/apps.nix
|
../../modules/darwin/apps.nix
|
||||||
|
|
||||||
|
../../secrets
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,20 @@
|
|||||||
# secrets management
|
|
||||||
|
|
||||||
This directory contains my secret files, encrypt by agenix:
|
# Secrets Management
|
||||||
|
|
||||||
- my wireguard configuration files, which is used by `wg-quick`
|
This directory contains my encrypted secret files managed by agenix.
|
||||||
- github token, used by nix flakes to query and downloads flakes from github
|
|
||||||
- without this, you may reach out github api rate limit.
|
|
||||||
- ssh key pairs for my homelab and other servers
|
|
||||||
- ...
|
|
||||||
|
|
||||||
## TODO
|
All these secrets are stored in a separate private GitHub repository and referenced as a flake input of this repository.
|
||||||
|
|
||||||
- a better way to manage all these secrets, is to used a separate private github repository to store all these secrets, and use it as a flakes input this this repo.
|
## Adding or Updating Secrets
|
||||||
- e.g. <https://github.com/xddxdd/nixos-config/blob/25ae3de/flake.nix#L82>
|
|
||||||
|
|
||||||
## Add or Update Secrets
|
> All the operations in this section should be performed in my private repository: `nix-secrets`.
|
||||||
|
|
||||||
This job is done by `agenix` CLI tool with the `./secrets.nix` file.
|
This task is accomplished using the `agenix` CLI tool with the `./secrets.nix` file.
|
||||||
|
|
||||||
Pretend you want to add a new secret file `xxx.age`, then:
|
Suppose you want to add a new secret file `xxx.age`. Follow these steps:
|
||||||
|
|
||||||
1. `cd` to this directory
|
1. Navigate to your private `nix-secrets` repository.
|
||||||
1. edit `secrets.nix`, add a new entry for `xxx.age`, which defines the
|
2. Edit `secrets.nix` and add a new entry for `xxx.age`, defining the encryption keys and the secret file path, for example:
|
||||||
encryption keys and the secret file path, e.g.
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
# This file is not imported into your NixOS configuration. It is only used for the agenix CLI.
|
# This file is not imported into your NixOS configuration. It is only used for the agenix CLI.
|
||||||
@@ -42,32 +35,69 @@ let
|
|||||||
systems = [ ai ];
|
systems = [ ai ];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
"./encrypt/xxx.age".publicKeys = users ++ systems;
|
"./xxx.age".publicKeys = users ++ systems;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
2. create and edit the secret file `xxx.age` interactively by command:
|
3. Create and edit the secret file `xxx.age` interactively using the following command:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
agenix -e ./encrypt/xxx.age
|
agenix -e ./xxx.age
|
||||||
```
|
```
|
||||||
|
|
||||||
3. or you can also encrypt an existing file to `xxx.age` by command:
|
Alternatively, you can encrypt an existing file to `xxx.age` using the following command:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
cat /path/to/xxx | agenix -e ./encrypt/xxx.age
|
cat /path/to/xxx | agenix -e ./xxx.age
|
||||||
```
|
```
|
||||||
|
|
||||||
the agenix use `~/.ssh/id_ed25519.pub` or `~/.ssh/id_rsa.pub` as encrypt key by default, you need to pass `--identity /path/to/key` to use a custom `/path/to/key.pub` for enctypt.
|
By default, agenix uses `~/.ssh/id_ed25519.pub` or `~/.ssh/id_rsa.pub` as the encryption key.
|
||||||
|
If you want to use a custom key located at `/path/to/key.pub` for encryption, pass `--identity /path/to/key`.
|
||||||
|
|
||||||
## Deploy Secrets
|
## Deploying Secrets
|
||||||
|
|
||||||
This job is done by `nixos-rebuild` with the `./default.nix` file.
|
> All the operations in this section should be performed in this repository.
|
||||||
|
|
||||||
An nixos module exmaple(need to set agenix as flake inputs first...):
|
First, add the private `nix-secrets` repository and `agenix` as flake inputs:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ config, pkgs, agenix, ... }:
|
{
|
||||||
|
inputs = {
|
||||||
|
# ......
|
||||||
|
|
||||||
|
# secrets management, lock with git commit at 2023/5/15
|
||||||
|
agenix.url = "github:ryantm/agenix/db5637d10f797bb251b94ef9040b237f4702cde3";
|
||||||
|
|
||||||
|
# my private secrets, it's a private repository, you need to replace it with your own.
|
||||||
|
mysecrets = { url = "github:ryan4yin/nix-secrets"; flake = false; };
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = inputs@{ self, nixpkgs, ... }: {
|
||||||
|
nixosConfigurations = {
|
||||||
|
nixos-test = nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
|
||||||
|
# Set all input parameters as specialArgs of all sub-modules
|
||||||
|
# so that we can use the `agenix` & `mysecrets` in sub-modules
|
||||||
|
specialArgs = inputs;
|
||||||
|
modules = [
|
||||||
|
# ......
|
||||||
|
|
||||||
|
# import & decrypt secrets in `mysecrets` in this module
|
||||||
|
./secrets/default.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, create `./secrets/default.nix` with the following content:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# import & decrypt secrets in `mysecrets` in this module
|
||||||
|
{ config, pkgs, agenix, mysecrets, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@@ -84,7 +114,7 @@ An nixos module exmaple(need to set agenix as flake inputs first...):
|
|||||||
# target path for decrypted file
|
# target path for decrypted file
|
||||||
path = "/etc/xxx/";
|
path = "/etc/xxx/";
|
||||||
# encrypted file path
|
# encrypted file path
|
||||||
file = ./encrypt/xxx.age;
|
file = "${mysecrets}/xxx.age"; # refer to ./xxx.age located in `mysecrets` repo
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
group = "root";
|
group = "root";
|
||||||
@@ -92,7 +122,10 @@ An nixos module exmaple(need to set agenix as flake inputs first...):
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`nixos-rebuild` will decrypt the secrets using the private keys defined by argument `age.identityPaths`,
|
From now on, every time you run `nixos-rebuild switch`, it will decrypt the secrets using the private keys defined by the `age.identityPaths` argument.
|
||||||
And then symlink the secrets to the path defined by argument `age.secrets.<name>.path`, it defaults to `/etc/secrets`.
|
It will then symlink the secrets to the path defined by the `age.secrets.<name>.path` argument, which defaults to `/etc/secrets`.
|
||||||
|
|
||||||
|
NOTE: By default, `age.identityPaths` is set to `~/.ssh/id_ed25519` and `~/.ssh/id_rsa`,
|
||||||
|
so make sure to place your decryption keys there.
|
||||||
|
If you're deploying to the same machine from which you encrypted the secrets, it should work out of the box.
|
||||||
|
|
||||||
NOTE: `age.identityPaths` it defaults to `~/.ssh/id_ed25519` and `~/.ssh/id_rsa`, so you should put your decrypt keys there. if you're deploying to the same machine as you're encrypting from, it should work out of the box.
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, agenix, ... }:
|
{ pkgs, agenix, mysecrets, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
# target path for decrypted file
|
# target path for decrypted file
|
||||||
path = "/etc/wireguard/";
|
path = "/etc/wireguard/";
|
||||||
# encrypted file path
|
# encrypted file path
|
||||||
file = ./encrypt/wg-business.conf.age;
|
file = "${mysecrets}/wg-business.conf.age";
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
group = "root";
|
group = "root";
|
||||||
@@ -30,6 +30,19 @@
|
|||||||
# wether secrets are symlinked to age.secrets.<name>.path
|
# wether secrets are symlinked to age.secrets.<name>.path
|
||||||
symlink = true;
|
symlink = true;
|
||||||
# encrypted file path
|
# encrypted file path
|
||||||
file = ./encrypt/smb-credentials.age;
|
file = "${mysecrets}/smb-credentials.age";
|
||||||
|
};
|
||||||
|
|
||||||
|
age.secrets."alias-for-work.nushell" = {
|
||||||
|
# wether secrets are symlinked to age.secrets.<name>.path
|
||||||
|
symlink = false;
|
||||||
|
# encrypted file path
|
||||||
|
file = "${mysecrets}/alias-for-work.nushell.age";
|
||||||
|
};
|
||||||
|
age.secrets."alias-for-work.bash" = {
|
||||||
|
# wether secrets are symlinked to age.secrets.<name>.path
|
||||||
|
symlink = false;
|
||||||
|
# encrypted file path
|
||||||
|
file = "${mysecrets}/alias-for-work.bash.age";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 epfRpA jNJBiC/XF/yZK+l5KoQiP9Q4Fd3DmkDy+g4NqFsoe3I
|
|
||||||
k1lFpYcTki0wjwFBDoAwRNZED1bbZI563fFs6wF6cQI
|
|
||||||
-> ssh-ed25519 Q4ARMQ A5e3ifhn8G+XS16KqT0xtSZVwfE6IXgfN4mP0sr+wQ0
|
|
||||||
dKHy5WGc8OxFhlDNEd/ZXPbDcvC7JcFChyK3vkquKjo
|
|
||||||
-> b9bIm-grease
|
|
||||||
Y+K1G8OK/DI2E0cCD27xOPeneAZ/hFkw8bvNBZRYmQ0kTLf017wNDrLcIbyYTjpa
|
|
||||||
/HrKBATlWanuLhzhUFWyBxaJMCqtP35j5TPRCTh7
|
|
||||||
--- rSOSvyrgXuiNAx8P3gDV7VaTcbOzwnufTnjhVvsMS7k
|
|
||||||
3¤&'§6ažè¢(Ï@OÃÒ2ì'ÕÓ<C393>§h&S¹UèãøûÃ…Ù[@¹h=ðFØäz̨ë¢_ä¿D<C2BF>ÿe‡LE{dñ ìs¨%³K’
|
|
||||||
Binary file not shown.
@@ -1,20 +0,0 @@
|
|||||||
# This file is not imported into your NixOS configuration. It is only used for the agenix CLI.
|
|
||||||
|
|
||||||
let
|
|
||||||
# get my ssh public key for agenix by command:
|
|
||||||
# cat ~/.ssh/juliet-age.pub
|
|
||||||
# if you do not have one, you can generate it by command:
|
|
||||||
# ssh-keygen -t ed25519
|
|
||||||
ryan = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP7FbSWehHoOWCZMDEHLiPCa1ZJ5c6hYMzhKdXssPpE9 ryan@juliet-age";
|
|
||||||
users = [ ryan ];
|
|
||||||
|
|
||||||
# get system's ssh public key by command:
|
|
||||||
# cat /etc/ssh/ssh_host_ed25519_key.pub
|
|
||||||
ai = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGeXNCazqiqxn8TmbCRjA+pLWrxwenn+CFhizBMP6en root@ai";
|
|
||||||
systems = [ ai ];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
"./encrypt/wg-business.conf.age".publicKeys = users ++ systems;
|
|
||||||
"./encrypt/smb-credentials.age".publicKeys = users ++ systems;
|
|
||||||
# "./encrypt/secret123.age".publicKeys = [ user1 system1 ];
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user