docs: init synthing & deltachat
This commit is contained in:
34
clanModules/syncthing/README.md
Normal file
34
clanModules/syncthing/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
Syncthing is a free, open-source file synchronization application designed to allow users to synchronize files between multiple devices over the internet or local networks securely and privately.
|
||||
|
||||
It is an alternative to cloud-based file sharing services.
|
||||
|
||||
## Usage
|
||||
|
||||
We recommend configuring this module as an sync-service through the provided options. Although it provides a Web GUI through which more usage scenarios are supported.
|
||||
|
||||
## Features
|
||||
|
||||
- **Private and Secure**: Syncthing uses TLS encryption to secure data transfer between devices, ensuring that only the intended devices can read your data.
|
||||
- **Decentralized**: No central server is involved in the data transfer. Each device communicates directly with others.
|
||||
- **Open Source**: The source code is openly available for audit and contribution, fostering trust and continuous improvement.
|
||||
- **Cross-Platform**: Syncthing supports multiple platforms including Windows, macOS, Linux, BSD, and Android.
|
||||
- **Real-time Synchronization**: Changes made to files are synchronized in real-time across all connected devices.
|
||||
- **Web GUI**: It includes a user-friendly web interface for managing devices and configurations. (`127.0.0.1:8384`)
|
||||
|
||||
## Configuration
|
||||
|
||||
- **Share Folders**: Select folders to share with connected devices and configure permissions and synchronization parameters.
|
||||
|
||||
!!! info
|
||||
Clan automatically discovers other devices. Automatic discovery requires one machine to be an [introducer](#clan.syncthing.introducer)
|
||||
|
||||
If that is not the case you can add the other device by its Device ID manually.
|
||||
You can find and share Device IDs under the "Add Device" button in the Web GUI. (`127.0.0.1:8384`)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Sync Conflicts**: Resolve synchronization conflicts manually by reviewing file versions and modification times in the Web GUI (`127.0.0.1:8384`).
|
||||
|
||||
## Support
|
||||
|
||||
- **Documentation**: Extensive documentation is available on the [Syncthing website](https://docs.syncthing.net/).
|
||||
202
clanModules/syncthing/default.nix
Normal file
202
clanModules/syncthing/default.nix
Normal file
@@ -0,0 +1,202 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.clan.syncthing = {
|
||||
id = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
example = "BABNJY4-G2ICDLF-QQEG7DD-N3OBNGF-BCCOFK6-MV3K7QJ-2WUZHXS-7DTW4AS";
|
||||
default = config.clanCore.facts.services.syncthing.public."syncthing.pub".value or null;
|
||||
defaultText = "config.clanCore.facts.services.syncthing.public.\"syncthing.pub\".value";
|
||||
};
|
||||
introducer = lib.mkOption {
|
||||
description = ''
|
||||
The introducer for the machine.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
autoAcceptDevices = lib.mkOption {
|
||||
description = ''
|
||||
Auto accept incoming device requests.
|
||||
Should only be used on the introducer.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
};
|
||||
autoShares = lib.mkOption {
|
||||
description = ''
|
||||
Auto share the following Folders by their ID's with introduced devices.
|
||||
Should only be used on the introducer.
|
||||
'';
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
{
|
||||
# Syncthing ports: 8384 for remote access to GUI
|
||||
# 22000 TCP and/or UDP for sync traffic
|
||||
# 21027/UDP for discovery
|
||||
# source: https://docs.syncthing.net/users/firewall.html
|
||||
networking.firewall.interfaces."zt+".allowedTCPPorts = [
|
||||
8384
|
||||
22000
|
||||
];
|
||||
networking.firewall.allowedTCPPorts = [ 8384 ];
|
||||
networking.firewall.interfaces."zt+".allowedUDPPorts = [
|
||||
22000
|
||||
21027
|
||||
];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = lib.all (
|
||||
attr: builtins.hasAttr attr config.services.syncthing.settings.folders
|
||||
) config.clan.syncthing.autoShares;
|
||||
message = ''
|
||||
Syncthing: If you want to AutoShare a folder, you need to have it configured on the sharing device.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
# Activates inotify compatibility on syncthing
|
||||
# use mkOverride 900 here as it otherwise would collide with the default of the
|
||||
# upstream nixos xserver.nix
|
||||
boot.kernel.sysctl."fs.inotify.max_user_watches" = lib.mkOverride 900 524288;
|
||||
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
configDir = "/var/lib/syncthing";
|
||||
|
||||
overrideFolders = lib.mkDefault (
|
||||
if (config.clan.syncthing.introducer == null) then true else false
|
||||
);
|
||||
overrideDevices = lib.mkDefault (
|
||||
if (config.clan.syncthing.introducer == null) then true else false
|
||||
);
|
||||
|
||||
dataDir = lib.mkDefault "/home/user/";
|
||||
|
||||
group = "syncthing";
|
||||
|
||||
key = lib.mkDefault config.clan.secrets.syncthing.secrets."syncthing.key".path or null;
|
||||
cert = lib.mkDefault config.clan.secrets.syncthing.secrets."syncthing.cert".path or null;
|
||||
|
||||
settings = {
|
||||
options = {
|
||||
urAccepted = -1;
|
||||
allowedNetworks = [ config.clan.networking.zerotier.subnet ];
|
||||
};
|
||||
devices =
|
||||
{ }
|
||||
// (
|
||||
if (config.clan.syncthing.introducer == null) then
|
||||
{ }
|
||||
else
|
||||
{
|
||||
"${config.clan.syncthing.introducer}" = {
|
||||
name = "introducer";
|
||||
id = config.clan.syncthing.introducer;
|
||||
introducer = true;
|
||||
autoAcceptFolders = true;
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
systemd.services.syncthing-auto-accept =
|
||||
let
|
||||
baseAddress = "127.0.0.1:8384";
|
||||
getPendingDevices = "/rest/cluster/pending/devices";
|
||||
postNewDevice = "/rest/config/devices";
|
||||
SharedFolderById = "/rest/config/folders/";
|
||||
apiKey = config.clanCore.facts.services.syncthing.secret."syncthing.api".path or null;
|
||||
in
|
||||
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||
description = "Syncthing auto accept devices";
|
||||
requisite = [ "syncthing.service" ];
|
||||
after = [ "syncthing.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
script = ''
|
||||
set -x
|
||||
# query pending deviceID's
|
||||
APIKEY=$(cat ${apiKey})
|
||||
PENDING=$(${lib.getExe pkgs.curl} -X GET -H "X-API-Key: $APIKEY" ${baseAddress}${getPendingDevices})
|
||||
PENDING=$(echo $PENDING | ${lib.getExe pkgs.jq} keys[])
|
||||
|
||||
# accept pending deviceID's
|
||||
for ID in $PENDING;do
|
||||
${lib.getExe pkgs.curl} -X POST -d "{\"deviceId\": $ID}" -H "Content-Type: application/json" -H "X-API-Key: $APIKEY" ${baseAddress}${postNewDevice}
|
||||
|
||||
# get all shared folders by their ID
|
||||
for folder in ${builtins.toString config.clan.syncthing.autoShares}; do
|
||||
SHARED_IDS=$(${lib.getExe pkgs.curl} -X GET -H "X-API-Key: $APIKEY" ${baseAddress}${SharedFolderById}"$folder" | ${lib.getExe pkgs.jq} ."devices")
|
||||
PATCHED_IDS=$(echo $SHARED_IDS | ${lib.getExe pkgs.jq} ".+= [{\"deviceID\": $ID, \"introducedBy\": \"\", \"encryptionPassword\": \"\"}]")
|
||||
${lib.getExe pkgs.curl} -X PATCH -d "{\"devices\": $PATCHED_IDS}" -H "X-API-Key: $APIKEY" ${baseAddress}${SharedFolderById}"$folder"
|
||||
done
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.syncthing-auto-accept = lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||
description = "Syncthing Auto Accept";
|
||||
|
||||
wantedBy = [ "syncthing-auto-accept.service" ];
|
||||
|
||||
timerConfig = {
|
||||
OnActiveSec = lib.mkDefault 60;
|
||||
OnUnitActiveSec = lib.mkDefault 60;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.syncthing-init-api-key =
|
||||
let
|
||||
apiKey = config.clanCore.facts.services.syncthing.secret."syncthing.api".path or null;
|
||||
in
|
||||
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||
description = "Set the api key";
|
||||
after = [ "syncthing-init.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = ''
|
||||
# set -x
|
||||
set -efu pipefail
|
||||
|
||||
APIKEY=$(cat ${apiKey})
|
||||
${lib.getExe pkgs.gnused} -i "s/<apikey>.*<\/apikey>/<apikey>$APIKEY<\/apikey>/" /var/lib/syncthing/config.xml
|
||||
# sudo systemctl restart syncthing.service
|
||||
systemctl restart syncthing.service
|
||||
'';
|
||||
serviceConfig = {
|
||||
WorkingDirectory = "/var/lib/syncthing";
|
||||
BindReadOnlyPaths = [ apiKey ];
|
||||
Type = "oneshot";
|
||||
};
|
||||
};
|
||||
|
||||
clanCore.facts.services.syncthing = {
|
||||
secret."syncthing.key" = { };
|
||||
secret."syncthing.cert" = { };
|
||||
secret."syncthing.api" = { };
|
||||
public."syncthing.pub" = { };
|
||||
generator.path = [
|
||||
pkgs.coreutils
|
||||
pkgs.gnugrep
|
||||
pkgs.syncthing
|
||||
];
|
||||
generator.script = ''
|
||||
syncthing generate --config "$secrets"
|
||||
mv "$secrets"/key.pem "$secrets"/syncthing.key
|
||||
mv "$secrets"/cert.pem "$secrets"/syncthing.cert
|
||||
cat "$secrets"/config.xml | grep -oP '(?<=<device id=")[^"]+' | uniq > "$facts"/syncthing.pub
|
||||
cat "$secrets"/config.xml | grep -oP '<apikey>\K[^<]+' | uniq > "$secrets"/syncthing.api
|
||||
'';
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user