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
{
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 ]);
};
archive =

View File

@@ -34,21 +34,21 @@ inputs:
name = builtins.elemAt cert.value.domains 0;
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;
group = inputs.lib.mkIf (cert.value.group != null) cert.value.group;
};
})
(inputs.localLib.attrsToList acme.cert));
};
sops =
nixos.system.sops =
{
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
'';
secrets."acme/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
secrets."acme/token" = {};
};
};
}

View File

@@ -14,14 +14,17 @@ inputs:
{
enable = 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;
cert = "${keydir}/full.pem";
pkey = "${keydir}/key.pem";
no-cli = true;
};
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
nixos.services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
nixos =
{
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;
{
allowedUDPPorts = [ listening-port tls-listening-port ];

View File

@@ -15,19 +15,18 @@ inputs:
enable = true;
baseUrl = "https://${freshrss.hostname}";
defaultUser = "chn";
passwordFile = inputs.config.sops.secrets."freshrss/chn".path;
database = { type = "mysql"; passFile = inputs.config.sops.secrets."freshrss/db".path; };
passwordFile = inputs.config.nixos.system.sops.secrets."freshrss/chn".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/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;
lfs.enable = true;
mailerPasswordFile = inputs.config.sops.secrets."gitea/mail".path;
mailerPasswordFile = inputs.config.nixos.system.sops.secrets."gitea/mail".path;
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 =
{
session.COOKIE_SECURE = true;
@@ -48,7 +52,15 @@ inputs:
[ "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 =
{
@@ -63,11 +75,6 @@ inputs:
};
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;
host = "mail.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";
ehlo_identity = grafana.hostname;
startTLS_policy = "MandatoryStartTLS";
@@ -32,9 +32,9 @@ inputs:
server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; };
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_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";
};
database =
@@ -42,7 +42,7 @@ inputs:
type = "postgres";
host = "127.0.0.1:5432";
user = "grafana";
password = "$__file{${inputs.config.sops.secrets."grafana/db".path}}";
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/db".path}}";
};
};
provision =
@@ -78,12 +78,14 @@ inputs:
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; };
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/secret".owner = owner;
@@ -91,6 +93,7 @@ inputs:
"grafana/db" = { owner = owner; key = "postgresql/grafana"; };
"mail/bot" = {};
};
};
environment.persistence."/nix/nodatacow".directories =
[{ directory = "/var/lib/prometheus2"; user = "prometheus"; group = "prometheus"; mode = "0700"; }];
};

View File

@@ -15,13 +15,13 @@ inputs:
grep = "${inputs.pkgs.gnugrep}/bin/grep";
curl = "${inputs.pkgs.curl}/bin/curl";
cat = "${inputs.pkgs.coreutils}/bin/cat";
token = inputs.config.sops.secrets."telegram/token".path;
chat = inputs.config.sops.secrets."telegram/user/chn".path;
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
date = "${inputs.pkgs.coreutils}/bin/date";
hpcstat = "${inputs.pkgs.localPackages.hpcstat}/bin/hpcstat";
ssh = "${inputs.pkgs.openssh}/bin/ssh -i ${key} -o StrictHostKeyChecking=no"
+ " -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";
ssh-agent = "${inputs.pkgs.openssh}/bin/ssh-agent";
in
@@ -105,10 +105,10 @@ inputs:
(inputs.localLib.attrsToList calenders));
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/user/chn" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
"telegram/token" = { group = "telegram"; mode = "0440"; };
"telegram/user/chn" = { group = "telegram"; mode = "0440"; };
"hpcstat/key" = { owner = "hpcstat"; group = "hpcstat"; };
};
users =

View File

@@ -10,7 +10,9 @@ inputs:
};
config = let inherit (inputs.config.nixos.services) httpapi; in inputs.lib.mkIf (httpapi != null)
{
nixos.services =
nixos =
{
services =
{
phpfpm.instances.httpapi = {};
nginx.https.${httpapi.hostname}.location =
@@ -19,12 +21,12 @@ inputs:
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
"/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;
};
};
};
sops =
system.sops =
{
templates."httpapi/notify.php" =
{
@@ -32,13 +34,13 @@ inputs:
group = inputs.config.users.users.httpapi.group;
content =
let
placeholder = inputs.config.sops.placeholder;
inherit (inputs.config.sops) placeholder;
request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
};
secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
{ "telegram/token" = { inherit sopsFile; }; "telegram/user/chn" = { inherit sopsFile; }; };
secrets = { "telegram/token" = {}; "telegram/user/chn" = {}; };
};
};
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";
imageFile = inputs.topInputs.self.src.huginn;
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
HUGINN_DATABASE_NAME=huginn
@@ -40,14 +48,6 @@ inputs:
'';
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
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";
in
# force user use password auth
''echo "ALTER USER '${db.value.user}' IDENTIFIED BY '$(cat ${passwordFile})';" | ${mysql} -N'')
(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; })
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList mariadb.instances)));
environment.persistence."/nix/nodatacow".directories =

View File

@@ -22,7 +22,8 @@ inputs:
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ];
requires = after;
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
{
User = "misskey-${instance.name}";
@@ -53,7 +54,39 @@ inputs:
};
})
(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:
{
name = "misskey/${instance.name}.yml";
@@ -61,7 +94,7 @@ inputs:
{
content =
let
placeholder = inputs.config.sops.placeholder;
placeholder = inputs.config.nixos.system.sops.placeholder;
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
in
''
@@ -97,35 +130,6 @@ inputs:
};
})
(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 =
{
dbtype = "pgsql";
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path;
dbpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/postgresql".path;
adminuser = "admin";
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path;
adminpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/admin".path;
};
configureRedis = true;
settings =
@@ -39,7 +39,7 @@ inputs:
overwriteprotocol = "https";
default_phone_region = "CN";
};
secretFile = inputs.config.sops.templates."nextcloud/secret".path;
secretFile = inputs.config.nixos.system.sops.templates."nextcloud/secret".path;
extraApps =
let
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); })
[ "phonetrack" "twofactor_webauthn" "calendar" ]);
};
nixos.services =
nixos =
{
postgresql.instances.nextcloud = {};
redis.instances.nextcloud.port = 3499;
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
};
sops =
system.sops =
{
templates."nextcloud/secret" =
{
content = builtins.toJSON
{
redis.password = inputs.config.sops.placeholder."redis/nextcloud";
mail_smtppassword = inputs.config.sops.placeholder."mail/bot";
redis.password = inputs.config.nixos.system.sops.placeholder."redis/nextcloud";
mail_smtppassword = inputs.config.nixos.system.sops.placeholder."mail/bot";
};
owner = inputs.config.users.users.nextcloud.name;
};
@@ -82,6 +78,13 @@ inputs:
"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; };
};
}

View File

@@ -95,17 +95,13 @@ inputs:
settings =
{
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" ];
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets."nginx/maxmind-license" =
{
owner = inputs.config.users.users.nginx.name;
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
};
nixos.system.sops.secrets."nginx/maxmind-license".owner = inputs.config.users.users.nginx.name;
systemd.services.nginx.serviceConfig =
{
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];

View File

@@ -177,7 +177,7 @@ inputs:
basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null)
(
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"
(
@@ -227,7 +227,7 @@ inputs:
let
inherit (inputs.lib.strings) escapeURL;
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;
}
@@ -247,7 +247,7 @@ inputs:
++ (inputs.lib.optionals (location.value.addAuth != null)
(
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);
nixos.services =
nixos =
{
services =
{
nginx =
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
@@ -324,7 +326,7 @@ inputs:
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
sites);
};
sops =
system.sops =
let
inherit (inputs.lib.strings) escapeURL;
detectAuthUsers = builtins.concatLists (builtins.map
@@ -353,32 +355,23 @@ inputs:
sites);
in
{
templates = builtins.listToAttrs
templates = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.listToAttrs
(
(builtins.map
(detectAuth:
{
name = "nginx/templates/detectAuth/${detectAuth.name}";
value =
(detectAuth: inputs.lib.nameValuePair "nginx/templates/detectAuth/${detectAuth.name}"
{
owner = inputs.config.users.users.nginx.name;
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);
};
})
detectAuthUsers)
++ (builtins.map
(addAuth:
{
name = "nginx/templates/addAuth/${addAuth.name}";
value =
(addAuth: inputs.lib.nameValuePair "nginx/templates/addAuth/${addAuth.name}"
{
owner = inputs.config.users.users.nginx.name;
content =
let placeholder = inputs.config.sops.placeholder."nginx/addAuth/${addAuth.value}";
in ''proxy_set_header Authorization "Basic ${placeholder}";'';
};
''proxy_set_header Authorization "Basic ${placeholder."nginx/addAuth/${addAuth.value}"}";'';
})
addAuth)
);
@@ -393,6 +386,7 @@ inputs:
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
);
};
};
}
)
]);

View File

@@ -15,12 +15,15 @@ inputs:
enable = true;
package = inputs.pkgs.nix-serve-ng;
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
# use this cache after official one
extraParams = "--priority 50";
};
sops.secrets."store/signingKey" = {};
nixos.services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
nixos =
{
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
(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;
restart = false;
})
@@ -122,52 +122,30 @@ inputs:
vnc_listen = "0.0.0.0"
'';
};
nixos.services =
nixos =
{
nginx =
let hosts = builtins.concatLists (builtins.map
(vm: builtins.map
(domain:
system.sops =
{
inherit domain;
ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}";
})
vm.network.portForward.web)
(builtins.attrValues nixvirt.instance));
in
templates = inputs.lib.mapAttrs'
(n: v: inputs.lib.nameValuePair "nixvirt/${n}.xml"
{
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 = {};
};
sops =
{
templates = builtins.listToAttrs (builtins.map
(vm:
{
name = "nixvirt/${vm.name}.xml";
value.content = inputs.topInputs.nixvirt.lib.domain.getXML
content = inputs.topInputs.nixvirt.lib.domain.getXML
# port from 8bcc23e27a62297254d0e9c87281e650ff777132
{
inherit (vm) name;
inherit (vm.value) uuid;
name = n;
inherit (v) uuid;
type = "kvm";
vcpu = { placement = "static"; count = vm.value.cpu.count; };
cputune = inputs.lib.optionalAttrs (vm.value.cpu.set != null)
vcpu = { placement = "static"; count = v.cpu.count; };
cputune = inputs.lib.optionalAttrs (v.cpu.set != null)
{
vcpupin = builtins.genList
(cpu: { vcpu = cpu; cpuset = builtins.elemAt vm.value.cpu.set cpu; })
vm.value.cpu.count;
vcpupin = builtins.genList (cpu: { vcpu = cpu; cpuset = builtins.elemAt v.cpu.set cpu; }) v.cpu.count;
};
memory =
{
count = vm.value.memory.sizeMB;
count = v.memory.sizeMB;
unit = "MiB";
nosharepages = vm.value.memory.dedicated;
locked = vm.value.memory.dedicated;
nosharepages = v.memory.dedicated;
locked = v.memory.dedicated;
};
os =
{
@@ -179,7 +157,7 @@ inputs:
nvram =
{
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";
format = "raw";
};
@@ -192,8 +170,8 @@ inputs:
{
sockets = 1;
dies = 1;
cores = if vm.value.cpu.hyprthread then vm.value.cpu.count / 2 else vm.value.cpu.count;
threads = if vm.value.cpu.hyprthread then 2 else 1;
cores = if v.cpu.hyprthread then v.cpu.count / 2 else v.cpu.count;
threads = if v.cpu.hyprthread then 2 else 1;
};
};
clock =
@@ -215,8 +193,8 @@ inputs:
type = "file";
device = "disk";
driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; };
source.file = "${if vm.value.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
+ "${vm.value.storage.name}.img";
source.file = "${if v.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
+ "${v.storage.name}.img";
target = { dev = "vda"; bus = "virtio"; };
boot.order = 1;
}
@@ -234,8 +212,8 @@ inputs:
{
type = "bridge";
model.type = "virtio";
mac.address = vm.value.network.mac;
source.bridge = if vm.value.network.bridge then "nixvirt" else "virbr0";
mac.address = v.network.mac;
source.bridge = if v.network.bridge then "nixvirt" else "virbr0";
};
input =
[
@@ -247,21 +225,39 @@ inputs:
{
type = "vnc";
autoport = false;
port = vm.value.network.vnc.port;
port = v.network.vnc.port;
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; };
rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; };
};
};
})
(inputs.localLib.attrsToList nixvirt.instance));
secrets = builtins.listToAttrs (builtins.map
(vm: { name = "nixvirt/${vm}"; value = {}; }) (builtins.attrNames nixvirt.instance));
placeholder = builtins.listToAttrs (builtins.map
(vm: { name = "nixvirt/${vm}"; value = builtins.hashString "sha256" "nixvirt/${vm}"; })
(builtins.attrNames nixvirt.instance));
nixvirt.instance;
secrets = inputs.lib.mapAttrs' (n: _: inputs.lib.nameValuePair "nixvirt/${n}" {}) nixvirt.instance;
};
services =
{
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 =
{

View File

@@ -28,11 +28,13 @@ inputs:
ENABLE_IMAGE_GENERATION = "True";
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"}
WEBUI_SECRET_KEY=${placeholder."open-webui/webui"}
@@ -40,7 +42,8 @@ inputs:
'';
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; };
};
};
}

View File

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

View File

@@ -23,21 +23,24 @@ inputs:
{
after = [ "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_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"}
'';
secrets."photoprism/adminPassword" = {};
};
nixos.services =
services =
{
mariadb.instances.photoprism = {};
nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; };
};
};
};
}

View File

@@ -63,7 +63,7 @@ inputs:
let
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 =
if db.value.initializeFlags != {} then
" WITH "
@@ -85,7 +85,7 @@ inputs:
+ " | grep -E '^${db.value.user}$' -q"
+ " || $PSQL -tAc \"ALTER DATABASE ${db.value.database} OWNER TO ${db.value.user}\"")
(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; })
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList postgresql.instances)));
environment.persistence."/nix/nodatacow".directories = inputs.lib.mkIf postgresql.nodatacow

View File

@@ -28,12 +28,13 @@ inputs:
# unixSocket = null; # bug
unixSocketPerm = 600;
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;
};
})
(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; })
(builtins.filter (server: server.value.passwordFile == null) (inputs.localLib.attrsToList redis.instances)));
systemd.services = builtins.listToAttrs (builtins.map

View File

@@ -15,11 +15,13 @@ inputs:
image = "rsshub:latest";
imageFile = inputs.topInputs.self.src.rsshub;
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
CACHE_TYPE=memory
@@ -34,7 +36,7 @@ inputs:
XDG_CACHE_HOME='/var/cache/rsshub/chromium'
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"
"youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token"
@@ -43,6 +45,7 @@ inputs:
"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;
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"}
'';
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;
host = "127.0.0.1";
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" ];

View File

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

View File

@@ -43,7 +43,7 @@ inputs:
let
package = inputs.pkgs.matrix-synapse.override
{ 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";
in
{
@@ -100,16 +100,17 @@ inputs:
];
})
(inputs.localLib.attrsToList synapse.instances));
sops = inputs.lib.mkMerge (builtins.map
nixos =
{
system.sops = inputs.lib.mkMerge (builtins.map
(instance:
{
templates."synapse/${instance.name}/config.yaml" =
{
owner = "synapse-${instance.name}";
group = "synapse-${instance.name}";
content =
let
inherit (inputs.config.sops) placeholder;
inherit (inputs.config.nixos.system.sops) placeholder;
in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml"
{
server_name = instance.value.matrixHostname;
@@ -146,7 +147,7 @@ inputs:
registration_shared_secret = placeholder."synapse/${instance.name}/registration";
macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon";
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 =
{
smtp_host = "mail.chn.moe";
@@ -203,7 +204,7 @@ inputs:
// { "mail/bot" = {}; };
})
(inputs.localLib.attrsToList synapse.instances));
nixos.services =
services =
{
postgresql.instances = builtins.listToAttrs (builtins.map
(instance:
@@ -239,4 +240,5 @@ inputs:
(inputs.localLib.attrsToList synapse.instances));
};
};
};
}

View File

@@ -25,11 +25,13 @@ inputs:
SMTP_SECURITY = "force_tls";
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";
group = "vaultwarden";
@@ -42,12 +44,13 @@ inputs:
};
secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; };
};
systemd.services.vaultwarden.after = [ "postgresql.service" ];
nixos.services =
services =
{
postgresql.instances.vaultwarden = {};
nginx.https.${vaultwarden.hostname}.location."/".proxy =
{ 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;
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
(peer:
{
@@ -45,6 +45,6 @@ inputs:
};
})
(inputs.localLib.attrsToList wireguard));
sops.secrets.wireguard = {};
nixos.system.sops.secrets.wireguard = {};
};
}

View File

@@ -43,7 +43,7 @@ inputs:
};
resolved.enable = false;
};
sops =
nixos.system.sops =
{
templates."xray-client.json" =
{
@@ -120,7 +120,7 @@ inputs:
port = 443;
users =
[{
id = inputs.config.sops.placeholder."xray-client/uuid";
id = inputs.config.nixos.system.sops.placeholder."xray-client/uuid";
encryption = "none";
flow = "xtls-rprx-vision-udp443";
}];
@@ -179,7 +179,8 @@ inputs:
{
after = [ "network.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 =
{
User = "v2ray";
@@ -191,7 +192,7 @@ inputs:
LimitNOFILE = 524288;
CPUSchedulingPolicy = "rr";
};
restartTriggers = [ inputs.config.sops.templates."xray-client.json".file ];
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-client.json".file ];
};
v2ray-forwarder =
{

View File

@@ -10,11 +10,14 @@ inputs:
};
config = let inherit (inputs.config.nixos.services.xray) server; in inputs.lib.mkIf (server != null)
(
let userList = builtins.attrNames
(inputs.pkgs.localPackages.fromYaml (builtins.readFile inputs.config.sops.defaultSopsFile)).xray-server.clients;
let userList = builtins.map (user: builtins.elemAt user 2) (builtins.filter
(user: builtins.elem user == 3 && inputs.lib.lists.hasPrefix [ "xray-server" "clients" ])
inputs.config.nixos.system.sops.availableKeys);
in
{
sops =
nixos =
{
system.sops =
{
templates."xray-server.json" =
{
@@ -38,7 +41,7 @@ inputs:
clients = builtins.map
(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";
email = "${n}@xray.chn.moe";
})
@@ -54,7 +57,7 @@ inputs:
{
dest = "127.0.0.1:${fallbackPort}";
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";
shortIds = [ "" ];
};
@@ -126,21 +129,26 @@ inputs:
};
};
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
(name:
{
name = "telegram/${name}";
value =
{
group = "telegram";
mode = "0440";
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
};
})
(name: inputs.lib.nameValuePair "telegram/${name}" { group = "telegram"; mode = "0440"; })
[ "token" "user/chn" ]))
// { "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 =
{
services =
@@ -149,8 +157,8 @@ inputs:
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script =
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-server.json".path}";
script = let config = inputs.config.nixos.system.sops.templates."xray-server.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
@@ -160,7 +168,7 @@ inputs:
LimitNPROC = 65536;
LimitNOFILE = 524288;
};
restartTriggers = [ inputs.config.sops.templates."xray-server.json".file ];
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-server.json".file ];
};
xray-stat =
{
@@ -172,8 +180,8 @@ inputs:
jq = "${inputs.pkgs.jq}/bin/jq";
sed = "${inputs.pkgs.gnused}/bin/sed";
cat = "${inputs.pkgs.coreutils}/bin/cat";
token = inputs.config.sops.secrets."telegram/token".path;
chat = inputs.config.sops.secrets."telegram/user/chn".path;
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
in
''
message='${inputs.config.nixos.model.hostname} xray:\n'
@@ -216,19 +224,6 @@ inputs:
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)
{
sops =
nixos.system.sops =
{
templates."xray-xmu-client.json" =
{
@@ -37,7 +37,8 @@ inputs:
[{
address = "webvpn.xmu.edu.cn";
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 =
{
@@ -61,8 +62,9 @@ inputs:
in "/https/${prefix}${paddedHex}/xsession";
mode = "packet-up";
security = "tls";
extra.headers.Cookie = "show_vpn=0; heartbeat=1; show_faq=0; "
+ "wengine_vpn_ticketwebvpn_xmu_edu_cn=${inputs.config.sops.placeholder."xray-xmu-client/cookie"}";
extra.headers.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" ];
};
@@ -77,8 +79,8 @@ inputs:
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script =
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-client.json".path}";
script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-client.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
@@ -90,7 +92,7 @@ inputs:
LimitNOFILE = 524288;
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 =

View File

@@ -10,12 +10,11 @@ inputs:
};
config = let inherit (inputs.config.nixos.services.xray) xmuServer; in inputs.lib.mkIf (xmuServer != null)
{
sops =
nixos.system.sops =
{
templates."xray-xmu-server.json" =
{
owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = builtins.toJSON
{
log.loglevel = "warning";
@@ -24,7 +23,11 @@ inputs:
port = 4727;
listen = "127.0.0.1";
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"; }; };
tag = "in";
}];
@@ -37,8 +40,8 @@ inputs:
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script =
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-server.json".path}";
script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-server.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
@@ -49,7 +52,7 @@ inputs:
LimitNPROC = 65536;
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 =
{

View File

@@ -146,19 +146,19 @@ inputs:
# wpa_passphrase SSID password
networks = builtins.listToAttrs (builtins.map
(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;
};
# dnsable dns fallback, use provided dns servers or no dns
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
(network: "${network}=${inputs.config.sops.placeholder."wireless/${network}"}")
(network: "${network}=${inputs.config.nixos.system.sops.placeholder."wireless/${network}"}")
network.wireless);
secrets = builtins.listToAttrs (builtins.map
(network: { name = "wireless/${network}"; value = {}; })
(network: inputs.lib.nameValuePair "wireless/${network}" {})
network.wireless);
};
})

View File

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

View File

@@ -2,38 +2,113 @@ inputs:
{
options.nixos.system.sops = let inherit (inputs.lib) mkOption types; in
{
crossSopsDir = mkOption
secrets = mkOption
{
type = types.nonEmptyStr;
default = "${inputs.topInputs.self}/devices/cross/secrets";
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
path = mkOption
{
type = types.path;
default = inputs.config.sops.secrets.${submoduleInputs.config.key}.path;
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;
default = if (inputs.config.nixos.model.cluster == null) then null
else "${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}/secrets";
type = types.path;
default =
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;
};
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 =
{
nixos.system.sops.placeholder = builtins.mapAttrs
(n: _: inputs.lib.mkOptionDefault "sops${builtins.hashString "sha256" n}sops")
inputs.config.nixos.system.sops.secrets;
sops =
{
defaultSopsFile =
let deviceDir =
if (inputs.config.nixos.model.cluster == null) then
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.hostname}"
else
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}"
+ "/${inputs.config.nixos.model.cluster.nodeName}";
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
secrets = builtins.mapAttrs
(n: v: { inherit (v) key format mode owner group sopsFile neededForUsers; })
inputs.config.nixos.system.sops.secrets;
templates = builtins.mapAttrs
(n: v: { inherit (v) content owner group mode; })
inputs.config.nixos.system.sops.templates;
inherit (inputs.config.nixos.system.sops) placeholder;
age.sshKeyPaths = [ "/nix/persistent/etc/ssh/ssh_host_ed25519_key" ];
};
};

View File

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

View File

@@ -40,30 +40,23 @@ inputs:
{
name = ".ssh/id_${type}";
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" ]
))
// {
".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
(name:
{
name = "chn/${name}";
value = { owner = "chn"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
})
(name: inputs.lib.nameValuePair "chn/${name}" { owner = "chn"; })
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" "xmuhk" ]))
{
"root/ed25519_sk" =
{ key = "chn/ed25519_sk"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
}
{ "root/ed25519_sk".key = "chn/ed25519_sk"; }
]);
};
}

View File

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