Finally switch to new secret management system
This commit is contained in:
parent
fd0ab95c95
commit
e9a30398db
28
flake.lock
generated
28
flake.lock
generated
@ -302,6 +302,7 @@
|
||||
"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",
|
||||
@ -309,6 +310,21 @@
|
||||
"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": {
|
||||
@ -333,15 +349,15 @@
|
||||
"locked": {
|
||||
"lastModified": 1608815402,
|
||||
"narHash": "sha256-oBgd7ZjGho0ivROpc9bIAqN+AbD70HBVWMz36LefK2E=",
|
||||
"ref": "master",
|
||||
"owner": "balsoft",
|
||||
"repo": "simple-osd-daemons",
|
||||
"rev": "dd5883f58c7e49d2b00bd186dfb54afe0dc8fa8a",
|
||||
"revCount": 20,
|
||||
"type": "git",
|
||||
"url": "https://code.balsoft.ru/balsoft/simple-osd-daemons.git"
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://code.balsoft.ru/balsoft/simple-osd-daemons.git"
|
||||
"owner": "balsoft",
|
||||
"repo": "simple-osd-daemons",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"weechat-notify-send": {
|
||||
|
@ -45,7 +45,9 @@
|
||||
ref = "flake";
|
||||
};
|
||||
nixos-fhs-compat.url = github:balsoft/nixos-fhs-compat;
|
||||
simple-osd-daemons.url = git+https://code.balsoft.ru/balsoft/simple-osd-daemons.git;
|
||||
simple-osd-daemons.url = github:balsoft/simple-osd-daemons;
|
||||
|
||||
secrets.url = git+ssh://git@github.com/balsoft/pass;
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, nix, self, ... }@inputs: {
|
||||
|
3
hardware-configuration/NixOS-VM.nix
Normal file
3
hardware-configuration/NixOS-VM.nix
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
9
hardware-configuration/iso-image.nix
Normal file
9
hardware-configuration/iso-image.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{ modulesPath, lib, ... }: {
|
||||
imports = [
|
||||
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
|
||||
];
|
||||
networking.wireless.enable = lib.mkForce false;
|
||||
services.openssh.permitRootLogin = lib.mkForce "no";
|
||||
services.mingetty.autologinUser = lib.mkForce "balsoft";
|
||||
disabledModules = [ "installer/cd-dvd/channel.nix" ];
|
||||
}
|
Binary file not shown.
@ -6,6 +6,7 @@ in {
|
||||
MOZ_USE_XINPUT2 = "1";
|
||||
MOZ_DBUS_REMOTE = "1";
|
||||
};
|
||||
programs.browserpass.enable = true;
|
||||
home-manager.users.balsoft = lib.mkIf (config.deviceSpecific.goodMachine) {
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
@ -57,6 +58,7 @@ in {
|
||||
close-other-windows
|
||||
adsum-notabs
|
||||
ublock-origin
|
||||
browserpass
|
||||
];
|
||||
};
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
with import ../../support.nix { inherit lib config; }; let
|
||||
gearyConfig = {
|
||||
Account = {
|
||||
label = "";
|
||||
ordinal = 6;
|
||||
prefetch_days = 30;
|
||||
prefetch_days = -1;
|
||||
save_drafts = true;
|
||||
save_sent = true;
|
||||
sender_mailboxes = "Alexander Bantyev <balsoft@balsoft.ru>;";
|
||||
@ -65,6 +65,6 @@ in {
|
||||
font-size: 16px;
|
||||
}
|
||||
'';
|
||||
xdg.configFile."geary/account_03/geary.ini".text = lib.generators.toGitINI gearyConfig;
|
||||
xdg.configFile."geary/account_03/geary.ini".text = genIni gearyConfig;
|
||||
};
|
||||
}
|
||||
|
@ -6,17 +6,10 @@ let
|
||||
};
|
||||
};
|
||||
in {
|
||||
home-manager.users.balsoft = {
|
||||
home.file.".weechat/python/autoload/notify_send.py".source =
|
||||
"${inputs.weechat-notify-send}/notify_send.py";
|
||||
|
||||
home.file.".weechat/perl/autoload/multiline.pl".source =
|
||||
"${inputs.weechat-scripts}/perl/multiline.pl";
|
||||
|
||||
home.file.".weechat/python/autoload/go.py".source =
|
||||
"${inputs.weechat-scripts}/python/go.py";
|
||||
|
||||
home.file.".weechat/plugins.conf".text = ''
|
||||
secrets-envsubst.weechat = {
|
||||
owner = "balsoft:users";
|
||||
directory = "weechat";
|
||||
template = ''
|
||||
[var]
|
||||
python.slack.auto_open_threads = "true"
|
||||
python.slack.background_load_all_history = "true"
|
||||
@ -46,12 +39,7 @@ in {
|
||||
python.slack.short_buffer_names = "false"
|
||||
python.slack.show_buflist_presence = "true"
|
||||
python.slack.show_reaction_nicks = "true"
|
||||
python.slack.slack_api_token = "${
|
||||
if isNull config.secrets.slack-term then
|
||||
""
|
||||
else
|
||||
config.secrets.slack-term
|
||||
}"
|
||||
python.slack.slack_api_token = "$slack_api_token"
|
||||
python.slack.slack_timeout = "20000"
|
||||
python.slack.switch_buffer_on_join = "true"
|
||||
python.slack.thread_messages_in_channel = "false"
|
||||
@ -59,6 +47,22 @@ in {
|
||||
python.slack.unfurl_ignore_alt_text = "false"
|
||||
python.slack.unhide_buffers_with_activity = "false"
|
||||
'';
|
||||
};
|
||||
|
||||
home-manager.users.balsoft = {
|
||||
home.file.".weechat/python/autoload/notify_send.py".source =
|
||||
"${inputs.weechat-notify-send}/notify_send.py";
|
||||
|
||||
home.file.".weechat/perl/autoload/multiline.pl".source =
|
||||
"${inputs.weechat-scripts}/perl/multiline.pl";
|
||||
|
||||
home.file.".weechat/python/autoload/go.py".source =
|
||||
"${inputs.weechat-scripts}/python/go.py";
|
||||
|
||||
home.activation.weechat = ''
|
||||
$DRY_RUN_CMD mkdir -p $HOME/.weechat
|
||||
$DRY_RUN_CMD ln -sf $VERBOSE_ARG ${config.secrets-envsubst.weechat} $HOME/.weechat/plugins.conf
|
||||
'';
|
||||
|
||||
home.file.".weechat/weechat.conf".text = ''
|
||||
#
|
||||
|
@ -1,8 +1,13 @@
|
||||
{ pkgs, config, lib, ... }: lib.mkIf (! isNull config.secrets.yt-utilities) {
|
||||
home-manager.users.balsoft = {
|
||||
home.file.".yt.yaml".text = builtins.toJSON {
|
||||
yt-token = config.secrets.yt-utilities.token;
|
||||
user = config.secrets.yt-utilities.user;
|
||||
{ pkgs, config, lib, ... }: {
|
||||
home-manager.users.balsoft = {
|
||||
home.activation.yt-config = "$DRY_RUN_CMD ln -sf $VERBOSE_ARG ${config.secrets-envsubst.yt} $HOME/.yt.yaml";
|
||||
};
|
||||
secrets-envsubst.yt = {
|
||||
directory = "yt";
|
||||
owner = "balsoft:users";
|
||||
template = builtins.toJSON {
|
||||
yt-token = "$user";
|
||||
user = "$token";
|
||||
from = {
|
||||
org = "/home/balsoft/Documents/serokell.org";
|
||||
full-file = true;
|
||||
|
@ -27,6 +27,7 @@ device:
|
||||
./themes.nix
|
||||
./applications.nix
|
||||
./secrets.nix
|
||||
./secrets-envsubst.nix
|
||||
./devices.nix
|
||||
./packages.nix
|
||||
./users.nix
|
||||
@ -39,7 +40,7 @@ device:
|
||||
./nextcloud.nix
|
||||
./mailserver.nix
|
||||
./matrix-synapse.nix
|
||||
./workspace/kanshi.nix
|
||||
# ./workspace/kanshi.nix
|
||||
./nginx.nix
|
||||
./gitea.nix
|
||||
./minidlna.nix
|
||||
|
@ -2,7 +2,7 @@
|
||||
with lib;
|
||||
with types; {
|
||||
options = {
|
||||
device = mkOption { type = strMatching "[A-z|0-9]*-(Laptop|Workstation|VM)"; };
|
||||
device = mkOption { type = strMatching "[A-z|0-9]*-(Laptop|Workstation|VM|image)"; };
|
||||
devices = mkOption { type = attrs; };
|
||||
deviceSpecific = mkOption { type = attrs; };
|
||||
};
|
||||
@ -28,7 +28,6 @@ with types; {
|
||||
T490s-Laptop = {
|
||||
cpu = {
|
||||
vendor = "intel";
|
||||
|
||||
clock = 4600;
|
||||
cores = 4;
|
||||
};
|
||||
@ -120,6 +119,19 @@ with types; {
|
||||
};
|
||||
ram = 4;
|
||||
};
|
||||
iso-image = {
|
||||
cpu = {
|
||||
vendor = "intel";
|
||||
clock = 1000;
|
||||
cores = 1;
|
||||
};
|
||||
drive = {
|
||||
type = "ssd";
|
||||
speed = 50;
|
||||
size = 8;
|
||||
};
|
||||
ram = 4;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ with deviceSpecific; {
|
||||
};
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
loader = lib.mkIf (config.device != "iso-image") ({
|
||||
timeout = 1;
|
||||
} // (if deviceSpecific.devInfo.legacy or false then { # Non-UEFI config
|
||||
grub.enable = true;
|
||||
@ -95,7 +95,7 @@ with deviceSpecific; {
|
||||
grub.device = "/dev/sda";
|
||||
} else { # UEFI config
|
||||
systemd-boot.enable = true;
|
||||
});
|
||||
}));
|
||||
kernelPackages = pkgs.linuxPackages_latest;
|
||||
consoleLogLevel = 3;
|
||||
extraModprobeConfig = ''
|
||||
|
@ -1,13 +1,12 @@
|
||||
{ pkgs, config, lib, inputs, ... }:
|
||||
let
|
||||
module = toString inputs.simple-nixos-mailserver;
|
||||
readCommandResult = command:
|
||||
builtins.readFile (pkgs.runCommand "cmd" { preferLocalBuild = true; }
|
||||
"echo -n $(${command}) > $out");
|
||||
hashedPassword = readCommandResult
|
||||
"${pkgs.mkpasswd}/bin/mkpasswd -m sha-512 '${config.secrets.mail.password}'";
|
||||
in {
|
||||
imports = [ module ];
|
||||
secrets.mailserver = {
|
||||
owner = "dovecot2:dovecot2";
|
||||
services = [ "dovecot2" ];
|
||||
};
|
||||
services.postfix = {
|
||||
dnsBlacklists = [
|
||||
"all.s5h.net"
|
||||
@ -72,15 +71,15 @@ in {
|
||||
192.168.0.0/16 OK
|
||||
'';
|
||||
};
|
||||
mailserver = lib.mkIf (! isNull config.secrets.mail) {
|
||||
mailserver = {
|
||||
enable = true;
|
||||
fqdn = config.secrets.mail.host;
|
||||
domains = [ config.secrets.mail.host ];
|
||||
fqdn = "balsoft.ru";
|
||||
domains = [ "balsoft.ru" ];
|
||||
loginAccounts = {
|
||||
"balsoft@balsoft.ru" = {
|
||||
aliases =
|
||||
[ "balsoft" "admin@balsoft.ru" "patches" "patches@balsoft.ru" "issues" "issues@balsoft.ru" "admin" "root@balsoft.ru" "root" ];
|
||||
inherit hashedPassword;
|
||||
hashedPasswordFile = config.secrets.mailserver.decrypted;
|
||||
};
|
||||
};
|
||||
localDnsResolver = false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ pkgs, config, lib, ... }: lib.mkIf (! isNull config.secrets.matrix) {
|
||||
{ pkgs, config, lib, ... }: {
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
allow_guest_access = true;
|
||||
@ -19,49 +19,191 @@
|
||||
tls = false;
|
||||
x_forwarded = true;
|
||||
}];
|
||||
registration_shared_secret = config.secrets.matrix.shared_secret;
|
||||
public_baseurl = "https://balsoft.ru";
|
||||
server_name = "balsoft.ru";
|
||||
app_service_config_files = [
|
||||
(builtins.toFile "registration_tg.yaml"
|
||||
(builtins.toJSON config.secrets.matrix.mautrix-telegram.registration))
|
||||
(builtins.toFile "registration_wa.yaml"
|
||||
(builtins.toJSON config.secrets.matrix.mautrix-whatsapp.registration))
|
||||
config.secrets-envsubst.mautrix-telegram-registration.substituted
|
||||
config.secrets-envsubst.mautrix-whatsapp-registration.substituted
|
||||
];
|
||||
};
|
||||
services.postgresql.enable = true;
|
||||
home-manager.users.balsoft.xsession.windowManager.i3.config.startup = [{
|
||||
command = "anbox launch --package=com.whatsapp --component=.HomeActivity";
|
||||
}];
|
||||
systemd.services.mautrix-whatsapp = {
|
||||
description = "A bridge between whatsapp and matrix";
|
||||
path = with pkgs; [ coreutils mautrix-whatsapp ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [
|
||||
"matrix-synapse.service"
|
||||
"network-online.target"
|
||||
];
|
||||
requires = [ "matrix-synapse.service" "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Restart = "always";
|
||||
RestartSec = 1;
|
||||
User = "mautrix-whatsapp";
|
||||
StateDirectory = "mautrix-whatsapp";
|
||||
};
|
||||
script = ''
|
||||
mkdir -p /var/lib/mautrix-whatsapp
|
||||
cd /var/lib/mautrix-whatsapp
|
||||
sleep 5
|
||||
mautrix-whatsapp -c ${
|
||||
builtins.toFile "config_wa.yaml"
|
||||
(builtins.toJSON config.secrets.matrix.mautrix-whatsapp.config)
|
||||
}
|
||||
mautrix-whatsapp -c ${config.secrets-envsubst.mautrix-whatsapp}
|
||||
'';
|
||||
};
|
||||
users.users.mautrix-whatsapp.isSystemUser = true;
|
||||
|
||||
services.mautrix-telegram = {
|
||||
enable = true;
|
||||
settings = config.secrets.matrix.mautrix-telegram.config;
|
||||
environmentFile = toString config.secrets-envsubst.mautrix-telegram;
|
||||
settings = {
|
||||
appservice = {
|
||||
address = "http://localhost:29317";
|
||||
bot_avatar = "mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX";
|
||||
id = "telegram";
|
||||
max_body_size = 1;
|
||||
port = 29317;
|
||||
};
|
||||
bridge = {
|
||||
alias_template = "tg_{groupname}";
|
||||
allow_matrix_login = true;
|
||||
bot_messages_as_notices = true;
|
||||
catch_up = true;
|
||||
command_prefix = "!tg";
|
||||
image_as_file_size = 10;
|
||||
max_document_size = 100;
|
||||
max_initial_member_sync = -1;
|
||||
max_telegram_delete = 10;
|
||||
permissions = {
|
||||
"*" = "relaybot";
|
||||
"@balsoft:balsoft.ru" = "admin";
|
||||
};
|
||||
plaintext_highlights = true;
|
||||
startup_sync = true;
|
||||
username_template = "tg_{userid}";
|
||||
};
|
||||
homeserver = {
|
||||
address = "https://matrix.balsoft.ru";
|
||||
domain = "balsoft.ru";
|
||||
verify_ssl = true;
|
||||
};
|
||||
telegram = { bot_token = "disabled"; };
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.mautrix-telegram.serviceConfig.DynamicUser = lib.mkForce false;
|
||||
secrets-envsubst.mautrix-telegram = {
|
||||
directory = "mautrix-telegram";
|
||||
template = ''
|
||||
MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=$as_token
|
||||
MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=$hs_token
|
||||
MAUTRIX_TELEGRAM_TELEGRAM_API_ID=$api_id
|
||||
MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=$api_hash
|
||||
'';
|
||||
};
|
||||
|
||||
secrets-envsubst.mautrix-telegram-registration = {
|
||||
directory = "mautrix-telegram";
|
||||
owner = "matrix-synapse";
|
||||
template = builtins.toJSON {
|
||||
as_token = "$as_token";
|
||||
hs_token = "$hs_token";
|
||||
id = "telegram";
|
||||
namespaces = {
|
||||
aliases = [{
|
||||
exclusive = true;
|
||||
regex = "#tg_.+:balsoft.ru";
|
||||
}];
|
||||
users = [{
|
||||
exclusive = true;
|
||||
regex = "@tg_.+:balsoft.ru";
|
||||
}];
|
||||
};
|
||||
rate_limited = false;
|
||||
sender_localpart = "telegrambot";
|
||||
url = "http://localhost:29317";
|
||||
};
|
||||
};
|
||||
|
||||
secrets-envsubst.mautrix-whatsapp = {
|
||||
directory = "mautrix-whatsapp";
|
||||
owner = "mautrix-whatsapp";
|
||||
template = builtins.toJSON {
|
||||
appservice = {
|
||||
address = "http://localhost:29318";
|
||||
as_token = "$as_token";
|
||||
bot = {
|
||||
avatar = "mxc://maunium.net/NeXNQarUbrlYBiPCpprYsRqr";
|
||||
displayname = "WhatsApp bridge bot";
|
||||
username = "whatsappbot";
|
||||
};
|
||||
database = {
|
||||
max_idle_conns = 2;
|
||||
max_open_conns = 20;
|
||||
type = "sqlite3";
|
||||
uri = "mautrix-whatsapp.db";
|
||||
};
|
||||
hostname = "0.0.0.0";
|
||||
hs_token = "$hs_token";
|
||||
id = "whatsapp";
|
||||
port = 29318;
|
||||
state_store_path = "./mx-state.json";
|
||||
};
|
||||
bridge = {
|
||||
command_prefix = "!wa";
|
||||
connection_retry_delay = -1;
|
||||
connection_timeout = 20;
|
||||
contact_wait_delay = 1;
|
||||
displayname_template =
|
||||
"{{if .Notify}}{{.Notify}}{{else}}{{.Jid}}{{end}} (WA)";
|
||||
initial_chat_sync_count = 10;
|
||||
initial_history_fill_count = 20;
|
||||
invite_own_puppet_for_backfilling = true;
|
||||
max_connection_attempts = 3;
|
||||
permissions = {
|
||||
"*" = 10;
|
||||
"@balsoft:balsoft.ru" = 100;
|
||||
};
|
||||
private_chat_portal_meta = false;
|
||||
recovery_chat_sync_count = -1;
|
||||
recovery_history_backfill = true;
|
||||
report_connection_retry = true;
|
||||
sync_max_chat_age = 259200;
|
||||
sync_with_custom_puppets = true;
|
||||
username_template = "whatsapp_{{.}}";
|
||||
};
|
||||
homeserver = {
|
||||
address = "http://localhost:13748";
|
||||
domain = "balsoft.ru";
|
||||
};
|
||||
logging = {
|
||||
directory = "./logs";
|
||||
file_date_format = "2006-01-02";
|
||||
file_mode = 384;
|
||||
file_name_format = "{{.Date}}-{{.Index}}.log";
|
||||
print_level = "debug";
|
||||
timestamp_format = "Jan _2, 2006 15:04:05";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
secrets-envsubst.mautrix-whatsapp-registration = {
|
||||
directory = "mautrix-whatsapp";
|
||||
owner = "matrix-synapse";
|
||||
template = builtins.toJSON {
|
||||
as_token = "$as_token";
|
||||
hs_token = "$hs_token";
|
||||
id = "whatsapp";
|
||||
namespaces = {
|
||||
users = [{
|
||||
exclusive = true;
|
||||
regex = "^@whatsapp_[0-9]+:balsoft.ru$";
|
||||
}];
|
||||
};
|
||||
rate_limited = false;
|
||||
sender_localpart = "whatsappbot";
|
||||
url = "http://localhost:29318";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.mautrix-telegram.serviceConfig.DynamicUser =
|
||||
lib.mkForce false;
|
||||
|
||||
systemd.services.mautrix-telegram.serviceConfig.User = "mautrix-telegram";
|
||||
|
||||
users.users.mautrix-telegram.isSystemUser = true;
|
||||
|
||||
users.users.matrix-synapse.name = lib.mkForce "matrix-synapse";
|
||||
}
|
||||
|
@ -3,10 +3,14 @@
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "nextcloud.balsoft.ru";
|
||||
config.adminpassFile = "/home/balsoft/nextcloud-admin";
|
||||
config.adminpassFile = config.secrets.nextcloud.decrypted;
|
||||
package = pkgs.nextcloud20;
|
||||
https = true;
|
||||
};
|
||||
secrets.nextcloud = {
|
||||
owner = "nextcloud:nextcloud";
|
||||
services = [ "nextcloud-setup" ];
|
||||
};
|
||||
services.nginx.virtualHosts."nextcloud.balsoft.ru" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
107
modules/secrets-envsubst.nix
Normal file
107
modules/secrets-envsubst.nix
Normal file
@ -0,0 +1,107 @@
|
||||
{ pkgs, config, lib, inputs, ... }:
|
||||
with lib;
|
||||
with types;
|
||||
let
|
||||
envsubstSecrets = { name, ... }: {
|
||||
options = {
|
||||
directory = mkOption { type = str; };
|
||||
template = mkOption { type = str; };
|
||||
prefix = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
substituted = mkOption {
|
||||
type = path;
|
||||
default = "/var/secrets/${name}-envsubst";
|
||||
};
|
||||
envsubst = mkOption {
|
||||
type = str;
|
||||
default = "${pkgs.envsubst}/bin/envsubst -no-unset -no-empty";
|
||||
};
|
||||
owner = mkOption {
|
||||
type = str;
|
||||
default = "root:root";
|
||||
};
|
||||
permissions = mkOption {
|
||||
type = lib.types.addCheck lib.types.str
|
||||
(perm: !isNull (builtins.match "[0-7]{3}" perm));
|
||||
default = "400";
|
||||
};
|
||||
services = mkOption {
|
||||
type = listOf str;
|
||||
default = [ "${name}.service" ];
|
||||
};
|
||||
__toString = mkOption {
|
||||
readOnly = true;
|
||||
default = s: s.substituted;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
after = 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
|
||||
mv -f '${substituted}.tmp' '${substituted}'
|
||||
chown '${owner}' '${substituted}'
|
||||
chmod '${permissions}' '${substituted}'
|
||||
else
|
||||
echo "Failed to run the substition"
|
||||
rm '${substituted}.tmp'
|
||||
fi
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
addDependencies = name: cfg:
|
||||
with cfg;
|
||||
genAttrs services (service: rec {
|
||||
requires = [ "${name}-envsubst" ];
|
||||
after = 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";
|
||||
services = [ ];
|
||||
};
|
||||
}) (individualSecrets name cfg);
|
||||
in {
|
||||
options.secrets-envsubst =
|
||||
lib.mkOption { type = attrsOf (submodule envsubstSecrets); };
|
||||
config.systemd.services =
|
||||
mkMerge (concatLists (mapAttrsToList mkServices config.secrets-envsubst));
|
||||
config.secrets = mkMerge
|
||||
(concatLists (mapAttrsToList mkIndividualSecrets config.secrets-envsubst));
|
||||
}
|
@ -2,98 +2,161 @@
|
||||
with lib;
|
||||
with types;
|
||||
let
|
||||
secret = description:
|
||||
mkOption {
|
||||
inherit description;
|
||||
type = nullOr str;
|
||||
};
|
||||
mkCredOption = service: extra:
|
||||
mkOption {
|
||||
description = "Credentials for ${service}";
|
||||
type = nullOr (submodule {
|
||||
options = {
|
||||
user = mkOption {
|
||||
type = str;
|
||||
description = "Username for ${service}";
|
||||
};
|
||||
password = mkOption {
|
||||
type = str;
|
||||
description = "Password for ${service}";
|
||||
};
|
||||
} // extra;
|
||||
});
|
||||
};
|
||||
in rec {
|
||||
options.secrets = {
|
||||
slack-term = secret "slack token";
|
||||
yt-utilities = mkOption {
|
||||
description = "youtrack";
|
||||
type = nullOr (submodule {
|
||||
options = {
|
||||
user = secret "youtrack user";
|
||||
url = secret "youtrack url";
|
||||
token = secret "youtrack token";
|
||||
};
|
||||
});
|
||||
};
|
||||
wage = secret "wage (sum CURRENCY/TIME, like 10EUR/h)";
|
||||
gcal = mkOption {
|
||||
description = "Google calendar auth";
|
||||
type = nullOr (submodule {
|
||||
options = {
|
||||
email = mkOption { type = lib.types.str; };
|
||||
client-id = mkOption { type = lib.types.str; };
|
||||
client-secret = mkOption { type = lib.types.str; };
|
||||
refresh-token = mkOption { type = lib.types.str; };
|
||||
};
|
||||
});
|
||||
};
|
||||
mail = mkCredOption "email" {
|
||||
host = mkOption {
|
||||
secret = { name, ... }: {
|
||||
options = {
|
||||
encrypted = mkOption {
|
||||
type = path;
|
||||
default = inputs.secrets + "/${name}.gpg";
|
||||
};
|
||||
decrypted = mkOption {
|
||||
type = path;
|
||||
default = "/var/secrets/${name}";
|
||||
};
|
||||
decrypt = mkOption {
|
||||
default = pkgs.writeShellScript "gpg-decrypt" ''
|
||||
set -euo pipefail
|
||||
export GPG_TTY="$(tty)"
|
||||
${pkgs.gnupg}/bin/gpg-connect-agent updatestartuptty /bye 1>&2
|
||||
${pkgs.gnupg}/bin/gpg --batch --no-tty --decrypt
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
type = str;
|
||||
description = "Mail server";
|
||||
default = "balsoft";
|
||||
};
|
||||
};
|
||||
openvpn = mkCredOption "openvpn" { };
|
||||
rclone = mkOption {
|
||||
type = nullOr str;
|
||||
description = "Rclone config";
|
||||
};
|
||||
ssl = mkOption {
|
||||
description = "Certs";
|
||||
type = nullOr (submodule {
|
||||
options = {
|
||||
cert = mkOption {
|
||||
type = nullOr str;
|
||||
description = "SSL certificate";
|
||||
};
|
||||
priv = mkOption {
|
||||
type = nullOr str;
|
||||
description = "SSL RSA private key";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
matrix = mkCredOption "matrix" rec {
|
||||
shared_secret = mkOption {
|
||||
type = nullOr str;
|
||||
description = "A shared secret for matrix instance";
|
||||
owner = mkOption {
|
||||
type = str;
|
||||
default = "root:root";
|
||||
};
|
||||
mautrix-whatsapp = {
|
||||
config = mkOption { type = attrs; };
|
||||
registration = mkOption { type = attrs; };
|
||||
permissions = mkOption {
|
||||
type = lib.types.addCheck lib.types.str
|
||||
(perm: !isNull (builtins.match "[0-7]{3}" perm));
|
||||
default = "400";
|
||||
};
|
||||
services = mkOption {
|
||||
type = listOf str;
|
||||
default = [ "${name}.service" ];
|
||||
};
|
||||
__toString = mkOption {
|
||||
readOnly = true;
|
||||
default = s: s.decrypted;
|
||||
};
|
||||
mautrix-telegram = mautrix-whatsapp;
|
||||
};
|
||||
};
|
||||
config = let
|
||||
unlocked = import (pkgs.runCommand "check-secret" { }
|
||||
"set +e; grep -qI . ${../secret.nix}; echo $? > $out") == 0;
|
||||
secretnix = import ../secret.nix;
|
||||
secrets = if !unlocked || isNull secretnix then
|
||||
builtins.trace "secret.nix locked, building without any secrets"
|
||||
(mapAttrs (n: v: null) options.secrets)
|
||||
else
|
||||
secretnix;
|
||||
in { inherit secrets; };
|
||||
|
||||
decrypt = name: cfg:
|
||||
with cfg; {
|
||||
"${name}-secrets" = rec {
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
requires = [ "user@1000.service" "gpg-setup.service" ];
|
||||
after = requires;
|
||||
|
||||
preStart = ''
|
||||
[[ -r '${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}'
|
||||
chmod '${permissions}' '${decrypted}'
|
||||
else
|
||||
echo "Failed to decrypt the secret"
|
||||
rm '${decrypted}.tmp'
|
||||
fi
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
};
|
||||
|
||||
unitConfig = {
|
||||
ConditionPathExists = [
|
||||
"/run/user/${
|
||||
toString config.users.users.${user}.uid
|
||||
}/gnupg/S.gpg-agent"
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
addDependencies = name: cfg:
|
||||
with cfg;
|
||||
genAttrs services (service: rec {
|
||||
requires = [ "${name}-secrets" ];
|
||||
after = 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.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"
|
||||
'');
|
||||
}];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -30,8 +30,10 @@
|
||||
systemd.services."user@" = { serviceConfig = { Restart = "always"; }; };
|
||||
|
||||
home-manager.users.balsoft.home.activation.yubi = {
|
||||
data =
|
||||
"[ -s /home/balsoft/.config/Yubico/u2f_keys ] || (pamu2fcfg > /home/balsoft/.config/Yubico/u2f_keys)";
|
||||
data = ''
|
||||
mkdir -p .config/Yubico
|
||||
[ -f /home/balsoft/.config/Yubico/u2f_keys ] || (pamu2fcfg > /home/balsoft/.config/Yubico/u2f_keys)
|
||||
'';
|
||||
after = [ "linkGeneration" ];
|
||||
before = [ ];
|
||||
};
|
||||
@ -55,11 +57,12 @@
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "lock" ''
|
||||
set -euo pipefail
|
||||
if [[ "$1" == this ]]
|
||||
then args="-s"
|
||||
else args="-san"
|
||||
fi
|
||||
USER=balsoft ${pkgs.vlock}/bin/vlock "$args"
|
||||
${lib.optionalString (config.deviceSpecific.isLaptop) ''USER=balsoft ${pkgs.vlock}/bin/vlock "$args"''}
|
||||
'')
|
||||
];
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
material-icons
|
||||
];
|
||||
fontconfig = {
|
||||
enable = true;
|
||||
enable = lib.mkForce true;
|
||||
defaultFonts = {
|
||||
monospace = [ "IBM Plex Mono 13" ];
|
||||
sansSerif = [ "IBM Plex Sans 13" ];
|
||||
|
@ -3,6 +3,11 @@ with import ../../../support.nix { inherit pkgs config lib; };
|
||||
with lib;
|
||||
let scripts = import ./scripts pkgs config;
|
||||
in {
|
||||
secrets.wage = {
|
||||
owner = "balsoft:users";
|
||||
services = [ ];
|
||||
};
|
||||
|
||||
home-manager.users.balsoft = {
|
||||
wayland.windowManager.sway.config.bars = [{
|
||||
id = "default";
|
||||
@ -39,10 +44,10 @@ in {
|
||||
in ''
|
||||
interval=60
|
||||
markup=pango
|
||||
'' + genIniOrdered (optional (!isNull config.secrets.mail) (scr "email")
|
||||
'' + genIniOrdered ([]
|
||||
# (scr "email")
|
||||
++ [ (scrint "weather" 600) (scr "emacs") (scr "nixos") ]
|
||||
++ optional (!isNull config.secrets.wage) (scrint "youtrack-wage" 3600)
|
||||
++ [ (scrint "music" 3) (scrint "sound" 1) ] ++ [
|
||||
++ [ (scrint "youtrack-wage" 3600) (scrint "music" 3) (scrint "sound" 1) ] ++ [
|
||||
(scrint "cpu" 5)
|
||||
(scrint "freq" 10)
|
||||
(scr "temperature")
|
||||
|
@ -5,17 +5,18 @@ in
|
||||
#!${bash}/bin/bash
|
||||
set -euo pipefail
|
||||
export PATH="$PATH:${yt-utilities}/bin:${ec}/bin:${libqalculate}/bin"
|
||||
WAGE=$(cat ${config.secrets.wage.decrypted})
|
||||
HOURS_MONTH=$(yt org local --since $(date +'%Y-%m-01') | tail -1)
|
||||
MONEY_MONTH=$(qalc -t "($HOURS_MONTH) * (${config.secrets.wage})")
|
||||
MONEY_MONTH=$(qalc -t "($HOURS_MONTH) * $WAGE")
|
||||
'' + (if config.deviceSpecific.bigScreen then ''
|
||||
HOURS_DAY=$(yt org local --since $(date +'%Y-%m-%d') | tail -1)
|
||||
HOURS_YEAR=$(yt org local --since $(date +'%Y-01-01') | tail -1)
|
||||
MONEY_DAY=$(qalc -t "($HOURS_DAY) * (${config.secrets.wage})")
|
||||
MONEY_YEAR=$(qalc -t "($HOURS_YEAR) * (${config.secrets.wage})")
|
||||
MONEY_DAY=$(qalc -t "($HOURS_DAY) * $WAGE")
|
||||
MONEY_YEAR=$(qalc -t "($HOURS_YEAR) * $WAGE")
|
||||
TASK=$(emacsclient --eval "org-mode-line-string" 2>/dev/null || echo -n none)
|
||||
if ! [[ "$TASK" == "none" ]]; then
|
||||
HOURS_TASK=$(echo "$TASK" | head -1 | cut -d\" -f 2 | cut -d\[ -f2 | cut -d\] -f1)h
|
||||
MONEY_TASK=$(qalc -t -e "$HOURS_TASK * (${config.secrets.wage})" )
|
||||
MONEY_TASK=$(qalc -t -e "$HOURS_TASK * $WAGE" )
|
||||
echo "$MONEY_TASK/$MONEY_DAY($HOURS_DAY)/$MONEY_MONTH($HOURS_MONTH)/$MONEY_YEAR"
|
||||
else
|
||||
echo "$MONEY_DAY($HOURS_DAY)/$MONEY_MONTH($HOURS_MONTH)/$MONEY_YEAR"
|
||||
|
@ -85,10 +85,6 @@ in {
|
||||
command =
|
||||
"${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1";
|
||||
}
|
||||
{
|
||||
command =
|
||||
"${pkgs.keepassxc}/bin/keepassxc /home/balsoft/projects/nixos-config/misc/Passwords.kdbx";
|
||||
}
|
||||
{ command = "${pkgs.spectral}/bin/spectral"; }
|
||||
{ command = "${pkgs.xorg.xrdb}/bin/xrdb -merge ~/.Xresources"; }
|
||||
|
||||
|
BIN
secret.nix
BIN
secret.nix
Binary file not shown.
Loading…
Reference in New Issue
Block a user