-{ config, pkgs, lib, ... }:
-let
- serverSpecificConfig = config.myEnv.serverSpecific.quatresaisons;
- yarnModules = pkgs.yarn2nix-moretea.mkYarnModules rec {
- name = "landing";
- pname = name;
- version = "v1.0.0";
- packageJSON = "${pkgs.sources.webapps-landing}/package.json";
- yarnLock = "${pkgs.sources.webapps-landing}/yarn.lock";
- yarnNix = ../websites/tools/tools/landing/yarn-packages.nix;
- };
- toLanding = landingConfig: pkgs.stdenv.mkDerivation rec {
- pname = "landing";
- version = "v1.0.0";
- src = pkgs.sources.webapps-landing;
-
- buildInputs = [ yarnModules pkgs.yarn2nix-moretea.yarn ];
- configurePhase = ''
- ln -s ${yarnModules}/node_modules .
- '';
- buildPhase = ''
- yarn build
- '';
- installPhase = ''
- cp -a dist $out
- cp -f ${landingConfig} $out/config.yml
- ln -s service-worker.js $out/worker.js
- '';
- };
- normalUsers = serverSpecificConfig.users;
- sponsoredUser = pkgs.writeScriptBin "sponsored_user" ''
- #!/usr/bin/env bash
-
- set -euo pipefail
- [ -z "''${SUDO_USER+x}" ] && echo "Must be run with sudo" && exit 1
-
- mygroup=$(id -ng $SUDO_USER)
-
- sponsored=$(getent group $mygroup | cut -d':' -f4)
-
- echo "Sponsored users: ''${sponsored:-<none>}"
-
- log () {
- touch /var/log/sponsored_users
- chmod go-rwx /var/log/sponsored_users
- echo "`date` $mygroup $1" | LANG=C cat -v | tr '\012' ' ' | sed 's:$:\x0a:' >> /var/log/sponsored_users
- }
-
- create_user () {
- log "creates $1: $2"
- useradd -m -G users,$mygroup -g $mygroup -p '!' "$1"
- touch /var/lib/nixos/sponsored_users
- 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 ${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
- description:: $(echo -n "$2" | base64)
- sn: $1
- uid: $1
- EOF
- while ! passwd "$1"; do
- echo "please give an initial password"
- done
- }
-
- delete_user () {
- IFS=",";
- for u in $sponsored; do
- if [ "$u" = "$1" ]; then
- log "deletes $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 ${config.secrets.fullPaths."ldap/sync_password"} \
- "uid=$1,uid=$mygroup,ou=users,dc=salle-s,dc=org"
- echo "deleted"
- exit 0
- fi
- done
-
- echo "User does not exist or does not belong to you";
- exit 1
- }
-
- reset_password () {
- IFS=",";
- for u in $sponsored; do
- if [ "$u" = "$1" ]; then
- log "resets password for $1"
- passwd "$1"
- exit 0
- fi
- done
-
- echo "User does not exist or does not belong to you";
- exit 1
- }
-
- reset_ldap_password () {
- if [ "$1" = "$mygroup" ]; then
- log "resets web password"
- ${pkgs.openldap}/bin/ldappasswd -D cn=root,dc=salle-s,dc=org \
- -y ${config.secrets.fullPaths."ldap/sync_password"} \
- -S "uid=$mygroup,ou=users,dc=salle-s,dc=org"
- else
- IFS=",";
- for u in $sponsored; do
- if [ "$u" = "$1" ]; then
- log "resets web password of $1"
- ${pkgs.openldap}/bin/ldappasswd -D cn=root,dc=salle-s,dc=org \
- -y ${config.secrets.fullPaths."ldap/sync_password"} \
- -S "uid=$1,uid=$mygroup,ou=users,dc=salle-s,dc=org"
- exit 0
- fi
- done
-
- echo "User does not exist or does not belong to you";
- exit 1
- fi
- }
-
- show_help () {
- echo "sponsored_users create username realname"
- echo " create a new sub-user attached to your account"
- echo "sponsored_users (delete|reset_password) username"
- echo " delete a sub-user attached to your account or reset his password"
- echo "sponsored_users reset_ldap_password username"
- echo " reset the web password of a sub-user or yourself"
- }
-
- [ -z "''${1+x}" -o -z "''${2+x}" ] && { show_help ; exit 0; }
- action="$1"
- username="$2"
- shift
- shift
-
- case "$action" in
- create)
- [ -z "''${1+x}" ] && { show_help ; echo "Conformément à la charte https://4c.salle-s.org/charte veuillez préciser le nom réel du futur utilisateur du compte $username, juste pour root." ; exit 1; }
- create_user "$username" "$*";
- ;;
- delete)
- delete_user "$username";
- ;;
- reset_password)
- reset_password "$username";
- ;;
- reset_ldap_password)
- reset_ldap_password "$username";
- ;;
- *)
- show_help
- ;;
- esac
- '';
-in
-{
- deployment = {
- targetUser = "root";
- targetHost = config.hostEnv.ips.main.ip4;
- substituteOnDestination = true;
- };
- # ssh-keyscan quatresaison | nix-shell -p ssh-to-age --run ssh-to-age
- secrets.ageKeys = [ "age1yz8u6xvh2fltvyp96ep8crce3qx4tuceyhun6pwddfe0uvcrkarscxl7e7" ];
-
- programs.ssh.package = pkgs.openssh.overrideAttrs(old: {
- PATH_PASSWD_PROG = "/run/wrappers/bin/passwd";
- buildFlags = [ "SSH_KEYSIGN=/run/wrappers/bin/ssh-keysign" ];
- });
-
- imports = builtins.attrValues (import ../..) ++
- [ ./quatresaisons/nextcloud.nix ./quatresaisons/databases.nix ];
-
- myEnv = import ../../../nixops/secrets/environment.nix;
-
- fileSystems = {
- "/" = { device = "/dev/disk/by-uuid/865931b4-c5cc-439f-8e42-8072c7a30634"; fsType = "ext4"; };
- "/home" = { device = "/dev/disk/by-uuid/76020bc4-5b88-464c-8952-9a59072c597f"; fsType = "ext4"; neededForBoot = true; };
- "/boot" = { device = "/dev/disk/by-uuid/0fb8421a-61e5-4ed5-a795-4dd3a9b2152a"; fsType = "ext4"; };
- "/var/lib" = { device = "/home/var_lib"; fsType = "none"; options = [ "defaults,bind" ]; };
- };
- powerManagement.cpuFreqGovernor = "powersave";
- hardware.enableRedistributableFirmware = true;
-
- boot.initrd.availableKernelModules = [ "ahci" "megaraid_sas" "sd_mod" ];
- boot.initrd.kernelModules = [ "dm-snapshot" ];
- boot.kernelModules = [ "kvm-intel" ];
-
- boot.loader.grub.enable = true;
- boot.loader.grub.version = 2;
- boot.loader.grub.device = "/dev/sda";
-
- networking.firewall.enable = false;
- networking.firewall.allowedTCPPorts = [ 80 443 ];
- networking.useDHCP = false;
- networking.interfaces.eth0.useDHCP = true;
- networking.interfaces.eth0.ipv6.addresses = [
- { address = pkgs.lib.head config.hostEnv.ips.main.ip6; prefixLength = 64; }
- ];
- networking.defaultGateway6 = { address = "fe80::1"; interface = "eth0"; };
- services.udev.extraRules = ''
- ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="c8:60:00:8b:2f:f0", NAME="eth0"
- '';
- security.pam.services.chage.text = ''
- auth sufficient pam_rootok.so
- auth required pam_unix.so
- account required pam_unix.so
- session required pam_unix.so
- password required pam_permit.so
- '';
- security.pam.services.sshd.makeHomeDir = true;
- security.pam.services.passwd_default = {};
- security.pam.services.passwd.text = ''
- password required pam_cracklib.so enforce_for_root difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
- '' + config.security.pam.services.passwd_default.text;
-
- system.activationScripts.ldapSync = {
- deps = [ "secrets" "users" ];
- text =
- let
- 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 ${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" |\
- grep "^uid" | ${pkgs.gnused}/bin/sed -e "s/uid: //" | while read ldapuser; do
-
- for user in ${builtins.concatStringsSep " " (builtins.attrNames normalUsers)}; do
- if [ "$user" = "$ldapuser" ]; then
- continue 2
- fi
- done
- ${pkgs.openldap}/bin/ldapdelete -r ${com} uid=$ldapuser,ou=users,dc=salle-s,dc=org
- done
-
- # Subusers
- if [ -f /var/lib/nixos/sponsored_users ]; then
- cat /var/lib/nixos/sponsored_users | while read mainUser subUser name; do
- (${pkgs.openldap}/bin/ldapadd -c ${com} 2>/dev/null >/dev/null || true) <<EOF
- dn: uid=$subUser,uid=$mainUser,ou=users,dc=salle-s,dc=org
- objectClass: inetOrgPerson
- cn: $subUser
- description:: $(echo -n "$name" | base64)
- sn: $subUser
- uid: $subUser
- EOF
- done
- fi
- '';
- };
-
- secrets.keys = {
- "ldap/sync_password" = {
- permissions = "0400";
- text = serverSpecificConfig.ldap_sync_password;
- };
- "ldap/ldaptree.ldif" = {
- permissions = "0400";
- text = serverSpecificConfig.ldap_service_users
- + (builtins.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
- dn: uid=${n},ou=users,dc=salle-s,dc=org
- objectClass: inetOrgPerson
- cn: ${n}
- description: ${v._meta.name or n} ${v._meta.email}
- sn: ${n}
- uid: ${n}
- '') normalUsers));
- };
- };
-
- myServices.monitoring.enable = true;
- myServices.certificates.enable = true;
- users.mutableUsers = true;
- system.stateVersion = "21.03";
- programs.zsh.enable = true;
-
- users.motd = ''
- Bienvenue sur quatresaisons.salle-s.org !
-
- * Charte :
- https://4c.salle-s.org/charte
- * Gérer les utilisateurs unix additionnels :
- sudo sponsored_user -h
- * Applications web :
- * tableau de bord : https://4c.salle-s.org/
- * nextcloud : https://nextcloud.4c.salle-s.org/
- '';
-
- users.groups =
- lib.mapAttrs (n: v: { gid = v.uid; }) normalUsers
- // { wwwrun = { gid = config.ids.gids.wwwrun; }; };
- users.users =
- let
- defaultNormal = n: {
- group = n;
- extraGroups = [ "users" ];
- isNormalUser = true;
- };
- in
- lib.mapAttrs (n: v: defaultNormal n // (lib.filterAttrs (k: _: k != "_meta") v)) normalUsers
- // {
- sponsored-separator = {
- uid = 10000;
- group = "users";
- home = "/var/empty";
- extraGroups = [];
- isNormalUser = true;
- createHome = false;
- };
- wwwrun = {
- group = "wwwrun";
- description = "Apache httpd user";
- uid = config.ids.uids.wwwrun;
- extraGroups = [ "keys" ];
- };
- };
-
- system.activationScripts.usersPost = {
- deps = [ "users" "groups" ];
- text = builtins.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
- if getent shadow "${n}" | grep -q '^${n}:${v.initialHashedPassword or "!"}:1'; then
- chage -d 0 "${n}"
- [ '${v.initialHashedPassword or "!"}' = '!' ] && passwd -d "${n}"
- fi
- '') normalUsers);
- };
- security.sudo.extraRules = [
- {
- commands = [
- { command = "${sponsoredUser}/bin/sponsored_user"; options = [ "NOPASSWD" ]; }
- { command = "/run/current-system/sw/bin/sponsored_user"; options = [ "NOPASSWD" ]; }
- ];
- users = builtins.attrNames normalUsers;
- runAs = "root";
- }
- ];
-
- environment.systemPackages = [
- sponsoredUser
- pkgs.git pkgs.vim pkgs.rsync pkgs.strace pkgs.home-manager
- pkgs.telnet pkgs.htop pkgs.iftop pkgs.bind.dnsutils pkgs.httpie
- pkgs.iotop pkgs.whois pkgs.ngrep pkgs.tcpdump pkgs.tshark
- pkgs.tcpflow pkgs.nmap pkgs.p0f pkgs.socat pkgs.lsof pkgs.psmisc
- pkgs.openssl pkgs.wget pkgs.pv pkgs.smartmontools pkgs.youtube-dl
- pkgs.unzip pkgs.octave pkgs.feh pkgs.xv pkgs.sshfs pkgs.gdb
- pkgs.file pkgs.lynx pkgs.tmux pkgs.awesome pkgs.libreoffice
- pkgs.evince pkgs.firefox pkgs.xcalib pkgs.python3 pkgs.python2
- pkgs.xorg.xkbcomp pkgs.subversion pkgs.xclip pkgs.imagemagick
- pkgs.bc pkgs.sox pkgs.zip pkgs.gnome3.gnome-screenshot
- pkgs.datadog-process-agent
- ];
-
- services.websites.env.production = {
- enable = true;
- adminAddr = "httpd@immae.eu";
- httpdName = "Prod";
- modules = [ "http2" "deflate" "filter" ];
- extraConfig = [
- ''
- LogFormat "%{Host}i:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedVhost
- Protocols h2 http/1.1
- AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
- '' ];
- ips =
- let ips = config.hostEnv.ips.main;
- in [ips.ip4] ++ (ips.ip6 or []);
-
- fallbackVhost = {
- certName = "quatresaisons";
- hosts = [ "quatresaisons.immae.eu" ];
- root = pkgs.runCommand "empty" {} "mkdir $out && touch $out/index.html";
- extraConfig = [ "DirectoryIndex index.html" ];
- };
- vhostConfs.salle-s = {
- certName = "quatresaisons";
- addToCerts = true;
- hosts = [ "salle-s.org" ];
- root = toLanding ./quatresaisons/landing.yml;
- extraConfig = [
- ''
- <Directory ${toLanding ./quatresaisons/landing.yml}>
- AllowOverride None
- Require all granted
- DirectoryIndex index.html
- </Directory>
- ''
- ];
- };
- vhostConfs.tools = {
- certName = "quatresaisons";
- addToCerts = true;
- hosts = [ "4c.salle-s.org" "quatresaisons.salle-s.org" "quatre-saisons.salle-s.org" ];
- root = toLanding ./quatresaisons/landing_4c.yml;
- extraConfig = [
- ''
- Alias /charte ${serverSpecificConfig.charte_path}
- <Directory ${serverSpecificConfig.charte_path}>
- AllowOverride None
- Require all granted
- DirectoryIndex index.html index.txt
- </Directory>
-
- <Directory ${toLanding ./quatresaisons/landing_4c.yml}>
- AllowOverride None
- Require all granted
- DirectoryIndex index.html
- </Directory>
- ''
- ];
- };
- };
- system.activationScripts.httpd = ''
- install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php
- install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions
- '';
-
- services.phpfpm = {
- phpOptions = ''
- session.save_path = "/var/lib/php/sessions"
- post_max_size = 20M
- ; 15 days (seconds)
- session.gc_maxlifetime = 1296000
- ; 30 days (minutes)
- session.cache_expire = 43200
- '';
- settings = {
- log_level = "notice";
- };
- };
-
-}