Compare commits
20 Commits
1d3847ec12
...
1b4b3fbd6a
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b4b3fbd6a | |||
| eac053ca07 | |||
| 33ccad5bf6 | |||
| 6bf45ce941 | |||
| b6be6eba68 | |||
| 5934568d10 | |||
| 3627cf57ec | |||
| 869bee8adc | |||
| 61964329fe | |||
| 1f4bc6f981 | |||
| 2ce1505fda | |||
| 3097fb0af1 | |||
| 9403b72a75 | |||
| 1658330591 | |||
| a45f5a4cca | |||
| 52a351ee8c | |||
| a2bcf3578e | |||
| 73bab574d4 | |||
| a59db0af58 | |||
| e925b43a2d |
@@ -2,7 +2,13 @@ keys:
|
|||||||
- &john-p14s age1f6drjusg866yscj8029tk4yfpgecklrvezldm02ankm6h8nnwu5s2u6ahy
|
- &john-p14s age1f6drjusg866yscj8029tk4yfpgecklrvezldm02ankm6h8nnwu5s2u6ahy
|
||||||
- &john-pc age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
|
- &john-pc age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
|
||||||
- &test-nix age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
|
- &test-nix age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
|
||||||
|
- &soteria age1h0prahyukq4l564yqwgcpg3g6gdrjflk0suklussjjrjstxd9uesws8633
|
||||||
creation_rules:
|
creation_rules:
|
||||||
|
- path_regex: soteria/secrets\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *john-pc
|
||||||
|
- *soteria
|
||||||
- path_regex: \.yaml$
|
- path_regex: \.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ in
|
|||||||
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
|
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
|
||||||
modules = with inputs.self.modules; [
|
modules = with inputs.self.modules; [
|
||||||
nixos.lxc
|
nixos.lxc
|
||||||
nixos.sops
|
nixos.mysops
|
||||||
nixos.step-ssh-host
|
nixos.step-ssh-host
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
nixos."${username}"
|
nixos."${username}"
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
let
|
let
|
||||||
username = "john";
|
username = "john";
|
||||||
hostname = "john-pc-ubuntu";
|
hostname = "john-pc-ubuntu";
|
||||||
testTarget = "fded:fb16:653e:25da:be24:11ff:fea0:753f";
|
# testTarget = "fded:fb16:653e:25da:be24:11ff:fea0:753f"; # test-nix
|
||||||
|
testTarget = "fded:fb16:653e:25da:be24:11ff:fe89:1cc3"; # soteria
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
flake.modules.homeManager."${hostname}" = { pkgs, config, ... }:
|
flake.modules.homeManager."${hostname}" = { pkgs, config, ... }:
|
||||||
@@ -17,7 +18,7 @@ in
|
|||||||
imports = with inputs.self.modules.homeManager; [
|
imports = with inputs.self.modules.homeManager; [
|
||||||
rebuild
|
rebuild
|
||||||
john
|
john
|
||||||
sops
|
mysops
|
||||||
step-ssh-user
|
step-ssh-user
|
||||||
mtls
|
mtls
|
||||||
restic
|
restic
|
||||||
@@ -34,28 +35,14 @@ in
|
|||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
nixos-rebuild
|
nixos-rebuild
|
||||||
(writeShellScriptBin "test-push" ''
|
(writeShellScriptBin "test-push" ''
|
||||||
nixos-rebuild switch --flake ${flakeDir}#soteria --target-host root@${testTarget}
|
mkdir -p /var/tmp/nix-build
|
||||||
|
chmod 1777 /var/tmp/nix-build
|
||||||
|
nixos-rebuild switch \
|
||||||
|
--flake ${flakeDir}#john-pc-ubuntu \
|
||||||
|
--target-host root@${testTarget}
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
mtls = {
|
|
||||||
enable = true;
|
|
||||||
caURL = "https://janus.john-stream.com/";
|
|
||||||
provisioner = "admin";
|
|
||||||
subject = hostname;
|
|
||||||
san = [
|
|
||||||
"${hostname}"
|
|
||||||
"192.168.1.85"
|
|
||||||
"spiffe://john-stream.com/ubuntu"
|
|
||||||
];
|
|
||||||
lifetime = "1h";
|
|
||||||
renew.onCalendar = "*:1/10";
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO: Add host-specific settings here:
|
|
||||||
# - sops secret for `restic_password/john_ubuntu`
|
|
||||||
# - zsh RESTIC* session variables
|
|
||||||
|
|
||||||
# TODO: make this more restrictive, rather than allowing all unfree packages
|
# TODO: make this more restrictive, rather than allowing all unfree packages
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
nixpkgs.config.permittedInsecurePackages = [ "openssl-1.1.1w" ];
|
nixpkgs.config.permittedInsecurePackages = [ "openssl-1.1.1w" ];
|
||||||
@@ -77,9 +64,17 @@ in
|
|||||||
dev = true;
|
dev = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
sops.secrets."restic_password/john_ubuntu" = {
|
|
||||||
|
# This provides the keys at build time and will be included in the nix store
|
||||||
|
sops.defaultSopsFile = ../../../keys/secrets.yaml;
|
||||||
|
|
||||||
|
# This will provide the edit-secrets script targeting this file
|
||||||
|
mysops.hostSecretFile = "${config.xdg.configHome}/home-manager/jsl-dendritic/keys/secrets.yaml";
|
||||||
|
|
||||||
|
sops.secrets."restic_password" = {
|
||||||
path = resticPasswordFile;
|
path = resticPasswordFile;
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
|
sopsFile = ./secrets.yaml;
|
||||||
};
|
};
|
||||||
restic = {
|
restic = {
|
||||||
passwordFile = resticPasswordFile;
|
passwordFile = resticPasswordFile;
|
||||||
@@ -93,6 +88,21 @@ in
|
|||||||
"/home/john/john-nas"
|
"/home/john/john-nas"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
mtls = {
|
||||||
|
enable = true;
|
||||||
|
subject = hostname;
|
||||||
|
ca = {
|
||||||
|
url = "https://janus.john-stream.com/";
|
||||||
|
fingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6";
|
||||||
|
};
|
||||||
|
san = [
|
||||||
|
"${hostname}"
|
||||||
|
"192.168.1.85"
|
||||||
|
"spiffe://john-stream.com/ubuntu"
|
||||||
|
];
|
||||||
|
lifetime = "1h";
|
||||||
|
renew.onCalendar = "*:1/10";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.homeConfigurations."${hostname}" = inputs.home-manager.lib.homeManagerConfiguration {
|
flake.homeConfigurations."${hostname}" = inputs.home-manager.lib.homeManagerConfiguration {
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
restic_password: ENC[AES256_GCM,data:BVP4do8UgSX48ovwDH3D2Px6p3lr859F43TTO6pr/fIo78kI0btLDtP+BKbIauawHdvOR7g3dIRrJIvUqDBUnKIH8NE9VxyUrK+U9UzwX17m7T96h/gf3FJ55BEKKVecbJdLrVriq9fVQwUT0Dg2cCZQLctfhwaPNa5Jhkb2oqSKbJ6OmM10eS9KqprE+bVXnCd5vZtRWMKAKiGn3kfKieC79kUcFZla7M739+BMiYa7KvPkhmPOBYwSsWIBQrBFr9X+IDxP0EuEMHrOItnAv/TzG773PM+T+h5rgv6xY+fd1i1cBl5XIijtOGmyJDvrOQLVLTjeoY9LHzYyy31N102mP0SLoz1F4bINMzn1ykvUZCbgSdbyfbBUSS2WJmpbKGrE+KYGxLybFr+4kVYrrONK7Bg7NTWDPcTwdpgDL+Fk8KCiP2jg7sAjpaWRAkwrXpbCwhHPmjmJ7P5tlsxmGy46dZVKmZ3BhPWZlZfQDJ+8NRGn3U56MjGBACLMn1ZvSYXxyWc0SzLRPe2F106XCx3c08jzBaFVP76fLMAY0TXJ6VpvHrEsQKMGLw0pfciisfjRpKmNIPczz5N9wqgJIOrYBTlc/ipugXfJ5HunoLegzc6P/Z2Xjr38Ug0pz86+KhRviLVLvtDtouzpeejOve7FGIiOrd5dNVUsZ2QG+YI5Pbm6tiO/NgTLAWLmlsti1TKN9pen6nvi7NhDPiFMRqQi9FRF2HFxhhvW8uE3Ax8G98xlKcqtmzNidqiZJndAP5EJcJKe0WQUCLnybWNi8nmneFx8iMPEMFpxx9PeYNte4Wdv51P7NYNZmju+4NNaSuWW1sqmi4VJqw0HvhPHJ/8R+AKG8h6BWk00Nsawbn4OHGnz5+jWczUq+hsxeNDutUQf3FWRQIXNE/XGsXXEXBguk1AOScVj2GtdMa5L/Abamq1kx3osXMf2P1HqPHyzQK2a6olZPSVeERr9vk7V5/a0ZYgaIUPq3X8gieo1Fv6gSKiilQ33oAJ3dt0nDvrtzTHtyEuPn4xfG2JKvsFAKQIFbjSObsO6Lb/bVZWjFYc1Wt7I3Jcu6atHxpaFqv+riI4gbdgZ4NcsoruDvm5pGoNfVPoEylstsWXRQ3FptohQ74qr+Z8rAUGwVOXg+HFtFQqETGxy8QPWk0hLupNotxt2uIKpBal/z/6IYvHtP/KwiTaY/tlQmQ9l5qGQJLm1LfhdPCJJNvGUFEDZnrCYl34STIATcFIYmy2AzBQPABH7CFk/4MLeu8aiDRC8LV9zwm5PqYJ8DR0gFk6OJIciJ9rnPomMhyI5svpDQN+q8JpXWkUDl2Hi6sAx/jevk4+RyQaD1z2rusZjO5FJ/zVI2sT//yBdcgg7sNb3UfrIU4RjFP4Ep9iu04Mn3gOpt9RBGt7ITyzqXIvV7Qfy/1C4Uk9Fgj9T+ANPIRtdImTuDB01yP14FBeV02KbdqJCnwpUvArJ85/JDtVZniDm9EwilWJuAMlehDqam7jZEGVJjbnM2PyTci3DOGHAtfxsYX6R6RMD43+ScVY26sLjqNWFJq0FTGqf+yqBlG3XrS0l4P985iy6wL53R+MHvwel2a4mqAW1BNMQT/pCGyBrwuAF1M4Zgz7WAyPU8xCT7dMrq0ZQtsLGgs3qeq5rRVOw61F9zlIgFq72whlQcm0YJ3gAXl+5w742/O2MMpZoixB84Ao34uwkAn3WzGNZvpD+UK0UlpnisiXSVKUxFWZZcssVWUFuFzOSxftvmJ4CWgZu7Waj1oyV6E1Emu/a+uaIhaThdtFdJFmtUQlOjRWQ3e6dGv4FOIIl3ndR,iv:cJZBim2+pQ7o+nhfsgfbWF6PlVizvcUnoc1liLKyxLw=,tag:QPlckxNJslHT5lJ0osHVgA==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1f6drjusg866yscj8029tk4yfpgecklrvezldm02ankm6h8nnwu5s2u6ahy
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvbE1nQXlwZkFBckg5RWNF
|
||||||
|
UFpGdVpXZG5xajFmQ0hoOGxGQVRoMlJDVXhFCjVYclNURmp1QTl6TXVsRFB6NWpm
|
||||||
|
L1pLcnVPT0lydUpWUTdPbkJiZVlPRDQKLS0tIENkY2JlSGRsUXdsUW9PVlNleUVG
|
||||||
|
OGgrQy84UmhHNVhqQkZneSt0cVdGUjAKOfsZOE3pyHdzE5c59HPJ5cw2NibWm6kK
|
||||||
|
bDElCvACeJ2j/zU1iVsdTJ8DNnDV3L9Y78lNobd+AVRjQ6y5AZMTzg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2a3NnNXo3dTVlcjB6TlFq
|
||||||
|
aGIvWG9xU1o1VVlKdUpCaFhTWm03cWROWFRjCmZkb3Npa3htS0JOeWltT0tYVkRw
|
||||||
|
RE5LMkVicHdsT216UVZDOW11SWtQT0EKLS0tIGFmTlhOVHhJTXhZWkpYdzU3SS9y
|
||||||
|
YSt4VTJoQ2IyM0JNY0JSWGdSbzI2RjgK9vOoUC/tPCI27W1Ma5GZ0qlb+hx9cWhX
|
||||||
|
9fxGAqyeGz6sQgdtfw5j0pGbPCASUb5E89UrFsnVdMAOIbuHX2LtAQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOUUU2Sjh0UFBKOGJiWkFu
|
||||||
|
MFZDQjJoc3l2eUNEeTlIMTRCQnkrVm04aXpnCjhUTTh2ZDg2V3BSYWl3RS9wSkVk
|
||||||
|
dSsrQythWDFPYzJJYTBuWWxTWUFXdUEKLS0tIFZqUnBnNlBNQUxoS1cvV0ZDR24w
|
||||||
|
SGY1K1dvTXdXemNrVE1zakJrN3FyS2cKk7KtnuffHkInCYw4t+WPPiYoBN1t2bu3
|
||||||
|
f/ECS1NnY06m+s3cB0TlphZoLQyKqx3zuOyAmm2i38KhkdOMFSc6IA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-25T03:59:38Z"
|
||||||
|
mac: ENC[AES256_GCM,data:6K7fXOkKbpvpvkuBR/INlAPFfvXAW2xwpdn0evB4OaF7NueZvtg9tDJVDtGAxmo78vAOLBEZX8x4h0ezuuWpkDW5LFP6N7O70h4ExlCEH01zcESgk3gjyXLu9gRTM2/7+bvlGLKq2TQYHOF4LYDhcs5/RzWgarFKYljh6m1KbSQ=,iv:Rlh1r588ymZF5BXf5S+gKLH77+kuaC19Ctvhctfu4EQ=,tag:b55Bx+dRwQPx10zdizUMeg==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.12.1
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
let
|
|
||||||
username = "john";
|
|
||||||
hostname = "soteria";
|
|
||||||
caURL = "https://janus.john-stream.com/";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
modules = with inputs.self.modules; [
|
|
||||||
nixos.lxc
|
|
||||||
nixos.sops
|
|
||||||
nixos.step-ssh-host
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
nixos."${username}"
|
|
||||||
nixos.zsh
|
|
||||||
nixos.login-text
|
|
||||||
nixos.mtls
|
|
||||||
nixos.restic-server
|
|
||||||
{
|
|
||||||
networking.hostName = hostname;
|
|
||||||
step-ssh-host = {
|
|
||||||
hostname = hostname;
|
|
||||||
caURL = caURL;
|
|
||||||
};
|
|
||||||
mtls = {
|
|
||||||
enable = true;
|
|
||||||
subject = hostname;
|
|
||||||
caURL = caURL;
|
|
||||||
san = [
|
|
||||||
"${hostname}.john-stream.com"
|
|
||||||
# "192.168.1.244"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users."${username}" = {
|
|
||||||
imports = with inputs.self.modules.homeManager; [
|
|
||||||
sops
|
|
||||||
step-ssh-user
|
|
||||||
];
|
|
||||||
shell.program = "zsh";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
janus:
|
||||||
|
admin_password: ENC[AES256_GCM,data:4pnSq0f1iTNFWn/Qcw+J7LWIXXd/j5v3WwFSzXfqgKA=,iv:/usSHYST8zv7AMvDNuW/fFLL+40IrderjL6bUWzBNd4=,tag:V/q1+SjIcYsZ0+PC/Q7c1A==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1ykcs39e62pz3xu6cedg8ea685kv5d5qsrhgkndygzm8rx30xd5ys5t3qxt
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0V1JsVDhnMHpaNHRQRCtw
|
||||||
|
V3JMQm1SREZSYUpaYmZNQ1FEVmN0VFZRSlQ0Ck9wQlpqZFBrRUJENWVBbTd5cVVo
|
||||||
|
ZlhYZnhGamk1ZlQ0N001ZWcrQ1Evb3cKLS0tIHpuTWhRTU1QeWFRUytiU21CMW94
|
||||||
|
eFc0ankvcWhqK3Q4MjRCVC9nTlJteU0K1tJvYM2M1XmlsCTpadHyf6EGE2Lg+XBL
|
||||||
|
TGTjMPSWqClWYB9HFZ4nCurEK/JidBanmGkc0Y9eFz9XYKl7rtyXUw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1h0prahyukq4l564yqwgcpg3g6gdrjflk0suklussjjrjstxd9uesws8633
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNRzFlWTNxSGpaNU85QTFj
|
||||||
|
SnlRZkpZQTZQVjNqWFhLMHhKVm5ZVXB4Rms0CmZQclFzYkpWLzlqT2xNUTJMd2dJ
|
||||||
|
Wm5PQXNabjRwV1hVRXFGVmxteGk2emMKLS0tIG5kcm5KamxNZmpKVGt5bUo1dVg5
|
||||||
|
dFN2RGdqM29mM3hadXpBakY4QThxZnMKI9RbfXJHIHvYHy/2corfwDq+OHRPrmkA
|
||||||
|
tWLH/KWqwGt0hvc5j8bUfRECgjdXmbC9kpAgDs8PhJF+X1ijVFrIYg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-23T22:27:45Z"
|
||||||
|
mac: ENC[AES256_GCM,data:tQ8EMXWqw7wd/QZqUPn/sAczk0G4jSUR96AF83cmJGYuoZkMkOzsMFt448IkWxNWOJHPmIc0vs+c3ngQxHyx6Uf9jVWzMkvfdzMYj82QuLsmXQ9e4/IAE9h+52uagbwgoOJwPCF+AQetSHez/jWPPIQPN5DLfz0edg4xYReX7DA=,iv:GsvotFkehIz5L4I9j0oQ89oM5XjZQAr6vrVd79tqFes=,tag:wLi4sXz8JqvaoUaYjEj/vA==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.12.1
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{ inputs, ... }:
|
||||||
|
let
|
||||||
|
username = "john";
|
||||||
|
hostname = "soteria";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
|
||||||
|
modules = with inputs.self.modules; [
|
||||||
|
nixos.lxc
|
||||||
|
nixos.mysops
|
||||||
|
nixos.step-ssh-host
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
nixos."${username}"
|
||||||
|
nixos.zsh
|
||||||
|
nixos.login-text
|
||||||
|
# nixos.mtls
|
||||||
|
# nixos.restic-server
|
||||||
|
# nixos.restic-envoy
|
||||||
|
{
|
||||||
|
networking.hostName = hostname;
|
||||||
|
nix.settings.build-dir = "/var/tmp/nix-build";
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /var/tmp/nix-build 1777 root root -"
|
||||||
|
];
|
||||||
|
step-ssh-host = {
|
||||||
|
hostname = hostname;
|
||||||
|
caURL = caURL;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager.users."${username}" = {
|
||||||
|
imports = with inputs.self.modules; [
|
||||||
|
homeManager"${hostname}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.modules.homeManager."${hostname}" = { config, lib, pkgs, ... }: {
|
||||||
|
imports = with inputs.self.modules; [
|
||||||
|
homeManager.rebuild
|
||||||
|
homeManager.mysops
|
||||||
|
homeManager.mtls
|
||||||
|
homeManager.docker
|
||||||
|
];
|
||||||
|
|
||||||
|
homeManagerFlakeDir = "${config.xdg.configHome}/home-manager";
|
||||||
|
home.username = "${username}";
|
||||||
|
home.homeDirectory = "/home/${username}";
|
||||||
|
shell.program = "zsh";
|
||||||
|
docker.enable = true;
|
||||||
|
|
||||||
|
# This will provide the edit-secrets script targeting this file
|
||||||
|
mysops.hostSecretFile = "${config.xdg.configHome}/home-manager/modules/hosts/soteria/secrets.yaml";
|
||||||
|
|
||||||
|
mtls = {
|
||||||
|
enable = true;
|
||||||
|
subject = hostname;
|
||||||
|
ca = {
|
||||||
|
url = "https://janus.john-stream.com/";
|
||||||
|
fingerprint = "2036c44f7b5901566ff7611ea6c927291ecc6d2dd00779c0eead70ec77fa10d6";
|
||||||
|
};
|
||||||
|
san = [
|
||||||
|
"${hostname}.john-stream.com"
|
||||||
|
"192.168.1.142"
|
||||||
|
];
|
||||||
|
lifetime = "1h";
|
||||||
|
renew.onCalendar = "*:3/15";
|
||||||
|
renew.postCommands = [
|
||||||
|
"${lib.getExe pkgs.docker} restart envoy"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.homeConfigurations."${hostname}" = inputs.home-manager.lib.homeManagerConfiguration {
|
||||||
|
pkgs = import inputs.nixpkgs { system = "x86_64-linux"; };
|
||||||
|
modules = with inputs.self.modules; [
|
||||||
|
homeManager."${username}"
|
||||||
|
homeManager."${hostname}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ in
|
|||||||
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
|
flake.nixosConfigurations."${hostname}" = inputs.nixpkgs.lib.nixosSystem {
|
||||||
modules = with inputs.self.modules; [
|
modules = with inputs.self.modules; [
|
||||||
nixos.lxc
|
nixos.lxc
|
||||||
nixos.sops
|
nixos.mysops
|
||||||
nixos.step-ssh-host
|
nixos.step-ssh-host
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
nixos."${username}"
|
nixos."${username}"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
'')
|
'')
|
||||||
(writeShellScriptBin "nhms" ''
|
(writeShellScriptBin "nhms" ''
|
||||||
HOSTNAME=$(hostname -s)
|
HOSTNAME=$(hostname -s)
|
||||||
|
echo "Switching to the $HOSTNAME profile"
|
||||||
${lib.getExe home-manager} switch --impure --flake ${flakeDir}#$HOSTNAME
|
${lib.getExe home-manager} switch --impure --flake ${flakeDir}#$HOSTNAME
|
||||||
'')
|
'')
|
||||||
(writeShellScriptBin "nhmu" ''
|
(writeShellScriptBin "nhmu" ''
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{ self, inputs, ... }: {
|
||||||
|
flake.modules.homeManager.gmail = {config, ... }: {
|
||||||
|
home.sessionVariables = {
|
||||||
|
GMAIL_CREDS_PATH = "${config.xdg.configHome}/sops-nix/gmail_api_credentials.json";
|
||||||
|
};
|
||||||
|
sops = {
|
||||||
|
secrets."api/gmail_client_secret" = { };
|
||||||
|
templates."gmail_creds" = {
|
||||||
|
path = "${config.xdg.configHome}/sops-nix/gmail_api_credentials.json";
|
||||||
|
content = ''
|
||||||
|
{
|
||||||
|
"installed": {
|
||||||
|
"client_id": "499012320469-vtml6emu6bmujpsj9lud2b44jqu7h26j.apps.googleusercontent.com",
|
||||||
|
"project_id": "python-apis-423500",
|
||||||
|
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
"token_uri": "https://oauth2.googleapis.com/token",
|
||||||
|
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||||
|
"client_secret": "${config.sops.placeholder."api/gmail_client_secret"}",
|
||||||
|
"redirect_uris": [ "http://localhost" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
+44
-44
@@ -10,78 +10,78 @@ in
|
|||||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.modules.nixos.sops = {
|
flake.modules.nixos.mysops = {
|
||||||
imports = with inputs.sops-nix.nixosModules; [
|
imports = [ inputs.sops-nix.nixosModules.sops ];
|
||||||
sops
|
|
||||||
];
|
|
||||||
|
|
||||||
sops.defaultSopsFile = ../../keys/secrets.yaml;
|
|
||||||
sops.secrets."test-nix/ssh_host_key" = {
|
|
||||||
owner = "john";
|
|
||||||
path = "/home/john/.ssh/host_key";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Define the homeModules that are used by flake-parts
|
# Define the homeModules that are used by flake-parts
|
||||||
# https://flake.parts/options/home-manager.html#opt-flake.modules.homeManager
|
# https://flake.parts/options/home-manager.html#opt-flake.modules.homeManager
|
||||||
flake.modules.homeManager.sops = { inputs, config, pkgs, lib, ... }:
|
flake.modules.homeManager.mysops = { inputs, config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
|
cfg = config.mysops;
|
||||||
sopsBin = lib.getExe pkgs.sops;
|
sopsBin = lib.getExe pkgs.sops;
|
||||||
sopsConfigPath = ../../.sops.yaml;
|
sopsConfigPath = ../../.sops.yaml;
|
||||||
sopsSecretsPath = ../../keys/secrets.yaml;
|
sopsSecretsPath = ../../keys/secrets.yaml;
|
||||||
ageKeyFile = "${config.xdg.configHome}/sops/age/keys.txt";
|
|
||||||
flakeDir = "${config.xdg.configHome}/home-manager/jsl-dendritic";
|
editScript = lib.optional (cfg.hostSecretFile != null) (pkgs.writeShellScriptBin "edit-secrets" ''
|
||||||
|
${sopsBin} --config ${sopsConfigPath} ${cfg.hostSecretFile}
|
||||||
|
'');
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
# This import makes the sops config attribute available below
|
||||||
|
inputs'.sops-nix.homeManagerModules.sops
|
||||||
|
];
|
||||||
|
|
||||||
|
options.mysops = {
|
||||||
|
ageKeyFile = lib.mkOption {
|
||||||
|
description = "Default location for the age key";
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "${config.xdg.configHome}/sops/age/keys.txt";
|
||||||
|
};
|
||||||
|
hostSecretFile = lib.mkOption {
|
||||||
|
description = "Path to the secrets file for this host";
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
eza
|
eza
|
||||||
age
|
age
|
||||||
sops # This is necessary to make the sops binary available
|
sops # This is necessary to make the sops binary available
|
||||||
ssh-to-age
|
ssh-to-age
|
||||||
(writeShellScriptBin "gen-age-key" ''
|
(writeShellScriptBin "gen-age-key" ''
|
||||||
${lib.getExe pkgs.ssh-to-age} -i ${config.ssh.IdentityFile} -private-key > ${ageKeyFile}
|
set -eu
|
||||||
echo -n "Created ${ageKeyFile}: "
|
|
||||||
|
if [ ! -f "${config.ssh.IdentityFile}" ]; then
|
||||||
|
echo "SSH identity file not found: ${config.ssh.IdentityFile}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e "${cfg.ageKeyFile}" ]; then
|
||||||
|
echo "Refusing to overwrite existing age key file: ${cfg.ageKeyFile}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "${cfg.ageKeyFile}")"
|
||||||
|
${lib.getExe pkgs.ssh-to-age} -i ${config.ssh.IdentityFile} -private-key > ${cfg.ageKeyFile}
|
||||||
|
echo -n "Created ${cfg.ageKeyFile}: "
|
||||||
echo $(show-age-key)
|
echo $(show-age-key)
|
||||||
'')
|
'')
|
||||||
(writeShellScriptBin "show-age-key" "${lib.getExe' pkgs.age "age-keygen"} -y ${ageKeyFile}")
|
(writeShellScriptBin "show-age-key" "${lib.getExe' pkgs.age "age-keygen"} -y ${cfg.ageKeyFile}")
|
||||||
(writeShellScriptBin "edit-secrets" "${sopsBin} --config ${sopsConfigPath} ${flakeDir}/keys/secrets.yaml")
|
|
||||||
(writeShellScriptBin "ls-secrets" "${lib.getExe pkgs.eza} -alT --follow-symlinks ~/.config/sops-nix/secrets")
|
(writeShellScriptBin "ls-secrets" "${lib.getExe pkgs.eza} -alT --follow-symlinks ~/.config/sops-nix/secrets")
|
||||||
];
|
] ++ editScript;
|
||||||
|
|
||||||
home.shellAliases.sops = "${sopsBin} --config ${sopsConfigPath}";
|
home.shellAliases.sops = "${sopsBin} --config ${sopsConfigPath}";
|
||||||
|
|
||||||
imports = [
|
|
||||||
# This import makes the sops config attribute available below
|
|
||||||
inputs'.sops-nix.homeManagerModules.sops
|
|
||||||
];
|
|
||||||
|
|
||||||
home.sessionVariables = {
|
|
||||||
GMAIL_CREDS_PATH = "${config.xdg.configHome}/sops-nix/gmail_api_credentials.json";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Option definitions for the sops home-manager module:
|
# Option definitions for the sops home-manager module:
|
||||||
# https://github.com/Mic92/sops-nix/blob/master/modules/home-manager/sops.nix
|
# https://github.com/Mic92/sops-nix/blob/master/modules/home-manager/sops.nix
|
||||||
sops = {
|
sops = {
|
||||||
defaultSopsFile = sopsSecretsPath;
|
defaultSopsFile = sopsSecretsPath;
|
||||||
defaultSopsFormat = "yaml";
|
defaultSopsFormat = "yaml";
|
||||||
age.sshKeyPaths = [ "${config.ssh.IdentityFile}" ];
|
age.sshKeyPaths = [ "${config.ssh.IdentityFile}" ];
|
||||||
|
|
||||||
secrets."api/gmail_client_secret" = { };
|
|
||||||
templates."gmail_creds" = {
|
|
||||||
path = "${config.xdg.configHome}/sops-nix/gmail_api_credentials.json";
|
|
||||||
content = ''
|
|
||||||
{
|
|
||||||
"installed": {
|
|
||||||
"client_id": "499012320469-vtml6emu6bmujpsj9lud2b44jqu7h26j.apps.googleusercontent.com",
|
|
||||||
"project_id": "python-apis-423500",
|
|
||||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
||||||
"token_uri": "https://oauth2.googleapis.com/token",
|
|
||||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
|
||||||
"client_secret": "${config.sops.placeholder."api/gmail_client_secret"}",
|
|
||||||
"redirect_uris": [ "http://localhost" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,323 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
flake.modules.nixos.restic-envoy = { config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.restic.envoy;
|
||||||
|
|
||||||
|
envoyConfig = {
|
||||||
|
static_resources = {
|
||||||
|
listeners = [
|
||||||
|
{
|
||||||
|
name = "listener_0";
|
||||||
|
address.socket_address = {
|
||||||
|
address = cfg.listenAddress;
|
||||||
|
port_value = cfg.port;
|
||||||
|
};
|
||||||
|
filter_chains = [
|
||||||
|
{
|
||||||
|
filter_chain_match.server_names = cfg.serverNames;
|
||||||
|
transport_socket = {
|
||||||
|
name = "envoy.transport_sockets.tls";
|
||||||
|
typed_config = {
|
||||||
|
"@type" = "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext";
|
||||||
|
require_client_certificate = true;
|
||||||
|
common_tls_context = {
|
||||||
|
tls_params.tls_minimum_protocol_version = "TLSv1_3";
|
||||||
|
validation_context = {
|
||||||
|
trusted_ca.filename = cfg.trustedCAPath;
|
||||||
|
match_typed_subject_alt_names = [
|
||||||
|
{
|
||||||
|
san_type = "URI";
|
||||||
|
matcher.prefix = cfg.spiffePrefix;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
tls_certificates = [
|
||||||
|
{
|
||||||
|
certificate_chain.filename = cfg.certificatePath;
|
||||||
|
private_key.filename = cfg.pkcs8PrivateKeyPath;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
filters = [
|
||||||
|
{
|
||||||
|
name = "envoy.filters.network.http_connection_manager";
|
||||||
|
typed_config = {
|
||||||
|
"@type" = "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager";
|
||||||
|
stat_prefix = "ingress_http";
|
||||||
|
use_remote_address = true;
|
||||||
|
http2_protocol_options.max_concurrent_streams = 100;
|
||||||
|
access_log = [
|
||||||
|
{
|
||||||
|
name = "envoy.access_loggers.file";
|
||||||
|
typed_config = {
|
||||||
|
"@type" = "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog";
|
||||||
|
path = cfg.accessLogPath;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
route_config = {
|
||||||
|
name = "local_route";
|
||||||
|
virtual_hosts = [
|
||||||
|
{
|
||||||
|
name = "local_service";
|
||||||
|
domains = [ "*" ];
|
||||||
|
routes = [
|
||||||
|
{
|
||||||
|
match.prefix = "/";
|
||||||
|
route.cluster = cfg.clusterName;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
http_filters = [
|
||||||
|
{
|
||||||
|
name = "envoy.filters.http.rbac";
|
||||||
|
typed_config = {
|
||||||
|
"@type" = "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC";
|
||||||
|
rules = {
|
||||||
|
action = "ALLOW";
|
||||||
|
policies = lib.mapAttrs (_: policy: {
|
||||||
|
permissions = [
|
||||||
|
{
|
||||||
|
and_rules.rules = [
|
||||||
|
{
|
||||||
|
header = {
|
||||||
|
name = ":path";
|
||||||
|
string_match.prefix = policy.pathPrefix;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
principals = [
|
||||||
|
{
|
||||||
|
authenticated.principal_name.exact = policy.principal;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}) cfg.policies;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "envoy.filters.http.router";
|
||||||
|
typed_config = {
|
||||||
|
"@type" = "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
clusters = [
|
||||||
|
{
|
||||||
|
name = cfg.clusterName;
|
||||||
|
connect_timeout = cfg.connectTimeout;
|
||||||
|
type = "STRICT_DNS";
|
||||||
|
lb_policy = "ROUND_ROBIN";
|
||||||
|
load_assignment = {
|
||||||
|
cluster_name = cfg.clusterName;
|
||||||
|
endpoints = [
|
||||||
|
{
|
||||||
|
lb_endpoints = [
|
||||||
|
{
|
||||||
|
endpoint.address.socket_address = {
|
||||||
|
address = cfg.upstreamHost;
|
||||||
|
port_value = cfg.upstreamPort;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = (pkgs.formats.json { }).generate "restic-envoy.json" envoyConfig;
|
||||||
|
ensurePkcs8Key = pkgs.writeShellScript "restic-envoy-prepare-key" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
install -d -m 0750 /run/restic-envoy
|
||||||
|
${lib.getExe pkgs.openssl} pkcs8 \
|
||||||
|
-topk8 \
|
||||||
|
-nocrypt \
|
||||||
|
-in ${lib.escapeShellArg cfg.sourcePrivateKeyPath} \
|
||||||
|
-out ${lib.escapeShellArg cfg.pkcs8PrivateKeyPath}
|
||||||
|
chmod 0600 ${lib.escapeShellArg cfg.pkcs8PrivateKeyPath}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.restic.envoy = {
|
||||||
|
enable = lib.mkEnableOption "an Envoy mTLS front-end for restic";
|
||||||
|
|
||||||
|
listenAddress = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
description = "Address for Envoy to bind to.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 10000;
|
||||||
|
description = "TCP port for the Envoy listener.";
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Open the configured listener port in the firewall.";
|
||||||
|
};
|
||||||
|
|
||||||
|
serverNames = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ "*.john-stream.com" ];
|
||||||
|
description = "Accepted SNI server names for the downstream TLS filter chain.";
|
||||||
|
};
|
||||||
|
|
||||||
|
spiffePrefix = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "spiffe://john-stream.com";
|
||||||
|
description = "Allowed SPIFFE URI prefix for client certificate SAN validation.";
|
||||||
|
};
|
||||||
|
|
||||||
|
trustedCAPath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/etc/step/certs/root_ca.crt";
|
||||||
|
description = "Path to the CA certificate used to validate client certificates.";
|
||||||
|
};
|
||||||
|
|
||||||
|
certificatePath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/etc/step/certs/cert.pem";
|
||||||
|
description = "Path to the server certificate presented by Envoy.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sourcePrivateKeyPath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/etc/step/certs/key.pem";
|
||||||
|
description = "Path to the source private key that will be converted to PKCS#8 for Envoy.";
|
||||||
|
};
|
||||||
|
|
||||||
|
pkcs8PrivateKeyPath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/run/restic-envoy/key_pkcs8.pem";
|
||||||
|
description = "Path to the PKCS#8 private key file consumed by Envoy.";
|
||||||
|
};
|
||||||
|
|
||||||
|
accessLogPath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/log/envoy/access.log";
|
||||||
|
description = "Path for the Envoy HTTP access log.";
|
||||||
|
};
|
||||||
|
|
||||||
|
clusterName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "restic";
|
||||||
|
description = "Name of the upstream Envoy cluster.";
|
||||||
|
};
|
||||||
|
|
||||||
|
connectTimeout = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "0.25s";
|
||||||
|
description = "Cluster connect timeout in Envoy duration format.";
|
||||||
|
};
|
||||||
|
|
||||||
|
upstreamHost = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "rest-server";
|
||||||
|
description = "DNS name or IP address for the upstream restic server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
upstreamPort = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 8000;
|
||||||
|
description = "TCP port for the upstream restic server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
logLevel = lib.mkOption {
|
||||||
|
type = lib.types.enum [ "trace" "debug" "info" "warning" "error" "critical" "off" ];
|
||||||
|
default = "info";
|
||||||
|
description = "Envoy application log level.";
|
||||||
|
};
|
||||||
|
|
||||||
|
policies = lib.mkOption {
|
||||||
|
description = "RBAC policy definitions keyed by Envoy policy name.";
|
||||||
|
type = lib.types.attrsOf (lib.types.submodule ({ ... }: {
|
||||||
|
options = {
|
||||||
|
pathPrefix = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Allowed HTTP path prefix for this principal.";
|
||||||
|
};
|
||||||
|
|
||||||
|
principal = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Exact SPIFFE principal required for this path prefix.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
default = {
|
||||||
|
ubuntu-policy = {
|
||||||
|
pathPrefix = "/john-ubuntu";
|
||||||
|
principal = "spiffe://john-stream.com/ubuntu";
|
||||||
|
};
|
||||||
|
p14-policy = {
|
||||||
|
pathPrefix = "/john-p14s";
|
||||||
|
principal = "spiffe://john-stream.com/john-p14s";
|
||||||
|
};
|
||||||
|
gitea-policy = {
|
||||||
|
pathPrefix = "/gitea";
|
||||||
|
principal = "spiffe://john-stream.com/gitea";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.serverNames != [ ];
|
||||||
|
message = "restic.envoy.serverNames must not be empty.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.policies != { };
|
||||||
|
message = "restic.envoy.policies must define at least one RBAC policy.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ cfg.port ];
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /var/log/envoy 0750 root root -"
|
||||||
|
"d /run/restic-envoy 0750 root root -"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.restic-envoy = {
|
||||||
|
description = "Envoy reverse proxy for the restic server";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
restartIfChanged = true;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
User = "root";
|
||||||
|
Group = "root";
|
||||||
|
ExecStartPre = ensurePkcs8Key;
|
||||||
|
ExecStart = "${lib.getExe pkgs.envoy} --config-path ${configFile} --log-level ${cfg.logLevel}";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "5s";
|
||||||
|
RuntimeDirectory = "restic-envoy";
|
||||||
|
LogsDirectory = "envoy";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,10 +3,14 @@ let
|
|||||||
# Options that will be in common between
|
# Options that will be in common between
|
||||||
opts = {
|
opts = {
|
||||||
enable = lib.mkEnableOption "Enable mTLS";
|
enable = lib.mkEnableOption "Enable mTLS";
|
||||||
caURL = lib.mkOption {
|
ca = {
|
||||||
description = "URL to the certificate authority";
|
url = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
|
fingerprint = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
subject = lib.mkOption {
|
subject = lib.mkOption {
|
||||||
description = "The Common Name, DNS Name, or IP address that will be set as the Subject Common Name for the certificate. If no Subject Alternative Names (SANs) are configured (via the --san flag) then the subject will be set as the only SAN.";
|
description = "The Common Name, DNS Name, or IP address that will be set as the Subject Common Name for the certificate. If no Subject Alternative Names (SANs) are configured (via the --san flag) then the subject will be set as the only SAN.";
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
@@ -110,7 +114,10 @@ let
|
|||||||
umask 077
|
umask 077
|
||||||
${lib.getExe' pkgs.coreutils "cat"} "${tlsCert}" "${tlsKey}" > "${mtlsBundle}"
|
${lib.getExe' pkgs.coreutils "cat"} "${tlsCert}" "${tlsKey}" > "${mtlsBundle}"
|
||||||
|
|
||||||
|
echo "Reloading units:"
|
||||||
${renewReloadScript}
|
${renewReloadScript}
|
||||||
|
|
||||||
|
echo "Post commands:"
|
||||||
${renewPostCommands}
|
${renewPostCommands}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
@@ -225,8 +232,6 @@ in
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
${lib.getExe pkgs.step-cli} ca certificate \
|
${lib.getExe pkgs.step-cli} ca certificate \
|
||||||
${cfg.subject} ${tlsCert} ${tlsKey} \
|
${cfg.subject} ${tlsCert} ${tlsKey} \
|
||||||
--ca-url ${cfg.caURL} \
|
|
||||||
--root ${rootCA} \
|
|
||||||
--provisioner ${cfg.provisioner} \
|
--provisioner ${cfg.provisioner} \
|
||||||
--not-before=-5m --not-after=${cfg.lifetime} \
|
--not-before=-5m --not-after=${cfg.lifetime} \
|
||||||
${sanArgs} \
|
${sanArgs} \
|
||||||
@@ -272,6 +277,12 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
home.file.".step/config/defaults.json".text = builtins.toJSON {
|
||||||
|
"ca-url" = cfg.ca.url;
|
||||||
|
fingerprint = cfg.ca.fingerprint;
|
||||||
|
root = "${cfg.certDir}/root_ca.crt";
|
||||||
|
};
|
||||||
|
|
||||||
home.packages = with pkgs; lib.optionals cfg.enable [
|
home.packages = with pkgs; lib.optionals cfg.enable [
|
||||||
step-cli
|
step-cli
|
||||||
(writeShellScriptBin "mtls-generate" ''
|
(writeShellScriptBin "mtls-generate" ''
|
||||||
|
|||||||
Reference in New Issue
Block a user