aboutsummaryrefslogtreecommitdiff
path: root/modules/services/nextcloud.nix
blob: d38fb921efd41ffd9d7d4d37e9aacabba130b4ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
{
  flake.modules.nixos.nextcloud =
    {
      config,
      lib,
      pkgs,
      ...
    }:
    {
      services.nextcloud = {
        enable = true;
        package = pkgs.nextcloud32;
        hostName = "cloud.schererleander.de";
        https = true;
        database.createLocally = true;
        maxUploadSize = "16G";
        config = {
          dbtype = "mysql";
          adminuser = "schererleander";
          adminpassFile = config.sops.secrets."nextcloud-admin-pass".path;
        };
        secretFile = config.sops.secrets."nextcloud-secrets".path;
        settings = {
          maintenance_window_start = 2; # 02:00
          default_phone_region = "de";
          overwriteProtocol = "https";
          trusted_domains = [ "cloud.schererleander.de" ];
          logtimezone = config.time.timeZone;
          log_type = "file";
          # Disable mail functionality for single-user instance
          mail_smtpmode = "null";
        };
        phpOptions."opcache.interned_strings_buffer" = "64";
      };

      services.nginx.virtualHosts = {
        "cloud.schererleander.de" = {
          forceSSL = true;
          sslCertificate = config.sops.secrets."cert_fullchain".path;
          sslCertificateKey = config.sops.secrets."cert_private".path;
        };
      };

      services.borgbackup.jobs.nextcloud = {
        paths = [
          "/var/lib/nextcloud"
          "/var/lib/backup/nextcloud/db"
        ];
        repo = "$BORG_REPO";
        encryption.mode = "none";
        user = "root";
        group = "root";
        environment = {
          BORG_RSH = "ssh -i ${
            config.sops.secrets."borgbase_ssh_key".path
          } -o StrictHostKeyChecking=accept-new";
          TMPDIR = "/var/tmp";
        };
        compression = "auto,lzma";
        startAt = "daily";
        readWritePaths = [
          "/var/lib/backup"
          "/var/lib/nextcloud"
        ];
        preHook = ''
          set -euo pipefail

          export BORG_REPO="$(cat ${config.sops.secrets."borg_repo".path})"

          INSTALL="${pkgs.coreutils}/bin/install"
          FIND="${pkgs.findutils}/bin/find"
          MYSQLDUMP="${pkgs.mariadb.client}/bin/mariadb-dump"
          GZIP="${pkgs.gzip}/bin/gzip"
          OCC="${lib.getExe config.services.nextcloud.occ}"

          # This command requires write access to /var/lib/backup.
          $INSTALL -d -m 0750 -o root -g root /var/lib/backup/nextcloud/db

          trap "$OCC maintenance:mode --off >/dev/null 2>&1 || true" EXIT

          $OCC maintenance:mode --on

          # Make a consistent database dump without locking the site.
          $MYSQLDUMP --single-transaction --quick --lock-tables=false --databases nextcloud \
            | $GZIP -c > /var/lib/backup/nextcloud/db/nextcloud-$(date +%F-%H%M%S).sql.gz

          # Delete local dump files older than 14 days.
          $FIND /var/lib/backup/nextcloud/db -type f -name "*.sql.gz" -mtime +14 -delete || true
        '';
        postHook = ''
          set -euo pipefail
          ${lib.getExe config.services.nextcloud.occ} maintenance:mode --off || true
        '';
      };

      services.fail2ban = {
        enable = true;
        bantime = lib.mkDefault "1h";
        jails = {
          nextcloud = {
            enabled = true;
            settings = {
              backend = "systemd";
              journalmatch = "SYSLOG_IDENTIFIER=Nextcloud";
              # END modification to work with syslog instead of logile
              port = 443;
              protocol = "tcp";
              filter = "nextcloud";
              maxretry = 3;
              findtime = 43200;
            };
          };
        };
      };

      environment.etc = {
        # Adapted failregex for syslogs
        "fail2ban/filter.d/nextcloud.local".text = pkgs.lib.mkDefault (
          pkgs.lib.mkAfter ''
            [Definition]
            _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
            failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
                          ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
            datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
          ''
        );
      };
    };
}