modules.system.sops: rewrite

This commit is contained in:
2025-07-12 10:18:28 +08:00
parent f9dc3d7357
commit 3e1b621434
38 changed files with 960 additions and 871 deletions

View File

@@ -40,7 +40,7 @@
dns-push = pkgs.callPackage ./dns dns-push = pkgs.callPackage ./dns
{ {
inherit localLib; inherit localLib;
tokenPath = inputs.self.nixosConfigurations.pc.config.sops.secrets."acme/token".path; tokenPath = inputs.self.nixosConfigurations.pc.config.nixos.system.sops.secrets."acme/token".path;
octodns = pkgs.octodns.withProviders (_: with pkgs.octodns-providers; [ cloudflare ]); octodns = pkgs.octodns.withProviders (_: with pkgs.octodns-providers; [ cloudflare ]);
}; };
archive = archive =

View File

@@ -34,21 +34,21 @@ inputs:
name = builtins.elemAt cert.value.domains 0; name = builtins.elemAt cert.value.domains 0;
value = value =
{ {
credentialsFile = inputs.config.sops.templates."acme/cloudflare.ini".path; credentialsFile = inputs.config.nixos.system.sops.templates."acme/cloudflare.ini".path;
extraDomainNames = builtins.tail cert.value.domains; extraDomainNames = builtins.tail cert.value.domains;
group = inputs.lib.mkIf (cert.value.group != null) cert.value.group; group = inputs.lib.mkIf (cert.value.group != null) cert.value.group;
}; };
}) })
(inputs.localLib.attrsToList acme.cert)); (inputs.localLib.attrsToList acme.cert));
}; };
sops = nixos.system.sops =
{ {
templates."acme/cloudflare.ini".content = templates."acme/cloudflare.ini".content =
'' ''
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.sops.placeholder."acme/token"} CLOUDFLARE_DNS_API_TOKEN=${inputs.config.nixos.system.sops.placeholder."acme/token"}
CLOUDFLARE_PROPAGATION_TIMEOUT=300 CLOUDFLARE_PROPAGATION_TIMEOUT=300
''; '';
secrets."acme/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; secrets."acme/token" = {};
}; };
}; };
} }

View File

@@ -14,14 +14,17 @@ inputs:
{ {
enable = true; enable = true;
use-auth-secret = true; use-auth-secret = true;
static-auth-secret-file = inputs.config.sops.secrets."coturn/auth-secret".path; static-auth-secret-file = inputs.config.nixos.system.sops.secrets."coturn/auth-secret".path;
realm = coturn.hostname; realm = coturn.hostname;
cert = "${keydir}/full.pem"; cert = "${keydir}/full.pem";
pkey = "${keydir}/key.pem"; pkey = "${keydir}/key.pem";
no-cli = true; no-cli = true;
}; };
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User; nixos =
nixos.services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group; {
system.sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
};
networking.firewall = with inputs.config.services.coturn; networking.firewall = with inputs.config.services.coturn;
{ {
allowedUDPPorts = [ listening-port tls-listening-port ]; allowedUDPPorts = [ listening-port tls-listening-port ];

View File

@@ -15,19 +15,18 @@ inputs:
enable = true; enable = true;
baseUrl = "https://${freshrss.hostname}"; baseUrl = "https://${freshrss.hostname}";
defaultUser = "chn"; defaultUser = "chn";
passwordFile = inputs.config.sops.secrets."freshrss/chn".path; passwordFile = inputs.config.nixos.system.sops.secrets."freshrss/chn".path;
database = { type = "mysql"; passFile = inputs.config.sops.secrets."freshrss/db".path; }; database = { type = "mysql"; passFile = inputs.config.nixos.system.sops.secrets."freshrss/db".path; };
}; };
sops.secrets = systemd.services.freshrss-config.after = [ "mysql.service" ];
nixos =
{
services = { mariadb.instances.freshrss = {}; nginx.https.${freshrss.hostname}.global.configName = "freshrss"; };
system.sops.secrets =
{ {
"freshrss/chn".owner = inputs.config.users.users.freshrss.name; "freshrss/chn".owner = inputs.config.users.users.freshrss.name;
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; }; "freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
}; };
systemd.services.freshrss-config.after = [ "mysql.service" ];
nixos.services =
{
mariadb = { enable = true; instances.freshrss = {}; };
nginx.https.${freshrss.hostname}.global.configName = "freshrss";
}; };
}; };
} }

View File

@@ -19,9 +19,13 @@ inputs:
{ {
enable = true; enable = true;
lfs.enable = true; lfs.enable = true;
mailerPasswordFile = inputs.config.sops.secrets."gitea/mail".path; mailerPasswordFile = inputs.config.nixos.system.sops.secrets."gitea/mail".path;
database = database =
{ createDatabase = false; type = "postgres"; passwordFile = inputs.config.sops.secrets."gitea/db".path; }; {
createDatabase = false;
type = "postgres";
passwordFile = inputs.config.nixos.system.sops.secrets."gitea/db".path;
};
settings = settings =
{ {
session.COOKIE_SECURE = true; session.COOKIE_SECURE = true;
@@ -48,7 +52,15 @@ inputs:
[ "DEFAULT" "MIGRATE" "MIRROR" "CLONE" "PULL" "GC" ]); [ "DEFAULT" "MIGRATE" "MIRROR" "CLONE" "PULL" "GC" ]);
}; };
}; };
nixos.services = nixos =
{
system.sops.secrets =
{
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
"mail/bot" = {};
};
services =
{ {
nginx.https.${gitea.hostname}.location = nginx.https.${gitea.hostname}.location =
{ {
@@ -63,11 +75,6 @@ inputs:
}; };
postgresql.instances.gitea = {}; postgresql.instances.gitea = {};
}; };
sops.secrets =
{
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
"mail/bot" = {};
}; };
}; };
} }

View File

@@ -24,7 +24,7 @@ inputs:
enabled = true; enabled = true;
host = "mail.chn.moe"; host = "mail.chn.moe";
user = "bot@chn.moe"; user = "bot@chn.moe";
password = "$__file{${inputs.config.sops.secrets."grafana/mail".path}}"; password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/mail".path}}";
from_address = "bot@chn.moe"; from_address = "bot@chn.moe";
ehlo_identity = grafana.hostname; ehlo_identity = grafana.hostname;
startTLS_policy = "MandatoryStartTLS"; startTLS_policy = "MandatoryStartTLS";
@@ -32,9 +32,9 @@ inputs:
server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; }; server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; };
security = security =
{ {
secret_key = "$__file{${inputs.config.sops.secrets."grafana/secret".path}}"; secret_key = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/secret".path}}";
admin_user = "chn"; admin_user = "chn";
admin_password = "$__file{${inputs.config.sops.secrets."grafana/chn".path}}"; admin_password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/chn".path}}";
admin_email = "chn@chn.moe"; admin_email = "chn@chn.moe";
}; };
database = database =
@@ -42,7 +42,7 @@ inputs:
type = "postgres"; type = "postgres";
host = "127.0.0.1:5432"; host = "127.0.0.1:5432";
user = "grafana"; user = "grafana";
password = "$__file{${inputs.config.sops.secrets."grafana/db".path}}"; password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/db".path}}";
}; };
}; };
provision = provision =
@@ -78,12 +78,14 @@ inputs:
extraFlags = [ "--storage.tsdb.max-block-chunk-segment-size=16MB" ]; extraFlags = [ "--storage.tsdb.max-block-chunk-segment-size=16MB" ];
}; };
}; };
nixos.services = nixos =
{
services =
{ {
nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; }; nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; };
postgresql.instances.grafana = {}; postgresql.instances.grafana = {};
}; };
sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in system.sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in
{ {
"grafana/mail" = { owner = owner; key = "mail/bot"; }; "grafana/mail" = { owner = owner; key = "mail/bot"; };
"grafana/secret".owner = owner; "grafana/secret".owner = owner;
@@ -91,6 +93,7 @@ inputs:
"grafana/db" = { owner = owner; key = "postgresql/grafana"; }; "grafana/db" = { owner = owner; key = "postgresql/grafana"; };
"mail/bot" = {}; "mail/bot" = {};
}; };
};
environment.persistence."/nix/nodatacow".directories = environment.persistence."/nix/nodatacow".directories =
[{ directory = "/var/lib/prometheus2"; user = "prometheus"; group = "prometheus"; mode = "0700"; }]; [{ directory = "/var/lib/prometheus2"; user = "prometheus"; group = "prometheus"; mode = "0700"; }];
}; };

View File

@@ -15,13 +15,13 @@ inputs:
grep = "${inputs.pkgs.gnugrep}/bin/grep"; grep = "${inputs.pkgs.gnugrep}/bin/grep";
curl = "${inputs.pkgs.curl}/bin/curl"; curl = "${inputs.pkgs.curl}/bin/curl";
cat = "${inputs.pkgs.coreutils}/bin/cat"; cat = "${inputs.pkgs.coreutils}/bin/cat";
token = inputs.config.sops.secrets."telegram/token".path; token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
chat = inputs.config.sops.secrets."telegram/user/chn".path; chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
date = "${inputs.pkgs.coreutils}/bin/date"; date = "${inputs.pkgs.coreutils}/bin/date";
hpcstat = "${inputs.pkgs.localPackages.hpcstat}/bin/hpcstat"; hpcstat = "${inputs.pkgs.localPackages.hpcstat}/bin/hpcstat";
ssh = "${inputs.pkgs.openssh}/bin/ssh -i ${key} -o StrictHostKeyChecking=no" ssh = "${inputs.pkgs.openssh}/bin/ssh -i ${key} -o StrictHostKeyChecking=no"
+ " -o ForwardAgent=yes -o AddKeysToAgent=yes"; + " -o ForwardAgent=yes -o AddKeysToAgent=yes";
key = inputs.config.sops.secrets."hpcstat/key".path; key = inputs.config.nixos.system.sops.secrets."hpcstat/key".path;
jykang = "${inputs.topInputs.self}/devices/jykang.xmuhpc/files"; jykang = "${inputs.topInputs.self}/devices/jykang.xmuhpc/files";
ssh-agent = "${inputs.pkgs.openssh}/bin/ssh-agent"; ssh-agent = "${inputs.pkgs.openssh}/bin/ssh-agent";
in in
@@ -105,10 +105,10 @@ inputs:
(inputs.localLib.attrsToList calenders)); (inputs.localLib.attrsToList calenders));
tmpfiles.rules = [ "d /var/lib/hpcstat 0700 hpcstat hpcstat" ]; tmpfiles.rules = [ "d /var/lib/hpcstat 0700 hpcstat hpcstat" ];
}; };
sops.secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in nixos.system.sops.secrets =
{ {
"telegram/token" = { group = "telegram"; mode = "0440"; inherit sopsFile; }; "telegram/token" = { group = "telegram"; mode = "0440"; };
"telegram/user/chn" = { group = "telegram"; mode = "0440"; inherit sopsFile; }; "telegram/user/chn" = { group = "telegram"; mode = "0440"; };
"hpcstat/key" = { owner = "hpcstat"; group = "hpcstat"; }; "hpcstat/key" = { owner = "hpcstat"; group = "hpcstat"; };
}; };
users = users =

View File

@@ -10,7 +10,9 @@ inputs:
}; };
config = let inherit (inputs.config.nixos.services) httpapi; in inputs.lib.mkIf (httpapi != null) config = let inherit (inputs.config.nixos.services) httpapi; in inputs.lib.mkIf (httpapi != null)
{ {
nixos.services = nixos =
{
services =
{ {
phpfpm.instances.httpapi = {}; phpfpm.instances.httpapi = {};
nginx.https.${httpapi.hostname}.location = nginx.https.${httpapi.hostname}.location =
@@ -19,12 +21,12 @@ inputs:
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; }; "/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
"/notify.php".php = "/notify.php".php =
{ {
root = builtins.dirOf inputs.config.sops.templates."httpapi/notify.php".path; root = builtins.dirOf inputs.config.nixos.system.sops.templates."httpapi/notify.php".path;
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi; fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
}; };
}; };
}; };
sops = system.sops =
{ {
templates."httpapi/notify.php" = templates."httpapi/notify.php" =
{ {
@@ -32,13 +34,13 @@ inputs:
group = inputs.config.users.users.httpapi.group; group = inputs.config.users.users.httpapi.group;
content = content =
let let
placeholder = inputs.config.sops.placeholder; inherit (inputs.config.sops) placeholder;
request = "https://api.telegram.org/bot${placeholder."telegram/token"}" request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text="; + "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>''; in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
}; };
secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in secrets = { "telegram/token" = {}; "telegram/user/chn" = {}; };
{ "telegram/token" = { inherit sopsFile; }; "telegram/user/chn" = { inherit sopsFile; }; }; };
}; };
systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ]; systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ];
}; };

View File

@@ -15,11 +15,19 @@ inputs:
image = "ghcr.io/huginn/huginn:latest"; image = "ghcr.io/huginn/huginn:latest";
imageFile = inputs.topInputs.self.src.huginn; imageFile = inputs.topInputs.self.src.huginn;
ports = [ "127.0.0.1:3000:3000/tcp" ]; ports = [ "127.0.0.1:3000:3000/tcp" ];
environmentFiles = [ inputs.config.sops.templates."huginn/env".path ]; environmentFiles = [ inputs.config.nixos.system.sops.templates."huginn/env".path ];
}; };
sops = nixos =
{ {
templates."huginn/env".content = let placeholder = inputs.config.sops.placeholder; in services =
{
nginx.https.${huginn.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3000"; websocket = true; };
mariadb.instances.huginn = {};
podman = {};
};
system.sops =
{
templates."huginn/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
'' ''
MYSQL_PORT_3306_TCP_ADDR=host.containers.internal MYSQL_PORT_3306_TCP_ADDR=host.containers.internal
HUGINN_DATABASE_NAME=huginn HUGINN_DATABASE_NAME=huginn
@@ -40,14 +48,6 @@ inputs:
''; '';
secrets = { "huginn/invitationCode" = {}; "mail/bot" = {}; }; secrets = { "huginn/invitationCode" = {}; "mail/bot" = {}; };
}; };
nixos =
{
services =
{
nginx.https.${huginn.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3000"; websocket = true; };
mariadb.instances.huginn = {};
podman = {};
};
}; };
}; };
} }

View File

@@ -40,13 +40,13 @@ inputs:
let let
passwordFile = passwordFile =
if db.value.passwordFile or null != null then db.value.passwordFile if db.value.passwordFile or null != null then db.value.passwordFile
else inputs.config.sops.secrets."mariadb/${db.value.user}".path; else inputs.config.nixos.system.sops.secrets."mariadb/${db.value.user}".path;
mysql = "${inputs.config.services.mysql.package}/bin/mysql"; mysql = "${inputs.config.services.mysql.package}/bin/mysql";
in in
# force user use password auth # force user use password auth
''echo "ALTER USER '${db.value.user}' IDENTIFIED BY '$(cat ${passwordFile})';" | ${mysql} -N'') ''echo "ALTER USER '${db.value.user}' IDENTIFIED BY '$(cat ${passwordFile})';" | ${mysql} -N'')
(inputs.localLib.attrsToList mariadb.instances))); (inputs.localLib.attrsToList mariadb.instances)));
sops.secrets = builtins.listToAttrs (builtins.map nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; }) (db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; })
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList mariadb.instances))); (builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList mariadb.instances)));
environment.persistence."/nix/nodatacow".directories = environment.persistence."/nix/nodatacow".directories =

View File

@@ -22,7 +22,8 @@ inputs:
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ]; after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ];
requires = after; requires = after;
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/${instance.name}.yml".path; environment.MISSKEY_CONFIG_YML =
inputs.config.nixos.system.sops.templates."misskey/${instance.name}.yml".path;
serviceConfig = rec serviceConfig = rec
{ {
User = "misskey-${instance.name}"; User = "misskey-${instance.name}";
@@ -53,7 +54,39 @@ inputs:
}; };
}) })
(inputs.localLib.attrsToList misskey.instances)); (inputs.localLib.attrsToList misskey.instances));
sops.templates = builtins.listToAttrs (builtins.map users = inputs.lib.mkMerge (builtins.map
(instance:
{
users."misskey-${instance.name}" =
{
uid = inputs.config.nixos.user.uid."misskey-${instance.name}";
group = "misskey-${instance.name}";
home = "/var/lib/misskey/${instance.name}";
createHome = true;
isSystemUser = true;
};
groups."misskey-${instance.name}".gid = inputs.config.nixos.user.gid."misskey-${instance.name}";
})
(inputs.localLib.attrsToList misskey.instances));
nixos =
{
services =
{
redis.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
(inputs.localLib.attrsToList misskey.instances));
postgresql.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
(inputs.localLib.attrsToList misskey.instances));
nginx.https = builtins.listToAttrs (builtins.map
(instance: with instance.value;
{
name = hostname;
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
})
(inputs.localLib.attrsToList misskey.instances));
};
system.sops.templates = builtins.listToAttrs (builtins.map
(instance: (instance:
{ {
name = "misskey/${instance.name}.yml"; name = "misskey/${instance.name}.yml";
@@ -61,7 +94,7 @@ inputs:
{ {
content = content =
let let
placeholder = inputs.config.sops.placeholder; placeholder = inputs.config.nixos.system.sops.placeholder;
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}"; redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
in in
'' ''
@@ -97,35 +130,6 @@ inputs:
}; };
}) })
(inputs.localLib.attrsToList misskey.instances)); (inputs.localLib.attrsToList misskey.instances));
users = inputs.lib.mkMerge (builtins.map
(instance:
{
users."misskey-${instance.name}" =
{
uid = inputs.config.nixos.user.uid."misskey-${instance.name}";
group = "misskey-${instance.name}";
home = "/var/lib/misskey/${instance.name}";
createHome = true;
isSystemUser = true;
};
groups."misskey-${instance.name}".gid = inputs.config.nixos.user.gid."misskey-${instance.name}";
})
(inputs.localLib.attrsToList misskey.instances));
nixos.services =
{
redis.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
(inputs.localLib.attrsToList misskey.instances));
postgresql.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
(inputs.localLib.attrsToList misskey.instances));
nginx.https = builtins.listToAttrs (builtins.map
(instance: with instance.value;
{
name = hostname;
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
})
(inputs.localLib.attrsToList misskey.instances));
}; };
}; };
} }

View File

@@ -21,9 +21,9 @@ inputs:
config = config =
{ {
dbtype = "pgsql"; dbtype = "pgsql";
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path; dbpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/postgresql".path;
adminuser = "admin"; adminuser = "admin";
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path; adminpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/admin".path;
}; };
configureRedis = true; configureRedis = true;
settings = settings =
@@ -39,7 +39,7 @@ inputs:
overwriteprotocol = "https"; overwriteprotocol = "https";
default_phone_region = "CN"; default_phone_region = "CN";
}; };
secretFile = inputs.config.sops.templates."nextcloud/secret".path; secretFile = inputs.config.nixos.system.sops.templates."nextcloud/secret".path;
extraApps = extraApps =
let let
version = inputs.lib.versions.major inputs.config.services.nextcloud.package.version; version = inputs.lib.versions.major inputs.config.services.nextcloud.package.version;
@@ -59,20 +59,16 @@ inputs:
(package: { name = package; value = inputs.pkgs.fetchNextcloudApp (getInfo package); }) (package: { name = package; value = inputs.pkgs.fetchNextcloudApp (getInfo package); })
[ "phonetrack" "twofactor_webauthn" "calendar" ]); [ "phonetrack" "twofactor_webauthn" "calendar" ]);
}; };
nixos.services = nixos =
{ {
postgresql.instances.nextcloud = {}; system.sops =
redis.instances.nextcloud.port = 3499;
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
};
sops =
{ {
templates."nextcloud/secret" = templates."nextcloud/secret" =
{ {
content = builtins.toJSON content = builtins.toJSON
{ {
redis.password = inputs.config.sops.placeholder."redis/nextcloud"; redis.password = inputs.config.nixos.system.sops.placeholder."redis/nextcloud";
mail_smtppassword = inputs.config.sops.placeholder."mail/bot"; mail_smtppassword = inputs.config.nixos.system.sops.placeholder."mail/bot";
}; };
owner = inputs.config.users.users.nextcloud.name; owner = inputs.config.users.users.nextcloud.name;
}; };
@@ -82,6 +78,13 @@ inputs:
"nextcloud/admin".owner = inputs.config.users.users.nextcloud.name; "nextcloud/admin".owner = inputs.config.users.users.nextcloud.name;
}; };
}; };
services =
{
postgresql.instances.nextcloud = {};
redis.instances.nextcloud.port = 3499;
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
};
};
systemd.services.nextcloud-setup = rec { requires = [ "postgresql.service" ]; after = requires; }; systemd.services.nextcloud-setup = rec { requires = [ "postgresql.service" ]; after = requires; };
}; };
} }

View File

@@ -95,17 +95,13 @@ inputs:
settings = settings =
{ {
AccountID = 901296; AccountID = 901296;
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path; LicenseKey = inputs.config.nixos.system.sops.secrets."nginx/maxmind-license".path;
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ]; EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
}; };
}; };
}; };
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets."nginx/maxmind-license" = nixos.system.sops.secrets."nginx/maxmind-license".owner = inputs.config.users.users.nginx.name;
{
owner = inputs.config.users.users.nginx.name;
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
};
systemd.services.nginx.serviceConfig = systemd.services.nginx.serviceConfig =
{ {
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];

View File

@@ -177,7 +177,7 @@ inputs:
basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null) basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null)
( (
let secret = "nginx/templates/detectAuth/${inputs.lib.strings.escapeURL site.name}-global"; let secret = "nginx/templates/detectAuth/${inputs.lib.strings.escapeURL site.name}-global";
in inputs.config.sops.templates.${secret}.path in inputs.config.nixos.system.sops.templates.${secret}.path
); );
extraConfig = builtins.concatStringsSep "\n" extraConfig = builtins.concatStringsSep "\n"
( (
@@ -227,7 +227,7 @@ inputs:
let let
inherit (inputs.lib.strings) escapeURL; inherit (inputs.lib.strings) escapeURL;
secret = "nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}"; secret = "nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}";
in inputs.config.sops.templates.${secret}.path in inputs.config.nixos.system.sops.templates.${secret}.path
); );
root = inputs.lib.mkIf (location.value.root or null != null) location.value.root; root = inputs.lib.mkIf (location.value.root or null != null) location.value.root;
} }
@@ -247,7 +247,7 @@ inputs:
++ (inputs.lib.optionals (location.value.addAuth != null) ++ (inputs.lib.optionals (location.value.addAuth != null)
( (
let authFile = "nginx/templates/addAuth/${location.value.addAuth}"; let authFile = "nginx/templates/addAuth/${location.value.addAuth}";
in [ "include ${inputs.config.sops.templates.${authFile}.path};" ] in [ "include ${inputs.config.nixos.system.sops.templates.${authFile}.path};" ]
)) ))
); );
}; };
@@ -285,7 +285,9 @@ inputs:
}; };
}) })
sites); sites);
nixos.services = nixos =
{
services =
{ {
nginx = nginx =
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; } # { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
@@ -324,7 +326,7 @@ inputs:
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; }) (site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
sites); sites);
}; };
sops = system.sops =
let let
inherit (inputs.lib.strings) escapeURL; inherit (inputs.lib.strings) escapeURL;
detectAuthUsers = builtins.concatLists (builtins.map detectAuthUsers = builtins.concatLists (builtins.map
@@ -353,32 +355,23 @@ inputs:
sites); sites);
in in
{ {
templates = builtins.listToAttrs templates = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.listToAttrs
( (
(builtins.map (builtins.map
(detectAuth: (detectAuth: inputs.lib.nameValuePair "nginx/templates/detectAuth/${detectAuth.name}"
{
name = "nginx/templates/detectAuth/${detectAuth.name}";
value =
{ {
owner = inputs.config.users.users.nginx.name; owner = inputs.config.users.users.nginx.name;
content = builtins.concatStringsSep "\n" (builtins.map content = builtins.concatStringsSep "\n" (builtins.map
(user: "${user}:{PLAIN}${inputs.config.sops.placeholder."nginx/detectAuth/${user}"}") (user: "${user}:{PLAIN}${placeholder."nginx/detectAuth/${user}"}")
detectAuth.value); detectAuth.value);
};
}) })
detectAuthUsers) detectAuthUsers)
++ (builtins.map ++ (builtins.map
(addAuth: (addAuth: inputs.lib.nameValuePair "nginx/templates/addAuth/${addAuth.name}"
{
name = "nginx/templates/addAuth/${addAuth.name}";
value =
{ {
owner = inputs.config.users.users.nginx.name; owner = inputs.config.users.users.nginx.name;
content = content =
let placeholder = inputs.config.sops.placeholder."nginx/addAuth/${addAuth.value}"; ''proxy_set_header Authorization "Basic ${placeholder."nginx/addAuth/${addAuth.value}"}";'';
in ''proxy_set_header Authorization "Basic ${placeholder}";'';
};
}) })
addAuth) addAuth)
); );
@@ -393,6 +386,7 @@ inputs:
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth))) (inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
); );
}; };
};
} }
) )
]); ]);

View File

@@ -15,12 +15,15 @@ inputs:
enable = true; enable = true;
package = inputs.pkgs.nix-serve-ng; package = inputs.pkgs.nix-serve-ng;
openFirewall = true; openFirewall = true;
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path; secretKeyFile = inputs.config.nixos.system.sops.secrets."store/signingKey".path;
# curl -L cache.nixos.org/nix-cache-info # curl -L cache.nixos.org/nix-cache-info
# use this cache after official one # use this cache after official one
extraParams = "--priority 50"; extraParams = "--priority 50";
}; };
sops.secrets."store/signingKey" = {}; nixos =
nixos.services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000"; {
system.sops.secrets."store/signingKey" = {};
services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
};
}; };
} }

View File

@@ -83,7 +83,7 @@ inputs:
domains = builtins.map domains = builtins.map
(vm: (vm:
{ {
definition = inputs.config.sops.templates."nixvirt/${vm.name}.xml".path; definition = inputs.config.nixos.system.sops.templates."nixvirt/${vm.name}.xml".path;
active = true; active = true;
restart = false; restart = false;
}) })
@@ -122,52 +122,30 @@ inputs:
vnc_listen = "0.0.0.0" vnc_listen = "0.0.0.0"
''; '';
}; };
nixos.services = nixos =
{ {
nginx = system.sops =
let hosts = builtins.concatLists (builtins.map
(vm: builtins.map
(domain:
{ {
inherit domain; templates = inputs.lib.mapAttrs'
ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}"; (n: v: inputs.lib.nameValuePair "nixvirt/${n}.xml"
})
vm.network.portForward.web)
(builtins.attrValues nixvirt.instance));
in
{ {
transparentProxy.map = builtins.listToAttrs (builtins.map content = inputs.topInputs.nixvirt.lib.domain.getXML
(host: { name = host.domain; value = "${host.ip}" + ":443"; }) hosts);
http = builtins.listToAttrs (builtins.map
(host: { name = host.domain; value.proxy.upstream = "http://${host.ip}" + ":80"; }) hosts);
};
kvm = {};
};
sops =
{
templates = builtins.listToAttrs (builtins.map
(vm:
{
name = "nixvirt/${vm.name}.xml";
value.content = inputs.topInputs.nixvirt.lib.domain.getXML
# port from 8bcc23e27a62297254d0e9c87281e650ff777132 # port from 8bcc23e27a62297254d0e9c87281e650ff777132
{ {
inherit (vm) name; name = n;
inherit (vm.value) uuid; inherit (v) uuid;
type = "kvm"; type = "kvm";
vcpu = { placement = "static"; count = vm.value.cpu.count; }; vcpu = { placement = "static"; count = v.cpu.count; };
cputune = inputs.lib.optionalAttrs (vm.value.cpu.set != null) cputune = inputs.lib.optionalAttrs (v.cpu.set != null)
{ {
vcpupin = builtins.genList vcpupin = builtins.genList (cpu: { vcpu = cpu; cpuset = builtins.elemAt v.cpu.set cpu; }) v.cpu.count;
(cpu: { vcpu = cpu; cpuset = builtins.elemAt vm.value.cpu.set cpu; })
vm.value.cpu.count;
}; };
memory = memory =
{ {
count = vm.value.memory.sizeMB; count = v.memory.sizeMB;
unit = "MiB"; unit = "MiB";
nosharepages = vm.value.memory.dedicated; nosharepages = v.memory.dedicated;
locked = vm.value.memory.dedicated; locked = v.memory.dedicated;
}; };
os = os =
{ {
@@ -179,7 +157,7 @@ inputs:
nvram = nvram =
{ {
template = "/run/libvirt/nix-ovmf/OVMF_VARS.fd"; template = "/run/libvirt/nix-ovmf/OVMF_VARS.fd";
path = "/var/lib/libvirt/qemu/nvram/${vm.name}_VARS.fd"; path = "/var/lib/libvirt/qemu/nvram/${n}_VARS.fd";
templateFormat = "raw"; templateFormat = "raw";
format = "raw"; format = "raw";
}; };
@@ -192,8 +170,8 @@ inputs:
{ {
sockets = 1; sockets = 1;
dies = 1; dies = 1;
cores = if vm.value.cpu.hyprthread then vm.value.cpu.count / 2 else vm.value.cpu.count; cores = if v.cpu.hyprthread then v.cpu.count / 2 else v.cpu.count;
threads = if vm.value.cpu.hyprthread then 2 else 1; threads = if v.cpu.hyprthread then 2 else 1;
}; };
}; };
clock = clock =
@@ -215,8 +193,8 @@ inputs:
type = "file"; type = "file";
device = "disk"; device = "disk";
driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; }; driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; };
source.file = "${if vm.value.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/" source.file = "${if v.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
+ "${vm.value.storage.name}.img"; + "${v.storage.name}.img";
target = { dev = "vda"; bus = "virtio"; }; target = { dev = "vda"; bus = "virtio"; };
boot.order = 1; boot.order = 1;
} }
@@ -234,8 +212,8 @@ inputs:
{ {
type = "bridge"; type = "bridge";
model.type = "virtio"; model.type = "virtio";
mac.address = vm.value.network.mac; mac.address = v.network.mac;
source.bridge = if vm.value.network.bridge then "nixvirt" else "virbr0"; source.bridge = if v.network.bridge then "nixvirt" else "virbr0";
}; };
input = input =
[ [
@@ -247,21 +225,39 @@ inputs:
{ {
type = "vnc"; type = "vnc";
autoport = false; autoport = false;
port = vm.value.network.vnc.port; port = v.network.vnc.port;
listen.type = "address"; listen.type = "address";
passwd = inputs.config.sops.placeholder."nixvirt/${vm.name}"; passwd = inputs.config.sops.placeholder."nixvirt/${n}";
}; };
video.model = { type = "qxl"; ram = 65536; vram = 65536; vgamem = 16384; heads = 1; primary = true; }; video.model = { type = "qxl"; ram = 65536; vram = 65536; vgamem = 16384; heads = 1; primary = true; };
rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; }; rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; };
}; };
}; };
}) })
(inputs.localLib.attrsToList nixvirt.instance)); nixvirt.instance;
secrets = builtins.listToAttrs (builtins.map secrets = inputs.lib.mapAttrs' (n: _: inputs.lib.nameValuePair "nixvirt/${n}" {}) nixvirt.instance;
(vm: { name = "nixvirt/${vm}"; value = {}; }) (builtins.attrNames nixvirt.instance)); };
placeholder = builtins.listToAttrs (builtins.map services =
(vm: { name = "nixvirt/${vm}"; value = builtins.hashString "sha256" "nixvirt/${vm}"; }) {
(builtins.attrNames nixvirt.instance)); nginx =
let hosts = builtins.concatLists (builtins.map
(vm: builtins.map
(domain:
{
inherit domain;
ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}";
})
vm.network.portForward.web)
(builtins.attrValues nixvirt.instance));
in
{
transparentProxy.map = builtins.listToAttrs (builtins.map
(host: { name = host.domain; value = "${host.ip}" + ":443"; }) hosts);
http = builtins.listToAttrs (builtins.map
(host: { name = host.domain; value.proxy.upstream = "http://${host.ip}" + ":80"; }) hosts);
};
kvm = {};
};
}; };
security.wrappers.vm = security.wrappers.vm =
{ {

View File

@@ -28,11 +28,13 @@ inputs:
ENABLE_IMAGE_GENERATION = "True"; ENABLE_IMAGE_GENERATION = "True";
IMAGES_OPENAI_API_BASE_URL = "https://oa.api2d.net/v1"; IMAGES_OPENAI_API_BASE_URL = "https://oa.api2d.net/v1";
}; };
environmentFile = inputs.config.sops.templates."open-webui.env".path; environmentFile = inputs.config.nixos.system.sops.templates."open-webui.env".path;
}; };
sops = nixos =
{ {
templates."open-webui.env".content = let inherit (inputs.config.sops) placeholder; in system.sops =
{
templates."open-webui.env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
'' ''
OPENAI_API_KEY=${placeholder."open-webui/openai"} OPENAI_API_KEY=${placeholder."open-webui/openai"}
WEBUI_SECRET_KEY=${placeholder."open-webui/webui"} WEBUI_SECRET_KEY=${placeholder."open-webui/webui"}
@@ -40,7 +42,8 @@ inputs:
''; '';
secrets = { "open-webui/openai" = {}; "open-webui/webui" = {}; }; secrets = { "open-webui/openai" = {}; "open-webui/webui" = {}; };
}; };
nixos.services.nginx.https."${open-webui.hostname}".location."/".proxy = services.nginx.https."${open-webui.hostname}".location."/".proxy =
{ upstream = "http://127.0.0.1:8080"; websocket = true; }; { upstream = "http://127.0.0.1:8080"; websocket = true; };
}; };
};
} }

View File

@@ -17,34 +17,31 @@ inputs:
listenHttp = 5046; listenHttp = 5046;
listenWeb = 443; listenWeb = 443;
enableWebHttps = true; enableWebHttps = true;
serviceEnvironmentFile = inputs.config.sops.templates."peertube/env".path; serviceEnvironmentFile = inputs.config.nixos.system.sops.templates."peertube/env".path;
secrets.secretsFile = inputs.config.sops.secrets."peertube/secrets".path; secrets.secretsFile = inputs.config.nixos.system.sops.secrets."peertube/secrets".path;
configureNginx = true; configureNginx = true;
database = database =
{ {
createLocally = true; createLocally = true;
host = "127.0.0.1"; host = "127.0.0.1";
passwordFile = inputs.config.sops.secrets."peertube/postgresql".path; passwordFile = inputs.config.nixos.system.sops.secrets."peertube/postgresql".path;
}; };
redis = redis =
{ {
host = "127.0.0.1"; host = "127.0.0.1";
port = 7599; port = 7599;
passwordFile = inputs.config.sops.secrets."redis/peertube".path; passwordFile = inputs.config.nixos.system.sops.secrets."redis/peertube".path;
}; };
smtp.passwordFile = inputs.config.sops.secrets."peertube/smtp".path; smtp.passwordFile = inputs.config.nixos.system.sops.secrets."peertube/smtp".path;
settings.smtp = settings.smtp = { host = "mail.chn.moe"; username = "bot@chn.moe"; from_address = "bot@chn.moe"; };
};
nixos =
{ {
host = "mail.chn.moe"; system.sops =
username = "bot@chn.moe";
from_address = "bot@chn.moe";
};
};
sops =
{ {
templates."peertube/env".content = templates."peertube/env".content =
'' ''
PT_INITIAL_ROOT_PASSWORD=${inputs.config.sops.placeholder."peertube/password"} PT_INITIAL_ROOT_PASSWORD=${inputs.config.nixos.system.sops.placeholder."peertube/password"}
''; '';
secrets = secrets =
{ {
@@ -54,12 +51,13 @@ inputs:
"peertube/smtp" = { owner = inputs.config.services.peertube.user; key = "mail/bot"; }; "peertube/smtp" = { owner = inputs.config.services.peertube.user; key = "mail/bot"; };
}; };
}; };
nixos.services = services =
{ {
nginx.https.${peertube.hostname}.global.configName = peertube.hostname; nginx.https.${peertube.hostname}.global.configName = peertube.hostname;
postgresql.instances.peertube = {}; postgresql.instances.peertube = {};
redis.instances.peertube.port = 7599; redis.instances.peertube.port = 7599;
}; };
};
systemd.services.peertube.after = [ "redis-peertube.service" ]; systemd.services.peertube.after = [ "redis-peertube.service" ];
}; };
} }

View File

@@ -23,21 +23,24 @@ inputs:
{ {
after = [ "mariadb.service" ]; after = [ "mariadb.service" ];
requires = [ "mariadb.service" ]; requires = [ "mariadb.service" ];
serviceConfig.EnvironmentFile = inputs.config.sops.templates."photoprism/env".path; serviceConfig.EnvironmentFile = inputs.config.nixos.system.sops.templates."photoprism/env".path;
}; };
sops = nixos =
{ {
templates."photoprism/env".content = let placeholder = inputs.config.sops.placeholder; in system.sops =
{
templates."photoprism/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
'' ''
PHOTOPRISM_ADMIN_PASSWORD=${placeholder."photoprism/adminPassword"} PHOTOPRISM_ADMIN_PASSWORD=${placeholder."photoprism/adminPassword"}
PHOTOPRISM_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"} PHOTOPRISM_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"}
''; '';
secrets."photoprism/adminPassword" = {}; secrets."photoprism/adminPassword" = {};
}; };
nixos.services = services =
{ {
mariadb.instances.photoprism = {}; mariadb.instances.photoprism = {};
nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; }; nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; };
}; };
}; };
};
} }

View File

@@ -63,7 +63,7 @@ inputs:
let let
passwordFile = passwordFile =
if db.value.passwordFile or null != null then db.value.passwordFile if db.value.passwordFile or null != null then db.value.passwordFile
else inputs.config.sops.secrets."postgresql/${db.value.user}".path; else inputs.config.nixos.system.sops.secrets."postgresql/${db.value.user}".path;
initializeFlag = initializeFlag =
if db.value.initializeFlags != {} then if db.value.initializeFlags != {} then
" WITH " " WITH "
@@ -85,7 +85,7 @@ inputs:
+ " | grep -E '^${db.value.user}$' -q" + " | grep -E '^${db.value.user}$' -q"
+ " || $PSQL -tAc \"ALTER DATABASE ${db.value.database} OWNER TO ${db.value.user}\"") + " || $PSQL -tAc \"ALTER DATABASE ${db.value.database} OWNER TO ${db.value.user}\"")
(inputs.localLib.attrsToList postgresql.instances))); (inputs.localLib.attrsToList postgresql.instances)));
sops.secrets = builtins.listToAttrs (builtins.map nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(db: { name = "postgresql/${db.value.user}"; value.owner = inputs.config.users.users.postgres.name; }) (db: { name = "postgresql/${db.value.user}"; value.owner = inputs.config.users.users.postgres.name; })
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList postgresql.instances))); (builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList postgresql.instances)));
environment.persistence."/nix/nodatacow".directories = inputs.lib.mkIf postgresql.nodatacow environment.persistence."/nix/nodatacow".directories = inputs.lib.mkIf postgresql.nodatacow

View File

@@ -28,12 +28,13 @@ inputs:
# unixSocket = null; # bug # unixSocket = null; # bug
unixSocketPerm = 600; unixSocketPerm = 600;
requirePassFile = requirePassFile =
if server.value.passwordFile == null then inputs.config.sops.secrets."redis/${server.name}".path if server.value.passwordFile == null
then inputs.config.nixos.system.sops.secrets."redis/${server.name}".path
else server.value.passwordFile; else server.value.passwordFile;
}; };
}) })
(inputs.localLib.attrsToList redis.instances)); (inputs.localLib.attrsToList redis.instances));
sops.secrets = builtins.listToAttrs (builtins.map nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.value.user}.name; }) (server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.value.user}.name; })
(builtins.filter (server: server.value.passwordFile == null) (inputs.localLib.attrsToList redis.instances))); (builtins.filter (server: server.value.passwordFile == null) (inputs.localLib.attrsToList redis.instances)));
systemd.services = builtins.listToAttrs (builtins.map systemd.services = builtins.listToAttrs (builtins.map

View File

@@ -15,11 +15,13 @@ inputs:
image = "rsshub:latest"; image = "rsshub:latest";
imageFile = inputs.topInputs.self.src.rsshub; imageFile = inputs.topInputs.self.src.rsshub;
ports = [ "127.0.0.1:5221:5221/tcp" ]; ports = [ "127.0.0.1:5221:5221/tcp" ];
environmentFiles = [ inputs.config.sops.templates."rsshub/env".path ]; environmentFiles = [ inputs.config.nixos.system.sops.templates."rsshub/env".path ];
}; };
sops = nixos =
{ {
templates."rsshub/env".content = let placeholder = inputs.config.sops.placeholder; in system.sops =
{
templates."rsshub/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
'' ''
PORT=5221 PORT=5221
CACHE_TYPE=memory CACHE_TYPE=memory
@@ -34,7 +36,7 @@ inputs:
XDG_CACHE_HOME='/var/cache/rsshub/chromium' XDG_CACHE_HOME='/var/cache/rsshub/chromium'
BILIBILI_COOKIE_data0='${placeholder."rsshub/bilibili-cookie"}' BILIBILI_COOKIE_data0='${placeholder."rsshub/bilibili-cookie"}'
''; '';
secrets = (builtins.listToAttrs (builtins.map (secret: { name = "rsshub/${secret}"; value = {}; }) secrets = (builtins.listToAttrs (builtins.map (secret: inputs.lib.nameValuePair "rsshub/${secret}" {})
[ [
"pixiv-refreshtoken" "pixiv-refreshtoken"
"youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token" "youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token"
@@ -43,6 +45,7 @@ inputs:
"zhihu-cookies" "zhihu-cookies"
])); ]));
}; };
nixos.services.nginx.https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5221"; services.nginx.https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5221";
};
}; };
} }

View File

@@ -14,16 +14,19 @@ inputs:
{ {
enable = true; enable = true;
settings.server = { port = 8081; bind_address = "127.0.0.1"; secret_key = "@SEARX_SECRET_KEY@"; }; settings.server = { port = 8081; bind_address = "127.0.0.1"; secret_key = "@SEARX_SECRET_KEY@"; };
environmentFile = inputs.config.sops.templates."searx.env".path; environmentFile = inputs.config.nixos.system.sops.templates."searx.env".path;
}; };
sops = nixos =
{ {
templates."searx.env".content = let inherit (inputs.config.sops) placeholder; in system.sops =
{
templates."searx.env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
'' ''
SEARX_SECRET_KEY=${placeholder."searx/secret-key"} SEARX_SECRET_KEY=${placeholder."searx/secret-key"}
''; '';
secrets."searx/secret-key" = {}; secrets."searx/secret-key" = {};
}; };
nixos.services.nginx.https.${searx.hostname}.location."/".proxy.upstream = "http://127.0.0.1:8081"; services.nginx.https.${searx.hostname}.location."/".proxy.upstream = "http://127.0.0.1:8081";
};
}; };
} }

View File

@@ -20,7 +20,7 @@ inputs:
createLocally = false; createLocally = false;
host = "127.0.0.1"; host = "127.0.0.1";
port = 9184; port = 9184;
passwordFile = inputs.config.sops.secrets."redis/send".path; passwordFile = inputs.config.nixos.system.sops.secrets."redis/send".path;
}; };
}; };
systemd.services.send.after = [ "redis-send.service" ]; systemd.services.send.after = [ "redis-send.service" ];

View File

@@ -177,7 +177,7 @@ inputs:
# ConstrainDevices=yes # ConstrainDevices=yes
''; '';
}; };
munge = { enable = true; password = inputs.config.sops.secrets."munge.key".path; }; munge = { enable = true; password = inputs.config.nixos.system.sops.secrets."munge.key".path; };
}; };
systemd.services.slurmd.environment = systemd.services.slurmd.environment =
let gpus = slurm.node.${inputs.config.nixos.model.hostname}.gpus or null; let gpus = slurm.node.${inputs.config.nixos.model.hostname}.gpus or null;
@@ -186,12 +186,16 @@ inputs:
CUDA_PATH = "${inputs.pkgs.cudatoolkit}"; CUDA_PATH = "${inputs.pkgs.cudatoolkit}";
LD_LIBRARY_PATH = "${inputs.config.hardware.nvidia.package}/lib"; LD_LIBRARY_PATH = "${inputs.config.hardware.nvidia.package}/lib";
}; };
sops.secrets."munge.key" = nixos.system.sops.secrets."munge.key" =
{ {
format = "binary"; format = "binary";
sopsFile = inputs.localLib.mkConditional (inputs.config.nixos.model.cluster == null) sopsFile =
"${builtins.dirOf inputs.config.sops.defaultSopsFile}/munge.key" let
"${inputs.config.nixos.system.sops.clusterSopsDir}/munge.key"; devicePath = "${inputs.topInputs.self}/devices";
inherit (inputs.config.nixos) model;
in inputs.localLib.mkConditional (model.cluster == null)
"${devicePath}/${model.hostname}/secrets/munge.key"
"${devicePath}/${model.cluster.clusterName}/secrets/munge.key";
owner = inputs.config.systemd.services.munged.serviceConfig.User; owner = inputs.config.systemd.services.munged.serviceConfig.User;
}; };
environment.sessionVariables = { SLURM_UNBUFFEREDIO = "1"; SLURM_CPU_BIND = "v"; }; environment.sessionVariables = { SLURM_UNBUFFEREDIO = "1"; SLURM_CPU_BIND = "v"; };
@@ -206,7 +210,7 @@ inputs:
{ {
enable = true; enable = true;
dbdHost = "localhost"; dbdHost = "localhost";
storagePassFile = inputs.config.sops.secrets."slurm/db".path; storagePassFile = inputs.config.nixos.system.sops.secrets."slurm/db".path;
extraConfig = extraConfig =
'' ''
StorageHost=* StorageHost=*
@@ -224,24 +228,20 @@ inputs:
services.slurmctld = { after = [ "suid-sgid-wrappers.service" ]; serviceConfig.MemorySwapMax = "0"; }; services.slurmctld = { after = [ "suid-sgid-wrappers.service" ]; serviceConfig.MemorySwapMax = "0"; };
tmpfiles.rules = [ "d /var/log/slurmctld 700 slurm slurm" ]; tmpfiles.rules = [ "d /var/log/slurmctld 700 slurm slurm" ];
}; };
sops = nixos.system.sops =
{ {
secrets = { "slurm/db" = { owner = "slurm"; key = "mariadb/slurm"; }; } secrets = { "slurm/db" = { owner = "slurm"; key = "mariadb/slurm"; }; }
// builtins.listToAttrs (builtins.map // builtins.listToAttrs (builtins.map
(n: (n: inputs.lib.nameValuePair "telegram/${n}" {})
{
name = "telegram/${n}";
value.sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
})
[ "token" "user/chn" "user/hjp" ]); [ "token" "user/chn" "user/hjp" ]);
templates."info.yaml" = templates."info.yaml" =
{ {
owner = "slurm"; owner = "slurm";
content = let inherit (inputs.config.sops) placeholder; in builtins.toJSON content = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.toJSON
{ {
token = placeholder."telegram/token"; token = placeholder."telegram/token";
user = builtins.listToAttrs (builtins.map (n: { name = n; value = placeholder."telegram/user/${n}"; }) user = builtins.listToAttrs (builtins.map
[ "chn" "hjp" ]); (n: inputs.lib.nameValuePair n placeholder."telegram/user/${n}") [ "chn" "hjp" ]);
slurmConf = "${inputs.config.services.slurm.etcSlurm}/slurm.conf"; slurmConf = "${inputs.config.services.slurm.etcSlurm}/slurm.conf";
}; };
}; };
@@ -252,7 +252,7 @@ inputs:
let info = inputs.pkgs.localPackages.info.override let info = inputs.pkgs.localPackages.info.override
{ {
slurm = inputs.config.services.slurm.package; slurm = inputs.config.services.slurm.package;
configFile = inputs.config.sops.templates."info.yaml".path; configFile = inputs.config.nixos.system.sops.templates."info.yaml".path;
}; };
in "${info}/bin/info"; in "${info}/bin/info";
program = "slurm-info"; program = "slurm-info";

View File

@@ -43,7 +43,7 @@ inputs:
let let
package = inputs.pkgs.matrix-synapse.override package = inputs.pkgs.matrix-synapse.override
{ extras = [ "url-preview" "postgres" "redis" ]; plugins = []; }; { extras = [ "url-preview" "postgres" "redis" ]; plugins = []; };
config = inputs.config.sops.templates."synapse/${instance.name}/config.yaml".path; config = inputs.config.nixos.system.sops.templates."synapse/${instance.name}/config.yaml".path;
homeserver = "${package}/bin/synapse_homeserver"; homeserver = "${package}/bin/synapse_homeserver";
in in
{ {
@@ -100,16 +100,17 @@ inputs:
]; ];
}) })
(inputs.localLib.attrsToList synapse.instances)); (inputs.localLib.attrsToList synapse.instances));
sops = inputs.lib.mkMerge (builtins.map nixos =
{
system.sops = inputs.lib.mkMerge (builtins.map
(instance: (instance:
{ {
templates."synapse/${instance.name}/config.yaml" = templates."synapse/${instance.name}/config.yaml" =
{ {
owner = "synapse-${instance.name}"; owner = "synapse-${instance.name}";
group = "synapse-${instance.name}";
content = content =
let let
inherit (inputs.config.sops) placeholder; inherit (inputs.config.nixos.system.sops) placeholder;
in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml" in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml"
{ {
server_name = instance.value.matrixHostname; server_name = instance.value.matrixHostname;
@@ -146,7 +147,7 @@ inputs:
registration_shared_secret = placeholder."synapse/${instance.name}/registration"; registration_shared_secret = placeholder."synapse/${instance.name}/registration";
macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon"; macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon";
form_secret = placeholder."synapse/${instance.name}/form"; form_secret = placeholder."synapse/${instance.name}/form";
signing_key_path = inputs.config.sops.secrets."synapse/${instance.name}/signing-key".path; signing_key_path = inputs.config.nixos.system.sops.secrets."synapse/${instance.name}/signing-key".path;
email = email =
{ {
smtp_host = "mail.chn.moe"; smtp_host = "mail.chn.moe";
@@ -203,7 +204,7 @@ inputs:
// { "mail/bot" = {}; }; // { "mail/bot" = {}; };
}) })
(inputs.localLib.attrsToList synapse.instances)); (inputs.localLib.attrsToList synapse.instances));
nixos.services = services =
{ {
postgresql.instances = builtins.listToAttrs (builtins.map postgresql.instances = builtins.listToAttrs (builtins.map
(instance: (instance:
@@ -239,4 +240,5 @@ inputs:
(inputs.localLib.attrsToList synapse.instances)); (inputs.localLib.attrsToList synapse.instances));
}; };
}; };
};
} }

View File

@@ -25,11 +25,13 @@ inputs:
SMTP_SECURITY = "force_tls"; SMTP_SECURITY = "force_tls";
SMTP_USERNAME = "bot@chn.moe"; SMTP_USERNAME = "bot@chn.moe";
}; };
environmentFile = inputs.config.sops.templates."vaultwarden.env".path; environmentFile = inputs.config.nixos.system.sops.templates."vaultwarden.env".path;
}; };
sops = nixos =
{ {
templates."vaultwarden.env" = let placeholder = inputs.config.sops.placeholder; in system.sops =
{
templates."vaultwarden.env" = let inherit (inputs.config.nixos.system.sops) placeholder; in
{ {
owner = "vaultwarden"; owner = "vaultwarden";
group = "vaultwarden"; group = "vaultwarden";
@@ -42,12 +44,13 @@ inputs:
}; };
secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; }; secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; };
}; };
systemd.services.vaultwarden.after = [ "postgresql.service" ]; services =
nixos.services =
{ {
postgresql.instances.vaultwarden = {}; postgresql.instances.vaultwarden = {};
nginx.https.${vaultwarden.hostname}.location."/".proxy = nginx.https.${vaultwarden.hostname}.location."/".proxy =
{ upstream = "http://127.0.0.1:8000"; websocket = true; }; { upstream = "http://127.0.0.1:8000"; websocket = true; };
}; };
}; };
systemd.services.vaultwarden.after = [ "postgresql.service" ];
};
} }

View File

@@ -33,7 +33,7 @@ inputs:
{ {
inherit (wg.value) listenPort; inherit (wg.value) listenPort;
ips = [ "${wg.value.ip}/${builtins.toString wg.value.netmask}" ]; ips = [ "${wg.value.ip}/${builtins.toString wg.value.netmask}" ];
privateKeyFile = inputs.config.sops.secrets.wireguard.path; privateKeyFile = inputs.config.nixos.system.sops.secrets.wireguard.path;
peers = builtins.map peers = builtins.map
(peer: (peer:
{ {
@@ -45,6 +45,6 @@ inputs:
}; };
}) })
(inputs.localLib.attrsToList wireguard)); (inputs.localLib.attrsToList wireguard));
sops.secrets.wireguard = {}; nixos.system.sops.secrets.wireguard = {};
}; };
} }

View File

@@ -43,7 +43,7 @@ inputs:
}; };
resolved.enable = false; resolved.enable = false;
}; };
sops = nixos.system.sops =
{ {
templates."xray-client.json" = templates."xray-client.json" =
{ {
@@ -120,7 +120,7 @@ inputs:
port = 443; port = 443;
users = users =
[{ [{
id = inputs.config.sops.placeholder."xray-client/uuid"; id = inputs.config.nixos.system.sops.placeholder."xray-client/uuid";
encryption = "none"; encryption = "none";
flow = "xtls-rprx-vision-udp443"; flow = "xtls-rprx-vision-udp443";
}]; }];
@@ -179,7 +179,8 @@ inputs:
{ {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = "exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-client.json".path}"; script = let config = inputs.config.nixos.system.sops.templates."xray-client.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig = serviceConfig =
{ {
User = "v2ray"; User = "v2ray";
@@ -191,7 +192,7 @@ inputs:
LimitNOFILE = 524288; LimitNOFILE = 524288;
CPUSchedulingPolicy = "rr"; CPUSchedulingPolicy = "rr";
}; };
restartTriggers = [ inputs.config.sops.templates."xray-client.json".file ]; restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-client.json".file ];
}; };
v2ray-forwarder = v2ray-forwarder =
{ {

View File

@@ -10,11 +10,14 @@ inputs:
}; };
config = let inherit (inputs.config.nixos.services.xray) server; in inputs.lib.mkIf (server != null) config = let inherit (inputs.config.nixos.services.xray) server; in inputs.lib.mkIf (server != null)
( (
let userList = builtins.attrNames let userList = builtins.map (user: builtins.elemAt user 2) (builtins.filter
(inputs.pkgs.localPackages.fromYaml (builtins.readFile inputs.config.sops.defaultSopsFile)).xray-server.clients; (user: builtins.elem user == 3 && inputs.lib.lists.hasPrefix [ "xray-server" "clients" ])
inputs.config.nixos.system.sops.availableKeys);
in in
{ {
sops = nixos =
{
system.sops =
{ {
templates."xray-server.json" = templates."xray-server.json" =
{ {
@@ -38,7 +41,7 @@ inputs:
clients = builtins.map clients = builtins.map
(n: (n:
{ {
id = inputs.config.sops.placeholder."xray-server/clients/${n}"; id = inputs.config.nixos.system.sops.placeholder."xray-server/clients/${n}";
flow = "xtls-rprx-vision"; flow = "xtls-rprx-vision";
email = "${n}@xray.chn.moe"; email = "${n}@xray.chn.moe";
}) })
@@ -54,7 +57,7 @@ inputs:
{ {
dest = "127.0.0.1:${fallbackPort}"; dest = "127.0.0.1:${fallbackPort}";
serverNames = [ server.serverName ]; serverNames = [ server.serverName ];
privateKey = inputs.config.sops.placeholder."xray-server/private-key"; privateKey = inputs.config.nixos.system.sops.placeholder."xray-server/private-key";
minClientVer = "1.8.0"; minClientVer = "1.8.0";
shortIds = [ "" ]; shortIds = [ "" ];
}; };
@@ -126,21 +129,26 @@ inputs:
}; };
}; };
secrets = builtins.listToAttrs secrets = builtins.listToAttrs
(builtins.map (n: { name = "xray-server/clients/${n}"; value = {}; }) userList) (builtins.map (n: inputs.lib.nameValuePair "xray-server/clients/${n}" {}) userList)
// (builtins.listToAttrs (builtins.map // (builtins.listToAttrs (builtins.map
(name: (name: inputs.lib.nameValuePair "telegram/${name}" { group = "telegram"; mode = "0440"; })
{
name = "telegram/${name}";
value =
{
group = "telegram";
mode = "0440";
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
};
})
[ "token" "user/chn" ])) [ "token" "user/chn" ]))
// { "xray-server/private-key" = {}; }; // { "xray-server/private-key" = {}; };
}; };
services =
{
acme.cert.${server.serverName}.group = inputs.config.users.users.nginx.group;
nginx =
{
transparentProxy.map.${server.serverName} = 4726;
https.${server.serverName} =
{
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
location."/".return.return = "400";
};
};
};
};
systemd = systemd =
{ {
services = services =
@@ -149,8 +157,8 @@ inputs:
{ {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = script = let config = inputs.config.nixos.system.sops.templates."xray-server.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-server.json".path}"; "exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig = serviceConfig =
{ {
User = "v2ray"; User = "v2ray";
@@ -160,7 +168,7 @@ inputs:
LimitNPROC = 65536; LimitNPROC = 65536;
LimitNOFILE = 524288; LimitNOFILE = 524288;
}; };
restartTriggers = [ inputs.config.sops.templates."xray-server.json".file ]; restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-server.json".file ];
}; };
xray-stat = xray-stat =
{ {
@@ -172,8 +180,8 @@ inputs:
jq = "${inputs.pkgs.jq}/bin/jq"; jq = "${inputs.pkgs.jq}/bin/jq";
sed = "${inputs.pkgs.gnused}/bin/sed"; sed = "${inputs.pkgs.gnused}/bin/sed";
cat = "${inputs.pkgs.coreutils}/bin/cat"; cat = "${inputs.pkgs.coreutils}/bin/cat";
token = inputs.config.sops.secrets."telegram/token".path; token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
chat = inputs.config.sops.secrets."telegram/user/chn".path; chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
in in
'' ''
message='${inputs.config.nixos.model.hostname} xray:\n' message='${inputs.config.nixos.model.hostname} xray:\n'
@@ -216,19 +224,6 @@ inputs:
telegram.gid = inputs.config.nixos.user.gid.telegram; telegram.gid = inputs.config.nixos.user.gid.telegram;
}; };
}; };
nixos.services =
{
acme.cert.${server.serverName}.group = inputs.config.users.users.nginx.group;
nginx =
{
transparentProxy.map.${server.serverName} = 4726;
https.${server.serverName} =
{
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
location."/".return.return = "400";
};
};
};
} }
); );
} }

View File

@@ -10,7 +10,7 @@ inputs:
}; };
config = let inherit (inputs.config.nixos.services.xray) xmuClient; in inputs.lib.mkIf (xmuClient != null) config = let inherit (inputs.config.nixos.services.xray) xmuClient; in inputs.lib.mkIf (xmuClient != null)
{ {
sops = nixos.system.sops =
{ {
templates."xray-xmu-client.json" = templates."xray-xmu-client.json" =
{ {
@@ -37,7 +37,8 @@ inputs:
[{ [{
address = "webvpn.xmu.edu.cn"; address = "webvpn.xmu.edu.cn";
port = 443; port = 443;
users = [{ id = inputs.config.sops.placeholder."xray-xmu-client/uuid"; encryption = "none"; }]; users =
[{ id = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/uuid"; encryption = "none"; }];
}]; }];
streamSettings = streamSettings =
{ {
@@ -61,8 +62,9 @@ inputs:
in "/https/${prefix}${paddedHex}/xsession"; in "/https/${prefix}${paddedHex}/xsession";
mode = "packet-up"; mode = "packet-up";
security = "tls"; security = "tls";
extra.headers.Cookie = "show_vpn=0; heartbeat=1; show_faq=0; " extra.headers.Cookie =
+ "wengine_vpn_ticketwebvpn_xmu_edu_cn=${inputs.config.sops.placeholder."xray-xmu-client/cookie"}"; let ticket = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/cookie";
in "show_vpn=0; heartbeat=1; show_faq=0; wengine_vpn_ticketwebvpn_xmu_edu_cn=${ticket}";
}; };
tlsSettings.alpn = [ "http/1.1" ]; tlsSettings.alpn = [ "http/1.1" ];
}; };
@@ -77,8 +79,8 @@ inputs:
{ {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-client.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-client.json".path}"; "exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig = serviceConfig =
{ {
User = "v2ray"; User = "v2ray";
@@ -90,7 +92,7 @@ inputs:
LimitNOFILE = 524288; LimitNOFILE = 524288;
CPUSchedulingPolicy = "rr"; CPUSchedulingPolicy = "rr";
}; };
restartTriggers = [ inputs.config.sops.templates."xray-xmu-client.json".file ]; restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-xmu-client.json".file ];
}; };
}; };
users = users =

View File

@@ -10,12 +10,11 @@ inputs:
}; };
config = let inherit (inputs.config.nixos.services.xray) xmuServer; in inputs.lib.mkIf (xmuServer != null) config = let inherit (inputs.config.nixos.services.xray) xmuServer; in inputs.lib.mkIf (xmuServer != null)
{ {
sops = nixos.system.sops =
{ {
templates."xray-xmu-server.json" = templates."xray-xmu-server.json" =
{ {
owner = inputs.config.users.users.v2ray.name; owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = builtins.toJSON content = builtins.toJSON
{ {
log.loglevel = "warning"; log.loglevel = "warning";
@@ -24,7 +23,11 @@ inputs:
port = 4727; port = 4727;
listen = "127.0.0.1"; listen = "127.0.0.1";
protocol = "vless"; protocol = "vless";
settings = { clients = [{ id = inputs.config.sops.placeholder."xray-xmu-server"; }]; decryption = "none"; }; settings =
{
clients = [{ id = inputs.config.nixos.system.sops.placeholder."xray-xmu-server"; }];
decryption = "none";
};
streamSettings = { network = "xhttp"; xhttpSettings = { mode = "stream-one"; path = "/xsession"; }; }; streamSettings = { network = "xhttp"; xhttpSettings = { mode = "stream-one"; path = "/xsession"; }; };
tag = "in"; tag = "in";
}]; }];
@@ -37,8 +40,8 @@ inputs:
{ {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-server.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-server.json".path}"; "exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig = serviceConfig =
{ {
User = "v2ray"; User = "v2ray";
@@ -49,7 +52,7 @@ inputs:
LimitNPROC = 65536; LimitNPROC = 65536;
LimitNOFILE = 524288; LimitNOFILE = 524288;
}; };
restartTriggers = [ inputs.config.sops.templates."xray-xmu-server.json".file ]; restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-xmu-server.json".file ];
}; };
users = users =
{ {

View File

@@ -146,19 +146,19 @@ inputs:
# wpa_passphrase SSID password # wpa_passphrase SSID password
networks = builtins.listToAttrs (builtins.map networks = builtins.listToAttrs (builtins.map
(network: { name = network; value.pskRaw = "ext:${network}"; }) network.wireless); (network: { name = network; value.pskRaw = "ext:${network}"; }) network.wireless);
secretsFile = inputs.config.sops.templates."wireless.env".path; secretsFile = inputs.config.nixos.system.sops.templates."wireless.env".path;
}; };
firewall.trustedInterfaces = network.trust; firewall.trustedInterfaces = network.trust;
}; };
# dnsable dns fallback, use provided dns servers or no dns # dnsable dns fallback, use provided dns servers or no dns
services.resolved.fallbackDns = []; services.resolved.fallbackDns = [];
sops = inputs.lib.mkIf (network.wireless != null) nixos.system.sops = inputs.lib.mkIf (network.wireless != null)
{ {
templates."wireless.env".content = builtins.concatStringsSep "\n" (builtins.map templates."wireless.env".content = builtins.concatStringsSep "\n" (builtins.map
(network: "${network}=${inputs.config.sops.placeholder."wireless/${network}"}") (network: "${network}=${inputs.config.nixos.system.sops.placeholder."wireless/${network}"}")
network.wireless); network.wireless);
secrets = builtins.listToAttrs (builtins.map secrets = builtins.listToAttrs (builtins.map
(network: { name = "wireless/${network}"; value = {}; }) (network: inputs.lib.nameValuePair "wireless/${network}" {})
network.wireless); network.wireless);
}; };
}) })

View File

@@ -105,26 +105,26 @@ inputs:
protocol = "ssh-ng"; protocol = "ssh-ng";
systems = [ "x86_64-linux" ]; systems = [ "x86_64-linux" ];
sshUser = "nix-ssh"; sshUser = "nix-ssh";
sshKey = inputs.config.sops.secrets."nix/remote".path; sshKey = inputs.config.nixos.system.sops.secrets."nix/remote".path;
maxJobs = 1; maxJobs = 1;
mandatoryFeatures = [ "big-parallel" ]; mandatoryFeatures = [ "big-parallel" ];
supportedFeatures = builtins.map (f: "gccarch-${f}") v; supportedFeatures = builtins.map (f: "gccarch-${f}") v;
}) })
nix.remote.master.host; nix.remote.master.host;
}; };
sops.secrets."nix/remote" = {}; nixos.system.sops.secrets."nix/remote" = {};
}) })
(inputs.lib.mkIf nix.githubToken.enable (inputs.lib.mkIf nix.githubToken.enable
{ {
nix.extraOptions = "!include ${inputs.config.sops.templates."nix-github.conf".path}"; nix.extraOptions = "!include ${inputs.config.nixos.system.sops.templates."nix-github.conf".path}";
sops = nixos.system.sops =
{ {
templates."nix-github.conf" = templates."nix-github.conf" =
{ {
content = "access-tokens = github.com=${inputs.config.sops.placeholder."github/token"}"; content = "access-tokens = github.com=${inputs.config.nixos.system.sops.placeholder."github/token"}";
mode = "0444"; mode = "0444";
}; };
secrets."github/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; secrets."github/token" = {};
}; };
}) })
# c++ include path # c++ include path

View File

@@ -2,38 +2,113 @@ inputs:
{ {
options.nixos.system.sops = let inherit (inputs.lib) mkOption types; in options.nixos.system.sops = let inherit (inputs.lib) mkOption types; in
{ {
crossSopsDir = mkOption secrets = mkOption
{ {
type = types.nonEmptyStr; type = types.attrsOf (types.submodule (submoduleInputs: { options =
default = "${inputs.topInputs.self}/devices/cross/secrets"; {
path = mkOption
{
type = types.path;
default = inputs.config.sops.secrets.${submoduleInputs.config.key}.path;
readOnly = true; readOnly = true;
}; };
clusterSopsDir = mkOption key = mkOption { type = types.str; default = submoduleInputs.config._module.args.name; };
format = mkOption { type = types.enum [ "yaml" "binary" ]; default = "yaml"; };
mode = mkOption { type = types.str; default = "0400"; };
owner = mkOption { type = types.nullOr types.str; default = null; };
group = mkOption { type = types.nullOr types.str; default = null; };
sopsFile = mkOption
{ {
type = types.nullOr types.nonEmptyStr; type = types.path;
default = if (inputs.config.nixos.model.cluster == null) then null default =
else "${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}/secrets"; let secretFileIndex =
inputs.lib.lists.findFirstIndex (x: x) null
(builtins.map
(file: inputs.lib.hasAttrByPath (inputs.lib.splitString "/" submoduleInputs.config.key)
(inputs.pkgs.localPackages.fromYaml (builtins.readFile file)))
inputs.config.nixos.system.sops.defaultSopsFile);
in
if secretFileIndex == null then builtins.abort "No sops file found for ${submoduleInputs.config.key}"
else builtins.elemAt inputs.config.nixos.system.sops.defaultSopsFile secretFileIndex;
};
neededForUsers = mkOption { type = types.bool; default = false; };
};}));
default = {};
};
templates = mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
content = mkOption { type = types.str; };
path = mkOption
{
type = types.path;
default = inputs.config.sops.templates.${submoduleInputs.config._module.args.name}.path;
readOnly = true; readOnly = true;
}; };
owner = mkOption { type = types.nullOr types.str; default = null; };
group = mkOption { type = types.nullOr types.str; default = null; };
mode = mkOption { type = types.str; default = "0400"; };
file = mkOption
{
type = types.path;
default = inputs.config.sops.templates.${submoduleInputs.config._module.args.name}.file;
readOnly = true;
};
};}));
default = {};
};
# define default in config
placeholder = mkOption { type = types.attrsOf types.str; };
defaultSopsFile = mkOption
{
type = types.nonEmptyListOf types.path;
readOnly = true;
default =
let
defaultSopsFile = path:
if builtins.pathExists "${path}/secrets.yaml" then [ "${path}/secrets.yaml" ]
else if builtins.pathExists "${path}/secrets/default.yaml" then [ "${path}/secrets/default.yaml" ]
else [];
devicePath = "${inputs.topInputs.self}/devices";
inherit (inputs.config.nixos) model;
in
[]
++ (inputs.lib.optionals (model.cluster == null) (defaultSopsFile "${devicePath}/${model.hostname}"))
++ (inputs.lib.optionals (model.cluster != null)
(
(defaultSopsFile "${devicePath}/${model.cluster.clusterName}/${model.cluster.nodeName}")
++ (defaultSopsFile "${devicePath}/${model.cluster.clusterName}")
))
++ (inputs.lib.optionals model.private [ "${devicePath}/cross/secrets/chn.yaml" ])
++ (defaultSopsFile "${devicePath}/cross");
};
availableKeys = mkOption
{
type = types.listOf (types.listOf types.str);
readOnly = true;
default =
let getPath = x:
if builtins.typeOf x == "string" then []
else if builtins.typeOf x == "set" then inputs.lib.mapAttrsToList (n: v: [ n ] ++ getPath v) x
else builtins.abort "Invalid type for availableKeys";
in builtins.concatLists (builtins.map getPath inputs.config.nixos.system.sops.defaultSopsFile);
};
}; };
config = config =
{ {
nixos.system.sops.placeholder = builtins.mapAttrs
(n: _: inputs.lib.mkOptionDefault "sops${builtins.hashString "sha256" n}sops")
inputs.config.nixos.system.sops.secrets;
sops = sops =
{ {
defaultSopsFile = secrets = builtins.mapAttrs
let deviceDir = (n: v: { inherit (v) key format mode owner group sopsFile neededForUsers; })
if (inputs.config.nixos.model.cluster == null) then inputs.config.nixos.system.sops.secrets;
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.hostname}" templates = builtins.mapAttrs
else (n: v: { inherit (v) content owner group mode; })
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}" inputs.config.nixos.system.sops.templates;
+ "/${inputs.config.nixos.model.cluster.nodeName}"; inherit (inputs.config.nixos.system.sops) placeholder;
in inputs.lib.mkMerge
[
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets.yaml") "${deviceDir}/secrets.yaml")
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets/default.yaml")
"${deviceDir}/secrets/default.yaml")
];
# sops start before impermanence, so we need to use the absolute path
age.sshKeyPaths = [ "/nix/persistent/etc/ssh/ssh_host_ed25519_key" ]; age.sshKeyPaths = [ "/nix/persistent/etc/ssh/ssh_host_ed25519_key" ];
}; };
}; };

View File

@@ -5,12 +5,8 @@ inputs:
home-manager.users.chn = homeInputs: home-manager.users.chn = homeInputs:
{ {
config.xdg.configFile."sops/age/keys.txt".source = config.xdg.configFile."sops/age/keys.txt".source =
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.sops.secrets."chn/age".path; homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.nixos.system.sops.secrets."chn/age".path;
};
sops.secrets."chn/age" =
{
owner = "chn";
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml";
}; };
nixos.system.sops.secrets."chn/age".owner = "chn";
}; };
} }

View File

@@ -40,30 +40,23 @@ inputs:
{ {
name = ".ssh/id_${type}"; name = ".ssh/id_${type}";
value.source = homeInputs.config.lib.file.mkOutOfStoreSymlink value.source = homeInputs.config.lib.file.mkOutOfStoreSymlink
inputs.config.sops.secrets."chn/${type}".path; inputs.config.nixos.system.sops.secrets."chn/${type}".path;
}) })
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" ] [ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" ]
)) ))
// { // {
".ssh/xmuhk_id_rsa".source = ".ssh/xmuhk_id_rsa".source =
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.sops.secrets."chn/xmuhk".path; homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.nixos.system.sops.secrets."chn/xmuhk".path;
} }
); );
}; };
}; };
sops.secrets = inputs.lib.mkIf inputs.config.nixos.model.private (inputs.lib.mkMerge nixos.system.sops.secrets = inputs.lib.mkIf inputs.config.nixos.model.private (inputs.lib.mkMerge
[ [
(builtins.listToAttrs (builtins.map (builtins.listToAttrs (builtins.map
(name: (name: inputs.lib.nameValuePair "chn/${name}" { owner = "chn"; })
{
name = "chn/${name}";
value = { owner = "chn"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
})
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" "xmuhk" ])) [ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" "xmuhk" ]))
{ { "root/ed25519_sk".key = "chn/ed25519_sk"; }
"root/ed25519_sk" =
{ key = "chn/ed25519_sk"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
}
]); ]);
}; };
} }

View File

@@ -101,17 +101,15 @@ inputs:
} }
# set hashedPassword if it exist in secrets # set hashedPassword if it exist in secrets
( (
let let hashedPasswordExist = userName: inputs.lib.lists.any
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; (inputs.lib.lists.hasPrefix [ "users" userName ]) inputs.config.nixos.system.sops.availableKeys;
secrets = inputs.pkgs.localPackages.fromYaml (builtins.readFile sopsFile);
hashedPasswordExist = userName: (secrets ? users) && ((secrets.users or {}) ? ${userName});
in in
{ {
users.users = builtins.listToAttrs (builtins.map users.users = builtins.listToAttrs (builtins.map
(name: { inherit name; value.hashedPasswordFile = inputs.config.sops.secrets."users/${name}".path; }) (name: { inherit name; value.hashedPasswordFile = inputs.config.sops.secrets."users/${name}".path; })
(builtins.filter (user: hashedPasswordExist user) user.users)); (builtins.filter (user: hashedPasswordExist user) user.users));
sops.secrets = builtins.listToAttrs (builtins.map nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(name: { name = "users/${name}"; value = { neededForUsers = true; inherit sopsFile; }; }) (name: inputs.lib.nameValuePair "users/${name}" { neededForUsers = true; })
(builtins.filter (user: hashedPasswordExist user) user.users)); (builtins.filter (user: hashedPasswordExist user) user.users));
} }
) )
@@ -143,7 +141,7 @@ inputs:
home.file = inputs.lib.mkIf inputs.config.nixos.model.private home.file = inputs.lib.mkIf inputs.config.nixos.model.private
{ {
".ssh/id_ed25519_sk".source = homeInputs.config.lib.file.mkOutOfStoreSymlink ".ssh/id_ed25519_sk".source = homeInputs.config.lib.file.mkOutOfStoreSymlink
inputs.config.sops.secrets."root/ed25519_sk".path; inputs.config.nixos.system.sops.secrets."root/ed25519_sk".path;
}; };
}; };
}; };