From 2a8fe0ad3bba202de92145a24834070f921640fb Mon Sep 17 00:00:00 2001 From: dogeystamp Date: Sun, 25 Dec 2022 21:00:16 -0500 Subject: [PATCH] syncthing: added role --- README.md | 4 + group_vars/all/vars.yml | 8 +- roles/firewall/tasks/main.yml | 8 ++ roles/services/syncthing/defaults/main.yaml | 48 +++++++ roles/services/syncthing/handlers/main.yaml | 4 + roles/services/syncthing/tasks/main.yml | 132 ++++++++++++++++++++ run.yml | 5 + 7 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 roles/services/syncthing/defaults/main.yaml create mode 100644 roles/services/syncthing/handlers/main.yaml create mode 100644 roles/services/syncthing/tasks/main.yml diff --git a/README.md b/README.md index f883d63..09948ad 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ This project was largely inspired by his own [infra](https://github.com/notthebe * MediaWiki farm * Navidrome music server * SFTP (not really a service, included in sshd) +* Syncthing * Firewall (UFW) ## Miscellaneous features @@ -31,6 +32,9 @@ This project was largely inspired by his own [infra](https://github.com/notthebe Install ansible. [Install guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) +Install python-hashlib. This is necessary for syncthing because for some reason +it can't compute hashes for bcrypt. + Clone the repo: ``` diff --git a/group_vars/all/vars.yml b/group_vars/all/vars.yml index 2628403..7b65c5e 100644 --- a/group_vars/all/vars.yml +++ b/group_vars/all/vars.yml @@ -201,6 +201,9 @@ registration_shared_secret: "secret" macaroon_secret_key: "secret" form_secret: "secret" +# Syncthing secrets +syncthing_gui_pass: "" + # Coturn secrets coturn_secret_key: "secret" @@ -268,7 +271,10 @@ enable_navidrome: yes enable_website: yes # SFTP read-only user -enable_sftpr: yes +enable_sftpr: no + +# Syncthing +enable_syncthing: yes # Mailserver (local only) enable_mail: yes diff --git a/roles/firewall/tasks/main.yml b/roles/firewall/tasks/main.yml index 9c8e3f3..50a9338 100644 --- a/roles/firewall/tasks/main.yml +++ b/roles/firewall/tasks/main.yml @@ -15,6 +15,14 @@ state: enabled when: enable_synapse +- name: Allow Syncthing port + community.general.ufw: + rule: allow + port: 22000 + proto: any + state: enabled + when: enable_syncthing + - name: Allow http/https ports community.general.ufw: rule: allow diff --git a/roles/services/syncthing/defaults/main.yaml b/roles/services/syncthing/defaults/main.yaml new file mode 100644 index 0000000..7dfbe1b --- /dev/null +++ b/roles/services/syncthing/defaults/main.yaml @@ -0,0 +1,48 @@ +syncthing_user: syncthing +# group for file management +syncthing_group: vault +syncthing_guiaddress: 127.0.0.1:8080 +syncthing_listen: tcp://0.0.0.0:22000 +syncthing_localannounce: true +syncthing_globalannounce: true +syncthing_home: "/home/{{ syncthing_user }}" +syncthing_gui_user: "{{ syncthing_user }}" + +# Paths for Syncthing folders +vault_path: "/mnt/disk/uv" +archive_path: "/mnt/disk/uva" + +# Put this in the vault in cleartext: the playbook hashes it +syncthing_gui_pass: "" + +# 22 chars for bcrypt +syncthing_gui_salt: "{{ lookup('password', '/dev/null chars=ascii_letters,digit length=22', seed=inventory_hostname) }}" + +# Put this in host-vars or group-vars +# Follows conventions of Syncthing's REST API: see https://docs.syncthing.net/dev/rest.html +# But write in YAML. +syncthing_devices: [] +# - name: "Example Device" +# deviceID: "AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA" +# - name: "Main Device" +# deviceID: "BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB" +# introducer: true + +# Also follows REST API convention +syncthing_folders: [] +# - label: "Example Folder" +# id: "example" +# path: "{{ syncthing_home }}/example/" + +# Settings to add to all folders if not specified otherwise +# Separated into default folder settings, and default device settings +# Follows REST API convention +syncthing_defaults: {} +# folder: +# devices: "{{ syncthing_devices }}" +# versioning: +# type: "staggered" +# params: +# cleanoutDays: "60" +# maxAge: "31536000" +# device: {} diff --git a/roles/services/syncthing/handlers/main.yaml b/roles/services/syncthing/handlers/main.yaml new file mode 100644 index 0000000..b042034 --- /dev/null +++ b/roles/services/syncthing/handlers/main.yaml @@ -0,0 +1,4 @@ +- name: Restart syncthing + systemd: + name: syncthing@syncthing + state: restarted diff --git a/roles/services/syncthing/tasks/main.yml b/roles/services/syncthing/tasks/main.yml new file mode 100644 index 0000000..2487fb9 --- /dev/null +++ b/roles/services/syncthing/tasks/main.yml @@ -0,0 +1,132 @@ +- name: Install packages for syncthing + community.general.pacman: + name: + - syncthing + - python-lxml + state: present + +- name: Create file management group + group: + name: "{{ syncthing_group }}" + +- name: Add unpriviledged user to file management group + user: + name: "{{ username }}" + append: yes + groups: "{{ syncthing_group }}" + +- name: Create syncthing user + user: + name: "{{ syncthing_user }}" + home: "{{ syncthing_home }}" + group: "{{ syncthing_group }}" + +- name: Enable syncthing service + systemd: + name: syncthing@syncthing + enabled: yes + state: started + +- name: Wait for configuration file to be created + wait_for: + path: "{{ syncthing_home }}/.config/syncthing/config.xml" + +- name: Configure globalannounce + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/options/globalAnnounceEnabled" + value: "{{ syncthing_globalannounce | lower}}" + notify: + - Restart syncthing + +- name: Configure localannounce + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/options/localAnnounceEnabled" + value: "{{ syncthing_localannounce | lower}}" + notify: + - Restart syncthing + +- name: Configure listen address + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/options/listenAddress" + value: "{{ syncthing_listen }}" + notify: + - Restart syncthing + +- name: Configure gui address + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/gui/address" + value: "{{ syncthing_guiaddress }}" + notify: + - Restart syncthing + +- name: Configure gui user + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/gui/user" + value: "{{ syncthing_gui_user }}" + notify: + - Restart syncthing + +- name: Configure gui password + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/gui/password" + value: "{{ syncthing_gui_pass | password_hash('bcrypt', syncthing_gui_salt) }}" + notify: + - Restart syncthing + +- name: Warn if gui password is empty + fail: + msg: "Syncthing has no configured password!" + when: syncthing_gui_pass is not defined or syncthing_gui_pass == '' + +- name: Get API key + xml: + file: "{{ syncthing_home }}/.config/syncthing/config.xml" + xpath: "/configuration/gui/apikey" + content: text + register: api_key + +- meta: flush_handlers + +- name: Delete default Syncthing folder + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/folders/default" + method: DELETE + return_content: yes + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + +- name: Add known syncthing devices + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/devices" + method: PUT + return_content: yes + body_format: json + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + body: "{{ syncthing_devices }}" + +- name: Set default folder settings + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/defaults/folder" + method: PATCH + return_content: yes + body_format: json + body: "{{ syncthing_defaults.folder }}" + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + +- name: Add syncthing folders + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/folders" + method: PUT + return_content: yes + body_format: json + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + body: "{{ syncthing_folders }}" diff --git a/run.yml b/run.yml index 0c8c017..39f8fd7 100644 --- a/run.yml +++ b/run.yml @@ -65,6 +65,11 @@ - mail when: enable_mail + - role: services/syncthing + tags: + - syncthing + when: enable_syncthing + # Main SSL certificate (with Let's Encrypt) - role: networking/ssl tags: