gerd.nextcloud: added nextcloud! ldap, authelia, encryption!
This commit is contained in:
parent
7de4bb578a
commit
239cb6f9b2
6 changed files with 219 additions and 0 deletions
|
@ -14,6 +14,7 @@
|
|||
./gerd/services/murmur.nix
|
||||
./gerd/services/hedgedoc.nix
|
||||
./gerd/services/cyberchef.nix
|
||||
./gerd/services/nextcloud.nix
|
||||
|
||||
./gerd/services/member-website
|
||||
|
||||
|
@ -30,6 +31,7 @@
|
|||
pools.rpool.datasets = {
|
||||
"safe/svcs/forgejo" = { mountpoint = "/srv/forgejo"; extra.options.quota = "5G"; };
|
||||
"safe/svcs/hedgedoc" = { mountpoint = "/srv/hedgedoc"; extra.options.quota = "5G"; };
|
||||
"safe/svcs/nextcloud" = { mountpoint = "/srv/nextcloud"; extra.options.quota = "5G"; };
|
||||
};
|
||||
};
|
||||
|
||||
|
|
209
machines/gerd/services/nextcloud.nix
Normal file
209
machines/gerd/services/nextcloud.nix
Normal file
|
@ -0,0 +1,209 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
svc_domain = "nextcloud.${config.mine.shared.settings.domain}";
|
||||
|
||||
# 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 = "n$dYTi7@!3v#sTbF2AV7mW7szS2Z$oFV";
|
||||
|
||||
# EDIT: Base DN
|
||||
ldapBase = config.mine.shared.settings.ldap.dc;
|
||||
ldapBaseUsers = config.mine.shared.settings.ldap.dc;
|
||||
ldapBaseGroups = config.mine.shared.settings.ldap.dc;
|
||||
ldapConfigurationActive = 1;
|
||||
ldapLoginFilter = "(&(objectclass=person)(${config.mine.shared.settings.ldap.attr.uid}=%uid))";
|
||||
|
||||
# EDIT: nextcloud_users group, contains the users who can login to Nextcloud
|
||||
ldapUserFilter = "(&(objectclass=person)${config.mine.shared.settings.ldap.user_filter})";
|
||||
ldapUserFilterObjectclass = "person";
|
||||
ldapGroupFilter = "(&(objectclass=groupOfUniqueNames)(cn=${config.mine.shared.settings.ldap.groups.member}))";
|
||||
ldapGroupFilterGroups = config.mine.shared.settings.ldap.groups.member;
|
||||
ldapGroupFilterObjectclass = "groupOfUniqueNames";
|
||||
ldapGroupMemberAssocAttr = "uniqueMember";
|
||||
ldapEmailAttribute = config.mine.shared.settings.ldap.attr.email;
|
||||
ldapUserFilterMode = 1;
|
||||
ldapExpertUsernameAttr = config.mine.shared.settings.ldap.attr.uid;
|
||||
};
|
||||
ldap_commands = lib.mapAttrsToList (n: v: "${occ} ldap:set-config s01 ${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
|
||||
|
||||
# ensure previous configs are deleted
|
||||
CONFIGS=$(${occ} ldap:show-config --output=json | ${pkgs.jq}/bin/jq -r '. | keys | .[]')
|
||||
echo "$CONFIGS" | while read configId; do
|
||||
${occ} ldap:delete-config "$configId"
|
||||
done
|
||||
|
||||
# create new empty config
|
||||
${occ} ldap:create-empty-config
|
||||
|
||||
# setup password
|
||||
BIND_USERPASS="$(cat $CREDENTIALS_DIRECTORY/lldap-bind-user-pass)"
|
||||
${occ} ldap:set-config s01 ldapAgentPassword "$BIND_USERPASS"
|
||||
|
||||
# set settings
|
||||
${builtins.concatStringsSep "\n" ldap_commands}
|
||||
'';
|
||||
|
||||
# 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!"
|
||||
printf "y\n" | ${occ} encryption:encrypt-all
|
||||
'';
|
||||
in {
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
package = pkgs.nextcloud29;
|
||||
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;
|
||||
oidc_login = let
|
||||
version = "3.1.1";
|
||||
# TODO(eyJhb): add to niv
|
||||
in pkgs.fetchNextcloudApp {
|
||||
sha256 = "sha256-EVHDDFtz92lZviuTqr+St7agfBWok83HpfuL6DFCoTE=";
|
||||
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;
|
||||
|
||||
# settings
|
||||
settings = {
|
||||
# open connect/oidc
|
||||
oidc_login_provider_url = "https://auth.fricloud.dk";
|
||||
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";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.nextcloud-setup = {
|
||||
# runs this after all the main nextcloud-setup stuff
|
||||
postStop = lib.mkAfter ''
|
||||
${nextcloudSetupLdap}
|
||||
${nextcloudSetupAdmin}
|
||||
${nextcloudSetupEncryption}
|
||||
'';
|
||||
|
||||
# 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}"
|
||||
];
|
||||
};
|
||||
|
||||
# ensure that nextcloud can access stateDir
|
||||
systemd.tmpfiles.rules = [
|
||||
"Z ${stateDir} 6770 ${nextcloud_user} ${nextcloud_group} -"
|
||||
];
|
||||
|
||||
# setup authelia for nextcloud
|
||||
services.authelia.instances.main.settings.identity_providers.oidc.clients = [{
|
||||
id = AUTHELIA_AUTH_NAME;
|
||||
description = "Nextcloud";
|
||||
|
||||
# authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
|
||||
secret = "$pbkdf2-sha512$310000$kLNQ/1A.uasSN4g8q94jUQ$8OKNUNNumHCh8dVG5/QWys7u.y1guqFXlrL.bMm7/HKTsWhpib/W.8qlU6VU7V1Be/h14Y.fJi3RLvbkEdo2kA";
|
||||
|
||||
public = false;
|
||||
authorization_policy = "one_factor";
|
||||
# require_pkce = true;
|
||||
# pkce_challenge_method = "S256";
|
||||
redirect_uris = [ "https://${svc_domain}/apps/oidc_login/oidc" ];
|
||||
scopes = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
"groups"
|
||||
];
|
||||
|
||||
userinfo_signing_algorithm = "none";
|
||||
}];
|
||||
|
||||
services.nginx.virtualHosts."${svc_domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
# teeworlds
|
||||
teeworlds-env.file = ./teeworlds/env.age;
|
||||
|
||||
# nextcloud
|
||||
nextcloud-admin-pass.file = ./nextcloud/admin-pass.age;
|
||||
nextcloud-secrets.file = ./nextcloud/secrets.age;
|
||||
};
|
||||
|
||||
users.groups.secrets-lldap-bind-user-pass = {};
|
||||
|
|
BIN
secrets/nextcloud/admin-pass.age
Normal file
BIN
secrets/nextcloud/admin-pass.age
Normal file
Binary file not shown.
BIN
secrets/nextcloud/secrets.age
Normal file
BIN
secrets/nextcloud/secrets.age
Normal file
Binary file not shown.
|
@ -31,4 +31,8 @@ in
|
|||
|
||||
# teeworlds
|
||||
"teeworlds/env.age".publicKeys = defaultAccess;
|
||||
|
||||
# nextcloud
|
||||
"nextcloud/admin-pass.age".publicKeys = defaultAccess;
|
||||
"nextcloud/secrets.age".publicKeys = defaultAccess;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue