
This adds the default claim policy, which can be used to provide the past behaviour for this. Services that require this still needs to be identified.
263 lines
9.2 KiB
Nix
263 lines
9.2 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
svc_domain = "nextcloud.${config.mine.shared.settings.domain}";
|
|
|
|
default_storage_quota = "1mb";
|
|
|
|
# place data into own zfs dataset
|
|
stateDir = config.mine.zfsMounts."rpool/safe/svcs/nextcloud";
|
|
|
|
# helper variables
|
|
nextcloud_user = config.users.users.nextcloud.name;
|
|
nextcloud_group = config.users.groups.nextcloud.name;
|
|
AUTHELIA_AUTH_NAME = "nextcloud";
|
|
|
|
# occ bin
|
|
occ = config.services.nextcloud.occ + "/bin/nextcloud-occ";
|
|
|
|
# script for setting up ldap for nextcloud
|
|
# - ensure user_ldap app is intalled
|
|
# - ensure user_ldap app is enabled
|
|
# - delete all ldap configurations
|
|
# - add new configuration with our settings
|
|
nextcloudSetupLdap = let
|
|
ldap_settings = {
|
|
ldapHost = "localhost";
|
|
ldapPort = 3890;
|
|
ldapAgentName = config.mine.shared.settings.ldap.bind_dn;
|
|
# ldapAgentPassword = "<insert-from-secret-env>";
|
|
|
|
ldapBase = config.mine.shared.settings.ldap.dc;
|
|
ldapBaseUsers = config.mine.shared.settings.ldap.dc;
|
|
ldapBaseGroups = config.mine.shared.settings.ldap.dc;
|
|
ldapLoginFilter = config.mine.shared.lib.ldap.mkFilter (lconfig: llib:
|
|
llib.mkAnd [
|
|
(llib.mkOC lconfig.oc.person)
|
|
(llib.mkSearch lconfig.attr.uid "%uid")
|
|
]
|
|
);
|
|
|
|
# EDIT: nextcloud_users group, contains the users who can login to Nextcloud
|
|
ldapUserFilter = config.mine.shared.lib.ldap.mkFilter (lconfig: llib:
|
|
llib.mkAnd [
|
|
(llib.mkOC lconfig.oc.person)
|
|
(llib.mkGroup lconfig.groups.member)
|
|
]
|
|
);
|
|
ldapUserFilterObjectclass = config.mine.shared.settings.ldap.oc.person;
|
|
ldapGroupFilter = config.mine.shared.lib.ldap.mkFilter (lconfig: llib:
|
|
llib.mkAnd [
|
|
(llib.mkOC lconfig.oc.groupOfUniqueNames)
|
|
(llib.mkOr [ "cn=${lconfig.groups.nextcloud_admin}" "cn=${lconfig.groups.member}"])
|
|
]
|
|
);
|
|
ldapGroupFilterGroups = "admin;user";
|
|
ldapGroupFilterObjectclass = config.mine.shared.settings.ldap.oc.groupOfUniqueNames;
|
|
ldapGroupMemberAssocAttr = "uniqueMember";
|
|
ldapEmailAttribute = config.mine.shared.settings.ldap.attr.email;
|
|
ldapUserFilterMode = 1;
|
|
ldapExpertUsernameAttr = config.mine.shared.settings.ldap.attr.uid;
|
|
ldapConfigurationActive = 1;
|
|
ldapQuotaDefault = 1;
|
|
ldapQuotaAttribute = config.mine.shared.settings.ldap.attr.nextcloudquota;
|
|
};
|
|
ldap_commands = lib.mapAttrsToList (n: v: "${occ} ldap:set-config $NEW_CONFIG_ID ${n} '${builtins.toString v}'") ldap_settings;
|
|
in pkgs.writeShellScript "nextcloud-add-ldap.sh" ''
|
|
# enable ldap service, remove config and create new empty one
|
|
${occ} app:install user_ldap
|
|
${occ} app:enable user_ldap
|
|
|
|
# create new empty config
|
|
NEW_CONFIG_ID="$(${occ} ldap:create-empty-config -p)"
|
|
|
|
# setup ldap password
|
|
BIND_USERPASS="$(cat $CREDENTIALS_DIRECTORY/lldap-bind-user-pass)"
|
|
${occ} ldap:set-config $NEW_CONFIG_ID ldapAgentPassword "$BIND_USERPASS"
|
|
# set settings
|
|
${builtins.concatStringsSep "\n" ldap_commands}
|
|
|
|
# delete all other configurations
|
|
CONFIGS=$(${occ} ldap:show-config --output=json | ${pkgs.jq}/bin/jq -r '. | keys | .[]')
|
|
echo "$CONFIGS" | while read CONFIG_ID; do
|
|
if [[ "$NEW_CONFIG_ID" != "$CONFIG_ID" ]]; then
|
|
${occ} ldap:delete-config "$CONFIG_ID"
|
|
fi
|
|
done
|
|
|
|
# promote ldap admin group to admins
|
|
${occ} ldap:promote-group ${config.mine.shared.settings.ldap.groups.nextcloud_admin} --yes -n
|
|
'';
|
|
|
|
# script for resetting nextcloud admin password on each startup
|
|
nextcloudSetupAdmin = pkgs.writeShellScript "nextcloud-setup-admin.sh" ''
|
|
# reset admin password on each start
|
|
export OC_PASS="$(cat $CREDENTIALS_DIRECTORY/nextcloud-admin-pass)"
|
|
${occ} user:resetpassword --password-from-env -- ${config.services.nextcloud.config.adminuser}
|
|
'';
|
|
|
|
# script for setting encryption for nextcloud
|
|
# - ensure encryption app is intalled
|
|
# - ensure encryption app is enabled
|
|
# - enable encryption
|
|
# - ensure all files are encrypted
|
|
nextcloudSetupEncryption = pkgs.writeShellScript "nextcloud-setup-encryption.sh" ''
|
|
# enable encryption
|
|
${occ} app:install encryption
|
|
${occ} app:enable encryption
|
|
${occ} encryption:enable
|
|
|
|
echo "Ensuring everything is encrypted!"
|
|
if [[ ! -e ${stateDir}/.encrypt-setup ]]; then
|
|
echo "Running encrypt-all!"
|
|
printf "y\n" | ${occ} encryption:encrypt-all
|
|
touch ${stateDir}/.encrypt-setup
|
|
else
|
|
echo "Encrypt all has already ran, not running again."
|
|
fi
|
|
'';
|
|
|
|
# script for setting up tho storage quota
|
|
# possible to set based on groups
|
|
# https://github.com/nextcloud/groupquota
|
|
nextcloudSetupStorageQuota = pkgs.writeShellScript "nextcloud-setup-storage-quota.sh" ''
|
|
# set default quota
|
|
${occ} config:app:set files default_quota --value '${default_storage_quota}'
|
|
'';
|
|
in {
|
|
services.nextcloud = {
|
|
enable = true;
|
|
package = pkgs.nextcloud30;
|
|
datadir = stateDir;
|
|
|
|
config.adminpassFile = config.age.secrets.nextcloud-admin-pass.path;
|
|
|
|
hostName = svc_domain;
|
|
https = true;
|
|
|
|
configureRedis = true;
|
|
|
|
# apps
|
|
extraAppsEnable = true;
|
|
extraApps = {
|
|
inherit (config.services.nextcloud.package.packages.apps) contacts calendar tasks gpoddersync;
|
|
oidc_login = let
|
|
version = "3.2.2";
|
|
# TODO(eyJhb): add to niv
|
|
in pkgs.fetchNextcloudApp {
|
|
sha256 = "sha256-RLYquOE83xquzv+s38bahOixQ+y4UI6OxP9HfO26faI=";
|
|
url = "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v${version}/oidc_login.tar.gz";
|
|
license = "agpl3Only";
|
|
};
|
|
};
|
|
|
|
# secrets
|
|
secretFile = config.age.secrets.nextcloud-secrets.path;
|
|
|
|
# use postgresql for database
|
|
# createLocally will enable postgresql, add database and user
|
|
database.createLocally = true;
|
|
config.dbtype = "pgsql";
|
|
|
|
# settings
|
|
settings = rec {
|
|
# open connect/oidc
|
|
oidc_login_provider_url = "https://${config.mine.shared.settings.authelia.domain}";
|
|
oidc_login_client_id = AUTHELIA_AUTH_NAME;
|
|
# oidc_login_client_secret = "<set-using-secrets-file>";
|
|
oidc_login_proxy_ldap = true; # SUPER IMPORTANT!
|
|
oidc_login_auto_redirect = true;
|
|
oidc_login_button_text = "Log in with Authelia";
|
|
oidc_login_use_id_token = true;
|
|
oidc_login_attributes = {
|
|
id = "preferred_username";
|
|
ldap_uid = "preferred_username";
|
|
name = "name";
|
|
mail = "email";
|
|
groups = "groups";
|
|
};
|
|
oidc_login_scope = "openid profile email groups";
|
|
oidc_login_code_challenge_method = "S256";
|
|
|
|
# mail
|
|
mail_from_address = "nextcloud";
|
|
mail_smtpmode = "smtp";
|
|
mail_sendmailmode = "smtp";
|
|
mail_domain = "${config.mine.shared.settings.domain}";
|
|
mail_smtphost = "${config.mine.shared.settings.mail.domain_smtp}";
|
|
mail_smtpport = config.mine.shared.settings.mail.ports.submissions;
|
|
mail_smtpsecure = "ssl";
|
|
mail_smtpname = mail_from_address;
|
|
# mail_smtppassword = "defined-in-the-secrets-file-and-in-a-separate-file-for-lldap";
|
|
};
|
|
};
|
|
|
|
# setup lldap user for nextcloud that can send emails
|
|
services.lldap.provision.users = config.mine.shared.lib.ldap.mkScope (lconfig: llib: {
|
|
nextcloud = llib.mkProvisionUserSystem "nextcloud" config.age.secrets.nextcloud-smtp-pass.path;
|
|
});
|
|
|
|
systemd.services.nextcloud-setup = {
|
|
# runs this after all the main nextcloud-setup stuff
|
|
script = lib.mkAfter ''
|
|
${nextcloudSetupLdap}
|
|
${nextcloudSetupAdmin}
|
|
${nextcloudSetupEncryption}
|
|
${nextcloudSetupStorageQuota}
|
|
'';
|
|
|
|
# setup credentials for service
|
|
serviceConfig.LoadCredential = [
|
|
"lldap-bind-user-pass:${config.age.secrets.lldap-bind-user-pass.path}"
|
|
"nextcloud-admin-pass:${config.age.secrets.nextcloud-admin-pass.path}"
|
|
];
|
|
|
|
# do not run on each nixos rebuild switch!!!!!!!!!!!
|
|
serviceConfig.RemainAfterExit = true;
|
|
};
|
|
|
|
# setup authelia for nextcloud
|
|
services.authelia.instances.main.settings.identity_providers.oidc.clients = [{
|
|
client_id = AUTHELIA_AUTH_NAME;
|
|
client_name = "Nextcloud";
|
|
client_secret = "$pbkdf2-sha512$310000$kLNQ/1A.uasSN4g8q94jUQ$8OKNUNNumHCh8dVG5/QWys7u.y1guqFXlrL.bMm7/HKTsWhpib/W.8qlU6VU7V1Be/h14Y.fJi3RLvbkEdo2kA";
|
|
consent_mode = "implicit";
|
|
redirect_uris = [ "https://${svc_domain}/apps/oidc_login/oidc" ];
|
|
claims_policy = "default";
|
|
scopes = [
|
|
"openid"
|
|
"profile"
|
|
"email"
|
|
"groups"
|
|
];
|
|
}];
|
|
|
|
services.nginx.virtualHosts."${svc_domain}" = {
|
|
forceSSL = true;
|
|
enableACME = true;
|
|
};
|
|
|
|
# ensure that nextcloud can access stateDir
|
|
systemd.tmpfiles.rules = [
|
|
"Z ${stateDir} 6770 ${nextcloud_user} ${nextcloud_group} -"
|
|
];
|
|
|
|
age.secrets = {
|
|
nextcloud-admin-pass.owner = nextcloud_user;
|
|
nextcloud-secrets.owner = nextcloud_user;
|
|
};
|
|
|
|
mine.shared.meta.nextcloud = {
|
|
name = "Nextcloud";
|
|
description = "We host our own Nextcloud for having a central place for personal files, etc. (all files are encrypted using the standard encryption module)! Login using your credentials.";
|
|
url = "https://${svc_domain}";
|
|
|
|
package = let
|
|
pkg = config.services.nextcloud.package;
|
|
in {
|
|
name = pkg.pname;
|
|
version = pkg.version;
|
|
meta = pkg.meta;
|
|
};
|
|
};
|
|
}
|