"files-watcher": "files-watcher",
"my-lib": "my-lib",
"nix-lib": "nix-lib",
- "openarc": "openarc"
+ "openarc": "openarc",
+ "secrets": "secrets"
+ }
+ },
+ "secrets": {
+ "locked": {
+ "narHash": "sha256-aRHKDVHDpnqpmgGhLGQxXwyTwmPuhUJTVcOLBYtY2ks=",
+ "path": "../../secrets",
+ "type": "path"
+ },
+ "original": {
+ "path": "../../secrets",
+ "type": "path"
}
}
},
path = "../../openarc";
type = "path";
};
+ inputs.secrets = {
+ path = "../../secrets";
+ type = "path";
+ };
inputs.files-watcher = {
path = "../../files-watcher";
type = "path";
inputs.nix-lib.url = "github:NixOS/nixpkgs";
description = "Private configuration for openarc";
- outputs = { self, nix-lib, my-lib, files-watcher, openarc }:
+ outputs = { self, nix-lib, my-lib, files-watcher, openarc, secrets }:
let
cfg = name': { config, lib, pkgs, name, ... }: {
imports = [
(my-lib.lib.withNarKey files-watcher "nixosModule")
(my-lib.lib.withNarKey openarc "nixosModule")
- #FIXME:
- #(my-lib.lib.withNarKey secrets "nixosModule")
+ (my-lib.lib.withNarKey secrets "nixosModule")
];
config = lib.mkIf (name == name') {
services.openarc = {
"files-watcher": "files-watcher",
"my-lib": "my-lib",
"nix-lib": "nix-lib",
- "opendmarc": "opendmarc"
+ "opendmarc": "opendmarc",
+ "secrets": "secrets"
+ }
+ },
+ "secrets": {
+ "locked": {
+ "narHash": "sha256-aRHKDVHDpnqpmgGhLGQxXwyTwmPuhUJTVcOLBYtY2ks=",
+ "path": "../../secrets",
+ "type": "path"
+ },
+ "original": {
+ "path": "../../secrets",
+ "type": "path"
}
}
},
path = "../../opendmarc";
type = "path";
};
+ inputs.secrets = {
+ path = "../../secrets";
+ type = "path";
+ };
inputs.files-watcher = {
path = "../../files-watcher";
type = "path";
inputs.nix-lib.url = "github:NixOS/nixpkgs";
description = "Private configuration for opendmarc";
- outputs = { self, nix-lib, opendmarc, my-lib, files-watcher }:
+ outputs = { self, nix-lib, opendmarc, my-lib, files-watcher, secrets }:
let
cfg = name': { config, lib, pkgs, name, ... }: {
imports = [
(my-lib.lib.withNarKey files-watcher "nixosModule")
(my-lib.lib.withNarKey opendmarc "nixosModule")
- #FIXME:
- #(my-lib.lib.withNarKey secrets "nixosModule")
+ (my-lib.lib.withNarKey secrets "nixosModule")
];
config = lib.mkIf (name == name') {
users.users."${config.services.opendmarc.user}".extraGroups = [ "keys" ];
--- /dev/null
+{
+ description = "Secrets handling";
+
+ outputs = { self }: {
+ nixosModule = { config, lib, pkgs, ... }: {
+ options.secrets = with lib; {
+ keys = mkOption {
+ type = types.listOf types.unspecified;
+ default = [];
+ description = "Keys to upload to server";
+ };
+ gpgKeys = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = "GPG public keys files to encrypt to";
+ };
+ ageKeys = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = "AGE keys to encrypt to";
+ };
+ decryptKey = mkOption {
+ type = types.str;
+ default = "/etc/ssh/ssh_host_ed25519_key";
+ description = "ed25519 key used to decrypt with AGE";
+ };
+ location = mkOption {
+ type = types.path;
+ default = "/var/secrets";
+ description = "Location where to put the keys";
+ };
+ secretsVars = mkOption {
+ type = types.path;
+ description = "Location where the secrets variables are defined, to be used to fill the templates in secrets";
+ };
+ deleteSecretsVars = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Delete secrets file after deployment";
+ };
+ # Read-only variables
+ fullPaths = mkOption {
+ type = types.attrsOf types.path;
+ default = builtins.listToAttrs
+ (map (v: { name = v.dest; value = "${config.secrets.location}/${v.dest}"; }) config.secrets.keys);
+ readOnly = true;
+ description = "set of full paths to secrets";
+ };
+ };
+
+ config = let
+ location = config.secrets.location;
+ keys = config.secrets.keys;
+ empty = pkgs.runCommand "empty" { preferLocalBuild = true; } "mkdir -p $out && touch $out/done";
+ fpath = v: "secrets/${v.dest}${lib.optionalString (v.isTemplated or true) ".gucci.tpl"}";
+ dumpKey = v:
+ if v.isDir or false then
+ ''
+ mkdir -p secrets/${v.dest}
+ cat >> mods <<EOF
+ ${v.user or "root"} ${v.group or "root"} ${v.permissions or "0600"} secrets/${v.dest}
+ EOF
+ ''
+ else ''
+ mkdir -p secrets/$(dirname ${v.dest})
+ echo -n ${lib.strings.escapeShellArg v.text} > ${fpath v}
+ cat >> mods <<EOF
+ ${v.user or "root"} ${v.group or "root"} ${v.permissions or "0600"} ${fpath v}
+ EOF
+ '';
+ secrets = pkgs.runCommand "secrets.tar.enc" {
+ buildInputs = [ pkgs.gnupg pkgs.sops ];
+ } ''
+ touch mods
+ tar --format=ustar --mtime='1970-01-01' -P --transform="s@${empty}@secrets@" -cf $out ${empty}/done
+ ${builtins.concatStringsSep "\n" (map dumpKey keys)}
+ cat mods | while read u g p k; do
+ tar --no-recursion --format=ustar --mtime='1970-01-01' --owner="$u" --group="$g" --mode="$p" --append -f $out "$k"
+ done
+ export HOME=$(pwd)
+ fingerprints=
+ for key in ${builtins.concatStringsSep " " config.secrets.gpgKeys}; do
+ gpg --import $key 2>/dev/null
+ fingerprints=$fingerprints,$(cat $key | gpg --with-colons --import-options show-only --import 2>/dev/null | grep ^fpr | cut -d: -f10 | head -n1)
+ done
+
+ sops --age ${builtins.concatStringsSep "," config.secrets.ageKeys} --pgp ''${fingerprints#,} --input-type binary -i -e $out 2>/dev/null
+ '';
+ pathChmodExcl =
+ let
+ dirs = builtins.filter (v: v.isDir or false) keys;
+ exclPath = builtins.concatStringsSep " -o " (map (d: " -path $TMP/${d.dest}") dirs);
+ in
+ lib.optionalString (builtins.length dirs > 0) " -not \\( ${exclPath} \\) ";
+ in lib.mkIf (builtins.length keys > 0) {
+ system.activationScripts.secrets = {
+ deps = [ "users" "wrappers" ];
+ text = ''
+ install -m0750 -o root -g keys -d ${location}
+ TMP=$(${pkgs.coreutils}/bin/mktemp -d)
+ TMPWORK=$(${pkgs.coreutils}/bin/mktemp -d)
+ chmod go-rwx $TMPWORK
+ if [ -n "$TMP" -a -n "$TMPWORK" ]; then
+ install -m0750 -o root -g keys -d $TMP
+ ${pkgs.ssh-to-age}/bin/ssh-to-age -private-key -i ${config.secrets.decryptKey} -o $TMPWORK/keys.txt
+ SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${secrets} | ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -x
+ if [ -f ${config.secrets.secretsVars} ]; then
+ SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${config.secrets.secretsVars} > $TMPWORK/vars.yml
+ fi
+ if [ -f $TMPWORK/vars.yml ]; then
+ find $TMP -name "*.gucci.tpl" -exec \
+ /bin/sh -c 'f="{}"; ${pkgs.gucci}/bin/gucci -f '$TMPWORK'/vars.yml "$f" > "''${f%.gucci.tpl}"; touch --reference "$f" ''${f%.gucci.tpl} ; chmod --reference="$f" ''${f%.gucci.tpl} ; chown --reference="$f" ''${f%.gucci.tpl}' \;
+ fi
+ find $TMP -type d ${pathChmodExcl}-exec chown root:keys {} \; -exec chmod o-rx {} \;
+ ${pkgs.rsync}/bin/rsync --exclude="*.gucci.tpl" -O -c -av --delete $TMP/ ${location}
+ rm -rf $TMP $TMPWORK ${lib.optionalString config.secrets.deleteSecretsVars config.secrets.secretsVars}
+ fi
+ '';
+ };
+
+ };
+ };
+ };
+}
in
{
myids = (flakeCompat ../flakes/myuids).nixosModule;
- secrets = ./secrets.nix;
+ secrets = flakeLib.withNarKeyCompat flakeCompat ../flakes/secrets "nixosModule";
filesWatcher = flakeLib.withNarKeyCompat flakeCompat ../flakes/files-watcher "nixosModule";
webstats = ./webapps/webstats;
dest = "backup/${varName k remote}/exclude";
text = v.excludeFile;
}
+ {
+ permissions = "0500";
+ dest = "backup/${varName k remote}";
+ isDir = true;
+ }
]) v.remotes) config.services.duplyBackup.profiles);
services.cron = {
map (remote: [
''
touch ${varDir}/${varName k remote}.log
- ${pkgs.duply}/bin/duply ${config.secrets.location}/backup/${varName k remote}/ ${action} --force >> ${varDir}/${varName k remote}.log
+ ${pkgs.duply}/bin/duply ${config.secrets.fullPaths."backup/${varName k remote}"}/ ${action} --force >> ${varDir}/${varName k remote}.log
[[ $? = 0 ]] || echo -e "Error when doing backup for ${varName k remote}, see above\n---------------------------------------" >&2
''
]) v.remotes
};
services.websites.env.tools.watchPaths = lib.attrsets.mapAttrsToList
- (k: project: "/var/secrets/buildbot/${project.name}/webhook-httpd-include")
+ (k: project: config.secrets.fullPaths."buildbot/${project.name}/webhook-httpd-include")
config.myEnv.buildbot.projects;
services.websites.env.tools.vhostConfs.git.extraConfig = lib.attrsets.mapAttrsToList (k: project: ''
<RequireAny>
Require local
Require ldap-group cn=users,ou=${project.name},cn=buildbot,ou=services,dc=immae,dc=eu
- Include /var/secrets/buildbot/${project.name}/webhook-httpd-include
+ Include ${config.secrets.fullPaths."buildbot/${project.name}/webhook-httpd-include"}
</RequireAny>
</Location>
'') config.myEnv.buildbot.projects;
services.filesWatcher = lib.attrsets.mapAttrs' (k: project: lib.attrsets.nameValuePair "buildbot-${project.name}" {
restart = true;
paths = [
- "/var/secrets/buildbot/ldap"
- "/var/secrets/buildbot/worker_password"
- "/var/secrets/buildbot/ssh_key"
- "/var/secrets/buildbot/${project.name}/environment_file"
- ] ++ lib.attrsets.mapAttrsToList (k: v: "/var/secrets/buildbot/${project.name}/${k}") project.secrets;
+ config.secrets.fullPaths."buildbot/ldap"
+ config.secrets.fullPaths."buildbot/worker_password"
+ config.secrets.fullPaths."buildbot/ssh_key"
+ config.secrets.fullPaths."buildbot/${project.name}/environment_file"
+ ] ++ lib.attrsets.mapAttrsToList (k: v: config.secrets.fullPaths."buildbot/${project.name}/${k}") project.secrets;
}) config.myEnv.buildbot.projects;
systemd.slices.buildbot = {
fi
ln -sf ${tac_file} ${varDir}/${project.name}/buildbot.tac
# different buildbots may be trying that simultaneously, add the || true to avoid complaining in case of race
- install -Dm600 -o buildbot -g buildbot -T /var/secrets/buildbot/ssh_key ${varDir}/buildbot_key || true
+ install -Dm600 -o buildbot -g buildbot -T ${config.secrets.fullPaths."buildbot/ssh_key"} ${varDir}/buildbot_key || true
buildbot_secrets=${varDir}/${project.name}/secrets
install -m 0700 -o buildbot -g buildbot -d $buildbot_secrets
- install -Dm600 -o buildbot -g buildbot -T /var/secrets/buildbot/ldap $buildbot_secrets/ldap
- install -Dm600 -o buildbot -g buildbot -T /var/secrets/buildbot/worker_password $buildbot_secrets/worker_password
+ install -Dm600 -o buildbot -g buildbot -T ${config.secrets.fullPaths."buildbot/ldap"} $buildbot_secrets/ldap
+ install -Dm600 -o buildbot -g buildbot -T ${config.secrets.fullPaths."buildbot/worker_password"} $buildbot_secrets/worker_password
${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList
- (k: v: "install -Dm600 -o buildbot -g buildbot -T /var/secrets/buildbot/${project.name}/${k} $buildbot_secrets/${k}") project.secrets
+ (k: v: "install -Dm600 -o buildbot -g buildbot -T ${config.secrets.fullPaths."buildbot/${project.name}/${k}"} $buildbot_secrets/${k}") project.secrets
)}
${buildbot}/bin/buildbot upgrade-master ${varDir}/${project.name}
'';
SupplementaryGroups = "keys";
WorkingDirectory = "${varDir}/${project.name}";
ExecStart = "${buildbot}/bin/buildbot start";
- EnvironmentFile = "/var/secrets/buildbot/${project.name}/environment_file";
+ EnvironmentFile = config.secrets.fullPaths."buildbot/${project.name}/environment_file";
};
}) config.myEnv.buildbot.projects;
};
mysql = {
text = ''
# https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
- auth required ${pam_ldap} config=${config.secrets.location}/mysql/pam
- account required ${pam_ldap} config=${config.secrets.location}/mysql/pam
+ auth required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam"}
+ account required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam"}
'';
};
mysql_replication = {
text = ''
- auth required ${pam_ldap} config=${config.secrets.location}/mysql/pam_replication
- account required ${pam_ldap} config=${config.secrets.location}/mysql/pam_replication
+ auth required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam_replication"}
+ account required ${pam_ldap} config=${config.secrets.fullPaths."mysql/pam_replication"}
'';
};
};
filename=${backupDir}/$(${pkgs.coreutils}/bin/date -Iminutes).sql
${hcfg.package}/bin/mysqldump \
- --defaults-file=${config.secrets.location}/mysql_replication/${name}/mysqldump \
+ --defaults-file=${config.secrets.fullPaths."mysql_replication/${name}/mysqldump"} \
-S /run/mysqld_${name}/mysqld.sock \
--gtid \
--master-data \
if ! test -e ${dataDir}/mysql; then
if ! test -e ${dataDir}/initial.sql; then
${hcfg.package}/bin/mysqldump \
- --defaults-file=${config.secrets.location}/mysql_replication/${name}/mysqldump_remote \
+ --defaults-file=${config.secrets.fullPaths."mysql_replication/${name}/mysqldump_remote"} \
-h ${hcfg.host} \
-P ${hcfg.port} \
--ssl \
cat \
${sql_before} \
${dataDir}/initial.sql \
- ${config.secrets.location}/mysql_replication/${name}/slave_init_commands \
+ ${config.secrets.fullPaths."mysql_replication/${name}/slave_init_commands"} \
| ${hcfg.package}/bin/mysql \
--defaults-file=/etc/mysql/${name}_my.cnf \
-S /run/mysqld_${name}/mysqld.sock \
permissions = "0400";
user = "openldap";
group = "openldap";
- text = builtins.readFile "${cfg.accessFile}";
+ text = builtins.readFile cfg.accessFile;
+ }
+ {
+ dest = "ldap";
+ permissions = "0500";
+ user = "openldap";
+ group = "openldap";
+ isDir = true;
}
];
users.users.openldap.extraGroups = [ "keys" ];
services.filesWatcher.openldap = {
restart = true;
- paths = [ "${config.secrets.location}/ldap/" ];
+ paths = [ config.secrets.fullPaths."ldap" ];
};
services.openldap = {
overlay syncprov
syncprov-checkpoint 100 10
- include ${config.secrets.location}/ldap/access
+ include ${config.secrets.fullPaths."ldap/access"}
'';
- rootpwFile = "${config.secrets.location}/ldap/password";
+ rootpwFile = config.secrets.fullPaths."ldap/password";
suffix = cfg.baseDn;
rootdn = cfg.rootDn;
database = "hdb";
index uid pres,eq
index entryUUID eq
- include ${config.secrets.location}/openldap_replication/${name}/replication_config
+ include ${config.secrets.fullPaths."openldap_replication/${name}/replication_config"}
'';
in
{
in {
postgresql = {
text = ''
- auth required ${pam_ldap} config=${config.secrets.location}/postgresql/pam
- account required ${pam_ldap} config=${config.secrets.location}/postgresql/pam
+ auth required ${pam_ldap} config=${config.secrets.fullPaths."postgresql/pam"}
+ account required ${pam_ldap} config=${config.secrets.fullPaths."postgresql/pam"}
'';
};
postgresql_replication = {
text = ''
- auth required ${pam_ldap} config=${config.secrets.location}/postgresql/pam_replication
- account required ${pam_ldap} config=${config.secrets.location}/postgresql/pam_replication
+ auth required ${pam_ldap} config=${config.secrets.fullPaths."postgresql/pam_replication"}
+ account required ${pam_ldap} config=${config.secrets.fullPaths."postgresql/pam_replication"}
'';
};
};
decrypt = true;
source = "0.0.0.0:16379";
target = "/run/redis/redis.sock";
- keyfile = "${config.secrets.location}/redis/spiped_keyfile";
+ keyfile = config.secrets.fullPaths."redis/spiped_keyfile";
};
};
systemd.services.spiped_redis = {
services.filesWatcher.predixy = {
restart = true;
- paths = [ "${config.secrets.location}/redis/predixy.conf" ];
+ paths = [ config.secrets.fullPaths."redis/predixy.conf" ];
};
networking.firewall.allowedTCPPorts = [ 7617 16379 ];
SupplementaryGroups = "keys";
Type = "simple";
- ExecStart = "${pkgs.predixy}/bin/predixy ${config.secrets.location}/redis/predixy.conf";
+ ExecStart = "${pkgs.predixy}/bin/predixy ${config.secrets.fullPaths."redis/predixy.conf"}";
};
};
encrypt = true;
source = "127.0.0.1:16379";
target = "${config.myEnv.servers.eldiron.ips.main.ip4}:16379";
- keyfile = "${config.secrets.location}/redis/spiped_eldiron_keyfile";
+ keyfile = config.secrets.fullPaths."redis/spiped_eldiron_keyfile";
};
};
unitConfig.RequiresMountsFor = dataDir;
serviceConfig = {
- ExecStart = "${hcfg.package}/bin/redis-server ${config.secrets.location}/redis_replication/${name}/config";
+ ExecStart = "${hcfg.package}/bin/redis-server ${config.secrets.fullPaths."redis_replication/${name}/config"}";
User = "redis";
RuntimeDirectory = "redis_${name}";
};
) listOfAttrs
) [{}] (attrNames attrsOfLists);
cfg = config.services.bind;
- keyIncludes = builtins.concatStringsSep "\n" (map (v: "include \"/var/secrets/bind/${v}.key\";") (builtins.attrNames config.myEnv.dns.keys));
+ keyIncludes = builtins.concatStringsSep "\n" (map (v: "include \"${config.secrets.fullPaths."bind/${v}.key"}\";") (builtins.attrNames config.myEnv.dns.keys));
cartProduct = lib.foldr
(s: servers: servers // { ${s.masters} = lib.unique ((servers.${s.masters} or []) ++ [s.keys]); })
{}
services.filesWatcher.pure-ftpd = {
restart = true;
- paths = [ "/var/secrets/pure-ftpd-ldap" ];
+ paths = [ config.secrets.fullPaths."pure-ftpd-ldap" ];
};
systemd.services.pure-ftpd = let
SyslogFacility ftp
DontResolve yes
MaxIdleTime 15
- LDAPConfigFile /var/secrets/pure-ftpd-ldap
+ LDAPConfigFile ${config.secrets.fullPaths."pure-ftpd-ldap"}
LimitRecursion 10000 8
AnonymousCanCreateDirs no
MaxLoad 4
};
config = lib.mkIf (config.myServices.mail.enable || config.myServices.mailBackup.enable) {
secrets.keys = [
+ {
+ dest = "opendkim";
+ isDir = true;
+ user = config.services.opendkim.user;
+ group = config.services.opendkim.group;
+ permissions = "0550";
+ }
{
dest = "opendkim/eldiron.private";
user = config.services.opendkim.user;
)
config.myEnv.dns.masterZones
));
- keyPath = "${config.secrets.location}/opendkim";
+ keyPath = config.secrets.fullPaths."opendkim";
selector = "eldiron";
configFile = pkgs.writeText "opendkim.conf" ''
SubDomains yes
fi
'';
scripts = lib.attrsets.mapAttrs (n: v:
- toScript n (pkgs.callPackage (builtins.fetchGit { url = v.src.url; ref = "master"; rev = v.src.rev; }) { scriptEnv = "/var/secrets/postfix/scripts/${n}-env"; })
+ toScript n (pkgs.callPackage (builtins.fetchGit { url = v.src.url; ref = "master"; rev = v.src.rev; }) { scriptEnv = config.secrets.fullPaths."postfix/scripts/${n}-env"; })
) config.myEnv.mail.scripts // {
testmail = pkgs.writeScript "testmail" ''
#! ${pkgs.stdenv.shell}
passiveInfo = defaultPassiveInfo // { servicegroups = "webstatus-databases"; };
service_description = "Mysql replication for eldiron is up to date";
use = "local-service";
- check_command = ["check_mysql_replication" "/run/mysqld_eldiron/mysqld.sock" "/var/secrets/mysql_replication/eldiron/client"];
+ check_command = ["check_mysql_replication" "/run/mysqld_eldiron/mysqld.sock" config.secrets.fullPaths."mysql_replication/eldiron/client"];
}
{
passiveInfo = defaultPassiveInfo // { servicegroups = "webstatus-databases,webstatus-backup"; };
"check_openldap_replication"
hcfg.url
hcfg.dn
- "${config.secrets.location}/openldap_replication/eldiron/replication_password"
+ config.secrets.fullPaths."openldap_replication/eldiron/replication_password"
hcfg.base
ldapConfig
];
systemd.services.mpd.serviceConfig.RuntimeDirectory = "mpd";
services.filesWatcher.mpd = {
restart = true;
- paths = [ "/var/secrets/mpd-config" ];
+ paths = [ config.secrets.fullPaths."mpd-config" ];
};
services.mpd = {
network.listenAddress = "any";
musicDirectory = config.myEnv.mpd.folder;
extraConfig = ''
- include "/var/secrets/mpd-config"
+ include "${config.secrets.fullPaths."mpd-config"}"
audio_output {
type "null"
name "No Output"
system.activationScripts.sshd = {
deps = [ "secrets" ];
text = ''
- install -Dm400 -o nobody -g nogroup -T /var/secrets/ssh-ldap /etc/ssh/ldap_password
+ install -Dm400 -o nobody -g nogroup -T ${config.secrets.fullPaths."ssh-ldap"} /etc/ssh/ldap_password
'';
};
# ssh is strict about parent directory having correct rights, don't
{ pkgs, lib, config, name, nodes, ... }:
{
config = {
+ deployment.secrets."secret_vars.yml" = {
+ source = builtins.toString ../../nixops/secrets/vars.yml;
+ destination = config.secrets.secretsVars;
+ owner.user = "root";
+ owner.group = "root";
+ permissions = "0400";
+ };
+
networking.extraHosts = builtins.concatStringsSep "\n"
(lib.mapAttrsToList (n: v: "${v.config.hostEnv.ips.main.ip4} ${n}") nodes);
secrets.gpgKeys = [
../../nixops/public_keys/Immae.pub
];
+ secrets.secretsVars = "/run/keys/vars.yml";
services.openssh.enable = true;
services.netdata.config.health."enabled" = "no";
services.netdata.config.web.mode = "none";
users.users."${config.services.netdata.user}".extraGroups = [ "keys" ];
- environment.etc."netdata/stream.conf".source = "/var/secrets/netdata-stream.conf";
+ environment.etc."netdata/stream.conf".source = config.secrets.fullPaths."netdata-stream.conf";
secrets.keys = [
{
dest = "netdata-stream.conf";
services.netdata.config.web."allow netdata.conf from" = "fd*";
services.netdata.config.web."allow management from" = "fd*";
networking.firewall.allowedTCPPorts = [ 19999 ];
- environment.etc."netdata/stream.conf".source = "/var/secrets/netdata-stream.conf";
+ environment.etc."netdata/stream.conf".source = config.secrets.fullPaths."netdata-stream.conf";
secrets.keys = [
{
chmod go-rwx /var/lib/nixos/sponsored_users
echo "$mygroup $1 $2" >> /var/lib/nixos/sponsored_users
(${pkgs.openldap}/bin/ldapadd -c -D cn=root,dc=salle-s,dc=org \
- -y /var/secrets/ldap/sync_password 2>/dev/null >/dev/null || true) <<EOF
+ -y ${config.secrets.fullPaths."ldap/sync_password"} 2>/dev/null >/dev/null || true) <<EOF
dn: uid=$1,uid=$mygroup,ou=users,dc=salle-s,dc=org
objectClass: inetOrgPerson
cn: $1
userdel -r "$1"
sed -i -e "/^$mygroup $1/d" /var/lib/nixos/sponsored_users
${pkgs.openldap}/bin/ldapdelete -D cn=root,dc=salle-s,dc=org \
- -y /var/secrets/ldap/sync_password \
+ -y ${config.secrets.fullPaths."ldap/sync_password"} \
"uid=$1,uid=$mygroup,ou=users,dc=salle-s,dc=org"
echo "deleted"
exit 0
if [ "$1" = "$mygroup" ]; then
log "resets web password"
${pkgs.openldap}/bin/ldappasswd -D cn=root,dc=salle-s,dc=org \
- -y /var/secrets/ldap/sync_password \
+ -y ${config.secrets.fullPaths."ldap/sync_password"} \
-S "uid=$mygroup,ou=users,dc=salle-s,dc=org"
else
IFS=",";
if [ "$u" = "$1" ]; then
log "resets web password of $1"
${pkgs.openldap}/bin/ldappasswd -D cn=root,dc=salle-s,dc=org \
- -y /var/secrets/ldap/sync_password \
+ -y ${config.secrets.fullPaths."ldap/sync_password"} \
-S "uid=$1,uid=$mygroup,ou=users,dc=salle-s,dc=org"
exit 0
fi
deps = [ "secrets" "users" ];
text =
let
- com = "-D cn=root,dc=salle-s,dc=org -y /var/secrets/ldap/sync_password";
+ com = "-D cn=root,dc=salle-s,dc=org -y ${config.secrets.fullPaths."ldap/sync_password"}";
in ''
# Add users
- ${pkgs.openldap}/bin/ldapadd -c ${com} -f /var/secrets/ldap/ldaptree.ldif 2>/dev/null >/dev/null || true
+ ${pkgs.openldap}/bin/ldapadd -c ${com} -f ${config.secrets.fullPaths."ldap/ldaptree.ldif"} 2>/dev/null >/dev/null || true
# Remove obsolete users
${pkgs.openldap}/bin/ldapsearch -LLL ${com} -s one -b "ou=users,dc=salle-s,dc=org" "uid" |\
{
config = let
serverSpecificConfig = config.myEnv.serverSpecific.quatresaisons;
- phpLdapAdmin = pkgs.webapps.phpldapadmin.override { config = "/var/secrets/webapps/tools-ldap"; };
+ phpLdapAdmin = pkgs.webapps.phpldapadmin.override { config = config.secrets.fullPaths."webapps/tools-ldap"; };
in {
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_12;
by anonymous auth
by * break
'';
- rootpwFile = "${config.secrets.location}/ldap/password";
+ rootpwFile = config.secrets.fullPaths."ldap/password";
suffix = "dc=salle-s,dc=org";
rootdn = "cn=root,dc=salle-s,dc=org";
database = "hdb";
group = "wwwrun";
settings =
let
- basedir = builtins.concatStringsSep ":" [ phpLdapAdmin "/var/secrets/webapps/tools-ldap" ];
+ basedir = builtins.concatStringsSep ":" [ phpLdapAdmin config.secrets.fullPaths."webapps/tools-ldap" ];
in {
"listen.owner" = "wwwrun";
"listen.group" = "wwwrun";
dateformat=${dateFormat}
'';
}) env.taskwarrior-web);
- services.websites.env.tools.watchPaths = [ "/var/secrets/webapps/tools-taskwarrior-web" ];
+ services.websites.env.tools.watchPaths = [ config.secrets.fullPaths."webapps/tools-taskwarrior-web" ];
services.websites.env.tools.modules = [ "proxy_fcgi" "sed" ];
services.websites.env.tools.vhostConfs.task = {
certName = "eldiron";
<FilesMatch "\.php$">
SetHandler "proxy:unix:${config.services.phpfpm.pools.tasks.socket}|fcgi://localhost"
</FilesMatch>
- Include /var/secrets/webapps/tools-taskwarrior-web
+ Include ${config.secrets.fullPaths."webapps/tools-taskwarrior-web"}
</Directory>
''
''
after = [ "network.target" ];
path = [ pkgs.taskwarrior ];
- environment.TASKRC = "/var/secrets/webapps/tools-taskwarrior/${name}-taskrc";
+ environment.TASKRC = config.secrets.fullPaths."webapps/tools-taskwarrior/${name}-taskrc";
environment.BUNDLE_PATH = "${taskwarrior-web.gems}/${taskwarrior-web.gems.ruby.gemPath}";
environment.BUNDLE_GEMFILE = "${taskwarrior-web.gems.confFiles}/Gemfile";
environment.LC_ALL = "fr_FR.UTF-8";
-{ environment ? "prod"
-, varDir ? "/var/lib/connexionswing_${environment}"
-, secretsPath ? "/var/secrets/webapps/${environment}-connexionswing"
+{ environment, varDir, secretsPath
, composerEnv, fetchurl, fetchgit, sources }:
let
app = composerEnv.buildPackage (
LDAPOpCacheTTL 600
</IfModule>
- Include /var/secrets/apache-ldap
+ Include ${config.secrets.fullPaths."apache-ldap"}
'';
};
global = {
};
};
- services.filesWatcher.httpdProd.paths = [ "/var/secrets/apache-ldap" ];
- services.filesWatcher.httpdInte.paths = [ "/var/secrets/apache-ldap" ];
- services.filesWatcher.httpdTools.paths = [ "/var/secrets/apache-ldap" ];
+ services.filesWatcher.httpdProd.paths = [ config.secrets.fullPaths."apache-ldap" ];
+ services.filesWatcher.httpdInte.paths = [ config.secrets.fullPaths."apache-ldap" ];
+ services.filesWatcher.httpdTools.paths = [ config.secrets.fullPaths."apache-ldap" ];
services.websites.env.production = {
enable = true;
-{ environment ? "prod"
-, varDir ? "/var/lib/tellesflorian_${environment}"
-, secretsPath ? "/var/secrets/webapps/${environment}-tellesflorian"
+{ environment, varDir, secretsPath
, composerEnv, fetchurl, sources }:
let
app = composerEnv.buildPackage (
exec ${pkgs.webapps.surfer}/bin/surfer-server ${varDir}
'';
serviceConfig = {
- EnvironmentFile = "/var/secrets/webapps/surfer";
+ EnvironmentFile = config.secrets.fullPaths."webapps/surfer";
User = "wwwrun";
Group = "wwwrun";
StateDirectory = "surfer";
-{ environment ? "prod"
-, varDir ? "/var/lib/ludivinecassal_${environment}"
-, secretsPath ? "/var/secrets/webapps/${environment}-ludivinecassal"
+{ environment, varDir, secretsPath
, composerEnv, fetchurl, fetchgit, imagemagick, sass, ruby, sources }:
let
app = composerEnv.buildPackage (
-{ environment ? "prod"
-, varDir ? "/var/lib/piedsjaloux_${environment}"
-, secretsPath ? "/var/secrets/webapps/${environment}-piedsjaloux"
+{ environment, varDir, secretsPath
, composerEnv, fetchurl, fetchgit, sources }:
let
app = composerEnv.buildPackage (
${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList (n: v:
"install -D -m 0644 -o wwwrun -g wwwrun -T ${v} ${varDir}/config/${n}.json"
) confs)}
- #install -D -m 0600 -o wwwrun -g wwwrun -T /var/secrets/webapps/tools-nextcloud ${varDir}/config/config.php
+ #install -D -m 0600 -o wwwrun -g wwwrun -T ${config.secrets.fullPaths."webapps/tools-nextcloud"} ${varDir}/config/config.php
'';
};
# FIXME: add a warning when config.php changes
-{ stdenv, fetchurl, gettext, writeText, env, awl, davical }:
+{ stdenv, fetchurl, gettext, writeText, env, awl, davical, config }:
rec {
activationScript = {
deps = [ "httpd" ];
include('drivers_ldap.php');
'';
}];
- webapp = davical.override { davical_config = "/var/secrets/webapps/dav-davical"; };
+ webapp = davical.override { davical_config = config.secrets.fullPaths."webapps/dav-davical"; };
webRoot = "${webapp}/htdocs";
apache = rec {
user = "wwwrun";
};
phpFpm = rec {
serviceDeps = [ "postgresql.service" "openldap.service" ];
- basedir = builtins.concatStringsSep ":" [ webapp "/var/secrets/webapps/dav-davical" awl ];
+ basedir = builtins.concatStringsSep ":" [ webapp config.secrets.fullPaths."webapps/dav-davical" awl ];
pool = {
"listen.owner" = apache.user;
"listen.group" = apache.group;
davical = pkgs.callPackage ./davical.nix {
env = config.myEnv.tools.davical;
inherit (pkgs.webapps) davical awl;
+ inherit config;
};
cfg = config.myServices.websites.tools.dav;
users.users.diaspora.extraGroups = [ "keys" ];
secrets.keys = [
+ {
+ dest = "webapps/diaspora";
+ isDir = true;
+ user = "diaspora";
+ group = "diaspora";
+ permissions = "0500";
+ }
{
dest = "webapps/diaspora/diaspora.yml";
user = "diaspora";
package = pkgs.webapps.diaspora.override { ldap = true; };
dataDir = "/var/lib/diaspora_immae";
adminEmail = "diaspora@tools.immae.eu";
- configDir = "/var/secrets/webapps/diaspora";
+ configDir = config.secrets.fullPaths."webapps/diaspora";
};
services.filesWatcher.diaspora = {
p.ep_timesliderdiff
]);
modules = [];
- sessionKeyFile = "/var/secrets/webapps/tools-etherpad-sessionkey";
- apiKeyFile = "/var/secrets/webapps/tools-etherpad-apikey";
- configFile = "/var/secrets/webapps/tools-etherpad";
+ sessionKeyFile = config.secrets.fullPaths."webapps/tools-etherpad-sessionkey";
+ apiKeyFile = config.secrets.fullPaths."webapps/tools-etherpad-apikey";
+ configFile = config.secrets.fullPaths."webapps/tools-etherpad";
};
systemd.services.etherpad-lite.serviceConfig.SupplementaryGroups = "keys";
mantisbt = pkgs.callPackage ./mantisbt.nix {
inherit (pkgs.webapps) mantisbt_2 mantisbt_2-plugins;
env = config.myEnv.tools.mantisbt;
+ inherit config;
};
gitweb = pkgs.callPackage ./gitweb.nix {
gitoliteDir = config.myServices.gitolite.gitoliteDir;
-{ env, mantisbt_2, mantisbt_2-plugins }:
+{ env, mantisbt_2, mantisbt_2-plugins, config }:
rec {
activationScript = {
deps = [ "httpd" ];
$g_ldap_organization = '${env.ldap.filter}';
'';
}];
- webRoot = (mantisbt_2.override { mantis_config = "/var/secrets/webapps/tools-mantisbt"; }).withPlugins (p: [p.slack p.source-integration]);
+ webRoot = (mantisbt_2.override { mantis_config = config.secrets.fullPaths."webapps/tools-mantisbt"; }).withPlugins (p: [p.slack p.source-integration]);
apache = rec {
user = "wwwrun";
group = "wwwrun";
phpFpm = rec {
serviceDeps = [ "postgresql.service" "openldap.service" ];
basedir = builtins.concatStringsSep ":" (
- [ webRoot "/var/secrets/webapps/tools-mantisbt" ]
+ [ webRoot config.secrets.fullPaths."webapps/tools-mantisbt" ]
++ webRoot.plugins);
pool = {
"listen.owner" = apache.user;
roundcubemail = pkgs.callPackage ./roundcubemail.nix {
inherit (pkgs.webapps) roundcubemail;
env = config.myEnv.tools.roundcubemail;
+ inherit config;
};
rainloop = pkgs.callPackage ./rainloop.nix {
rainloop = pkgs.rainloop-community;
-{ env, roundcubemail, apacheHttpd }:
+{ env, roundcubemail, apacheHttpd, config }:
rec {
varDir = "/var/lib/roundcubemail";
activationScript = {
$config['mime_types'] = '${apacheHttpd}/conf/mime.types';
'';
}];
- webRoot = (roundcubemail.override { roundcube_config = "/var/secrets/webapps/tools-roundcube"; }).withPlugins (p: [ p.automatic_addressbook p.carddav p.contextmenu p.contextmenu_folder p.html5_notifier p.ident_switch p.message_highlight p.thunderbird_labels ]);
+ webRoot = (roundcubemail.override { roundcube_config = config.secrets.fullPaths."webapps/tools-roundcube"; }).withPlugins (p: [ p.automatic_addressbook p.carddav p.contextmenu p.contextmenu_folder p.html5_notifier p.ident_switch p.message_highlight p.thunderbird_labels ]);
apache = rec {
user = "wwwrun";
group = "wwwrun";
phpFpm = rec {
serviceDeps = [ "postgresql.service" ];
basedir = builtins.concatStringsSep ":" (
- [ webRoot "/var/secrets/webapps/tools-roundcube" varDir ]
+ [ webRoot config.secrets.fullPaths."webapps/tools-roundcube" varDir ]
++ webRoot.plugins
++ webRoot.skins);
pool = {
}];
services.mastodon = {
enable = true;
- configFile = "/var/secrets/webapps/tools-mastodon";
+ configFile = config.secrets.fullPaths."webapps/tools-mastodon";
socketsPrefix = "live_immae";
dataDir = "/var/lib/mastodon_immae";
};
services.mediagoblin = {
enable = true;
package = pkgs.webapps.mediagoblin.withPlugins (p: [p.basicsearch]);
- configFile = "/var/secrets/webapps/tools-mediagoblin";
+ configFile = config.secrets.fullPaths."webapps/tools-mediagoblin";
};
services.filesWatcher.mediagoblin-web = {
restart = true;
};
services.peertube = {
enable = true;
- configFile = "/var/secrets/webapps/tools-peertube";
+ configFile = config.secrets.fullPaths."webapps/tools-peertube";
};
users.users.peertube.extraGroups = [ "keys" ];
"pm.min_spare_servers" = "1";
"pm.max_spare_servers" = "10";
- "php_admin_value[open_basedir]" = "${package}:/tmp:/var/secrets/status_engine_ui";
+ "php_admin_value[open_basedir]" = "${package}:/tmp:${config.secrets.fullPaths."status_engine_ui"}";
};
phpPackage = pkgs.php74;
};
inherit (pkgs.webapps) ttrss ttrss-plugins;
env = config.myEnv.tools.ttrss;
php = pkgs.php72;
+ inherit config;
};
kanboard = pkgs.callPackage ./kanboard.nix {
+ inherit config;
env = config.myEnv.tools.kanboard;
};
wallabag = pkgs.callPackage ./wallabag.nix {
};
};
env = config.myEnv.tools.wallabag;
+ inherit config;
};
yourls = pkgs.callPackage ./yourls.nix {
inherit (pkgs.webapps) yourls yourls-plugins;
env = config.myEnv.tools.yourls;
+ inherit config;
};
rompr = pkgs.callPackage ./rompr.nix {
inherit (pkgs.webapps) rompr;
};
shaarli = pkgs.callPackage ./shaarli.nix {
env = config.myEnv.tools.shaarli;
+ inherit config;
};
dokuwiki = pkgs.callPackage ./dokuwiki.nix {
inherit (pkgs.webapps) dokuwiki dokuwiki-plugins;
ldap = pkgs.callPackage ./ldap.nix {
inherit (pkgs.webapps) phpldapadmin;
env = config.myEnv.tools.phpldapadmin;
+ inherit config;
};
grocy = pkgs.callPackage ./grocy.nix {
grocy = pkgs.webapps.grocy.override { composerEnv = pkgs.composerEnv.override { php = pkgs.php72; }; };
};
dmarc-reports = pkgs.callPackage ./dmarc_reports.nix {
env = config.myEnv.tools.dmarc_reports;
+ inherit config;
};
csp-reports = pkgs.callPackage ./csp_reports.nix {
env = config.myEnv.tools.csp_reports;
Require all granted
</Directory>
- Alias /webhooks ${config.secrets.location}/webapps/webhooks
- <Directory "${config.secrets.location}/webapps/webhooks">
+ Alias /webhooks ${config.secrets.fullPaths."webapps/webhooks"}
+ <Directory "${config.secrets.fullPaths."webapps/webhooks"}">
Options -Indexes
Require all granted
AllowOverride None
description = "Standalone MPD Web GUI written in C";
wantedBy = [ "multi-user.target" ];
script = ''
- export MPD_PASSWORD=$(cat /var/secrets/mpd)
+ export MPD_PASSWORD=$(cat ${config.secrets.fullPaths."mpd"})
${pkgs.ympd}/bin/ympd --host ${ympd.config.host} --port ${toString ympd.config.port} --webport ${ympd.config.webPort} --user nobody
'';
};
services.filesWatcher.ympd = {
restart = true;
- paths = [ "/var/secrets/mpd" ];
+ paths = [ config.secrets.fullPaths."mpd" ];
};
services.phpfpm.pools = {
"php_value[session.name]" = "ToolsPHPSESSID";
"php_admin_value[open_basedir]" = builtins.concatStringsSep ":" [
"/run/wrappers/bin/sendmail" landing "/tmp"
- "${config.secrets.location}/webapps/webhooks"
+ config.secrets.fullPaths."webapps/webhooks"
];
- "include" = "${config.secrets.location}/webapps/tools-csp-reports.conf";
+ "include" = config.secrets.fullPaths."webapps/tools-csp-reports.conf";
};
phpEnv = {
CONTACT_EMAIL = config.myEnv.tools.contact;
};
services.websites.env.tools.watchPaths = [
- "/var/secrets/webapps/tools-shaarli"
+ config.secrets.fullPaths."webapps/tools-shaarli"
];
services.filesWatcher.phpfpm-wallabag = {
restart = true;
- paths = [ "/var/secrets/webapps/tools-wallabag" ];
+ paths = [ config.secrets.fullPaths."webapps/tools-wallabag" ];
};
};
-{ env }:
+{ env, config }:
rec {
keys = [{
dest = "webapps/tools-dmarc-reports.php";
};
phpFpm = rec {
basedir = builtins.concatStringsSep ":"
- [ webRoot "/var/secrets/webapps/tools-dmarc-reports.php" ];
+ [ webRoot config.secrets.fullPaths."webapps/tools-dmarc-reports.php" ];
pool = {
"listen.owner" = apache.user;
"listen.group" = apache.group;
"php_admin_value[open_basedir]" = "${basedir}:/tmp";
};
phpEnv = {
- SECRETS_FILE = "/var/secrets/webapps/tools-dmarc-reports.php";
+ SECRETS_FILE = config.secrets.fullPaths."webapps/tools-dmarc-reports.php";
};
};
}
-{ env, kanboard }:
+{ env, kanboard, config }:
rec {
backups = {
rootDir = varDir;
?>
'';
}];
- webRoot = kanboard { kanboard_config = "/var/secrets/webapps/tools-kanboard"; };
+ webRoot = kanboard { kanboard_config = config.secrets.fullPaths."webapps/tools-kanboard"; };
apache = rec {
user = "wwwrun";
group = "wwwrun";
};
phpFpm = rec {
serviceDeps = [ "postgresql.service" "openldap.service" ];
- basedir = builtins.concatStringsSep ":" [ webRoot varDir "/var/secrets/webapps/tools-kanboard" ];
+ basedir = builtins.concatStringsSep ":" [ webRoot varDir config.secrets.fullPaths."webapps/tools-kanboard" ];
pool = {
"listen.owner" = apache.user;
"listen.group" = apache.group;
-{ lib, php, env, writeText, phpldapadmin }:
+{ lib, php, env, writeText, phpldapadmin, config }:
rec {
activationScript = {
deps = [ "httpd" ];
$servers->setValue('login','fallback_dn',true);
'';
}];
- webRoot = phpldapadmin.override { config = "/var/secrets/webapps/tools-ldap"; };
+ webRoot = phpldapadmin.override { config = config.secrets.fullPaths."webapps/tools-ldap"; };
apache = rec {
user = "wwwrun";
group = "wwwrun";
};
phpFpm = rec {
serviceDeps = [ "openldap.service" ];
- basedir = builtins.concatStringsSep ":" [ webRoot "/var/secrets/webapps/tools-ldap" ];
+ basedir = builtins.concatStringsSep ":" [ webRoot config.secrets.fullPaths."webapps/tools-ldap" ];
pool = {
"listen.owner" = apache.user;
"listen.group" = apache.group;
-{ lib, env, stdenv, fetchurl, shaarli }:
+{ lib, env, stdenv, fetchurl, shaarli, config }:
let
varDir = "/var/lib/shaarli";
in rec {
vhostConf = socket: ''
Alias /Shaarli "${root}"
- Include /var/secrets/webapps/tools-shaarli
+ Include ${config.secrets.fullPaths."webapps/tools-shaarli"}
<Location /Shaarli>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
-{ php, env, ttrss, ttrss-plugins }:
+{ php, env, ttrss, ttrss-plugins, config }:
rec {
backups = {
rootDir = varDir;
define('LDAP_AUTH_DEBUG', FALSE);
'';
}];
- webRoot = (ttrss.override { ttrss_config = "/var/secrets/webapps/tools-ttrss"; }).withPlugins (p: [
+ webRoot = (ttrss.override { ttrss_config = config.secrets.fullPaths."webapps/tools-ttrss"; }).withPlugins (p: [
p.auth_ldap p.ff_instagram p.tumblr_gdpr_ua
(p.af_feedmod.override { patched = true; })
(p.feediron.override { patched = true; })
phpFpm = rec {
serviceDeps = [ "postgresql.service" "openldap.service" ];
basedir = builtins.concatStringsSep ":" (
- [ webRoot "/var/secrets/webapps/tools-ttrss" varDir ]
+ [ webRoot config.secrets.fullPaths."webapps/tools-ttrss" varDir ]
++ webRoot.plugins);
pool = {
"listen.owner" = apache.user;
-{ env, wallabag, mylibs }:
+{ env, wallabag, mylibs, config }:
rec {
backups = {
rootDir = varDir;
arguments: ['/run/wrappers/bin/sendmail -bs']
'';
}];
- webappDir = wallabag.override { ldap = true; wallabag_config = "/var/secrets/webapps/tools-wallabag"; };
+ webappDir = wallabag.override { ldap = true; wallabag_config = config.secrets.fullPaths."webapps/tools-wallabag"; };
activationScript = ''
install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \
${varDir}/var ${varDir}/data/db ${varDir}/assets/images
/run/wrappers/bin/sudo -u wwwrun ./bin/console --env=prod doctrine:migrations:migrate --no-interaction
popd > /dev/null
echo -n "${webappDir}" > ${varDir}/currentWebappDir
- sha512sum /var/secrets/webapps/tools-wallabag > ${varDir}/currentKey
+ sha512sum ${config.secrets.fullPaths."webapps/tools-wallabag"} > ${varDir}/currentKey
fi
'';
serviceDeps = [ "postgresql.service" "openldap.service" ];
- basedir = builtins.concatStringsSep ":" [ webappDir "/var/secrets/webapps/tools-wallabag" varDir ];
+ basedir = builtins.concatStringsSep ":" [ webappDir config.secrets.fullPaths."webapps/tools-wallabag" varDir ];
pool = {
"listen.owner" = apache.user;
"listen.group" = apache.group;
group = "wwwrun";
permissions = "0400";
text = v;
- }) env;
+ }) env ++ [{
+ dest = "webapps/webhooks";
+ isDir = true;
+ user = "wwwrun";
+ group = "wwwrun";
+ permissions = "0500";
+ }];
}
-{ env, yourls, yourls-plugins }:
+{ env, yourls, yourls-plugins, config }:
rec {
activationScript = {
deps = [ "httpd" ];
define( 'LDAPAUTH_USERCACHE_TYPE', 0);
'';
}];
- webRoot = (yourls.override { yourls_config = "/var/secrets/webapps/tools-yourls"; }).withPlugins (p: [p.ldap]);
+ webRoot = (yourls.override { yourls_config = config.secrets.fullPaths."webapps/tools-yourls"; }).withPlugins (p: [p.ldap]);
apache = rec {
user = "wwwrun";
group = "wwwrun";
phpFpm = rec {
serviceDeps = [ "mysql.service" "openldap.service" ];
basedir = builtins.concatStringsSep ":" (
- [ webRoot "/var/secrets/webapps/tools-yourls" ]
+ [ webRoot config.secrets.fullPaths."webapps/tools-yourls" ]
++ webRoot.plugins);
pool = {
"listen.owner" = apache.user;
+++ /dev/null
-{ lib, pkgs, config, ... }:
-{
- options.secrets = {
- keys = lib.mkOption {
- type = lib.types.listOf lib.types.unspecified;
- default = [];
- description = "Keys to upload to server";
- };
- gpgKeys = lib.mkOption {
- type = lib.types.listOf lib.types.path;
- default = [];
- description = "GPG public keys files to encrypt to";
- };
- ageKeys = lib.mkOption {
- type = lib.types.listOf lib.types.str;
- default = [];
- description = "AGE keys to encrypt to";
- };
- decryptKey = lib.mkOption {
- type = lib.types.str;
- default = "/etc/ssh/ssh_host_ed25519_key";
- description = "ed25519 key used to decrypt with AGE";
- };
- location = lib.mkOption {
- type = lib.types.path;
- default = "/var/secrets";
- description = "Location where to put the keys";
- };
- secretsVars = lib.mkOption {
- type = lib.types.path;
- default = "/run/keys/vars.yml";
- description = "Location where the secrets variables are defined, to be used to fill the templates in secrets";
- };
- deleteSecretsVars = lib.mkOption {
- type = lib.types.bool;
- default = false;
- description = "Delete secrets file after deployment";
- };
- # Read-only variables
- fullPaths = lib.mkOption {
- type = lib.types.attrsOf lib.types.path;
- default = builtins.listToAttrs
- (map (v: { name = v.dest; value = "${config.secrets.location}/${v.dest}"; }) config.secrets.keys);
- readOnly = true;
- description = "set of full paths to secrets";
- };
- };
-
- config = let
- location = config.secrets.location;
- keys = config.secrets.keys;
- empty = pkgs.runCommand "empty" { preferLocalBuild = true; } "mkdir -p $out && touch $out/done";
- fpath = v: "secrets/${v.dest}${lib.optionalString (v.isTemplated or true) ".gucci.tpl"}";
- dumpKey = v: ''
- mkdir -p secrets/$(dirname ${v.dest})
- echo -n ${lib.strings.escapeShellArg v.text} > ${fpath v}
- cat >> mods <<EOF
- ${v.user or "root"} ${v.group or "root"} ${v.permissions or "0600"} ${fpath v}
- EOF
- '';
- secrets = pkgs.runCommand "secrets.tar.enc" {
- buildInputs = [ pkgs.gnupg pkgs.sops ];
- } ''
- touch mods
- tar --format=ustar --mtime='1970-01-01' -P --transform="s@${empty}@secrets@" -cf $out ${empty}/done
- ${builtins.concatStringsSep "\n" (map dumpKey keys)}
- cat mods | while read u g p k; do
- tar --format=ustar --mtime='1970-01-01' --owner="$u" --group="$g" --mode="$p" --append -f $out "$k"
- done
- export HOME=$(pwd)
- fingerprints=
- for key in ${builtins.concatStringsSep " " config.secrets.gpgKeys}; do
- gpg --import $key 2>/dev/null
- fingerprints=$fingerprints,$(cat $key | gpg --with-colons --import-options show-only --import 2>/dev/null | grep ^fpr | cut -d: -f10 | head -n1)
- done
-
- sops --age ${builtins.concatStringsSep "," config.secrets.ageKeys} --pgp ''${fingerprints#,} --input-type binary -i -e $out 2>/dev/null
- '';
- in lib.mkIf (builtins.length keys > 0) {
- system.activationScripts.secrets = {
- deps = [ "users" "wrappers" ];
- text = ''
- install -m0750 -o root -g keys -d ${location}
- TMP=$(${pkgs.coreutils}/bin/mktemp -d)
- TMPWORK=$(${pkgs.coreutils}/bin/mktemp -d)
- chmod go-rwx $TMPWORK
- if [ -n "$TMP" -a -n "$TMPWORK" ]; then
- install -m0750 -o root -g keys -d $TMP
- ${pkgs.ssh-to-age}/bin/ssh-to-age -private-key -i ${config.secrets.decryptKey} -o $TMPWORK/keys.txt
- SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${secrets} | ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -x
- if [ -f ${config.secrets.secretsVars} ]; then
- SOPS_AGE_KEY_FILE=$TMPWORK/keys.txt ${pkgs.sops}/bin/sops -d ${config.secrets.secretsVars} > $TMPWORK/vars.yml
- fi
- if [ -f $TMPWORK/vars.yml ]; then
- find $TMP -name "*.gucci.tpl" -exec \
- /bin/sh -c 'f="{}"; ${pkgs.gucci}/bin/gucci -f '$TMPWORK'/vars.yml "$f" > "''${f%.gucci.tpl}"; touch --reference "$f" ''${f%.gucci.tpl} ; chmod --reference="$f" ''${f%.gucci.tpl} ; chown --reference="$f" ''${f%.gucci.tpl}' \;
- fi
- find $TMP -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
- ${pkgs.rsync}/bin/rsync --exclude="*.gucci.tpl" -O -c -av --delete $TMP/ ${location}
- rm -rf $TMP $TMPWORK ${lib.optionalString config.secrets.deleteSecretsVars config.secrets.secretsVars}
- fi
- '';
- };
-
- deployment.secrets."secret_vars.yml" = {
- source = builtins.toString ../nixops/secrets/vars.yml;
- destination = config.secrets.secretsVars;
- owner.user = "root";
- owner.group = "root";
- permissions = "0400";
- };
- };
-}
-Subproject commit a1e6498139cc51a3d68e5655480542e6ccd3a45f
+Subproject commit 0b9f489a7e2e01208d4285c26348b4fa09607e1b