MOAR SECRETS STUFF
This commit is contained in:
parent
5ecf2285a5
commit
b930d66869
16
flake.lock
generated
16
flake.lock
generated
@ -302,7 +302,6 @@
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nixpkgs-old": "nixpkgs-old",
|
||||
"nixpkgs-wayland": "nixpkgs-wayland",
|
||||
"secrets": "secrets",
|
||||
"simple-nixos-mailserver": "simple-nixos-mailserver",
|
||||
"simple-osd-daemons": "simple-osd-daemons",
|
||||
"weechat-notify-send": "weechat-notify-send",
|
||||
@ -310,21 +309,6 @@
|
||||
"yt-utilities": "yt-utilities"
|
||||
}
|
||||
},
|
||||
"secrets": {
|
||||
"locked": {
|
||||
"lastModified": 1610367002,
|
||||
"narHash": "sha256-u2bwZhhTvXl9XK6EMVRyBiEjs7DDTCx1Nog1mQkB0yQ=",
|
||||
"ref": "master",
|
||||
"rev": "77a6f919690c8a0dd383fccdd61f2c7c99fc24cb",
|
||||
"revCount": 1,
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/balsoft/pass"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/balsoft/pass"
|
||||
}
|
||||
},
|
||||
"simple-nixos-mailserver": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
@ -46,8 +46,6 @@
|
||||
};
|
||||
nixos-fhs-compat.url = github:balsoft/nixos-fhs-compat;
|
||||
simple-osd-daemons.url = github:balsoft/simple-osd-daemons;
|
||||
|
||||
secrets.url = git+ssh://git@github.com/balsoft/pass;
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, nix, self, ... }@inputs: {
|
||||
|
@ -8,7 +8,7 @@ let
|
||||
in {
|
||||
secrets-envsubst.weechat = {
|
||||
owner = "balsoft:users";
|
||||
directory = "weechat";
|
||||
secrets = [ "slack_api_token" ];
|
||||
template = ''
|
||||
[var]
|
||||
python.slack.auto_open_threads = "true"
|
||||
|
@ -3,7 +3,7 @@
|
||||
home.activation.yt-config = "$DRY_RUN_CMD ln -sf $VERBOSE_ARG ${config.secrets-envsubst.yt} $HOME/.yt.yaml";
|
||||
};
|
||||
secrets-envsubst.yt = {
|
||||
directory = "yt";
|
||||
secrets = [ "user" "template" ];
|
||||
owner = "balsoft:users";
|
||||
template = builtins.toJSON {
|
||||
yt-token = "$user";
|
||||
|
@ -85,7 +85,7 @@
|
||||
};
|
||||
|
||||
secrets-envsubst.mautrix-telegram = {
|
||||
directory = "mautrix-telegram";
|
||||
secrets = [ "as_token" "hs_token" "api_id" "api_hash" ];
|
||||
template = ''
|
||||
MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=$as_token
|
||||
MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=$hs_token
|
||||
@ -96,6 +96,7 @@
|
||||
|
||||
secrets-envsubst.mautrix-telegram-registration = {
|
||||
directory = "mautrix-telegram";
|
||||
secrets = [ "as_token" "hs_token" ];
|
||||
owner = "matrix-synapse";
|
||||
template = builtins.toJSON {
|
||||
as_token = "$as_token";
|
||||
@ -118,7 +119,7 @@
|
||||
};
|
||||
|
||||
secrets-envsubst.mautrix-whatsapp = {
|
||||
directory = "mautrix-whatsapp";
|
||||
secrets = [ "as_token" "hs_token" ];
|
||||
owner = "mautrix-whatsapp";
|
||||
template = builtins.toJSON {
|
||||
appservice = {
|
||||
@ -181,6 +182,7 @@
|
||||
|
||||
secrets-envsubst.mautrix-whatsapp-registration = {
|
||||
directory = "mautrix-whatsapp";
|
||||
secrets = [ "as_token" "hs_token" ];
|
||||
owner = "matrix-synapse";
|
||||
template = builtins.toJSON {
|
||||
as_token = "$as_token";
|
||||
|
@ -4,7 +4,11 @@ with types;
|
||||
let
|
||||
envsubstSecrets = { name, ... }: {
|
||||
options = {
|
||||
directory = mkOption { type = str; };
|
||||
directory = mkOption {
|
||||
type = nullOr str;
|
||||
default = name;
|
||||
};
|
||||
secrets = mkOption { type = listOf str; };
|
||||
template = mkOption { type = str; };
|
||||
prefix = mkOption {
|
||||
type = nullOr str;
|
||||
@ -38,34 +42,32 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
individualSecrets = name: cfg:
|
||||
map (x: builtins.elemAt (builtins.match "(.*).gpg" x) 0) (builtins.attrNames (lib.filterAttrs (n: v: v == "regular" || v == "symlink")
|
||||
(builtins.readDir (inputs.secrets + "/${cfg.directory}"))));
|
||||
|
||||
exportSecrets = name: cfg:
|
||||
let prefix = lib.optionalString (!isNull cfg.prefix) "${cfg.prefix}_";
|
||||
in map (secret:
|
||||
''
|
||||
export ${prefix}${secret}="$(cat ${
|
||||
config.secrets."${name}-envsubst-${secret}".decrypted
|
||||
})"'') (individualSecrets name cfg);
|
||||
})"'') cfg.secrets;
|
||||
|
||||
envsubst = name: cfg:
|
||||
with cfg; {
|
||||
"${name}-envsubst" = rec {
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
requires = [ "user@1000.service" "gpg-setup.service" ]
|
||||
++ map (secret: "${name}-envsubst-${secret}-secrets.service") (individualSecrets name cfg);
|
||||
requires = [ "user@1000.service" ]
|
||||
++ map (secret: "${name}-envsubst-${secret}-secrets.service")
|
||||
cfg.secrets;
|
||||
after = requires;
|
||||
bindsTo = requires;
|
||||
|
||||
preStart = "mkdir -p '${builtins.dirOf substituted}'";
|
||||
|
||||
script = ''
|
||||
${builtins.concatStringsSep "\n" (exportSecrets name cfg)}
|
||||
|
||||
if cat '${builtins.toFile "template" template}' | ${cfg.envsubst} > '${substituted}.tmp'; then
|
||||
if cat '${
|
||||
builtins.toFile "template" template
|
||||
}' | ${cfg.envsubst} > '${substituted}.tmp'; then
|
||||
mv -f '${substituted}.tmp' '${substituted}'
|
||||
chown '${owner}' '${substituted}'
|
||||
chmod '${permissions}' '${substituted}'
|
||||
@ -87,16 +89,17 @@ let
|
||||
genAttrs services (service: rec {
|
||||
requires = [ "${name}-envsubst" ];
|
||||
after = requires;
|
||||
bindsTo = requires;
|
||||
});
|
||||
mkServices = name: cfg: [ (envsubst name cfg) (addDependencies name cfg) ];
|
||||
|
||||
mkIndividualSecrets = name: cfg:
|
||||
map (x: {
|
||||
"${name}-envsubst-${x}" = {
|
||||
encrypted = inputs.secrets + "/${cfg.directory}/${x}.gpg";
|
||||
encrypted = "/home/balsoft/.password-store/${lib.optionalString (! isNull cfg.directory) "${cfg.directory}/"}${x}.gpg";
|
||||
services = [ ];
|
||||
};
|
||||
}) (individualSecrets name cfg);
|
||||
}) cfg.secrets;
|
||||
in {
|
||||
options.secrets-envsubst =
|
||||
lib.mkOption { type = attrsOf (submodule envsubstSecrets); };
|
||||
|
@ -6,7 +6,7 @@ let
|
||||
options = {
|
||||
encrypted = mkOption {
|
||||
type = path;
|
||||
default = inputs.secrets + "/${name}.gpg";
|
||||
default = "/home/balsoft/.password-store/${name}.gpg";
|
||||
};
|
||||
decrypted = mkOption {
|
||||
type = path;
|
||||
@ -48,22 +48,15 @@ let
|
||||
with cfg; {
|
||||
"${name}-secrets" = rec {
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
requires = [ "user@1000.service" "gpg-setup.service" ];
|
||||
requires = [ "user@1000.service" ];
|
||||
after = requires;
|
||||
|
||||
preStart = ''
|
||||
[[ -r '${encrypted}' ]]
|
||||
stat '${encrypted}'
|
||||
mkdir -p '${builtins.dirOf decrypted}'
|
||||
'';
|
||||
|
||||
script = ''
|
||||
${optionalString (pkgs.gnupg.version == "2.2.24")
|
||||
"/run/wrappers/bin/sudo -u ${user} ${pkgs.gnupg}/bin/gpg --card-status"
|
||||
# 2.2.24 is broken and needs this hack for yubi to work
|
||||
}
|
||||
|
||||
if cat '${encrypted}' | /run/wrappers/bin/sudo -u ${user} ${cfg.decrypt} > '${decrypted}.tmp'; then
|
||||
mv -f '${decrypted}.tmp' '${decrypted}'
|
||||
chown '${owner}' '${decrypted}'
|
||||
@ -95,68 +88,46 @@ let
|
||||
genAttrs services (service: rec {
|
||||
requires = [ "${name}-secrets" ];
|
||||
after = requires;
|
||||
bindsTo = requires;
|
||||
});
|
||||
|
||||
gpg-setup = rec {
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
requires = [ "user@1000.service" ];
|
||||
after = requires;
|
||||
|
||||
path = [ pkgs.gnupg ];
|
||||
|
||||
script = "echo fetch | gpg --card-edit --no-tty --command-fd=0";
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
User = "balsoft";
|
||||
};
|
||||
};
|
||||
|
||||
mkServices = name: cfg: [ (decrypt name cfg) (addDependencies name cfg) ];
|
||||
in {
|
||||
options.secrets = lib.mkOption { type = attrsOf (submodule secret); };
|
||||
config.systemd.services = mkMerge ([{ inherit gpg-setup; }]
|
||||
++ concatLists (mapAttrsToList mkServices config.secrets));
|
||||
config.systemd.services =
|
||||
mkMerge (concatLists (mapAttrsToList mkServices config.secrets));
|
||||
|
||||
config.environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "activate-secrets" ''
|
||||
set -euo pipefail
|
||||
# Make sure card is available and unlocked
|
||||
echo fetch | gpg --card-edit --no-tty --command-fd=0
|
||||
${pkgs.gnupg}/bin/gpg --card-status
|
||||
if [ -d "$HOME/.password-store" ]; then
|
||||
cd "$HOME/.password-store"; ${pkgs.git}/bin/git pull
|
||||
else
|
||||
${pkgs.git}/bin/git clone ssh://git@github.com/balsoft/pass "$HOME/.password-store"
|
||||
fi
|
||||
ln -sf ${
|
||||
pkgs.writeShellScript "push" "${pkgs.git}/bin/git push origin master"
|
||||
} "$HOME/.password-store/.git/hooks/post-commit"
|
||||
cat $HOME/.password-store/email/balsoft@balsoft.ru.gpg | ${pkgs.gnupg}/bin/gpg --decrypt > /dev/null
|
||||
sudo systemctl restart '*-secrets.service' '*-envsubst.service'
|
||||
'')
|
||||
];
|
||||
|
||||
config.security.sudo.extraRules = [{
|
||||
users = [ "balsoft" ];
|
||||
commands = [{
|
||||
command =
|
||||
"/run/current-system/sw/bin/systemctl restart '*-secrets.service' '*-envsubst.service'";
|
||||
options = [ "NOPASSWD" ];
|
||||
}];
|
||||
}];
|
||||
|
||||
config.home-manager.users.balsoft = {
|
||||
systemd.user.services.pass-sync = {
|
||||
Install.WantedBy =
|
||||
[ "sway-session.target" ]; # Start when the gpg agent is ready
|
||||
|
||||
Service = {
|
||||
ExecStartPre = toString (pkgs.writeShellScript "clone-pass-repo" ''
|
||||
set -euo pipefail
|
||||
|
||||
'');
|
||||
ExecStart = toString (pkgs.writeShellScript "pass-sync" ''
|
||||
set -euo pipefail
|
||||
cd $HOME/.password-store
|
||||
while ${pkgs.inotifyTools}/bin/inotifywait "$HOME/.password-store/.git" -r -e modify -e close_write -e move -e create -e delete; do
|
||||
sleep 0.5
|
||||
${pkgs.git}/bin/git push
|
||||
done
|
||||
'');
|
||||
};
|
||||
};
|
||||
wayland.windowManager.sway = {
|
||||
config.startup = [{
|
||||
command = toString (pkgs.writeShellScript "activate-secrets" ''
|
||||
set -euo pipefail
|
||||
# Make sure card is available and unlocked
|
||||
${pkgs.gnupg}/bin/gpg --card-status
|
||||
cat ${inputs.secrets}/email/balsoft@balsoft.ru.gpg | ${pkgs.gnupg}/bin/gpg --decrypt
|
||||
systemctl restart '*-secrets.service' '*-envsubst.service'
|
||||
if [ -d "$HOME/.password-store" ]; then
|
||||
cd "$HOME/.password-store"; ${pkgs.git}/bin/git pull
|
||||
else
|
||||
${pkgs.git}/bin/git clone ssh://git@github.com/balsoft/pass "$HOME/.password-store"
|
||||
fi
|
||||
ln -sf ${pkgs.writeShellScript "push" "${pkgs.git}/bin/git push origin master"} "$HOME/.password-store/.git/hooks/post-commit"
|
||||
'');
|
||||
}];
|
||||
config.startup = [{ command = "activate-secrets"; }];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -12,6 +12,10 @@
|
||||
services.geoclue2.enable = true;
|
||||
home-manager.users.balsoft = {
|
||||
xdg.userDirs.enable = true;
|
||||
home.activation.gnome-keyring = ''
|
||||
ln -sf ${config.secrets-envsubst.gnome-keyring} "$XDG_DATA_HOME/keyrings/Default_keyring.keyring"
|
||||
echo "Default_keyring" > "$XDG_DATA_HOME/keyrings/default"
|
||||
'';
|
||||
dconf.settings = {
|
||||
"org/gnome/nautilus/icon-view" = {
|
||||
captions = [ "size" "date_modified" "none" ];
|
||||
@ -53,4 +57,94 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
secrets-envsubst.gnome-keyring = {
|
||||
owner = "balsoft:users";
|
||||
secrets = [ "matrix_token" "matrix_password" "email" "nextcloud" ];
|
||||
template = ''
|
||||
[keyring]
|
||||
display-name=Default keyring
|
||||
ctime=1609508068
|
||||
mtime=0
|
||||
lock-on-idle=false
|
||||
lock-after=false
|
||||
|
||||
[5]
|
||||
item-type=0
|
||||
display-name=fractal-token
|
||||
secret=$matrix_token
|
||||
mtime=1610374847
|
||||
ctime=1610374847
|
||||
|
||||
[5:attribute0]
|
||||
name=uid
|
||||
type=string
|
||||
value=@balsoft:balsoft.ru
|
||||
|
||||
[3]
|
||||
item-type=0
|
||||
display-name=Geary IMAP password
|
||||
secret=$email
|
||||
mtime=1610307006
|
||||
ctime=1609572471
|
||||
|
||||
[3:attribute0]
|
||||
name=host
|
||||
type=string
|
||||
value=balsoft.ru
|
||||
|
||||
[3:attribute1]
|
||||
name=login
|
||||
type=string
|
||||
value=balsoft@balsoft.ru
|
||||
|
||||
[3:attribute2]
|
||||
name=proto
|
||||
type=string
|
||||
value=IMAP
|
||||
|
||||
[3:attribute3]
|
||||
name=xdg:schema
|
||||
type=string
|
||||
value=org.gnome.Geary
|
||||
|
||||
[1]
|
||||
item-type=0
|
||||
display-name=GOA owncloud credentials for identity account_1609508064_4
|
||||
secret={'password': <'$nextcloud'>}
|
||||
mtime=1609508086
|
||||
ctime=1609508086
|
||||
|
||||
[1:attribute0]
|
||||
name=goa-identity
|
||||
type=string
|
||||
value=owncloud:gen0:account_1609508064_4
|
||||
|
||||
[1:attribute1]
|
||||
name=xdg:schema
|
||||
type=string
|
||||
value=org.gnome.OnlineAccounts
|
||||
|
||||
[4]
|
||||
item-type=0
|
||||
display-name=fractal
|
||||
secret=$matrix_password
|
||||
mtime=1610374846
|
||||
ctime=1610374846
|
||||
|
||||
[4:attribute0]
|
||||
name=identity
|
||||
type=string
|
||||
value=https://vector.im/
|
||||
|
||||
[4:attribute1]
|
||||
name=server
|
||||
type=string
|
||||
value=https://balsoft.ru/
|
||||
|
||||
[4:attribute2]
|
||||
name=username
|
||||
type=string
|
||||
value=balsoft
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user