diff --git a/.gitignore b/.gitignore index bbd70ea..6370c3b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,10 @@ +# vim: nospell # SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. # # SPDX-License-Identifier: CC0-1.0 -# vim: nospell qusal/qubesos-github-io qusal/sys-audio qusal/sys-gui qusal/sys-wireguard qusal/sys-syncthing -qusal/sys-rsync -qusal/sys-sshfs -qusal/sys-mirage-firewall diff --git a/.reuse/dep5 b/.reuse/dep5 index 9bcc0c0..6fe640b 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -7,6 +7,17 @@ Files: */README.md Copyright: 2023 Benjamin Grande M. S. License: CC-BY-SA-4.0 +Files: qusal/sys-mirage-firewall/files/admin/mirage-firewall.tar.bz2 +Copyright: 2019 Thomas Leonard +License: BSD-2-Clause + +Files: qusal/qubes-builder/files/client/keys/* +Copyright: The Qubes OS Project + Frédéric Pierret + Marek Marczykowski-Górecki + Simon Gaiser +License: CC0-1.0 + Files: qusal/ansible/files/repo/* Copyright: 2014 Ansible, Inc. License: CC0-1.0 @@ -31,11 +42,4 @@ Files: qusal/terraform/files/repo/* Copyright: 2023 HashiCorp Inc. License: CC0-1.0 -Files: qusal/qubes-builder/files/keys/* -Copyright: The Qubes OS Project - Frédéric Pierret - Marek Marczykowski-Górecki - Simon Gaiser -License: CC0-1.0 - # vim: ft=debcopyright diff --git a/README.md b/README.md index 308f78c..7993d3a 100644 --- a/README.md +++ b/README.md @@ -79,10 +79,21 @@ The RPM Spec is not ready, don't try it unless for development. Qusal is now installed. Please read the README.md of each project for further information on how to install the desired package. -The intended behaviour is to enforce the state of qubes and their services. If +Every project creates its own template, client and server (when necessary) +with only the required packages and configuration. You don't need to use a +separate template for everything, but if you want to do that, you will have +adjust the target of the qubesctl call or write Salt Top files. + +When allowing more Qrexec calls than the default shipped by Qubes OS, you are +increasing the attack surface of the target, normally valuable qube that can +hold secrets or pristine data. A compromise of the client qube can extend to +the server, therefore configure the installation according to your threat +model. + +The intended behavior is to enforce the state of qubes and their services. If you modify the qubes and their services and apply the state again, there is a -good chance your choices will be overwritten. To enforce your state, -declaratively specify the desired state, do not do it manually, we are past +good chance your choices will be overwritten. To enforce your state, write a +SaltFile to specify the desired state, do not do it manually, we are past that. Qubes global settings (qubes-prefs) that will be managed: diff --git a/qusal/ansible/configure-minion.sls b/qusal/ansible/configure-minion.sls index f4186d3..f9a20f2 100644 --- a/qusal/ansible/configure-minion.sls +++ b/qusal/ansible/configure-minion.sls @@ -9,7 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-minion-start-sshd": file.managed: - name: /rw/config/rc.local - - source: salt://{{ slsdotpath }}/files/minion/rc.local + - source: salt://{{ slsdotpath }}/files/client/rc.local - mode: '0755' - user: root - group: root diff --git a/qusal/ansible/files/policy/default.policy b/qusal/ansible/files/admin/policy/default.policy similarity index 100% rename from qusal/ansible/files/policy/default.policy rename to qusal/ansible/files/admin/policy/default.policy diff --git a/qusal/ansible/files/minion/99-sshd-ansible.conf b/qusal/ansible/files/client/99-sshd-ansible.conf similarity index 100% rename from qusal/ansible/files/minion/99-sshd-ansible.conf rename to qusal/ansible/files/client/99-sshd-ansible.conf diff --git a/qusal/ansible/files/client/rc.local b/qusal/ansible/files/client/rc.local new file mode 100755 index 0000000..1a0c18f --- /dev/null +++ b/qusal/ansible/files/client/rc.local @@ -0,0 +1,8 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +systemctl unmask ssh +systemctl --no-block start ssh diff --git a/qusal/ansible/files/server/rc.local b/qusal/ansible/files/server/rc.local new file mode 100755 index 0000000..865d6ee --- /dev/null +++ b/qusal/ansible/files/server/rc.local @@ -0,0 +1,7 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +qvm-connect-tcp 22000:@default:22 diff --git a/qusal/ansible/install.sls b/qusal/ansible/install.sls index 81ff350..ec252ab 100644 --- a/qusal/ansible/install.sls +++ b/qusal/ansible/install.sls @@ -55,7 +55,7 @@ include: "{{ slsdotpath }}-sshd-config": file.managed: - name: /etc/ssh/sshd_config.d/99-sshd-ansible.conf - - source: salt://{{ slsdotpath }}/files/minion/99-sshd-ansible.conf + - source: salt://{{ slsdotpath }}/files/client/99-sshd-ansible.conf - mode: '0644' - user: root - group: root diff --git a/qusal/browser/create.sls b/qusal/browser/create.sls index b488d85..a8d55ce 100644 --- a/qusal/browser/create.sls +++ b/qusal/browser/create.sls @@ -18,9 +18,6 @@ prefs: - memory: 300 - maxmem: 2000 features: -- disable: - - service.tracker - - service.evolution-data-server - set: - default-menu-items: "firefox-esr.desktop chromium.desktop google-chrome.desktop qubes-run-terminal.desktop qubes-start.desktop" - menu-items: "firefox-esr.desktop chromium.desktop google-chrome.desktop qubes-run-terminal.desktop qubes-start.desktop" diff --git a/qusal/browser/install-common.sls b/qusal/browser/install-common.sls index 028908b..5e659ed 100644 --- a/qusal/browser/install-common.sls +++ b/qusal/browser/install-common.sls @@ -22,8 +22,8 @@ include: - qubes-core-agent-networking - ca-certificates - curl - - qubes-core-agent-nautilus - - nautilus + - qubes-core-agent-thunar + - thunar - zenity - libgdk-pixbuf2.0-bin - pulseaudio-qubes diff --git a/qusal/docker/configure.sls b/qusal/docker/configure.sls index 16b1b6f..3ed51f5 100644 --- a/qusal/docker/configure.sls +++ b/qusal/docker/configure.sls @@ -11,6 +11,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - name: /rw/config/rc.local - text: | usermod -aG docker user - systemctl start docker + systemctl unmask docker + systemctl --no-block restart docker {% endif -%} diff --git a/qusal/dom0/backup.sls b/qusal/dom0/backup.sls index 7e15f04..b349c51 100644 --- a/qusal/dom0/backup.sls +++ b/qusal/dom0/backup.sls @@ -6,7 +6,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-backup-find-script": file.managed: - - name: /usr/bin/qvm-backup-find-last + - name: /usr/local/bin/qvm-backup-find-last - source: salt://{{ slsdotpath }}/files/bin/qvm-backup-find-last - mode: '0755' - user: root diff --git a/qusal/dom0/files/bin/qubes-update b/qusal/dom0/files/bin/qubes-update new file mode 100755 index 0000000..d35b7dd --- /dev/null +++ b/qusal/dom0/files/bin/qubes-update @@ -0,0 +1,151 @@ +#!/usr/bin/python3 + +# SPDX-FileCopyrightText: 2015 Jason Mehring +# SPDX-FileCopyrightText: 2016 Bahtiar Gadimov +# SPDX-FileCopyrightText: 2016 - 2019 Marek Marczykowsk-Gorecki +# +# SPDX-FileCopyrightText: 2017 unman +# SPDX-FileCopyrightText: 2020 Frederic Pierret +# SPDX-FileCopyrightText: 2021 ctrlaltf24 +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. 1 and sys.argv[1] == '--dom0-only': + try: + import qubes.mgmt.patches + except ImportError: + pass + from salt.scripts import salt_call + + sys.argv[1] = '--local' + salt_call() + else: + sys.exit(main()) diff --git a/qusal/dom0/install.sls b/qusal/dom0/install.sls index b4d60a7..93a8b09 100644 --- a/qusal/dom0/install.sls +++ b/qusal/dom0/install.sls @@ -19,4 +19,12 @@ SPDX-License-Identifier: GPL-3.0-or-later - vim - xclip +"{{ slsdotpath }}-qubes-update-script": + file.managed: + - name: /usr/local/bin/qubes-update + - source: salt://{{ slsdotpath }}/files/bin/qubes-update + - mode: '0755' + - user: root + - group: root + {% endif -%} diff --git a/qusal/dotfiles b/qusal/dotfiles index edd1ac0..60b22d6 160000 --- a/qusal/dotfiles +++ b/qusal/dotfiles @@ -1 +1 @@ -Subproject commit edd1ac0a8a66f3aab4a348d0a9b34e290b536fcf +Subproject commit 60b22d66d248a2083b015e1aab2b8a711fae91cc diff --git a/qusal/media/configure.sls b/qusal/media/configure.sls index d4f5d3a..ba78c63 100644 --- a/qusal/media/configure.sls +++ b/qusal/media/configure.sls @@ -10,7 +10,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-home-config-mimeapps.list": file.managed: - name: /home/user/.config/mimeapps.list - - source: salt://{{ slsdotpath }}/files/app/mimeapps.list + - source: salt://{{ slsdotpath }}/files/client/mimeapps.list - mode: '0644' - user: user - group: user diff --git a/qusal/media/create.sls b/qusal/media/create.sls index c9cb850..51fe09c 100644 --- a/qusal/media/create.sls +++ b/qusal/media/create.sls @@ -81,7 +81,7 @@ prefs: - autostart: False - include_in_backups: False features: -- appemenus-dispvm: True +- appmenus-dispvm: True - disable: - service.cups - service.cups-browsed diff --git a/qusal/media/files/policy/default.policy b/qusal/media/files/admin/policy/default.policy similarity index 100% rename from qusal/media/files/policy/default.policy rename to qusal/media/files/admin/policy/default.policy diff --git a/qusal/media/files/app/mimeapps.list b/qusal/media/files/client/mimeapps.list similarity index 100% rename from qusal/media/files/app/mimeapps.list rename to qusal/media/files/client/mimeapps.list diff --git a/qusal/media/files/disp/mimeapps.list b/qusal/media/files/server/mimeapps.list similarity index 100% rename from qusal/media/files/disp/mimeapps.list rename to qusal/media/files/server/mimeapps.list diff --git a/qusal/media/install.sls b/qusal/media/install.sls index 277c718..9b8fab0 100644 --- a/qusal/media/install.sls +++ b/qusal/media/install.sls @@ -30,7 +30,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-etc-mimeapps.list": file.managed: - name: /etc/xdg/mimeapps.list - - source: salt://{{ slsdotpath }}/files/disp/mimeapps.list + - source: salt://{{ slsdotpath }}/files/server/mimeapps.list - mode: '0644' - user: root - group: root @@ -38,7 +38,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-idle-trimleness": file.replace: - - name: /lib/python3/dist-packages/qubesidle/idleness_monitor.py + - name: /usr/lib/python3/dist-packages/qubesidle/idleness_monitor.py - pattern: '15 \* 60' - repl: '3 * 60' diff --git a/qusal/qubes-builder/configure-qubes-executor.sls b/qusal/qubes-builder/configure-qubes-executor.sls index d3b9d56..d6ac460 100644 --- a/qusal/qubes-builder/configure-qubes-executor.sls +++ b/qusal/qubes-builder/configure-qubes-executor.sls @@ -12,16 +12,14 @@ include: - dotfiles.copy-x11 "{{ slsdotpath }}-executor-rpc": - file.managed: + file.recurse: + - name: /usr/local/etc/qubes-rpc/ + - source: salt://{{ slsdotpath }}/files/server/rpc/ - user: root - group: root - - mode: '0755' + - dir_mode: '0755' + - file_mode: '0755' - makedirs: True - - names: - - /usr/local/etc/qubes-rpc/qubesbuilder.FileCopyIn: - - source: salt://{{ slsdotpath }}/files/rpc/qubesbuilder.FileCopyIn - - /usr/local/etc/qubes-rpc/qubesbuilder.FileCopyOut: - - source: salt://{{ slsdotpath }}/files/rpc/qubesbuilder.FileCopyOut "{{ slsdotpath }}-executor-makedir-binded-builder": file.directory: @@ -34,7 +32,7 @@ include: "{{ slsdotpath }}-executor-bind-dirs": file.managed: - name: /rw/config/qubes-bind-dirs.d/builder.conf - - source: salt://{{ slsdotpath }}/files/qubes-executor/builder.conf + - source: salt://{{ slsdotpath }}/files/server/builder.conf - user: root - group: root - mode: '0644' diff --git a/qusal/qubes-builder/configure.sls b/qusal/qubes-builder/configure.sls index 3af8830..006f930 100644 --- a/qusal/qubes-builder/configure.sls +++ b/qusal/qubes-builder/configure.sls @@ -18,7 +18,7 @@ include: "{{ slsdotpath }}-gpg-split-domain": file.managed: - name: /rw/config/gpg-split-domain - - source: salt://{{ slsdotpath }}/files/qubes-builder/gpg-split-domain + - source: salt://{{ slsdotpath }}/files/client/gpg-split-domain - mode: '0644' - user: root - group: root @@ -26,7 +26,7 @@ include: "{{ slsdotpath }}-rpmmacros": file.managed: - name: /home/user/.rpmmacros - - source: salt://{{ slsdotpath }}/files/qubes-builder/rpmmacros + - source: salt://{{ slsdotpath }}/files/client/rpmmacros - mode: '0644' - user: user - group: user @@ -65,9 +65,9 @@ include: - mode: '0600' - names: - /home/user/.gnupg/qubes-builder/pubring.kbx: - - source: salt://{{ slsdotpath }}/files/keys/pubring.kbx + - source: salt://{{ slsdotpath }}/files/client/keys/pubring.kbx - /home/user/.gnupg/qubes-builder/trustdb.gpg: - - source: salt://{{ slsdotpath }}/files/keys/trustdb.gpg + - source: salt://{{ slsdotpath }}/files/client/keys/trustdb.gpg "{{ slsdotpath }}-git-verify-HEAD-builderv2": cmd.run: diff --git a/qusal/qubes-builder/files/policy/default.policy b/qusal/qubes-builder/files/admin/policy/default.policy similarity index 100% rename from qusal/qubes-builder/files/policy/default.policy rename to qusal/qubes-builder/files/admin/policy/default.policy diff --git a/qusal/qubes-builder/files/qubes-builder/gpg-split-domain b/qusal/qubes-builder/files/client/gpg-split-domain similarity index 100% rename from qusal/qubes-builder/files/qubes-builder/gpg-split-domain rename to qusal/qubes-builder/files/client/gpg-split-domain diff --git a/qusal/qubes-builder/files/keys/0064428F455451B3EBE78A7F063938BA42CFA724.asc b/qusal/qubes-builder/files/client/keys/0064428F455451B3EBE78A7F063938BA42CFA724.asc similarity index 100% rename from qusal/qubes-builder/files/keys/0064428F455451B3EBE78A7F063938BA42CFA724.asc rename to qusal/qubes-builder/files/client/keys/0064428F455451B3EBE78A7F063938BA42CFA724.asc diff --git a/qusal/qubes-builder/files/keys/274E12AB03F2FE293765FC06DA0434BC706E1FCF.asc b/qusal/qubes-builder/files/client/keys/274E12AB03F2FE293765FC06DA0434BC706E1FCF.asc similarity index 100% rename from qusal/qubes-builder/files/keys/274E12AB03F2FE293765FC06DA0434BC706E1FCF.asc rename to qusal/qubes-builder/files/client/keys/274E12AB03F2FE293765FC06DA0434BC706E1FCF.asc diff --git a/qusal/qubes-builder/files/keys/427F11FD0FAA4B080123F01CDDFA1A3E36879494.asc b/qusal/qubes-builder/files/client/keys/427F11FD0FAA4B080123F01CDDFA1A3E36879494.asc similarity index 100% rename from qusal/qubes-builder/files/keys/427F11FD0FAA4B080123F01CDDFA1A3E36879494.asc rename to qusal/qubes-builder/files/client/keys/427F11FD0FAA4B080123F01CDDFA1A3E36879494.asc diff --git a/qusal/qubes-builder/files/keys/9FA64B92F95E706BF28E2CA6484010B5CDC576E2.asc b/qusal/qubes-builder/files/client/keys/9FA64B92F95E706BF28E2CA6484010B5CDC576E2.asc similarity index 100% rename from qusal/qubes-builder/files/keys/9FA64B92F95E706BF28E2CA6484010B5CDC576E2.asc rename to qusal/qubes-builder/files/client/keys/9FA64B92F95E706BF28E2CA6484010B5CDC576E2.asc diff --git a/qusal/qubes-builder/files/keys/otrust.txt b/qusal/qubes-builder/files/client/keys/otrust.txt similarity index 100% rename from qusal/qubes-builder/files/keys/otrust.txt rename to qusal/qubes-builder/files/client/keys/otrust.txt diff --git a/qusal/qubes-builder/files/keys/pubring.kbx b/qusal/qubes-builder/files/client/keys/pubring.kbx similarity index 100% rename from qusal/qubes-builder/files/keys/pubring.kbx rename to qusal/qubes-builder/files/client/keys/pubring.kbx diff --git a/qusal/qubes-builder/files/keys/trustdb.gpg b/qusal/qubes-builder/files/client/keys/trustdb.gpg similarity index 100% rename from qusal/qubes-builder/files/keys/trustdb.gpg rename to qusal/qubes-builder/files/client/keys/trustdb.gpg diff --git a/qusal/qubes-builder/files/qubes-builder/rpmmacros b/qusal/qubes-builder/files/client/rpmmacros similarity index 100% rename from qusal/qubes-builder/files/qubes-builder/rpmmacros rename to qusal/qubes-builder/files/client/rpmmacros diff --git a/qusal/qubes-builder/files/qubes-executor/builder.conf b/qusal/qubes-builder/files/server/builder.conf similarity index 100% rename from qusal/qubes-builder/files/qubes-executor/builder.conf rename to qusal/qubes-builder/files/server/builder.conf diff --git a/qusal/qubes-builder/files/server/rc.local b/qusal/qubes-builder/files/server/rc.local new file mode 100644 index 0000000..8c29de4 --- /dev/null +++ b/qusal/qubes-builder/files/server/rc.local @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2023 The Qubes OS Project +# +# SPDX-License-Identifier: GPL-3.0-or-later + +mount /builder -o dev,suid,remount diff --git a/qusal/qubes-builder/files/rpc/qubesbuilder.FileCopyIn b/qusal/qubes-builder/files/server/rpc/qubesbuilder.FileCopyIn similarity index 100% rename from qusal/qubes-builder/files/rpc/qubesbuilder.FileCopyIn rename to qusal/qubes-builder/files/server/rpc/qubesbuilder.FileCopyIn diff --git a/qusal/qubes-builder/files/rpc/qubesbuilder.FileCopyOut b/qusal/qubes-builder/files/server/rpc/qubesbuilder.FileCopyOut similarity index 100% rename from qusal/qubes-builder/files/rpc/qubesbuilder.FileCopyOut rename to qusal/qubes-builder/files/server/rpc/qubesbuilder.FileCopyOut diff --git a/qusal/signal/configure.sls b/qusal/signal/configure.sls index 2a3aba8..fcdd879 100644 --- a/qusal/signal/configure.sls +++ b/qusal/signal/configure.sls @@ -6,6 +6,9 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' -%} +include: + - dotfiles.copy-x11 + "{{ slsdotpath }}-create-autostart-dir": cmd.run: - name: mkdir -p ~/.config/autostart diff --git a/qusal/signal/create.sls b/qusal/signal/create.sls index be26d3a..b1d9f97 100644 --- a/qusal/signal/create.sls +++ b/qusal/signal/create.sls @@ -16,9 +16,6 @@ force: True require: - sls: {{ slsdotpath }}.clone features: -- disable: - - service.tracker - - service.evolution-data-server - set: - menu-items: "signal-desktop.desktop qubes-open-file-manager.desktop qubes-run-terminal.desktop qubes-start.desktop" - default-menu-items: "signal-desktop.desktop qubes-open-file-manager.desktop qubes-run-terminal.desktop qubes-start.desktop" diff --git a/qusal/signal/install.sls b/qusal/signal/install.sls index fddab69..4fe44d4 100644 --- a/qusal/signal/install.sls +++ b/qusal/signal/install.sls @@ -9,6 +9,9 @@ SPDX-License-Identifier: GPL-3.0-or-later {% from 'utils/macros/install-repo.sls' import install_repo -%} {{ install_repo(sls_path, 'signal') }} +include: + - dotfiles.copy-x11 + "{{ slsdotpath }}-updated": pkg.uptodate: - refresh: True @@ -21,8 +24,8 @@ SPDX-License-Identifier: GPL-3.0-or-later - pkgs: - qubes-core-agent-networking - ca-certificates - - qubes-core-agent-nautilus - - nautilus + - qubes-core-agent-thunar + - thunar - pulseaudio-qubes - signal-desktop - zenity diff --git a/qusal/ssh/install.sls b/qusal/ssh/install.sls index 5f71d6b..274da6b 100644 --- a/qusal/ssh/install.sls +++ b/qusal/ssh/install.sls @@ -7,6 +7,36 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' -%} include: - - sys-ssh-agent.install-client + - dotfiles.copy-x11 + - dotfiles.copy-ssh -{% endif -%} +"{{ slsdotpath }}-client-updated": + pkg.uptodate: + - refresh: True + +"{{ slsdotpath }}-client-installed": + pkg.installed: + - refresh: True + - install_recommends: False + - skip_suggestions: True + - pkgs: + - qubes-core-agent-networking + - ca-certificates + +{% set pkg = { + 'Debian': { + 'pkg': ['openssh-client'], + }, + 'RedHat': { + 'pkg': ['openssh-clients'], + }, +}.get(grains.os_family) -%} + +"{{ slsdotpath }}-client-installed-os-specific": + pkg.installed: + - refresh: True + - install_recommends: False + - skip_suggestions: True + - pkgs: {{ pkg.pkg|sequence|yaml }} + +{% endif %} diff --git a/qusal/sys-cacher/configure.sls b/qusal/sys-cacher/configure.sls index f8e3980..d490caa 100644 --- a/qusal/sys-cacher/configure.sls +++ b/qusal/sys-cacher/configure.sls @@ -16,7 +16,7 @@ include: chown -R apt-cacher-ng:apt-cacher-ng /var/log/apt-cacher-ng chown -R apt-cacher-ng:apt-cacher-ng /var/cache/apt-cacher-ng systemctl unmask apt-cacher-ng - systemctl start apt-cacher-ng + systemctl --no-block restart apt-cacher-ng nft 'insert rule ip filter INPUT tcp dport 8082 counter accept' "{{ slsdotpath }}-install-qubes-firewall-user-script": @@ -26,8 +26,8 @@ include: "{{ slsdotpath }}-bind-dirs": file.managed: - - name: /rw/config/qubes-bind-dirs.d/50_user.conf - - source: salt://{{ slsdotpath }}/files/bind-dirs/50_user.conf + - name: /rw/config/qubes-bind-dirs.d/50_cacher.conf + - source: salt://{{ slsdotpath }}/files/server/bind-dirs/50_cacher.conf - user: root - group: root - makedirs: True diff --git a/qusal/sys-cacher/files/policy/default.policy b/qusal/sys-cacher/files/admin/policy/default.policy similarity index 100% rename from qusal/sys-cacher/files/policy/default.policy rename to qusal/sys-cacher/files/admin/policy/default.policy diff --git a/qusal/sys-cacher/files/bind-dirs/50_user.conf b/qusal/sys-cacher/files/server/bind-dirs/50_cacher.conf similarity index 100% rename from qusal/sys-cacher/files/bind-dirs/50_user.conf rename to qusal/sys-cacher/files/server/bind-dirs/50_cacher.conf diff --git a/qusal/sys-cacher/files/conf/acng.conf b/qusal/sys-cacher/files/server/conf/acng.conf similarity index 97% rename from qusal/sys-cacher/files/conf/acng.conf rename to qusal/sys-cacher/files/server/conf/acng.conf index b2cebd0..820945f 100644 --- a/qusal/sys-cacher/files/conf/acng.conf +++ b/qusal/sys-cacher/files/server/conf/acng.conf @@ -86,6 +86,15 @@ Remap-epel: file:epel_mirrors # Fedora EPEL Remap-slrep: file:sl_mirrors # Scientific Linux Remap-gentoo: file:gentoo_mirrors.gz /gentoo ; file:backends_gentoo # Gentoo Archives Remap-secdeb: security.debian.org security.debian.org/debian-security deb.debian.org/debian-security /debian-security cdn-fastly.deb.debian.org/debian-security ; deb.debian.org/debian-security security.debian.org cdn-fastly.deb.debian.org/debian-security +# Qusal external repositories +Remap-qubesdebrep: https://deb.qubes-os.org http://deb.qubes-os.org +Remap-qubesyumrep: https://yum.qubes-os.org http://yum.qubes-os.org +Remap-dockerrep: https://download.docker.com http://download.docker.com +Remap-googlerep: https://dl.google.com http://dl.google.com +Remap-hashicorprep: https://apt.releases.hashicorp.com http://apt.releases.hashicorp.com +Remap-launchpadrep: https://ppa.launchpad.net http://ppa.launchpad.net +Remap-signalrep: https://updates.signal.org http://updates.signal.org +Remap-syncthingrep: https://apt.syncthing.net # Virtual page accessible in a web browser to see statistics and status # information, i.e. under http://localhost:3142/acng-report.html @@ -455,6 +464,9 @@ AllowUserPorts: 80 443 # and means fetching the whole file from the beginning. # # VfileUseRangeOps: 1 +# +# Syncthing server: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1053833 +VfileUseRangeOps: 0 # Allow data pass-through mode for certain hosts when requested by the client # using a CONNECT request. This is particularly useful to allow access to SSL diff --git a/qusal/sys-cacher/files/mirrors/archlx_mirrors b/qusal/sys-cacher/files/server/mirrors/archlx_mirrors similarity index 100% rename from qusal/sys-cacher/files/mirrors/archlx_mirrors rename to qusal/sys-cacher/files/server/mirrors/archlx_mirrors diff --git a/qusal/sys-cacher/files/mirrors/fedora_mirrors b/qusal/sys-cacher/files/server/mirrors/fedora_mirrors similarity index 100% rename from qusal/sys-cacher/files/mirrors/fedora_mirrors rename to qusal/sys-cacher/files/server/mirrors/fedora_mirrors diff --git a/qusal/sys-cacher/install.sls b/qusal/sys-cacher/install.sls index 7d5a77a..ff0f80f 100644 --- a/qusal/sys-cacher/install.sls +++ b/qusal/sys-cacher/install.sls @@ -44,20 +44,20 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-update-debian-mirrors": cmd.run: - - name: cp /lib/apt-cacher-ng/deb_mirrors.gz /etc/apt-cacher-ng/deb_mirrors.gz + - name: cp /usr/lib/apt-cacher-ng/deb_mirrors.gz /etc/apt-cacher-ng/deb_mirrors.gz - runas: root "{{ slsdotpath }}-update-fedora-mirrors": file.managed: - name: /etc/apt-cacher-ng/fedora_mirrors - - source: salt://{{ slsdotpath }}/files/mirrors/fedora_mirrors + - source: salt://{{ slsdotpath }}/files/server/mirrors/fedora_mirrors - user: root - group: root "{{ slsdotpath }}-update-arch-mirrors": file.managed: - name: /etc/apt-cacher-ng/archlx_mirrors - - source: salt://{{ slsdotpath }}/files/mirrors/archlx_mirrors + - source: salt://{{ slsdotpath }}/files/server/mirrors/archlx_mirrors - user: root - group: root @@ -69,7 +69,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-acng.conf": file.managed: - name: /etc/apt-cacher-ng/acng.conf - - source: salt://{{ slsdotpath }}/files/conf/acng.conf + - source: salt://{{ slsdotpath }}/files/server/conf/acng.conf - user: root - group: root - makedirs: True diff --git a/qusal/sys-git/files/policy/default.policy b/qusal/sys-git/files/admin/policy/default.policy similarity index 100% rename from qusal/sys-git/files/policy/default.policy rename to qusal/sys-git/files/admin/policy/default.policy diff --git a/qusal/sys-git/files/rpc/qusal.GitFetch b/qusal/sys-git/files/server/rpc/qusal.GitFetch similarity index 100% rename from qusal/sys-git/files/rpc/qusal.GitFetch rename to qusal/sys-git/files/server/rpc/qusal.GitFetch diff --git a/qusal/sys-git/files/rpc/qusal.GitInit b/qusal/sys-git/files/server/rpc/qusal.GitInit similarity index 100% rename from qusal/sys-git/files/rpc/qusal.GitInit rename to qusal/sys-git/files/server/rpc/qusal.GitInit diff --git a/qusal/sys-git/files/rpc/qusal.GitPush b/qusal/sys-git/files/server/rpc/qusal.GitPush similarity index 100% rename from qusal/sys-git/files/rpc/qusal.GitPush rename to qusal/sys-git/files/server/rpc/qusal.GitPush diff --git a/qusal/sys-git/install.sls b/qusal/sys-git/install.sls index 326e634..5f1c7e7 100644 --- a/qusal/sys-git/install.sls +++ b/qusal/sys-git/install.sls @@ -27,7 +27,7 @@ include: "{{ slsdotpath }}-rpc": file.recurse: - name: /etc/qubes-rpc/ - - source: salt://{{ slsdotpath }}/files/rpc/ + - source: salt://{{ slsdotpath }}/files/server/rpc - user: root - group: root - file_mode: '0755' diff --git a/qusal/sys-mirage-firewall/README.md b/qusal/sys-mirage-firewall/README.md new file mode 100644 index 0000000..46f2781 --- /dev/null +++ b/qusal/sys-mirage-firewall/README.md @@ -0,0 +1,51 @@ +# sys-mirage-firewall + +## Table of Contents + +* [Description](#description) +* [Installation](#installation) + +## Description + +Mirage Firewall on Qubes OS. + +Creates a Mirage Firewall qube named "sys-mirage-firewall". It is an OCaml +program compiled to run as an operating system kernel, in this case, a +MirageOS unikernel replacement for the default firewall (sys-firewall). It +pulls in just the code it needs as libraries. + +Contrary to a standard Linux Firewall, Mirage Firewall doesn't need a full +system to run an excessive resources. + +## Installation + +- Top +```sh +qubesctl top.enable sys-mirage-firewall +qubesctl state.apply +qubesctl top.disable sys-mirage-firewall +``` + +- State +```sh +qubesctl state.apply sys-mirage-firewall.create +``` + +Set qubes `netvm` to `sys-mirage-firewall`: +```sh +qvm-prefs --set QUBE netvm sys-mirage-firewall +``` + +## Usage + +From Dom0, set the firewall rules with `qvm-firewall`. + +From Dom0, inspect the Unikernel console: +```sh +sudo xl console sys-mirage-firewall +``` +Exit the console with `Ctrl-]`. + +## Credits + +- [Unman](https://github.com/unman/shaker/tree/master/mirage) diff --git a/qusal/sys-mirage-firewall/create.sls b/qusal/sys-mirage-firewall/create.sls new file mode 100644 index 0000000..b4217f7 --- /dev/null +++ b/qusal/sys-mirage-firewall/create.sls @@ -0,0 +1,72 @@ +{# +SPDX-FileCopyrightText: 2023 unman +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{%- from "qvm/template.jinja" import load -%} + +{# Use the netvm of the default_netvm. #} +{% set default_netvm = salt['cmd.shell']('qubes-prefs default_netvm') -%} +{% set netvm = salt['cmd.shell']('qvm-prefs ' + default_netvm + ' netvm') -%} +{# +If netvm of default_netvm is empty, user's default_netvm is the first in +the chain (sys-net). +#} +{% if netvm == '' %} + {% set netvm = default_netvm %} +{% endif %} + +"sys-mirage-firewall-create-vm-kernels-dir": + file.directory: + - name: /var/lib/qubes/vm-kernels/mirage-firewall + - mode: '0755' + - user: root + - group: root + - makedirs: True + +"sys-mirage-firewall-extract-to-vm-kernels": + archive.extracted: + - name: /var/lib/qubes/vm-kernels/ + - require: + - file: sys-mirage-firewall-create-vm-kernels-dir + - source: salt://sys-mirage-firewall/files/admin/mirage-firewall.tar.bz2 + - source_hash: salt://sys-mirage-firewall/files/admin/mirage-firewall.sha256 + - archive_format: tar + - options: -j + +"sys-mirage-firewall-save-version": + file.managed: + - name: /var/lib/qubes/vm-kernels/mirage-firewall/version.txt + - source: salt://sys-mirage-firewall/files/admin/version.txt + - mode: '0644' + - user: root + - group: root + - makedirs: True + +{% load_yaml as defaults -%} +name: sys-mirage-firewall +force: True +require: + - file: sys-mirage-firewall-save-version +present: +- class: StandaloneVM +- label: orange +- virt_mode: pvh +prefs: +- label: orange +- netvm: {{ netvm }} +- memory: 64 +- maxmem: 64 +- vcpus: 1 +- provides-network: True +- default_dispvm: "" +- kernel: mirage-firewall +- kernelopts: '' +features: +- enable: + - service.qubes-firewall + - no-default-kernelopts +{%- endload %} +{{ load(defaults) }} diff --git a/qusal/sys-mirage-firewall/create.top b/qusal/sys-mirage-firewall/create.top new file mode 100644 index 0000000..34253da --- /dev/null +++ b/qusal/sys-mirage-firewall/create.top @@ -0,0 +1,10 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'dom0': + - match: nodegroup + - sys-mirage-firewall.create diff --git a/qusal/sys-mirage-firewall/files/admin/mirage-firewall.sha256 b/qusal/sys-mirage-firewall/files/admin/mirage-firewall.sha256 new file mode 100644 index 0000000..2fb7aab --- /dev/null +++ b/qusal/sys-mirage-firewall/files/admin/mirage-firewall.sha256 @@ -0,0 +1 @@ +833cea063ab8fa87954c56e75e326f0d0ac9b9a2ee8e88a05e2a50af50666ef2 mirage-firewall.tar.bz2 diff --git a/qusal/sys-mirage-firewall/files/admin/mirage-firewall.tar.bz2 b/qusal/sys-mirage-firewall/files/admin/mirage-firewall.tar.bz2 new file mode 100644 index 0000000..38223cf Binary files /dev/null and b/qusal/sys-mirage-firewall/files/admin/mirage-firewall.tar.bz2 differ diff --git a/qusal/sys-mirage-firewall/files/admin/version.txt b/qusal/sys-mirage-firewall/files/admin/version.txt new file mode 100644 index 0000000..9fbdd82 --- /dev/null +++ b/qusal/sys-mirage-firewall/files/admin/version.txt @@ -0,0 +1 @@ +v0.8.5 diff --git a/qusal/sys-mirage-firewall/init.top b/qusal/sys-mirage-firewall/init.top new file mode 100644 index 0000000..34253da --- /dev/null +++ b/qusal/sys-mirage-firewall/init.top @@ -0,0 +1,10 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'dom0': + - match: nodegroup + - sys-mirage-firewall.create diff --git a/qusal/sys-net/files/policy/default.policy b/qusal/sys-net/files/admin/policy/default.policy similarity index 100% rename from qusal/sys-net/files/policy/default.policy rename to qusal/sys-net/files/admin/policy/default.policy diff --git a/qusal/sys-pgp/README.md b/qusal/sys-pgp/README.md index 76b6640..31d5590 100644 --- a/qusal/sys-pgp/README.md +++ b/qusal/sys-pgp/README.md @@ -36,10 +36,9 @@ Install on the client template: qubesctl --skip-dom0 --targets=tpl-qubes-builder,tpl-dev state.apply sys-pgp.install-client ``` -The client qube also requires the service to be enabled: +The client qube requires the split GPG client service to be enabled: ```sh -qvm-features qubes-builder service.split-gpg2-client -qvm-features dev service.split-gpg2-client +qvm-features QUBE service.split-gpg2-client ``` ## Access Control diff --git a/qusal/sys-pgp/files/policy/default.policy b/qusal/sys-pgp/files/admin/policy/default.policy similarity index 100% rename from qusal/sys-pgp/files/policy/default.policy rename to qusal/sys-pgp/files/admin/policy/default.policy diff --git a/qusal/sys-pihole/README.md b/qusal/sys-pihole/README.md index fc751d5..fa8392b 100644 --- a/qusal/sys-pihole/README.md +++ b/qusal/sys-pihole/README.md @@ -25,9 +25,9 @@ to it. - Top: ```sh qubesctl top.enable sys-pihole browser -qubesctl --targets=tpl-browser,sys-pihole,dvm-sys-pihole state.apply +qubesctl --targets=tpl-browser,sys-pihole,sys-pihole-browser state.apply qubesctl top.disable sys-pihole browser -qubesctl state.apply browser.appmenus +qubesctl state.apply sys-pihole.appmenus ``` - State: @@ -35,8 +35,8 @@ qubesctl state.apply browser.appmenus qubesctl state.apply sys-pihole.create qubesctl --skip-dom0 --targets=tpl-browser state.apply browser.install qubesctl --skip-dom0 --targets=sys-pihole state.apply sys-pihole.install -qubesctl --skip-dom0 --targets=dvm-browser-sys-pihole state.apply sys-pihole.configure-dvm -qubesctl state.apply browser.appmenus +qubesctl --skip-dom0 --targets=sys-pihole-browser state.apply sys-pihole.configure-browser +qubesctl state.apply sys-pihole.appmenus ``` If you want to change the global preferences `updatevm` and `default_netvm` @@ -63,12 +63,16 @@ You should change this password on first use by running in `sys-pihole`: pihole -a -p ``` -If you want to view statistics or manage Pi-Hole through the browser, open the -browser in `disp-browser-sys-pihole`. This disposable qube has no netvm and -has connection to the Pi-Hole server. The browser separation is to prevent the -use of a browser in the same machine the server is running, which you could -mistakenly browse the internet in the proxy qube if the separation was not -done. +If you want to view statistics or manage the server through a GUI, open +`sys-pihole` or `sys-pihole-browser` desktop file `pihole-browser.desktop` +from Dom0. Addresses starting with `http` or `https` will be redirected +to `sys-pihole-browser`. + +The browser separation from the server is to avoid browsing malicious sites +and exposing the browser to direct network on the same machine the server is +running. The browser qube is offline and only has access to the admin +interface. In other words, it has control over the server functions, if the +browser is compromised, it can compromise the server. You can clone `sys-pihole`. If you do, you must manually change the IP address of the clone. diff --git a/qusal/sys-pihole/appmenus.sls b/qusal/sys-pihole/appmenus.sls new file mode 100644 index 0000000..560fb81 --- /dev/null +++ b/qusal/sys-pihole/appmenus.sls @@ -0,0 +1,14 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +include: + - browser.appmenus + +{% from 'utils/macros/sync-appmenus.sls' import sync_appmenus -%} +{{ sync_appmenus(sls_path) }} + +{% from 'utils/macros/sync-appmenus.sls' import sync_appmenus -%} +{{ sync_appmenus(sls_path ~ '-browser') }} diff --git a/qusal/sys-pihole/configure-dvm.top b/qusal/sys-pihole/appmenus.top similarity index 69% rename from qusal/sys-pihole/configure-dvm.top rename to qusal/sys-pihole/appmenus.top index d06d45e..8f21efa 100644 --- a/qusal/sys-pihole/configure-dvm.top +++ b/qusal/sys-pihole/appmenus.top @@ -5,5 +5,6 @@ SPDX-License-Identifier: GPL-3.0-or-later #} base: - 'dvm-browser-sys-pihole': - - sys-pihole.configure-dvm + 'dom0': + - match: nodegroup + - sys-pihole.appmenus diff --git a/qusal/sys-pihole/configure-dvm.sls b/qusal/sys-pihole/configure-browser.sls similarity index 51% rename from qusal/sys-pihole/configure-dvm.sls rename to qusal/sys-pihole/configure-browser.sls index 58f925f..d41c5e4 100644 --- a/qusal/sys-pihole/configure-dvm.sls +++ b/qusal/sys-pihole/configure-browser.sls @@ -7,9 +7,18 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' %} -"{{ slsdotpath }}-dvm-rc.local": +"{{ slsdotpath }}-browser-rc.local": file.append: - name: /rw/config/rc.local - text: "qvm-connect-tcp 80:@default:80" +"{{ slsdotpath }}-browser-desktop-application": + file.managed: + - name: /home/user/.local/share/applications/pihole-browser.desktop + - source: salt://{{ slsdotpath }}/files/browser/pihole-browser.desktop + - mode: '0644' + - user: user + - group: user + - makedirs: True + {% endif -%} diff --git a/qusal/sys-pihole/configure-browser.top b/qusal/sys-pihole/configure-browser.top new file mode 100644 index 0000000..70a2acb --- /dev/null +++ b/qusal/sys-pihole/configure-browser.top @@ -0,0 +1,9 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'sys-pihole-browser': + - sys-pihole.configure-browser diff --git a/qusal/sys-pihole/create.sls b/qusal/sys-pihole/create.sls index 3b8834e..7effe59 100644 --- a/qusal/sys-pihole/create.sls +++ b/qusal/sys-pihole/create.sls @@ -50,11 +50,13 @@ features: - service.cups-browsed - service.tracker - service.evolution-data-server +- set: + - menu-items: "pihole-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" {%- endload %} {{ load(defaults) }} {% load_yaml as defaults -%} -name: dvm-browser-{{ slsdotpath }} +name: {{ slsdotpath }}-browser force: True require: - sls: browser.create @@ -67,43 +69,15 @@ prefs: - maxmem: 600 - vcpus: 1 - netvm: "" -- template_for_dispvms: True - include_in_backups: False features: -- disable: - - service.tracker - - service.evolution-data-server -- enable: - - appmenus-dispvm -- set: - - menu-items: "firefox-esr.desktop chromium.desktop google-chrome.desktop qubes-open-file-manager.desktop qubes-run-terminal.desktop" -{%- endload %} -{{ load(defaults) }} - - -{% load_yaml as defaults -%} -name: disp-browser-{{ slsdotpath }} -force: True -require: -- sls: browser.create -present: -- template: dvm-browser-{{ slsdotpath }} -- label: orange -- class: DispVM -prefs: -- label: orange -- memory: 300 -- maxmem: 600 -- vcpus: 1 -- netvm: "" -features: - disable: - service.cups - service.cups-browsed - service.tracker - service.evolution-data-server - set: - - menu-items: "firefox-esr.desktop chromium.desktop google-chrome.desktop qubes-open-file-manager.desktop qubes-run-terminal.desktop" + - menu-items: "pihole-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" {%- endload %} {{ load(defaults) }} diff --git a/qusal/sys-pihole/files/policy/default.policy b/qusal/sys-pihole/files/admin/policy/default.policy similarity index 51% rename from qusal/sys-pihole/files/policy/default.policy rename to qusal/sys-pihole/files/admin/policy/default.policy index 65dd0e1..6d575ef 100644 --- a/qusal/sys-pihole/files/policy/default.policy +++ b/qusal/sys-pihole/files/admin/policy/default.policy @@ -4,6 +4,8 @@ ## Do not modify this file, create a new policy with with a lower number in the ## file name instead. For example `30-user.policy`. -qubes.ConnectTCP +80 disp-browser-{{ sls_path }} @default allow target={{ sls_path }} -qubes.ConnectTCP * disp-browser-{{ sls_path }} @anyvm deny +qubes.OpenURL * {{ sls_path }} @default allow target={{ sls_path }}-browser +qubes.OpenURL * {{ sls_path }} @anyvm deny +qubes.ConnectTCP +80 {{ sls_path }}-browser @default allow target={{ sls_path }} +qubes.ConnectTCP * {{ sls_path }}-browser @anyvm deny ## vim:ft=qrexecpolicy diff --git a/qusal/sys-pihole/files/prefs.sh b/qusal/sys-pihole/files/admin/prefs.sh similarity index 100% rename from qusal/sys-pihole/files/prefs.sh rename to qusal/sys-pihole/files/admin/prefs.sh diff --git a/qusal/sys-pihole/files/browser/pihole-browser.desktop b/qusal/sys-pihole/files/browser/pihole-browser.desktop new file mode 100644 index 0000000..91fb2ff --- /dev/null +++ b/qusal/sys-pihole/files/browser/pihole-browser.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Pi-Hole Browser +Exec=xdg-open http://127.0.0.1:80 +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser;FileTransfer;P2P; diff --git a/qusal/sys-pihole/files/firewall/flush b/qusal/sys-pihole/files/server/firewall/flush similarity index 100% rename from qusal/sys-pihole/files/firewall/flush rename to qusal/sys-pihole/files/server/firewall/flush diff --git a/qusal/sys-pihole/files/firewall/flush.sh b/qusal/sys-pihole/files/server/firewall/flush.sh similarity index 100% rename from qusal/sys-pihole/files/firewall/flush.sh rename to qusal/sys-pihole/files/server/firewall/flush.sh diff --git a/qusal/sys-pihole/files/firewall/internalise.sh b/qusal/sys-pihole/files/server/firewall/internalise.sh similarity index 100% rename from qusal/sys-pihole/files/firewall/internalise.sh rename to qusal/sys-pihole/files/server/firewall/internalise.sh diff --git a/qusal/sys-pihole/files/firewall/update_nft.sh b/qusal/sys-pihole/files/server/firewall/update_nft.sh similarity index 100% rename from qusal/sys-pihole/files/firewall/update_nft.sh rename to qusal/sys-pihole/files/server/firewall/update_nft.sh diff --git a/qusal/sys-pihole/files/server/mimeapps.list b/qusal/sys-pihole/files/server/mimeapps.list new file mode 100644 index 0000000..5b9ecb9 --- /dev/null +++ b/qusal/sys-pihole/files/server/mimeapps.list @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2023 unman +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Default Applications] +x-scheme-handler/http=pihole-browser-general.desktop +x-scheme-handler/https=pihole-browser-general.desktop diff --git a/qusal/sys-pihole/files/network/eth0 b/qusal/sys-pihole/files/server/network/eth0 similarity index 100% rename from qusal/sys-pihole/files/network/eth0 rename to qusal/sys-pihole/files/server/network/eth0 diff --git a/qusal/sys-pihole/files/network/setupVars.conf b/qusal/sys-pihole/files/server/network/setupVars.conf similarity index 100% rename from qusal/sys-pihole/files/network/setupVars.conf rename to qusal/sys-pihole/files/server/network/setupVars.conf diff --git a/qusal/sys-pihole/files/server/pihole-browser-general.desktop b/qusal/sys-pihole/files/server/pihole-browser-general.desktop new file mode 100644 index 0000000..a5971d0 --- /dev/null +++ b/qusal/sys-pihole/files/server/pihole-browser-general.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Pi-Hole Browser URL Forwarder +Exec=qvm-open-in-vm -- @default %u +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser;FileTransfer;P2P; diff --git a/qusal/sys-pihole/files/server/pihole-browser.desktop b/qusal/sys-pihole/files/server/pihole-browser.desktop new file mode 100644 index 0000000..0094036 --- /dev/null +++ b/qusal/sys-pihole/files/server/pihole-browser.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Pi-Hole Browser +Exec=qvm-open-in-vm -- @default http://127.0.0.1:80 +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser; diff --git a/qusal/sys-pihole/init.top b/qusal/sys-pihole/init.top index 0b26151..102acd5 100644 --- a/qusal/sys-pihole/init.top +++ b/qusal/sys-pihole/init.top @@ -10,5 +10,5 @@ base: - sys-pihole.create 'sys-pihole': - sys-pihole.install - 'dvm-browser-sys-pihole': - - sys-pihole.configure-dvm + 'sys-pihole-browser': + - sys-pihole.configure-browser diff --git a/qusal/sys-pihole/install.sls b/qusal/sys-pihole/install.sls index 5194191..abe5517 100644 --- a/qusal/sys-pihole/install.sls +++ b/qusal/sys-pihole/install.sls @@ -16,7 +16,7 @@ include: "{{ slsdotpath }}-set-eth0-interface": file.managed: - name: /etc/network/interfaces.d/eth0 - - source: salt://{{ slsdotpath }}/files/network/eth0 + - source: salt://{{ slsdotpath }}/files/server/network/eth0 - user: root - group: root - makedirs: True @@ -82,7 +82,7 @@ include: "{{ slsdotpath }}-setupVars.conf": file.managed: - name: /etc/pihole/setupVars.conf - - source: salt://{{ slsdotpath }}/files/network/setupVars.conf + - source: salt://{{ slsdotpath }}/files/server/network/setupVars.conf - user: root - group: root - makedirs: True @@ -104,7 +104,7 @@ include: "{{ slsdotpath }}-firewall-update-nft-rules": file.managed: - name: /rw/config/qubes-firewall.d/update_nft.sh - - source: salt://{{ slsdotpath }}/files/firewall/update_nft.sh + - source: salt://{{ slsdotpath }}/files/server/firewall/update_nft.sh - user: root - group: root - makedirs: True @@ -113,7 +113,7 @@ include: "{{ slsdotpath }}-firewall-route-localnet": file.managed: - name: /rw/config/network-hooks.d/internalise.sh - - source: salt://{{ slsdotpath }}/files/firewall/internalise.sh + - source: salt://{{ slsdotpath }}/files/server/firewall/internalise.sh - user: root - group: root - makedirs: True @@ -122,7 +122,7 @@ include: "{{ slsdotpath }}-firewall-flush": file.managed: - name: /rw/config/network-hooks.d/flush.sh - - source: salt://{{ slsdotpath }}/files/firewall/flush.sh + - source: salt://{{ slsdotpath }}/files/server/firewall/flush.sh - user: root - group: root - makedirs: True @@ -131,7 +131,7 @@ include: "{{ slsdotpath }}-firewall-flush-rules": file.managed: - name: /rw/config/network-hooks.d/flush - - source: salt://{{ slsdotpath }}/files/firewall/flush + - source: salt://{{ slsdotpath }}/files/server/firewall/flush - user: root - group: root - makedirs: True @@ -144,4 +144,31 @@ include: - interface=lo - bind-interfaces +"{{ slsdotpath }}-desktop-application-browser": + file.managed: + - name: /usr/share/applications/pihole-browser.desktop + - source: salt://{{ slsdotpath }}/files/server/pihole-browser.desktop + - mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-desktop-application-open-general": + file.managed: + - name: /usr/share/applications/pihole-browser-general.desktop + - source: salt://{{ slsdotpath }}/files/server/pihole-browser-general.desktop + - mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-etc-mimeapps.list": + file.managed: + - name: /etc/xdg/mimeapps.list + - source: salt://{{ slsdotpath }}/files/server/mimeapps.list + - mode: '0644' + - user: root + - group: root + - makedirs: True + {% endif -%} diff --git a/qusal/sys-pihole/prefs.sls b/qusal/sys-pihole/prefs.sls index 04cc424..95104f2 100644 --- a/qusal/sys-pihole/prefs.sls +++ b/qusal/sys-pihole/prefs.sls @@ -7,7 +7,7 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-change-prefs": cmd.script: - name: prefs.sh - - source: salt://{{ slsdotpath }}/files/prefs.sh + - source: salt://{{ slsdotpath }}/files/admin/prefs.sh {# "{{ slsdotpath }}-start": diff --git a/qusal/sys-rsync/README.md b/qusal/sys-rsync/README.md new file mode 100644 index 0000000..d9135b4 --- /dev/null +++ b/qusal/sys-rsync/README.md @@ -0,0 +1,100 @@ +# sys-rsync + +## Table of Contents + +* [Description](#description) +* [Installation](#installation) +* [Access Control](#access-control) +* [Usage](#usage) + * [Server](#server) + * [Client](#client) +* [Credits](#credits) + +## Description + +Rsync over Qrexec on Qubes OS. + +Creates a Rsync server qube named "sys-rsync" to be a central document +store to which other qubes have access. This is a simple tool that allows +individual qubes read/write access to the store using Rsync, rather than using +`qvm-copy` or `qvm-move`. + +The greatest problem with SSH is that with large file system, it can freeze +or be very slow to navigate the directories (not so much with Qrexec as the +connection does not go over the network) and chroots need to be configured by +the user. + +## Installation + +- Top: +```sh +qubesctl top.enable sys-rsync +qubesctl --targets=tpl-sys-rsync,sys-rsync state.apply +qubesctl top.disable sys-rsync +``` + +- State: +```sh +qubesctl state.apply sys-rsync.create +qubesctl --skip-dom0 --targets=tpl-sys-rsync state.apply sys-rsync.install +qubesctl --skip-dom0 --targets=sys-rsync state.apply sys-rsync.configure +``` + +Install on the client template: +```sh +qubesctl --skip-dom0 --targets=QUBE state.apply sys-rsync.install-client +``` + +The client qube requires the Rsync forwarder service to be enabled: +``` +qvm-features QUBE service.rsync-setup 1 +``` + +## Access Control + +A `qusal.Rsync` service is created to allow use of Rsync over Qrexec. The +default policy `asks` if you want to connect with the `sys-rsync` qube. + +If you want to `allow` Rsync between qubes, insert in you user policy file +`/etc/qubes/policy.d/30-user.policy` to allow the service using the following +format: +```qrexecpolicy +qusal.Rsync * SOURCE @default allow target=TARGET +``` + +When the client can change the data on the server, it can also possibly +compromise the server or at least make it hold malicious files and propagate +the malicious data with client it is connected to. + +## Usage + +### Server + +The default setting is to have a **read/write** store at `/home/user/shared`, +and a **read-only** directory at `/home/user/archive`. All the usual Rsync +configuration options are available and you can create other shared +directories at will. Additional configuration can be made by editing `.conf` +files in `/usr/local/etc/rsync.d/*.conf`. Because access appears to come from +localhost, host control directives will not work. + +If you have more than one rsync server qube, you can use +[bind-dirs](https://www.qubes-os.org/doc/bind-dirs/) to change the available +folders on each server qube. + +### Client + +The Rsync connection is available with the socket `localhost:1839`. + +Rsync the server `shared` read/write directory: +```sh +rsync --port=1839 localhost::shared /LOCAL/PATH/TO/RSYNC +``` + +Rsync the server `archive` read-only directory: +```sh +rsync --port=1839 localhost::archive /LOCAL/PATH/TO/RSYNC +``` + +## Credits + +- [Unman](https://github.com/unman/qubes-sync) diff --git a/qusal/sys-sshfs/clone.sls b/qusal/sys-rsync/clone.sls similarity index 100% rename from qusal/sys-sshfs/clone.sls rename to qusal/sys-rsync/clone.sls diff --git a/qusal/sys-sshfs/clone.top b/qusal/sys-rsync/clone.top similarity index 88% rename from qusal/sys-sshfs/clone.top rename to qusal/sys-rsync/clone.top index 9b3896a..a4d4bf9 100644 --- a/qusal/sys-sshfs/clone.top +++ b/qusal/sys-rsync/clone.top @@ -7,4 +7,4 @@ SPDX-License-Identifier: GPL-3.0-or-later base: 'dom0': - match: nodegroup - - sys-sshfs.clone + - sys-rsync.clone diff --git a/qusal/sys-rsync/configure.sls b/qusal/sys-rsync/configure.sls new file mode 100644 index 0000000..29db7bc --- /dev/null +++ b/qusal/sys-rsync/configure.sls @@ -0,0 +1,38 @@ +{# +SPDX-FileCopyrightText: 2022 unman +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +include: + - dev.home-cleanup + +"{{ slsdotpath }}-start-rsync-on-boot": + file.append: + - name: /rw/config/rc.local + - source: salt://{{ slsdotpath }}/files/server/rc.local + +"{{ slsdotpath }}-creates-local-rsync-configuration-dir": + file.directory: + - name: /usr/local/etc/rsync.d + - mode: '0755' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-creates-archive-dir": + file.directory: + - name: /home/user/archive + - mode: '0777' + - user: user + - group: user + - makedirs: True + +"{{ slsdotpath }}-creates-shared-dir": + file.directory: + - name: /home/user/shared + - mode: '0777' + - user: user + - group: user + - makedirs: True diff --git a/qusal/sys-sshfs/configure.top b/qusal/sys-rsync/configure.top similarity index 76% rename from qusal/sys-sshfs/configure.top rename to qusal/sys-rsync/configure.top index c8b494c..3f01682 100644 --- a/qusal/sys-sshfs/configure.top +++ b/qusal/sys-rsync/configure.top @@ -5,5 +5,5 @@ SPDX-License-Identifier: GPL-3.0-or-later #} base: - 'sys-sshfs': - - sys-sshfs.configure + 'sys-rsync': + - sys-rsync.configure diff --git a/qusal/sys-sshfs/create.sls b/qusal/sys-rsync/create.sls similarity index 100% rename from qusal/sys-sshfs/create.sls rename to qusal/sys-rsync/create.sls diff --git a/qusal/sys-sshfs/create.top b/qusal/sys-rsync/create.top similarity index 87% rename from qusal/sys-sshfs/create.top rename to qusal/sys-rsync/create.top index 3cae880..0dc8dc3 100644 --- a/qusal/sys-sshfs/create.top +++ b/qusal/sys-rsync/create.top @@ -7,4 +7,4 @@ SPDX-License-Identifier: GPL-3.0-or-later base: 'dom0': - match: nodegroup - - sys-sshfs.create + - sys-rsync.create diff --git a/qusal/sys-syncthing/files/policy/default.policy b/qusal/sys-rsync/files/admin/policy/default.policy similarity index 66% rename from qusal/sys-syncthing/files/policy/default.policy rename to qusal/sys-rsync/files/admin/policy/default.policy index 82692f7..6cf5022 100644 --- a/qusal/sys-syncthing/files/policy/default.policy +++ b/qusal/sys-rsync/files/admin/policy/default.policy @@ -4,6 +4,6 @@ ## Do not modify this file, create a new policy with with a lower number in the ## file name instead. For example `30-user.policy`. -qusal.Syncthing * @anyvm @default ask target={{ sls_path }} default_target={{ sls_path }} -qusal.Syncthing * @anyvm @anyvm deny +qusal.Rsync * @anyvm @default ask target=sys-rsync default_target=sys-rsync +qusal.Rsync * @anyvm @anyvm deny ## vim:ft=qrexecpolicy diff --git a/qusal/sys-rsync/files/client/systemd/qubes-rsync-forwarder.socket b/qusal/sys-rsync/files/client/systemd/qubes-rsync-forwarder.socket new file mode 100644 index 0000000..6040dd7 --- /dev/null +++ b/qusal/sys-rsync/files/client/systemd/qubes-rsync-forwarder.socket @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'dom0': + - match: nodegroup + - sys-rsync.create + 'tpl-sys-rsync': + - sys-rsync.install + 'sys-rsync': + - sys-rsync.configure diff --git a/qusal/sys-rsync/install-client.sls b/qusal/sys-rsync/install-client.sls new file mode 100644 index 0000000..d788bfa --- /dev/null +++ b/qusal/sys-rsync/install-client.sls @@ -0,0 +1,36 @@ +{# +SPDX-FileCopyrightText: 2022 unman +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{% if grains['nodename'] != 'dom0' -%} + +"{{ slsdotpath }}-updated-client": + pkg.uptodate: + - refresh: True + +"{{ slsdotpath }}-installed-client": + pkg.installed: + - refresh: True + - install_recommends: False + - skip_suggestions: True + - pkgs: + - rsync + +"{{ slsdotpath }}-client-systemd": + file.recurse: + - name: /usr/lib/systemd/system/ + - source: salt://{{ slsdotpath }}/files/client/systemd/ + - dir_mode: '0755' + - file_mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-client-systemd-start-qubes-rsync-forwarder.socket": + service.enabled: + - name: qubes-rsync-forwarder.socket + +{% endif -%} diff --git a/qusal/sys-sshfs/install-client.top b/qusal/sys-rsync/install-client.top similarity index 81% rename from qusal/sys-sshfs/install-client.top rename to qusal/sys-rsync/install-client.top index 236620e..05e6345 100644 --- a/qusal/sys-sshfs/install-client.top +++ b/qusal/sys-rsync/install-client.top @@ -6,4 +6,4 @@ SPDX-License-Identifier: GPL-3.0-or-later base: '*': - - sys-sshfs.install-client + - sys-rsync.install-client diff --git a/qusal/sys-rsync/install.sls b/qusal/sys-rsync/install.sls new file mode 100644 index 0000000..ad7101d --- /dev/null +++ b/qusal/sys-rsync/install.sls @@ -0,0 +1,54 @@ +{# +SPDX-FileCopyrightText: 2022 unman +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{% if grains['nodename'] != 'dom0' -%} + +"{{ slsdotpath }}-updated": + pkg.uptodate: + - refresh: True + +"{{ slsdotpath }}-installed": + pkg.installed: + - refresh: True + - install_recommends: False + - skip_suggestions: True + - pkgs: + - rsync + - socat + +"{{ slsdotpath }}-stop-rsync": + service.dead: + - name: rsync + +"{{ slsdotpath }}-disable-rsync": + service.disabled: + - name: rsync + +"{{ slsdotpath }}-mask-rsync": + service.masked: + - name: rsync + +"{{ slsdotpath }}-set-rsyncd.conf": + file.managed: + - name: /etc/rsyncd.conf + - source: salt://{{ slsdotpath }}/files/server/rsync/rsyncd.conf + - mode: '0755' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-set-rpc-services": + file.recurse: + - name: /etc/qubes-rpc/ + - source: salt://{{ slsdotpath }}/files/server/rpc/ + - dir_mode: '0755' + - file_mode: '0755' + - user: root + - group: root + - makedirs: True + +{% endif -%} diff --git a/qusal/sys-sshfs/install.top b/qusal/sys-rsync/install.top similarity index 76% rename from qusal/sys-sshfs/install.top rename to qusal/sys-rsync/install.top index 3833a34..5f27504 100644 --- a/qusal/sys-sshfs/install.top +++ b/qusal/sys-rsync/install.top @@ -5,5 +5,5 @@ SPDX-License-Identifier: GPL-3.0-or-later #} base: - 'tpl-sys-sshfs': - - sys-sshfs.install + 'tpl-sys-rsync': + - sys-rsync.install diff --git a/qusal/sys-ssh-agent/README.md b/qusal/sys-ssh-agent/README.md index 25715f8..3fd3770 100644 --- a/qusal/sys-ssh-agent/README.md +++ b/qusal/sys-ssh-agent/README.md @@ -68,7 +68,7 @@ qubesctl --skip-dom0 --targets=sys-ssh-agent state.apply sys-ssh-agent.configure Installation on the client template: ```sh -qubesctl --skip-dom0 --targets=tpl-ssh,tpl-dev state.apply sys-ssh-agent.install-client +qubesctl --skip-dom0 --targets=QUBE state.apply sys-ssh-agent.install-client ``` ## Access Control @@ -131,7 +131,7 @@ ssh-keygen -t ed25519 -f ~/.ssh/identities.d/work/id_example #### Limit key usage For exceptionally valuable keys you may want to limit the time that they are -available. +available and the agent forwarding permission to different hosts. You can set custom options by writing them to a file on the same path of the private key, but ending with the suffix `.ssh-add-option`. If the key is named @@ -151,41 +151,26 @@ AGENT, SECS, and LIFE for their appropriate values): SSH_AUTH_SOCK="/run/user/1000/qubes-ssh-agent/.sock" ssh-add -t -f ``` -#### Enable and Start the service - -Enable and start the connection to the SSH Agent via Qrexec for specified -``: -```sh -systemctl --user enable qubes-ssh-agent-sock@.service -systemctl --user start qubes-ssh-agent-sock@.service -``` -The systemd-user service for this agent will be enabled and started and keys -will be automatically added upon boot. - -Here is one example using the `work` agent: -```sh -systemctl --user enable qubes-ssh-agent-sock@work.service -systemctl --user start qubes-ssh-agent-sock@work.service -``` +#### Reload agent +The keys are added to the agent on the first call to that specific agent. If you have added keys to the correct agent directory but haven't rebooted yet, you will have to add the keys by executing: ```sh -qvm-ssh-agent key -qvm-ssh-agent key work +qvm-ssh-agent reload +qvm-ssh-agent reload work ``` -If agent is not provided, all keys from all agents will be removed and added. #### Debug Agent side You can list agents and their keys with: ```sh -qvm-ssh-agent ls +qvm-ssh-agent ls ``` Follow SSH agents journal: ```sh -journalctl --user -fu qubes-ssh-agent-sock@*.service +journalctl --user -fu qubes-ssh-agent@*.service ``` ### Client @@ -195,21 +180,17 @@ journalctl --user -fu qubes-ssh-agent-sock@*.service Enable and start the connection to the SSH Agent via Qrexec for specified ``: ```sh -systemctl --user enable qubes-ssh-agent-client@.service -systemctl --user start qubes-ssh-agent-client@.service +sudo systemctl --no-block restart qubes-ssh-agent-forwarder@.service +sudo systemctl --no-block restart qubes-ssh-agent-forwarder@personal.service ``` +You can start the service on boot if you place the above line +`/rw/config/rc.local` of the client. -Here is one example using the `work` agent: -```sh -systemctl --user enable qubes-ssh-agent-client@work.service -systemctl --user start qubes-ssh-agent-client@work.service -``` - -The ssh-agent socket will be at `/tmp/qubes-ssh-agent-client/.sock`. +The ssh-agent socket will be at `/tmp/qubes-ssh-agent-forwarder/.sock`. You can test the connection is working with: ```sh -SSH_AUTH_SOCK="/tmp/qubes-ssh-agent-client/personal.sock" ssh-add -l +SSH_AUTH_SOCK="/tmp/qubes-ssh-agent-forwarder/personal.sock" ssh-add -l ``` #### Single agent per client @@ -218,8 +199,8 @@ You might want to set the `SSH_AUTH_SOCK` and `SSH_AGENT_PID` environment variables to point to the `work` agent so every connection will use the same agent: ```sh -echo 'export SSH_AUTH_SOCK=/tmp/qubes-ssh-agent-client/work.sock; -SSH_AGENT_PID="$(pgrep -f -x "/usr/bin/ssh-agent -s -a /tmp/qubes-ssh-agent-client/work.sock")"; +echo 'export SSH_AUTH_SOCK=/tmp/qubes-ssh-agent-forwarder/work.sock; +SSH_AGENT_PID="$(pgrep -f "/tmp/qubes-ssh-agent-forwarder/work.sock")"; ' | tee -a ~/.profile ``` @@ -232,16 +213,16 @@ the `IdentityAgent` option. You can control the SSH agent via SSH command-line option: ```sh -ssh -o IdentityAgent=/tmp/qubes-ssh-agent-client/personal.sock personal-site.com -ssh -o IdentityAgent=/tmp/qubes-ssh-agent-client/work.sock work-site.com +ssh -o IdentityAgent=/tmp/qubes-ssh-agent-forwarder/personal.sock personal-site.com +ssh -o IdentityAgent=/tmp/qubes-ssh-agent-forwarder/work.sock work-site.com ``` You can control the SSH agent via SSH configuration: ```sshconfig Host personal - IdentityAgent /tmp/qubes-ssh-agent-client/personal.sock + IdentityAgent /tmp/qubes-ssh-agent-forwarder/personal.sock ... Host work - IdentityAgent /tmp/qubes-ssh-agent-client/work.sock + IdentityAgent /tmp/qubes-ssh-agent-forwarder/work.sock ... ``` diff --git a/qusal/sys-ssh-agent/files/policy/default.policy b/qusal/sys-ssh-agent/files/admin/policy/default.policy similarity index 100% rename from qusal/sys-ssh-agent/files/policy/default.policy rename to qusal/sys-ssh-agent/files/admin/policy/default.policy diff --git a/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-client-sock@.service b/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-client-sock@.service deleted file mode 100644 index 523de9f..0000000 --- a/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-client-sock@.service +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. -# -# SPDX-License-Identifier: GPL-3.0-or-later - -[Unit] -Description=SSH Agent on the Client targetting Qrexec SSH Agent %i -ConditionUser=!root -ConditionGroup=qubes -Before=qubes-ssh-agent-client@%i.service - -[Service] -Type=forking -UMask=0177 -ExecStartPre=mkdir -m 0700 -p %T/qubes-ssh-agent-client -ExecStart=/usr/bin/ssh-agent -a %T/qubes-ssh-agent-client/%i.sock - -[Install] -WantedBy=default.target diff --git a/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-client@.service b/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-forwarder@.service similarity index 63% rename from qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-client@.service rename to qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-forwarder@.service index fb8be9e..d6a5fbd 100644 --- a/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-client@.service +++ b/qusal/sys-ssh-agent/files/client/systemd/qubes-ssh-agent-forwarder@.service @@ -3,14 +3,15 @@ # SPDX-License-Identifier: GPL-3.0-or-later [Unit] -Description=Qrexec Client targetting SSH Agent %i -ConditionUser=!root -ConditionGroup=qubes -Requires=qubes-ssh-agent-client-sock@%i.service -After=qubes-ssh-agent-client-sock@%i.service +Description=SSH Agent Forwarder to Qrexec SSH Agent %i [Service] +User=user +Group=user Type=simple +UMask=0177 +ExecStartPre=/usr/bin/mkdir -m 700 -p %T/%p +ExecStartPre=/usr/bin/ssh-agent -a %T/%p/%i.sock ExecStart=/usr/bin/socat UNIX-LISTEN:"%T/%p/%i.sock,unlink-early,reuseaddr,fork" EXEC:"qrexec-client-vm -- @default qusal.SshAgent+%i" [Install] diff --git a/qusal/sys-ssh-agent/files/rpc/qusal.SshAgent b/qusal/sys-ssh-agent/files/rpc/qusal.SshAgent deleted file mode 100644 index b33ee18..0000000 --- a/qusal/sys-ssh-agent/files/rpc/qusal.SshAgent +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. -# -# SPDX-License-Identifier: GPL-3.0-or-later - -set -eu - -die(){ - echo "error: $1" >&2 - exit 1 -} - -#origin="$QREXEC_REMOTE_DOMAIN" -agent="$QREXEC_SERVICE_ARGUMENT" -socket="/tmp/qubes-ssh-agent/${agent}.sock" -service="qubes-ssh-agent-sock@${agent}.service" - -## Trust the service is activating and sleep a bit more before failing later. -systemctl --user is-active "${service}" >/dev/null 2>&1 \ - || sleep 10 -systemctl --user is-active "${service}" >/dev/null 2>&1 \ - || die "Agent is not enabled: ${agent}" -active_timestamp="$(systemctl --user show "${service}" --property ActiveEnterTimestamp | cut -d "=" -f2)" -test -n "${active_timestamp:-}" \ - || die "Failed to get agent active timestamp: ${agent}" - -active_epoch="$(date -d"${active_timestamp}" "+%s")" -now_epoch="$(date --utc "+%s")" -difference="$((now_epoch-active_epoch))" -test "${difference}" -gt 15 || sleep 5 - -test -e "$socket" || die "Socket doesn't exist: $socket" -test -S "$socket" || die "Not a socket: $socket" - -exec socat STDIO UNIX-CLIENT:"$socket" diff --git a/qusal/sys-ssh-agent/files/server/bin/qvm-ssh-agent b/qusal/sys-ssh-agent/files/server/bin/qvm-ssh-agent index b2a07f1..f4c9a2d 100755 --- a/qusal/sys-ssh-agent/files/server/bin/qvm-ssh-agent +++ b/qusal/sys-ssh-agent/files/server/bin/qvm-ssh-agent @@ -6,71 +6,71 @@ set -eu -sock_dir="qubes-ssh-agent" -service="${sock_dir}-sock" +service="qubes-ssh-agent" usage(){ - echo "Usage: ${0##*/} [ls|key] [] + echo "Usage: ${0##*/} [ls|add] ls: list agent(s) - key: add keys to agent(s) -If agent is not specified, action is taken on all agents. + add: add keys to agent(s) + reload: reload/readd keys from agent(s) Example: - ${0##*/} ls # list all agents - ${0##*/} ls work # list the work agent and its keys - ${0##*/} key # add keys for each agent - ${0##*/} key work # add keys for the work agent" + ${0##*/} ls work # list the work agent keys + ${0##*/} add work # add keys to the work agent + ${0##*/} reload work # reload/readd keys from the work agent" exit 1 } ls_agent(){ - echo "Systemd user units:" - # shellcheck disable=SC2086 - systemctl --user --no-pager list-units ${service}@$agent.service \ - | grep "${service}@.*\.service" | sed "s/^[[:space:]]*//" - echo - for socket in /tmp/${sock_dir}/$agent.sock; do - test -S "$socket" || continue - agent="$(echo "$socket" | sed "s|.*${sock_dir}/||;s/\.sock//")" - echo "Agent: ($agent) $socket" - SSH_AUTH_SOCK="$socket" ssh-add -l || true - echo + socket="/tmp/${service}/$agent.sock" + test -S "$socket" || return 1 + agent="$(echo "$socket" | sed "s|.*${service}/||;s/\.sock//")" + echo "Agent: ($agent) $socket" + SSH_AUTH_SOCK="$socket" ssh-add -l || true +} + +add_agent(){ + # shellcheck disable=SC2174 + mkdir -m 0700 -p "/tmp/${service}" + dir="$HOME/.ssh/identities.d/${agent}" + if ! test -d "$dir"; then + echo "Directory not found: $dir" >&2 + return 1 + fi + dir="${dir##*/}" + socket="/tmp/${service}/${dir}.sock" + if ! test -S "$socket"; then + reload_agent=1 + ssh-agent -a "/tmp/${service}/${agent}.sock" + fi + if ! test "${reload_agent}" = "1"; then + return + fi + keys="$(grep -sl -- "-----BEGIN OPENSSH PRIVATE KEY-----" \ + "$HOME/.ssh/identities.d/$dir"/* || true)" + if test -z "$keys"; then + echo "Directory has no key: $dir" >&2 + return 1 + fi + SSH_AUTH_SOCK="$socket" ssh-add -D 2>/dev/null || true + for k in $(printf '%s\n' "$keys"); do + test -f "$k" || continue + ssh_add_option="" + if test -f "$k.ssh-add-option"; then + ssh_add_option="$(cat "$k.ssh-add-option")" + fi + # shellcheck disable=SC2086 + SSH_AUTH_SOCK="$socket" ssh-add $ssh_add_option "$k" done } -add_key(){ - for dir in $HOME/.ssh/identities.d/$agent; do - test -d "$dir" || continue - dir="${dir##*/}" - socket="/tmp/${sock_dir}/${dir}.sock" - test -S "$socket" || continue - keys="$(grep -sl -- "-----BEGIN OPENSSH PRIVATE KEY-----" \ - "$HOME/.ssh/identities.d/$dir"/* || true)" - test -n "$keys" || continue - echo "Agent: ($dir) $socket" - SSH_AUTH_SOCK="$socket" ssh-add -D 2>/dev/null || true - for k in $(printf '%s\n' "$keys"); do - test -f "$k" || continue - ssh_add_option="" - if test -f "$k.ssh-add-option"; then - ssh_add_option="$(cat "$k.ssh-add-option")" - fi - # shellcheck disable=SC2086 - SSH_AUTH_SOCK="$socket" ssh-add $ssh_add_option "$k" - done - echo - done -} - -test -z "${1-}" && usage +test -z "${2-}" && usage action="${1-}" agent="${2-}" - -case "$action" in - ls|key) agent="${agent:-*}";; - *) usage;; -esac +reload_agent="" case "$action" in ls) ls_agent;; - key) add_key;; + add) add_agent;; + reload) reload_agent="1"; add_agent;; + *) usage;; esac diff --git a/qusal/sys-ssh-agent/files/server/rpc/qusal.SshAgent b/qusal/sys-ssh-agent/files/server/rpc/qusal.SshAgent new file mode 100644 index 0000000..0d883b3 --- /dev/null +++ b/qusal/sys-ssh-agent/files/server/rpc/qusal.SshAgent @@ -0,0 +1,14 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +set -eu + +#origin="$QREXEC_REMOTE_DOMAIN" +agent="$QREXEC_SERVICE_ARGUMENT" +socket="/tmp/qubes-ssh-agent/${agent}.sock" + +qvm-ssh-agent add "${agent}" >/dev/null +exec socat STDIO UNIX-CLIENT:"$socket" diff --git a/qusal/sys-ssh-agent/files/server/systemd/qubes-ssh-agent-sock@.service b/qusal/sys-ssh-agent/files/server/systemd/qubes-ssh-agent-sock@.service deleted file mode 100644 index b0674a5..0000000 --- a/qusal/sys-ssh-agent/files/server/systemd/qubes-ssh-agent-sock@.service +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. -# -# SPDX-License-Identifier: GPL-3.0-or-later - -[Unit] -Description=SSH Agent on the Agent for Qrexec connections to %i -ConditionUser=!root -ConditionGroup=qubes - -[Service] -Type=forking -UMask=0177 -ExecStartPre=mkdir -m 0700 -p /tmp/qubes-ssh-agent -ExecStart=/usr/bin/ssh-agent -a /tmp/qubes-ssh-agent/%i.sock -ExecStartPost=qvm-ssh-agent key %i - -[Install] -WantedBy=default.target diff --git a/qusal/sys-ssh-agent/install-client.sls b/qusal/sys-ssh-agent/install-client.sls index 09dab17..bfd402f 100644 --- a/qusal/sys-ssh-agent/install-client.sls +++ b/qusal/sys-ssh-agent/install-client.sls @@ -7,9 +7,11 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' -%} include: + - ssh.install - dev.home-cleanup - - dotfiles.copy-x11 + - dotfiles.copy-sh - dotfiles.copy-ssh + - dotfiles.copy-x11 "{{ slsdotpath }}-client-updated": pkg.uptodate: @@ -21,16 +23,14 @@ include: - install_recommends: False - skip_suggestions: True - pkgs: - - qubes-core-agent-networking - - ca-certificates - socat {% set pkg = { 'Debian': { - 'pkg': ['libpam-systemd', 'procps', 'openssh-client'], + 'pkg': ['procps'], }, 'RedHat': { - 'pkg': ['systemd-pam', 'procps-ng', 'openssh-clients'], + 'pkg': ['procps-ng'], }, }.get(grains.os_family) -%} @@ -41,23 +41,13 @@ include: - skip_suggestions: True - pkgs: {{ pkg.pkg|sequence|yaml }} -"{{ slsdotpath }}-client-user-systemd-dir": +"{{ slsdotpath }}-client-system-systemd-dir": file.recurse: - source: salt://{{ slsdotpath }}/files/client/systemd/ - - name: /usr/lib/systemd/user/ + - name: /usr/lib/systemd/system/ - dir_mode: '0755' - file_mode: '0644' - user: root - group: root -"{{ slsdotpath }}-client-start-systemd-dbus-login-service": - service.running: - - name: dbus-org.freedesktop.login1.service - -"{{ slsdotpath }}-client-start-systemd-user-services-on-boot": - cmd.run: - - require: - - service: "{{ slsdotpath }}-client-start-systemd-dbus-login-service" - - name: loginctl enable-linger user - {% endif %} diff --git a/qusal/sys-ssh-agent/install.sls b/qusal/sys-ssh-agent/install.sls index 5bd6b43..35d7df3 100644 --- a/qusal/sys-ssh-agent/install.sls +++ b/qusal/sys-ssh-agent/install.sls @@ -7,8 +7,11 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' -%} include: - - dotfiles.copy-x11 - ssh.install + - dev.home-cleanup + - dotfiles.copy-sh + - dotfiles.copy-ssh + - dotfiles.copy-x11 "{{ slsdotpath }}-updated": pkg.uptodate: @@ -22,22 +25,6 @@ include: - pkgs: - socat -{% set pkg = { - 'Debian': { - 'pkg': ['libpam-systemd', 'procps', 'openssh-client'], - }, - 'RedHat': { - 'pkg': ['systemd-pam', 'procps-ng', 'openssh-clients'], - }, -}.get(grains.os_family) -%} - -"{{ slsdotpath }}-installed-os-specific": - pkg.installed: - - refresh: True - - install_recommends: False - - skip_suggestions: True - - pkgs: {{ pkg.pkg|sequence|yaml }} - "{{ slsdotpath }}-agent-bin-dir": file.recurse: - source: salt://{{ slsdotpath }}/files/server/bin @@ -46,29 +33,10 @@ include: - user: root - group: root -"{{ slsdotpath }}-agent-user-systemd-dir": - file.recurse: - - source: salt://{{ slsdotpath }}/files/server/systemd/ - - name: /usr/lib/systemd/user/ - - dir_mode: '0755' - - file_mode: '0644' - - user: root - - group: root - -"{{ slsdotpath }}-agent-start-systemd-dbus-login-service": - service.running: - - name: dbus-org.freedesktop.login1.service - -"{{ slsdotpath }}-agent-start-systemd-user-services-on-boot": - cmd.run: - - require: - - service: "{{ slsdotpath }}-agent-start-systemd-dbus-login-service" - - name: loginctl enable-linger user - "{{ slsdotpath }}-install-rpc-service": file.managed: - name: /etc/qubes-rpc/qusal.SshAgent - - source: salt://{{ slsdotpath }}/files/rpc/qusal.SshAgent + - source: salt://{{ slsdotpath }}/files/server/rpc/qusal.SshAgent - mode: '0755' - user: root - group: root diff --git a/qusal/sys-ssh/README.md b/qusal/sys-ssh/README.md new file mode 100644 index 0000000..a4c2e3e --- /dev/null +++ b/qusal/sys-ssh/README.md @@ -0,0 +1,112 @@ +# sys-ssh + +## Table of Contents + +* [Description](#description) +* [Installation](#installation) +* [Access Control](#access-control) +* [Usage](#usage) + * [Server](#server) + * [Client](#client) + * [Passwordless login](#passwordless-login) + * [Mount the file system](#mount-the-file-system) +* [Credits](#credits) + +## Description + +SSH over Qrexec on Qubes OS. + +Creates a SSH server qube named "sys-ssh" to be a central document +store to which other qubes have access with SSH File Transfer Protocol, using +the tool sshfs. This is a simple tool that allows individual qubes to mount a +another qube's filesystem rather than using `qvm-copy` or `qvm-move`. + +The greatest problem with the Rsync solution is that it makes copies of the +files or directories. This may be fine with a small amount of data, but with +large files, or large numbers of files, there's a significant overhead. SSH +File Transfer Protocol provides a way for clients to access files on the +server qube directly. + +## Installation + +- Top: +```sh +qubesctl top.enable sys-ssh +qubesctl --targets=tpl-sys-ssh,sys-ssh state.apply +qubesctl top.disable sys-ssh +``` + +- State: +```sh +qubesctl state.apply sys-ssh.create +qubesctl --skip-dom0 --targets=tpl-sys-ssh state.apply sys-ssh.install +qubesctl --skip-dom0 --targets=sys-ssh state.apply sys-ssh.configure +``` + +Install on the client template: +```sh +qubesctl --skip-dom0 --targets=QUBE state.apply sys-ssh.install-client +``` + +The client qube requires the SSH forwarder service to be enabled: +``` +qvm-features QUBE service.ssh-setup 1 +``` + +## Access Control + +A `qusal.Ssh` service is created to allow use of SSH over Qrexec. The default +policy `asks` if you want to connect with the `sys-ssh` qube. + +If you want to `allow` SSH between qubes, insert in you user policy +file `/etc/qubes/policy.d/30-user.policy` to allow the service using the +following format: +```qrexecpolicy +qusal.Ssh * SOURCE @default allow target=TARGET +``` + +When the client can change the data on the server, it can also possibly +compromise the server or at least make it hold malicious files and propagate +the malicious data with clients it is connected to. + +## Usage + +### Server + +It is possible to constrain access to files on the server, using (e.g) SSH +chroots and access control mechanisms. This is left for the user to configure. + +### Client + +##### Passwordless login + +The client can be the sys-ssh-agent's client and not hold the private keys at +all. Consult sys-ssh-agent documentation for more information. + +In the client, create SSH keys and copy them to the server: +```sh +ssh-keygen -t ed25519 +qvm-copy .ssh/id_ed25519.pub +``` + +On the server, create the SSH directory and copy the client key to the +authorized list: +```sh +mkdir -m 0700 ~/.ssh +cat ~/QubesIncoming//id_ed25519.pub | tee -a ~/.ssh/authorized_keys +``` + +##### Mount the file system + +The SSH connection is available with the socket `localhost:1840`. + +From the client, mount the server `/home/user` directory as a SSH File System +in the client `/home/user/sshfs` directory: +```sh +mkdir ~/sshfs +sshfs -p 1840 localhost:/home/user /home/user/sshfs +``` + +## Credits + +- [Unman](https://github.com/unman/qubes-sync) diff --git a/qusal/sys-ssh/clone.sls b/qusal/sys-ssh/clone.sls new file mode 100644 index 0000000..5e5c122 --- /dev/null +++ b/qusal/sys-ssh/clone.sls @@ -0,0 +1,8 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{% from 'utils/macros/clone-template.sls' import clone_template -%} +{{ clone_template('debian-minimal', sls_path) }} diff --git a/qusal/sys-ssh/clone.top b/qusal/sys-ssh/clone.top new file mode 100644 index 0000000..888c2d7 --- /dev/null +++ b/qusal/sys-ssh/clone.top @@ -0,0 +1,10 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'dom0': + - match: nodegroup + - sys-ssh.clone diff --git a/qusal/sys-sshfs/configure.sls b/qusal/sys-ssh/configure.sls similarity index 60% rename from qusal/sys-sshfs/configure.sls rename to qusal/sys-ssh/configure.sls index e9c8cdb..e1b6f8e 100644 --- a/qusal/sys-sshfs/configure.sls +++ b/qusal/sys-ssh/configure.sls @@ -5,14 +5,17 @@ SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. SPDX-License-Identifier: GPL-3.0-or-later #} +{% if grains['nodename'] != 'dom0' -%} + +include: + - dev.home-cleanup + "{{ slsdotpath }}-start-ssh-on-boot": file.append: - name: /rw/config/rc.local - - text: | - systemctl unmask ssh - systemctl start ssh + - source: salt://{{ slsdotpath }}/files/server/rc.local -"{{ slsdotpath }}-create-home-ssh-dir": +"{{ slsdotpath }}-creates-home-ssh-dir": file.directory: - name: /home/user/.ssh - mode: '0700' @@ -20,10 +23,4 @@ SPDX-License-Identifier: GPL-3.0-or-later - group: user - makedirs: True -"{{ slsdotpath }}-creates-tx-dir": - file.directory: - - name: /home/tx - - mode: '0777' - - user: user - - group: user - - makedirs: True +{% endif -%} diff --git a/qusal/sys-ssh/configure.top b/qusal/sys-ssh/configure.top new file mode 100644 index 0000000..3a040d1 --- /dev/null +++ b/qusal/sys-ssh/configure.top @@ -0,0 +1,9 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'sys-ssh': + - sys-ssh.configure diff --git a/qusal/sys-ssh/create.sls b/qusal/sys-ssh/create.sls new file mode 100644 index 0000000..806e2c1 --- /dev/null +++ b/qusal/sys-ssh/create.sls @@ -0,0 +1,48 @@ +{# +SPDX-FileCopyrightText: 2022 unman +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{%- from "qvm/template.jinja" import load -%} + +include: + - .clone + +{% load_yaml as defaults -%} +name: {{ slsdotpath }} +force: True +require: +- sls: {{ slsdotpath }}.clone +present: +- template: tpl-{{ slsdotpath }} +- label: yellow +prefs: +- template: tpl-{{ slsdotpath }} +- label: yellow +- netvm: "" +- vcpus: 1 +- memory: 300 +- maxmem: 600 +- autostart: False +- include_in_backups: True +features: +- enable: + - servicevm +- disable: + - service.cups + - service.cups-browsed +- set: + - menu-items: "qubes-run-terminal.desktop qubes-start.desktop" +{%- endload %} +{{ load(defaults) }} + +"{{ slsdotpath }}-resize-private-volume": + cmd.run: + - name: qvm-volume extend {{ slsdotpath }}:private 40Gi + - require: + - qvm: {{ slsdotpath }} + +{% from 'utils/macros/policy.sls' import policy_set with context -%} +{{ policy_set(sls_path, '80') }} diff --git a/qusal/sys-ssh/create.top b/qusal/sys-ssh/create.top new file mode 100644 index 0000000..e72583d --- /dev/null +++ b/qusal/sys-ssh/create.top @@ -0,0 +1,10 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'dom0': + - match: nodegroup + - sys-ssh.create diff --git a/qusal/sys-sshfs/files/policy/default.policy b/qusal/sys-ssh/files/admin/policy/default.policy similarity index 71% rename from qusal/sys-sshfs/files/policy/default.policy rename to qusal/sys-ssh/files/admin/policy/default.policy index 636ec22..8c45fb2 100644 --- a/qusal/sys-sshfs/files/policy/default.policy +++ b/qusal/sys-ssh/files/admin/policy/default.policy @@ -4,6 +4,6 @@ ## Do not modify this file, create a new policy with with a lower number in the ## file name instead. For example `30-user.policy`. -qusal.Sshfs * @anyvm @default ask target=sys-sshfs default_target=sys-sshfs -qusal.Sshfs * @anyvm @anyvm deny +qusal.Ssh * @anyvm @default ask target=sys-ssh default_target=sys-ssh +qusal.Ssh * @anyvm @anyvm deny ## vim:ft=qrexecpolicy diff --git a/qusal/sys-sshfs/files/client/qubes-ssh-forwarder.socket b/qusal/sys-ssh/files/client/systemd/qubes-ssh-forwarder.socket similarity index 61% rename from qusal/sys-sshfs/files/client/qubes-ssh-forwarder.socket rename to qusal/sys-ssh/files/client/systemd/qubes-ssh-forwarder.socket index 97d086d..05ac969 100644 --- a/qusal/sys-sshfs/files/client/qubes-ssh-forwarder.socket +++ b/qusal/sys-ssh/files/client/systemd/qubes-ssh-forwarder.socket @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2022 unman +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'dom0': + - match: nodegroup + - sys-ssh.create + 'tpl-sys-ssh': + - sys-ssh.install + 'sys-ssh': + - sys-ssh.configure diff --git a/qusal/sys-sshfs/install-client.sls b/qusal/sys-ssh/install-client.sls similarity index 55% rename from qusal/sys-sshfs/install-client.sls rename to qusal/sys-ssh/install-client.sls index 4b99e9a..8e14fe2 100644 --- a/qusal/sys-sshfs/install-client.sls +++ b/qusal/sys-ssh/install-client.sls @@ -7,24 +7,19 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' -%} +include: + - sys-ssh-agent.install-client + "{{ slsdotpath }}-updated-client": pkg.uptodate: - refresh: True -"{{ slsdotpath }}-installed-client": - pkg.installed: - - refresh: True - - install_recommends: False - - skip_suggestions: True - - pkgs: - - socat - {% set pkg = { 'Debian': { - 'pkg': ['sshfs', 'openssh-client'], + 'pkg': ['sshfs'], }, 'RedHat': { - 'pkg': ['fuse-sshfs', 'openssh-clients'], + 'pkg': ['fuse-sshfs'], }, }.get(grains.os_family) -%} @@ -35,4 +30,18 @@ SPDX-License-Identifier: GPL-3.0-or-later - skip_suggestions: True - pkgs: {{ pkg.pkg|sequence|yaml }} +"{{ slsdotpath }}-client-systemd": + file.recurse: + - name: /usr/lib/systemd/system/ + - source: salt://{{ slsdotpath }}/files/client/systemd/ + - dir_mode: '0755' + - file_mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-client-systemd-start-qubes-ssh-forwarder.socket": + service.enabled: + - name: qubes-ssh-forwarder.socket + {% endif -%} diff --git a/qusal/sys-sshfs/configure-client.top b/qusal/sys-ssh/install-client.top similarity index 80% rename from qusal/sys-sshfs/configure-client.top rename to qusal/sys-ssh/install-client.top index effc333..aa1ac19 100644 --- a/qusal/sys-sshfs/configure-client.top +++ b/qusal/sys-ssh/install-client.top @@ -6,4 +6,4 @@ SPDX-License-Identifier: GPL-3.0-or-later base: '*': - - sys-sshfs.configure-client + - sys-ssh.install-client diff --git a/qusal/sys-sshfs/install.sls b/qusal/sys-ssh/install.sls similarity index 80% rename from qusal/sys-sshfs/install.sls rename to qusal/sys-ssh/install.sls index 887584a..bd7f50b 100644 --- a/qusal/sys-sshfs/install.sls +++ b/qusal/sys-ssh/install.sls @@ -32,11 +32,12 @@ SPDX-License-Identifier: GPL-3.0-or-later service.masked: - name: ssh -"{{ slsdotpath }}-set-rpc-service": - file.managed: - - name: /etc/qubes-rpc/qusal.Sshfs - - source: salt://{{ slsdotpath }}/files/rpc/qusal.Sshfs - - mode: '0755' +"{{ slsdotpath }}-set-rpc-services": + file.recurse: + - name: /etc/qubes-rpc/ + - source: salt://{{ slsdotpath }}/files/server/rpc/ + - dir_mode: '0755' + - file_mode: '0755' - user: root - group: root - makedirs: True diff --git a/qusal/sys-ssh/install.top b/qusal/sys-ssh/install.top new file mode 100644 index 0000000..347892a --- /dev/null +++ b/qusal/sys-ssh/install.top @@ -0,0 +1,9 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'tpl-sys-ssh': + - sys-ssh.install diff --git a/qusal/sys-sshfs/README.md b/qusal/sys-sshfs/README.md deleted file mode 100644 index 56486d4..0000000 --- a/qusal/sys-sshfs/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# sys-sshfs - -## Table of Contents - -* [Description](#description) -* [Installation](#installation) -* [Access Control](#access-control) -* [Credits](#credits) - -## Description - -SSH File System over Qrexec on Qubes OS. - -Creates a SSH server qube named "sys-sshfs". -TODO - -## Installation - -The SSH connector service is only started if the service is enabled for that -qube in Dom0: -``` -qvm-features QUBE service.qubes-sshfs 1 -``` - -- Top: -```sh -qubesctl top.enable sys-sshfs -qubesctl --targets=tpl-sys-sshfs,sys-sshfs state.apply -qubesctl top.disable sys-sshfs -``` - -- State: -```sh -qubesctl state.apply sys-sshfs.create -qubesctl --skip-dom0 --targets=tpl-sys-sshfs state.apply sys-sshfs.install -qubesctl --skip-dom0 --targets=sys-sshfs state.apply sys-sshfs.configure -``` - -Install on the client template: -```sh -qubesctl --skip-dom0 --targets=QUBE state.apply sys-sshfs.install-client -``` - -Configure the client: -```sh -qubesctl --skip-dom0 --targets=QUBE state.apply sys-sshfs.configure-client -``` - -## Access Control - -A `qusal.Sshfs` service is created to allow use of SSH File Transfer Protocol -over Qrexec. The default policy `asks` if you want to sync with the -`sys-sshfs` qube. - -If you want to `allow` SSH between qubes, insert in you user policy file -`/etc/qubes/policy.d/30-user.policy` to allow the service using the following -format: -```qrexecpolicy -qusal.Sshfs * SOURCE @default allow target=TARGET default_target=DEFAULT_TARGET -``` - -## Usage - -TODO - -## Credits - -- [Unman](https://github.com/unman/shaker/tree/master/share) diff --git a/qusal/sys-sshfs/configure-client.sls b/qusal/sys-sshfs/configure-client.sls deleted file mode 100644 index 298277a..0000000 --- a/qusal/sys-sshfs/configure-client.sls +++ /dev/null @@ -1,57 +0,0 @@ -{# -SPDX-FileCopyrightText: 2022 unman -SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. - -SPDX-License-Identifier: GPL-3.0-or-later -#} - -"{{ slsdotpath }}-client-rc.local": - file.append: - - name: /rw/config/rc.local - - text: | - systemctl enable qubes-ssh-forwarder.socket - systemctl start qubes-ssh-forwarder.socket - sshfs -p 840 localhost:/home/tx tx - -"{{ slsdotpath }}-home-tx-dir-client": - file.directory: - - name: /home/user/tx - - mode: '0700' - - user: user - - group: user - - makedirs: True - -"{{ slsdotpath }}-home-ssh-dir-client": - file.directory: - - name: /home/user/.ssh - - mode: '0700' - - user: user - - group: user - - makedirs: True - -"{{ slsdotpath }}-ssh-forwarder-template-to-systemd-bind": - file.managed: - - name: /rw/bind-dirs/lib/systemd/system/qubes-ssh-forwarder@.service - - source: salt://{{ slsdotpath }}/files/client/qubes-ssh-forwarder@.service - - mode: '0644' - - user: root - - group: root - - makedirs: True - -"{{ slsdotpath }}-ssh-forwarder-socket-to-systemd-bind": - file.managed: - - name: /rw/bind-dirs/lib/systemd/system/qubes-ssh-forwarder.socket - - source: salt://{{ slsdotpath }}/files/client/qubes-ssh-forwarder.socket - - mode: '0644' - - user: root - - group: root - - makedirs: True - -"{{ slsdotpath }}-bind-sshfs-client" - file.managed: - - name: /rw/config/qubes-bind-dirs.d/50_sshfs.conf - - source: salt://{{ slsdotpath }}/files/client/50_sshfs.conf - - mode: '0644' - - user: root - - group: root - - makedirs: True diff --git a/qusal/sys-sshfs/files/client/50_sshfs.conf b/qusal/sys-sshfs/files/client/50_sshfs.conf deleted file mode 100644 index 87e6a65..0000000 --- a/qusal/sys-sshfs/files/client/50_sshfs.conf +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: 2022 unman -# -# SPDX-License-Identifier: GPL-3.0-or-later - -binds+=( '/lib/systemd/system/qubes-ssh-forwarder.socket') -binds+=( '/lib/systemd/system/qubes-ssh-forwarder@.service') - -# vim: ft=bash diff --git a/qusal/sys-syncthing/README.md b/qusal/sys-syncthing/README.md index e35647e..be46a86 100644 --- a/qusal/sys-syncthing/README.md +++ b/qusal/sys-syncthing/README.md @@ -5,6 +5,7 @@ * [Description](#description) * [Installation](#installation) * [Access Control](#access-control) +* [Usage](#usage) * [Debugging](#debugging) * [Uninstallation](#uninstallation) * [Credits](#credits) @@ -22,39 +23,36 @@ accessible externally. ## Installation -The Syncthing service is only started if the service is enabled for that qube -in Dom0: -``` -qvm-features QUBE service.qubes-syncthing 1 -``` -The client requires `socat` to be installed. - -To use the service, add a Remote Device, and copy the `DeviceID` from the -target qube. On the Advanced tab, under Addresses, change `dynamic` to -`tcp://127.0.0.1:22001` - -If the sender qube has no netvm set, under `Settings`, disable -`Enable NAT traversal`, `Local Discovery`, `Global Discovery`, and -`Enable Relaying` - - Top: ```sh -qubesctl top.enable sys-syncthing -qubesctl --targets=tpl-sys-syncthing,sys-syncthing state.apply -qubesctl top.disable sys-syncthing +qubesctl top.enable sys-syncthing browser +qubesctl --targets=tpl-browser,tpl-sys-syncthing,sys-syncthing,sys-syncthing-browser state.apply +qubesctl top.disable sys-syncthing browser qubesctl state.apply sys-syncthing.appmenus -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh -a -p add sys-syncthing tcp 22000 -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh -a -p add sys-syncthing udp 22000 +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh -a -p add sys-syncthing tcp 22000 +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh -a -p add sys-syncthing udp 22000 ``` - State: ```sh qubesctl state.apply sys-syncthing.create +qubesctl --skip-dom0 --targets=tpl-browser state.apply browser.install qubesctl --skip-dom0 --targets=tpl-sys-syncthing state.apply sys-syncthing.install qubesctl --skip-dom0 --targets=sys-syncthing state.apply sys-syncthing.configure +qubesctl --skip-dom0 --targets=sys-syncthing-browser state.apply sys-syncthing.configure-browser qubesctl state.apply sys-syncthing.appmenus -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh -a -p add sys-syncthing tcp 22000 -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh -a -p add sys-syncthing udp 22000 +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh -a -p add sys-syncthing tcp 22000 +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh -a -p add sys-syncthing udp 22000 +``` + +Install Syncthing on the client template: +```sh +qubesctl --skip-dom0 --targets=QUBE state.apply sys-syncthing.install-client +``` + +The client qube requires the split Syncthing service to be enabled: +```sh +qvm-features QUBE service.syncthing-setup 1 ``` ## Access Control @@ -70,16 +68,39 @@ format: qusal.Syncthing * SOURCE @default allow target=DESTINATION default_target=DEFAULT_DESTINATION ``` +## Usage + +The Syncthing address is `http://127.0.0.1:8384`. + +If you want to view statistics or manage the server through a GUI, open +`sys-syncthing` or `sys-syncthing-browser` desktop file +`syncthing-browser.desktop` from Dom0 or run `syncthing -browser-only` from +`sys-syncthing`. Addresses starting with `http` or `https` will be redirected +to `sys-syncthing-browser`. + +The browser separation from the server is to avoid browsing malicious sites +and exposing the browser to direct network on the same machine the server is +running. The browser qube is offline and only has access to the admin +interface. In other words, it has control over the server functions, if the +browser is compromised, it can compromise the server. + +To use the service, from the client, add a Remote Device, and copy the +`DeviceID` from the server qube. On the Advanced tab, under Addresses, change +`dynamic` to `tcp://127.0.0.1:22001` + +If the sender qube has no netvm set, under `Settings`, disable `Enable NAT +traversal`, `Local Discovery`, `Global Discovery`, and `Enable Relaying` + ## Debugging If sys-net has more than one network card the first external interface will be used by default. If this is incorrect, you must change it manually. In Dom0 run: ```sh -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh delete sys-syncthing tcp 22000 -a -p -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh delete sys-syncthing udp 22000 -a -p -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh add sys-syncthing tcp 22000 -p -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh add sys-syncthing udp 22000 -p +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh delete sys-syncthing tcp 22000 -a -p +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh delete sys-syncthing udp 22000 -a -p +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh add sys-syncthing tcp 22000 -p +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh add sys-syncthing udp 22000 -p ``` This will let you choose the NIC. @@ -93,8 +114,8 @@ Syncthing between qubes. Uninstallation procedure: ```sh -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh -a -p delete sys-syncthing tcp 22000 -/srv/salt/qusal/sys-syncthing/files/firewall/in.sh -a -p delete sys-syncthing udp 22000 +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh -a -p delete sys-syncthing tcp 22000 +/srv/salt/qusal/sys-syncthing/files/admin/firewall/in.sh -a -p delete sys-syncthing udp 22000 qubesctl --skip-dom0 --targets=sys-syncthing state.apply sys-syncthing.cancel qubesctl state.apply sys-syncthing.clean ``` diff --git a/qusal/sys-syncthing/appmenus.sls b/qusal/sys-syncthing/appmenus.sls index 7b3e9c0..642db38 100644 --- a/qusal/sys-syncthing/appmenus.sls +++ b/qusal/sys-syncthing/appmenus.sls @@ -4,5 +4,11 @@ SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. SPDX-License-Identifier: GPL-3.0-or-later #} +include: + - browser.appmenus + {% from 'utils/macros/sync-appmenus.sls' import sync_appmenus -%} {{ sync_appmenus('tpl-' ~ sls_path) }} + +{% from 'utils/macros/sync-appmenus.sls' import sync_appmenus -%} +{{ sync_appmenus(sls_path ~ '-browser') }} diff --git a/qusal/sys-syncthing/configure.sls b/qusal/sys-syncthing/configure.sls index 6951f6d..e0dbb66 100644 --- a/qusal/sys-syncthing/configure.sls +++ b/qusal/sys-syncthing/configure.sls @@ -10,4 +10,4 @@ SPDX-License-Identifier: GPL-3.0-or-later - name: /rw/config/rc.local - text: | systemctl unmask syncthing@user.service - systemctl start syncthing@user.service + systemctl --no-block restart syncthing@user.service diff --git a/qusal/sys-syncthing/create.sls b/qusal/sys-syncthing/create.sls index 5abae0a..7904e98 100644 --- a/qusal/sys-syncthing/create.sls +++ b/qusal/sys-syncthing/create.sls @@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later include: - .clone + - browser.create {% load_yaml as defaults -%} name: tpl-{{ slsdotpath }} @@ -28,8 +29,8 @@ features: - service.tracker - service.evolution-data-server - set: - - menu-items: "qubes-run-terminal.desktop qubes-start.desktop firefox-esr.desktop syncthing-ui.desktop" - - default-menu-items: "qubes-run-terminal.desktop qubes-start.desktop firefox-esr.desktop syncthing-ui.desktop" + - menu-items: "syncthing-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" + - default-menu-items: "syncthing-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" {%- endload %} {{ load(defaults) }} @@ -40,10 +41,10 @@ require: - sls: {{ slsdotpath }}.clone present: - template: tpl-{{ slsdotpath }} -- label: gray +- label: yellow prefs: - template: tpl-{{ slsdotpath }} -- label: gray +- label: yellow - vcpus: 1 - memory: 300 - maxmem: 700 @@ -52,13 +53,39 @@ prefs: features: - enable: - servicevm +- disable: + - service.cups + - service.cups-browsed +- set: + - menu-items: "syncthing-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" +{%- endload %} +{{ load(defaults) }} + +{% load_yaml as defaults -%} +name: {{ slsdotpath }}-browser +force: True +require: +- sls: {{ slsdotpath }}.clone +present: +- template: tpl-browser +- label: yellow +prefs: +- template: tpl-browser +- label: yellow +- vcpus: 1 +- netvm: "" +- memory: 300 +- maxmem: 600 +- autostart: False +- include_in_backups: False +features: - disable: - service.cups - service.cups-browsed - service.tracker - service.evolution-data-server - set: - - menu-items: "qubes-run-terminal.desktop qubes-start.desktop firefox-esr.desktop syncthing-ui.desktop" + - menu-items: "syncthing-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" {%- endload %} {{ load(defaults) }} diff --git a/qusal/sys-syncthing/files/firewall/in.sh b/qusal/sys-syncthing/files/firewall/in.sh deleted file mode 100644 index c49d315..0000000 --- a/qusal/sys-syncthing/files/firewall/in.sh +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2022 unman -# -# SPDX-License-Identifier: GPL-3.0-or-later - -## Credits: https://github.com/unman/shaker/blob/main/i2p/in.sh -## Recursively open ports through the firewall to allow remote access to a qube. - -me="${0##*/}" - -usage(){ -cat </dev/null)" - if test -z "$found"; then - qvm-run -q -u root "${my_netvms[$i]}" -- "iptables -I QBS-FORWARD -i $iface -p $proto --dport $portnum_target -d ${my_ips[$i-1]} -j ACCEPT" - qvm-run -q -u root "${my_netvms[$i]}" -- "iptables -t nat -I PR-QBS-SERVICES -i $iface -p $proto --dport $portnum_used -j DNAT --to-destination ${my_ips[$i-1]}:$portnum_target" - if test "$permanent" = "1"; then - qvm-run -q -u root "${my_netvms[$i]}" -- "echo iptables -I QBS-FORWARD -i $iface -p $proto --dport $portnum_target -d ${my_ips[$i-1]} -j ACCEPT >> /rw/config/rc.local" - qvm-run -q -u root "${my_netvms[$i]}" -- "echo iptables -t nat -I PR-QBS-SERVICES -i $iface -p $proto --dport $portnum_used -j DNAT --to-destination ${my_ips[$i-1]}:$portnum_target >> /rw/config/rc.local" - fi - else - qvm-run -q -u root "${my_netvms[$i]}" -- nft insert rule nat PR-QBS-SERVICES meta iifname "$iface" "$proto" dport "$portnum_used" dnat to "${my_ips[$i-1]}:$portnum_target" - qvm-run -q -u root "${my_netvms[$i]}" -- nft insert rule filter QBS-FORWARD meta iifname "$iface" ip daddr "${my_ips[$i-1]}" "$proto" dport "$portnum_target" ct state new accept - if test "$permanent" = "1"; then - qvm-run -q -u root "${my_netvms[$i]}" -- "echo nft insert rule nat PR-QBS-SERVICES meta iifname $iface $proto dport $portnum_used dnat to ${my_ips[$i-1]}:$portnum_target >> /rw/config/rc.local" - qvm-run -q -u root "${my_netvms[$i]}" -- "echo nft insert rule filter QBS-FORWARD meta iifname $iface ip daddr ${my_ips[$i-1]} $proto dport $portnum_target ct state new accept >> /rw/config/rc.local" - fi - fi - ((i++)) - done -} - - -## Teardown from top netvm down -teardown(){ - declare -a my_netvms=("${!1}") - declare -a my_ips=("${!2}") - declare -i numhops - numhops=${#my_ips[@]} - numhops=$((numhops-1)) - local i=$numhops - iface="eth0" - echo "Removing firewall rules" - while [ $i -gt 0 ]; do - if [ $i -eq 1 ]; then - portnum_used=$external_portnum - portnum_target=$portnum - else - portnum_used=$external_portnum - portnum_target=$external_portnum - fi - # Is it nft or iptables? - echo "${my_netvms[$i]}" - local found - found="$( qvm-run -p -q -u root "${my_netvms[$i]}" -- "nft list table nat 2>/dev/null" )" - if test -z "$found"; then - qvm-run -q -u root "${my_netvms[$i]}" -- "iptables -D QBS-FORWARD -i $iface -p $proto --dport $portnum_target -d ${my_ips[$i-1]} -j ACCEPT" - qvm-run -q -u root "${my_netvms[$i]}" -- "iptables -t nat -D PR-QBS-SERVICES -i $iface -p $proto --dport $external_portnum -j DNAT --to-destination ${my_ips[$i-1]}:$portnum_target" - if [ "$permanent" -eq 1 ]; then - qvm-run -q -u root "${my_netvms[$i]}" -- "sed -i '/iptables -D QBS-FORWARD -i $iface -p $proto --dport $portnum_target -d ${my_ips[$i-1]} -j ACCEPT/d' /rw/config/rc.local" - qvm-run -q -u root "${my_netvms[$i]}" -- "sed -i '/iptables -t nat -D PR-QBS-SERVICES -i $iface -p $proto --dport $external_portnum -j DNAT --to-destination ${my_ips[$i-1]}:$portnum_target/d' /rw/config/rc.local" - fi - else - local handle - handle="$( get_handle "${my_netvms[$i]}" nat "dport $external_portnum " 1 )" - qvm-run -q -u root "${my_netvms[$i]}" -- "nft delete rule nat PR-QBS-SERVICES handle $handle" - local handle - handle="$( get_handle "${my_netvms[$i]}" filter "dport $external_portnum " 1 )" - qvm-run -q -u root "${my_netvms[$i]}" -- "nft delete rule filter QBS-FORWARD handle $handle" - if [ "$permanent" -eq 1 ]; then - qvm-run -q -u root "${my_netvms[$i]}" -- "sed -i '/nft insert rule nat PR-QBS-SERVICES meta iifname $iface $proto dport $portnum_used dnat to ${my_ips[$i-1]}:$portnum_target/d' /rw/config/rc.local" - qvm-run -q -u root "${my_netvms[$i]}" -- "sed -i '/nft insert rule filter QBS-FORWARD meta iifname $iface ip daddr ${my_ips[$i-1]} $proto dport $portnum_target ct state new accept/d' /rw/config/rc.local" - fi - fi - ((i--)) - done - local found - found="$( qvm-run -p -q -u root "${my_netvms[$i]}" -- nft list table nat 2>/dev/null )" - if test -z "$found"; then - qvm-run -q -u root "${my_netvms[$i]}" " iptables -D INPUT -p $proto --dport $external_portnum -j ACCEPT" - else - handle=$( get_handle "${my_netvms[$i]}" filter "dport $portnum " 1 ) - qvm-run -q -u root "${my_netvms[$i]}" -- nft delete rule filter INPUT handle "$handle" - fi - exit -} - - -list(){ - return -} - - -## Defaults -auto=0 -permanent=0 - -## Get options -optstring=":hap" -while getopts ${optstring} option ; do - case $option in - h) usage;; - a) auto=1;; - p) permanent=1;; - ?) usage;; - esac -done -shift $((OPTIND -1)) - -## Check inputs -test "$#" -lt 4 && usage -if ! qvm-check -q "$2" 2>/dev/null; then - echo "$2 is not the name of any qube" - exit 1 -fi -qube_name="$2" -if test "$3" != "tcp" && test "$3" != "udp"; then - echo "Specify tcp or udp" - exit -fi -proto="$3" -portnum="$(check_port "$3" "$4")" - -if [ $# -eq 5 ]; then - external_portnum="$(check_port "$3" "$5")" -else - external_portnum=$portnum -fi - -## Get all netvms -declare -a netvms -declare -a ips -declare -a external_ips -hop=0 -# shellcheck disable=SC2004 -netvms[${hop}]="$qube_name" -IFS='|' read -r netvms[$hop+1] ips[$hop] <<< "$(qvm-ls "$qube_name" --raw-data -O netvm,IP)" -while [ "${netvms[hop+1]}" != "-" ] -do - ((hop++)) - IFS='|' read -r netvms[$hop+1] ips[$hop] <<< "$(qvm-ls "${netvms[$hop]}" --raw-data -O netvm,IP)" -done - -if test "$1" = "delete"; then - teardown netvms[@] ips[@] -elif test "$1" = "add"; then - if [ "$hop" -eq 0 ]; then - echo "$qube_name is not network connected" - echo "Cannot set up a tunnel" - exit - fi - - # Check last hop has external IP address - readarray -t external_ips < <( qvm-run -p "${netvms[$hop]}" "ip -4 -o a|grep -wv 'lo\|vif[0-9]*.*'"|awk '{print $2,$4}') - #readarray -t external_ips < <( qvm-run -p ${netvms[$hop]} "ip -4 -o a|grep -wv 'vif[0-9]'"|awk '{print $2,$4}') - num_ifs=${#external_ips[@]} - if [ "$num_ifs" -eq 1 ]; then - interface=0 - elif [ $auto -eq 1 ]; then - interface=0 - elif [ "$num_ifs" -gt 1 ]; then - echo "${netvms[$hop]} has more than 1 external interface" - echo "Which one do you want to use?" - for i in $(seq "$num_ifs"); do - echo "$i. ${external_ips[$i-1]}" - done - read -r interface - if ! [ "$interface" -eq "$interface" ] 2> /dev/null; then - echo "No such interface" - exit - elif [ "$interface" -gt "$num_ifs" ] || [ "$interface" -lt 1 ]; then - echo "No such interface" - exit - fi - ((interface--)) - else - echo "${netvms[$hop]} does not have an external interface" - echo "Cannot set up a tunnel" - exit - fi - external_ip="${external_ips[$interface]}" - external_iface="${external_ip%[[:space:]]*}" - ip="${external_ip#*[0-9]}" - ip="${ip%%/*}" - # shellcheck disable=SC2004,SC2034 - ips[$hop]="$ip" - - # Create tunnel - found="$(qvm-run -p -q -u root "$qube_name" -- nft list table nat 2>/dev/null)" - if test -z "$found"; then - found=$(qvm-run -p -u root "$qube_name" "iptables -L -nv | grep -c '.*ACCEPT.*$proto dpt:$portnum' ") - if [ "$found" -gt 0 ]; then - echo "Input rule in $qube_name already exists" - echo "Please check configuration - exiting now." - exit - else - qvm-run -q -u root "$qube_name" "iptables -I INPUT -p $proto --dport $portnum -j ACCEPT " - fi - else - if qvm-run -q -u root "$qube_name" "nft list table filter | grep '$proto dport $portnum accept' " - then - echo "Input rule in $qube_name already exists" - echo "Please check configuration - exiting now." - exit - else - handle="$(get_handle "$qube_name" filter related,established 1)" - qvm-run -q -u root "$qube_name" -- nft add rule filter INPUT position "$handle" iifname eth0 "$proto" dport "$portnum" accept - fi - fi - if ! tunnel netvms[@] ips[@]; then - teardown netvms[@] ips[@] - fi -else - usage -fi diff --git a/qusal/sys-syncthing/files/rpc/qubes-syncthing.service b/qusal/sys-syncthing/files/rpc/qubes-syncthing.service deleted file mode 100644 index 8c89597..0000000 --- a/qusal/sys-syncthing/files/rpc/qubes-syncthing.service +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-FileCopyrightText: 2022 unman -# -# SPDX-License-Identifier: GPL-3.0-or-later - -[Unit] -Description=Syncthing over Qrexec -After=qubes-qrexec-agent.service -ConditionPathExists=/var/run/qubes-service/qubes-syncthing - -[Service] -ExecStart=/usr/bin/socat TCP4-LISTEN:22001,reuseaddr,fork,end-close EXEC:"qrexec-client-vm @default qusal.Syncthing" -Restart=on-failure -RestartSec=3 - -# Hardening -ProtectSystem=full -PrivateTmp=true -SystemCallArchitectures=native -MemoryDenyWriteExecute=true -NoNewPrivileges=true - -[Install] -WantedBy=multi-user.target diff --git a/qusal/sys-syncthing/init.top b/qusal/sys-syncthing/init.top index d584d0b..8a9121f 100644 --- a/qusal/sys-syncthing/init.top +++ b/qusal/sys-syncthing/init.top @@ -12,3 +12,5 @@ base: - sys-syncthing.install 'sys-syncthing': - sys-syncthing.configure + 'sys-syncthing-browser': + - sys-syncthing.configure-browser diff --git a/qusal/sys-syncthing/install.sls b/qusal/sys-syncthing/install.sls index e5a3dff..683be4b 100644 --- a/qusal/sys-syncthing/install.sls +++ b/qusal/sys-syncthing/install.sls @@ -20,44 +20,17 @@ SPDX-License-Identifier: GPL-3.0-or-later - install_recommends: False - skip_suggestions: True - pkgs: - ## minimum - qubes-core-agent-networking - - socat - syncthing - ## UI - - firefox-esr - - qubes-core-agent-nautilus - - nautilus - -{% set pkg = { - 'Debian': { - 'pkg': ['libpam-systemd'], - }, - 'RedHat': { - 'pkg': ['systemd-pam'], - }, -}.get(grains.os_family) -%} - -"{{ slsdotpath }}-installed-os-specific": - pkg.installed: - - refresh: True - - install_recommends: False - - skip_suggestions: True - - pkgs: {{ pkg.pkg|sequence|yaml }} + - jq + - socat + - qubes-core-agent-thunar + - thunar "{{ slsdotpath }}-rpc-service": file.managed: - name: /etc/qubes-rpc/qusal.Syncthing - - source: salt://{{ slsdotpath }}/files/rpc/qusal.Syncthing - - user: root - - group: root - - mode: '0755' - - makedirs: True - -"{{ slsdotpath }}-qubes-service": - file.managed: - - name: /lib/systemd/system/qubes-syncthing.service - - source: salt://{{ slsdotpath }}/files/rpc/qubes-syncthing.service + - source: salt://{{ slsdotpath }}/files/server/rpc/qusal.Syncthing - user: root - group: root - mode: '0755' @@ -68,8 +41,31 @@ SPDX-License-Identifier: GPL-3.0-or-later - name: syncthing@user.service - runtime: False -"{{ slsdotpath }}-enable-qubes-syncthing": - service.enabled: - - name: qubes-syncthing.service +"{{ slsdotpath }}-desktop-application-browser": + file.managed: + - name: /usr/share/applications/syncthing-browser.desktop + - source: salt://{{ slsdotpath }}/files/server/syncthing-browser.desktop + - mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-desktop-application-open-general": + file.managed: + - name: /usr/share/applications/syncthing-browser-general.desktop + - source: salt://{{ slsdotpath }}/files/server/syncthing-browser-general.desktop + - mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-etc-mimeapps.list": + file.managed: + - name: /etc/xdg/mimeapps.list + - source: salt://{{ slsdotpath }}/files/server/mimeapps.list + - mode: '0644' + - user: root + - group: root + - makedirs: True {% endif -%} diff --git a/qusal/sys-usb/files/policy/default.policy b/qusal/sys-usb/files/admin/policy/default.policy similarity index 100% rename from qusal/sys-usb/files/policy/default.policy rename to qusal/sys-usb/files/admin/policy/default.policy diff --git a/qusal/utils/macros/policy.sls b/qusal/utils/macros/policy.sls index 18fa762..2a9c86c 100644 --- a/qusal/utils/macros/policy.sls +++ b/qusal/utils/macros/policy.sls @@ -20,7 +20,7 @@ SET POLICY: {{ policy_set(sls_path, '80') }} {% from 'utils/macros/policy.sls' import policy_set_full with context -%} -{{ policy_set_full('project', '/etc/qubes/policy.d/80-project.policy', 'salt://project/files/policy/default.policy') }} +{{ policy_set_full('project', '/etc/qubes/policy.d/80-project.policy', 'salt://project/files/admin/policy/default.policy') }} If you prefer to use 'contents' instead of 'source': {% from 'utils/macros/policy.sls' import load_policy -%} @@ -49,7 +49,7 @@ contents: "{{ project }}-set-rpc-policy": file.managed: - name: /etc/qubes/policy.d/{{ number ~ '-' ~ project }}.policy - - source: salt://{{ project }}/files/policy/default.policy + - source: salt://{{ project }}/files/admin/policy/default.policy - template: jinja - context: sls_path: {{ project }} diff --git a/qusal/utils/macros/sync-appmenus.sls b/qusal/utils/macros/sync-appmenus.sls index 7672fd5..d3a220f 100644 --- a/qusal/utils/macros/sync-appmenus.sls +++ b/qusal/utils/macros/sync-appmenus.sls @@ -18,6 +18,11 @@ Usage: {% macro sync_appmenus(qube) -%} +{% set running = 0 -%} +{% if salt['cmd.shell']('qvm-ls --no-spinner --raw-list --running ' ~ qube) == qube -%} + {% set running = 1 -%} +{% endif -%} + "{{ qube }}-start": qvm.start: - name: {{ qube }} @@ -30,10 +35,12 @@ Usage: - name: qvm-sync-appmenus {{ qube }} - runas: {{ gui_user }} +{% if running == 0 -%} "{{ qube }}-shutdown": qvm.shutdown: - require: - cmd: {{ qube }}-sync-appmenus - name: {{ qube }} +{% endif -%} {% endmacro -%} diff --git a/qusal/vault/README.md b/qusal/vault/README.md index 340e825..0555f3f 100644 --- a/qusal/vault/README.md +++ b/qusal/vault/README.md @@ -32,9 +32,7 @@ qubesctl --skip-dom0 --targets=tpl-vault state.apply vault.install ## Usage The intended usage is to hold passwords and keys. You should copy the keys -generated from the vault to the target qube, which can be a split agent -server for SSH, PGP, Pass. - -You should use a separate qube for split-ssh, split-gpg2 or any other -split-action operations that allows access to the vault qube, as it increases -the attack surface. +generated from the vault to another qube, which can be a split agent +server for SSH, PGP, Pass. A compromise of the client qube can escalate into a +compromise of the qubes it can run RPC services, therefore a separate vault is +appropriate according to your threat model.