summaryrefslogtreecommitdiff
path: root/modules/syncthing.nix
blob: e261a12bf679e129da8d900fb8e676b08ca379c7 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
{
  config,
  inputs,
  lib,
  libNginx,
  this,
  ...
}:
with lib;
let
  cfg = config.nixfiles.modules.syncthing;
in
{
  options.nixfiles.modules.syncthing = {
    enable = mkEnableOption "Syncthing";

    port = mkOption {
      description = "Port.";
      type = with types; port;
      default = 8384;
    };

    domain = mkOption {
      description = "Domain name sans protocol scheme.";
      type = with types; str;
      default = "syncthing.${config.networking.fqdn}";
    };
  };

  config = mkIf cfg.enable (mkMerge [
    {
      secrets = {
        "syncthing-cert-${this.hostname}" = with config.services.syncthing; {
          file = "${inputs.self}/secrets/syncthing-cert-${this.hostname}";
          owner = user;
          inherit group;
        };

        "syncthing-key-${this.hostname}" = with config.services.syncthing; {
          file = "${inputs.self}/secrets/syncthing-key-${this.hostname}";
          owner = user;
          inherit group;
        };
      };

      services.syncthing = {
        enable = true;

        user = my.username;
        inherit (config.my) group;

        dataDir = "${config.dirs.config}/syncthing";
        configDir = config.services.syncthing.dataDir;

        guiAddress = "127.0.0.1:${toString cfg.port}";

        cert = config.secrets."syncthing-cert-${this.hostname}".path;
        key = config.secrets."syncthing-key-${this.hostname}".path;

        overrideDevices = false;
        overrideFolders = false;

        settings = {
          options = {
            announceLANAddresses = false;
            autoUpgradeIntervalH = 0;
            crashReportingEnabled = false;
            globalAnnounceEnabled = false;
            relaysEnabled = false;
            setLowPriority = this.isHeadful;
            stunKeepaliveStartS = 0;
            urAccepted = -1;
          };

          gui = {
            insecureAdminAccess = this.isHeadless;
            insecureSkipHostcheck = this.isHeadless;
          };

          devices = mapAttrs (
            name: attr:
            mkIf (attr.syncthing.id != null && hasAttr "wireguard" attr) {
              inherit (attr.syncthing) id;
              compression = "always";
              introducer = false;
              addresses = [
                "quic://${name}.${config.networking.domain}:22000"
                "tcp://${name}.${config.networking.domain}:22000"
              ];
              autoAcceptFolders = true;
              untrusted = false;
            }
          ) my.configurations;

          folders =
            let
              filterDevices =
                f:
                attrNames (
                  filterAttrs (
                    _: attr: (attr.hostname != this.hostname) && (attr.syncthing.id != null) && f attr
                  ) my.configurations
                );
              all = filterDevices (_: true);
              notHeadless = filterDevices (attr: !attr.isHeadless);
              notOther = filterDevices (attr: !attr.isOther);

              simple = {
                type = "simple";
                params.keep = "5";
              };
              trashcan = {
                type = "trashcan";
                params.cleanoutDays = "7";
              };
            in
            with config.hm.xdg.userDirs;
            {
              share = {
                path = publicShare;
                devices = notHeadless;
                versioning = trashcan;
              };
              pass = {
                path = config.hm.programs.password-store.settings.PASSWORD_STORE_DIR;
                devices = notOther;
                versioning = trashcan;
              };
              org = {
                path = "${documents}/org";
                devices = all;
                versioning = simple;
              };
              roam = {
                path = "${documents}/roam";
                devices = notOther;
                versioning = simple;
              };
              elfeed = {
                path = "${config.my.home}/.elfeed";
                devices = notOther;
                versioning = trashcan;
              };
              books = {
                path = "${documents}/books";
                devices = notOther;
                versioning = trashcan;
              };
            };
        };
      };

      systemd.services.syncthing.environment.STNODEFAULTFOLDER = "yes";
    }
    (mkIf this.isHeadless {
      nixfiles.modules.nginx = {
        enable = true;
        upstreams.syncthing.servers.${config.services.syncthing.guiAddress} = { };
        virtualHosts.${cfg.domain} = {
          locations."/".proxyPass = "http://syncthing";
          extraConfig = libNginx.config.internalOnly;
        };
      };
    })
  ]);
}