diff --git a/.gitignore b/.gitignore index 6370c3b..50fb1c5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,3 @@ qusal/qubesos-github-io qusal/sys-audio qusal/sys-gui qusal/sys-wireguard -qusal/sys-syncthing diff --git a/.reuse/dep5 b/.reuse/dep5 index 6fe640b..ad2dadd 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -3,14 +3,20 @@ Upstream-Name: qusal Upstream-Contact: Benjamin Grande M. S. Source: https://github.com/ben-grande/qusal -Files: */README.md +Files: README.md CONTRIBUTING.md */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 + qusal/sys-mirage-firewall/files/admin/mirage-firewall.sha256 + qusal/sys-mirage-firewall/files/admin/version.txt Copyright: 2019 Thomas Leonard License: BSD-2-Clause +Files: qusal/sys-pihole/files/server/keys/* +Copyright: 2017 Github, Inc. +License: CC0-1.0 + Files: qusal/qubes-builder/files/client/keys/* Copyright: The Qubes OS Project Frédéric Pierret diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3614fc4..194f86c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,10 @@ - - # Contributing to Qusal ## Table of Contents * [Format](#format) * [File naming](#file-naming) + * [State ID](#state-id) * [Readme](#readme) * [Qube naming](#qube-naming) * [Qrexec](#qrexec) @@ -22,9 +17,17 @@ SPDX-License-Identifier: CC-BY-SA-4.0 every state can be applied with top. 2. Every project must have a `init.top`, it facilitates applying every state by enabling a single top file. -3. State file naming should be common between the projects, it helps +3. State file naming must be common between the projects, it helps understand the project as if it was any other. -5. Files names and state IDs should use `-` as separator, not `_`. +4. File name must use `-` as separator, not `_`. + +### State ID + +1. State IDs must use `-` as separator, not `_`. The underline is allowed in + case the features it is changing has underline, such as `default_netvm`. +2. State IDs must always have the project ID, thus allowing to target multiple + states to the same minion from different projects without having + conflicting IDs. ### Readme diff --git a/LICENSES/BSD-2-Clause.txt b/LICENSES/BSD-2-Clause.txt new file mode 100644 index 0000000..5f662b3 --- /dev/null +++ b/LICENSES/BSD-2-Clause.txt @@ -0,0 +1,9 @@ +Copyright (c) + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index e0516ec..485557d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,3 @@ - - # qusal ## Table of Contents @@ -21,6 +15,9 @@ SPDX-License-Identifier: CC-BY-SA-4.0 Qusal - Salt Formulas for Qubes OS. +**Warning**: This project is in Alpha stage, no ready for production. Try in +development only. + Qusal providers a Free and Open Source solution to customizing various tasks in Qubes OS, from switching PCI handlers to be disposables or app qubes, installing different pieces of software on dedicated minimal templates for @@ -126,11 +123,7 @@ tool: reuse spdx ``` -You can also check these information manually by checking in the file header, -a companion `.license` or in `.reuse/dep5`. +You can also check these information manually by looking in the file header, +a companion `.license` file or in `.reuse/dep5`. -Here is a brief summary as of October 2023: - -- Source code is licensed under GPL-3.0-or-later; -- Documentation is licensed under CC-BY-SA-4.0; and -- Configuration and data files are licensed under CC0-1.0. +All licenses are present in the LICENSES directory. diff --git a/qusal/browser/README.md b/qusal/browser/README.md index 13ea288..663951d 100644 --- a/qusal/browser/README.md +++ b/qusal/browser/README.md @@ -74,3 +74,10 @@ Open a disposable qube simply by clicking on the desktop application If you want to use a permanent browser session, create an app qube based on `tpl-browser`. + +If you are forwarding URLs from other qubes via `qvm-open-in-(d)vm`, you might +want to set your preferred browser as the default browser in `tpl-browser` +targeting the desired desktop file: +```sh +xdg-settings set default-web-browser firefox-esr.desktop +``` diff --git a/qusal/debian-minimal/README.md b/qusal/debian-minimal/README.md index 4023ae1..753c7fa 100644 --- a/qusal/debian-minimal/README.md +++ b/qusal/debian-minimal/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -22,3 +23,7 @@ qubesctl top.disable debian-minimal qubesctl state.apply debian-minimal.create qubesctl --skip-dom0 --targets=debian-12-minimal state.apply debian-minimal.install ``` + +## Usage + +AppVMs and StandaloneVMs can be based on this minimal template. diff --git a/qusal/debian/README.md b/qusal/debian/README.md index 5dcc39a..753771d 100644 --- a/qusal/debian/README.md +++ b/qusal/debian/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -22,3 +23,7 @@ qubesctl top.disable debian qubesctl state.apply debian.create qubesctl --skip-dom0 --targets=debian-12 state.apply debian.install ``` + +## Usage + +AppVMs and StandaloneVMs can be based on this template. diff --git a/qusal/dev/README.md b/qusal/dev/README.md index 28e14fe..d71135f 100644 --- a/qusal/dev/README.md +++ b/qusal/dev/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -28,3 +29,13 @@ qubesctl state.apply dev.create qubesctl --skip-dom0 --targets=tpl-dev state.apply dev.install qubesctl --skip-dom0 --targets=dev state.apply dev.configure ``` + +## Usage + +The development qube `dev` can be used for: + +- code development; +- building programs; +- signing commits, tags, pushes and verifying with split-gpg; +- fetching and pushing to and from local qube repository with split-git; and +- fetching and pushing to and from remote repository with split-ssh-agent. diff --git a/qusal/dev/init.sls b/qusal/dev/init.sls index 7e64397..ad72463 100644 --- a/qusal/dev/init.sls +++ b/qusal/dev/init.sls @@ -4,7 +4,8 @@ SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. SPDX-License-Identifier: GPL-3.0-or-later #} -## TODO: should we allow minions to decide which states they should run? +## TODO: Should we allow minions to decide which states they should run? +## This is a hack substitute for top files, but it looks bad. {# include: {% if grains['id'] == 'dom0' -%} diff --git a/qusal/docker/README.md b/qusal/docker/README.md index 6491100..b2e73a2 100644 --- a/qusal/docker/README.md +++ b/qusal/docker/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -25,3 +26,11 @@ qubesctl top.disable docker qubesctl --skip-dom0 --targets=tpl-qubes-builder state.apply docker.install qubesctl --skip-dom0 --targets=qubes-builder state.apply docker.configure ``` + +## Usage + +The only qubes specific configuration to docker is changing its [root +directory](https://docs.docker.com/config/daemon/#daemon-data-directory) to +the private volume or using [qubes +bind-dirs](https://www.qubes-os.org/doc/bind-dirs/) for persistence of the +docker root directory in the root volume. diff --git a/qusal/dom0/README.md b/qusal/dom0/README.md index d8cb0b3..0119610 100644 --- a/qusal/dom0/README.md +++ b/qusal/dom0/README.md @@ -2,8 +2,9 @@ ## Table of Contents -* [Description](#description) -* [Installation](#installation) + * [Description](#description) + * [Installation](#installation) +* [Usage](#usage) ## Description @@ -24,3 +25,15 @@ qubesctl top.disable dom0 ```sh qubesctl state.apply dom0 ``` + +# Usage + +You may have noticed the desktop experience in Dom0 has enhanced. You are +using KDE now. You can enforce domains to appear in certain activity with KWin +rules, a tool `qubes-kde-win-rules` is provided to assist you. + +Qubes backup has also improved, you may use `qvm-backup --profile qusal`, +the profile provided is an example. Use the tool `qvm-backup-find-last` to +find the last Qubes Backup made locally to a qube or a remote system, this +facilitates verifying the last backup made with `qvm-backup-restore +--verify-only`. An example is provided in /etc/qubes/backup/qusal.conf. diff --git a/qusal/dom0/files/bin/qubes-update b/qusal/dom0/files/bin/qubes-update index d35b7dd..10667fa 100755 --- a/qusal/dom0/files/bin/qubes-update +++ b/qusal/dom0/files/bin/qubes-update @@ -74,7 +74,6 @@ def main(args=None): # pylint: disable=missing-docstring if args.dom0: args.command.append('update.qubes-dom0') try: - # TODO: handle args.show_output - if false, log to some file subprocess.check_call(['qubesctl', '--dom0-only'] + args.command) except subprocess.CalledProcessError: print("DOM0 configuration failed, not continuing", file=sys.stderr) @@ -118,7 +117,6 @@ def main(args=None): # pylint: disable=missing-docstring args.command.remove('update.qubes-vm') args.command.append('update.qubes-dom0') try: - # TODO: handle args.show_output - if false, log to some file subprocess.check_call(['qubesctl', '--dom0-only'] + args.command) except subprocess.CalledProcessError: print("DOM0 configuration failed, not continuing", file=sys.stderr) diff --git a/qusal/dotfiles b/qusal/dotfiles index 60b22d6..2c9b7f1 160000 --- a/qusal/dotfiles +++ b/qusal/dotfiles @@ -1 +1 @@ -Subproject commit 60b22d66d248a2083b015e1aab2b8a711fae91cc +Subproject commit 2c9b7f1ca7c510b1fca7229deaaedc1320bfd980 diff --git a/qusal/fedora-minimal/README.md b/qusal/fedora-minimal/README.md index 0535243..980bd1d 100644 --- a/qusal/fedora-minimal/README.md +++ b/qusal/fedora-minimal/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -22,3 +23,7 @@ qubesctl top.disable fedora-minimal qubesctl state.apply fedora-minimal.create qubesctl --skip-dom0 --targets=fedora-38-minimal state.apply fedora-minimal.install ``` + +## Usage + +AppVMs and StandaloneVMs can be based on this minimal template. diff --git a/qusal/fedora/README.md b/qusal/fedora/README.md index 8dddb14..e4a0597 100644 --- a/qusal/fedora/README.md +++ b/qusal/fedora/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -22,3 +23,7 @@ qubesctl top.disable fedora qubesctl state.apply fedora.create qubesctl --skip-dom0 --targets=fedora-38 state.apply fedora.install ``` + +## Usage + +AppVMs and StandaloneVMs can be based on this template. diff --git a/qusal/media/README.md b/qusal/media/README.md index e823c1e..d705b54 100644 --- a/qusal/media/README.md +++ b/qusal/media/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) * [Credits](#credits) ## Description @@ -29,6 +30,17 @@ qubesctl --skip-dom0 --targets=tpl-media state.apply media.install qubesctl --skip-dom0 --targets=media state.apply media.configure ``` +## Usage + +You will store multimedia files in the "media" qube. When you try to open a +file in that qube, it will open instead in the disposable "disp-media". + +No file browser is installed in the "media" qube as code execution exploits in +file browsers are common when rendering thumbnails, indexing file name, +automatically running scripts saved in the home directory. You are open to +forward files from the "media" qube to "disp-media" by running `xdg-open +/path/file` or more explicitly, `qvm-open-in-dvm /path/file`. + ## Credits - [Unman](https://github.com/unman/shaker/tree/main/multimedia) diff --git a/qusal/media/configure.sls b/qusal/media/configure.sls index ba78c63..d8f2eff 100644 --- a/qusal/media/configure.sls +++ b/qusal/media/configure.sls @@ -18,11 +18,11 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-home-local-share-mimeapps.list": file.symlink: - - name: /home/user/.config/mimeapps.list - - target: /home/user/.local/share/applications/mimeapps.list + - name: /home/user/.local/share/applications/mimeapps.list + - target: /home/user/.config/mimeapps.list - user: user - group: user - - makedirs: True - force: True + - makedirs: True {% endif -%} diff --git a/qusal/media/create.sls b/qusal/media/create.sls index 51fe09c..d0c6c00 100644 --- a/qusal/media/create.sls +++ b/qusal/media/create.sls @@ -34,6 +34,8 @@ features: - service.cups - service.cups-browsed - service.tinyproxy + - service.tracker + - service.evolution-data-server {%- endload %} {{ load(defaults) }} @@ -59,6 +61,8 @@ features: - service.cups - service.cups-browsed - service.tinyproxy + - service.tracker + - service.evolution-data-server {%- endload %} {{ load(defaults) }} @@ -86,6 +90,8 @@ features: - service.cups - service.cups-browsed - service.tinyproxy + - service.tracker + - service.evolution-data-server - enable: - service.shutdownle {%- endload %} diff --git a/qusal/media/files/admin/policy/default.policy b/qusal/media/files/admin/policy/default.policy index 4f255fd..ae8c74b 100644 --- a/qusal/media/files/admin/policy/default.policy +++ b/qusal/media/files/admin/policy/default.policy @@ -5,4 +5,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`. qubes.OpenInVM * {{ sls_path }} @dispvm allow target=disp-{{ sls_path }} +qubes.OpenInVM * {{ sls_path }} @default allow target=disp-{{ sls_path }} +qubes.OpenInVM * {{ sls_path }} @anyvm deny ## vim:ft=qrexecpolicy diff --git a/qusal/media/files/server/mimeapps.list b/qusal/media/files/browser/mimeapps.list similarity index 100% rename from qusal/media/files/server/mimeapps.list rename to qusal/media/files/browser/mimeapps.list diff --git a/qusal/media/install.sls b/qusal/media/install.sls index 9b8fab0..99851f0 100644 --- a/qusal/media/install.sls +++ b/qusal/media/install.sls @@ -7,6 +7,9 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' -%} +include: + - browser.install + "{{ slsdotpath }}-updated": pkg.uptodate: - refresh: True @@ -26,11 +29,12 @@ SPDX-License-Identifier: GPL-3.0-or-later - xpdf - ffmpeg - ffmpegthumbnailer + - mousepad "{{ slsdotpath }}-etc-mimeapps.list": file.managed: - name: /etc/xdg/mimeapps.list - - source: salt://{{ slsdotpath }}/files/server/mimeapps.list + - source: salt://{{ slsdotpath }}/files/browser/mimeapps.list - mode: '0644' - user: root - group: root diff --git a/qusal/mgmt/README.md b/qusal/mgmt/README.md index 2618f07..8797ecc 100644 --- a/qusal/mgmt/README.md +++ b/qusal/mgmt/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -21,3 +22,8 @@ qubesctl state.apply mgmt.create qubesctl --skip-dom0 --targets=tpl-mgmt state.apply mgmt.install qubesctl state.apply mgmt.prefs ``` + +## Usage + +You will use the Template for DispVMs "dvm-mgmt" indirectly when running salt +states on minions/DomUs or when opening a disposable console of a qube. diff --git a/qusal/mutt/README.md b/qusal/mutt/README.md index da923e8..0229857 100644 --- a/qusal/mutt/README.md +++ b/qusal/mutt/README.md @@ -31,7 +31,7 @@ qubesctl --skip-dom0 --targets=mutt state.apply mutt.configure ## Usage You will use local files to override the ones provided by this package. Few -options need to be set. +options must be set. The file `~/.muttrc-credentials.local` will set some variables that will be used by other configuration files sourced later: @@ -47,7 +47,14 @@ set my_pass = "mypassword" You can define aliases in `~/.muttrc-aliases.local`. If you want to override any option, put the settings in `~/.muttrc.local`, -as this is the last file to be sourced. +as this is the last file to be sourced. You might want to put for example, +subscribed lists in this file: +```muttrc +lists .*@googlegroups\\.com +subscribe qubes-(announce|devel)@googlegroups\\.com +fcc-save-hook qubes-annount@googlegroups\\.com =list/qubes-announce/ +fcc-save-hook qubes-devel@googlegroups\\.com =list/qubes-devel/ +``` If you want to have your e-mail signature (not PGP) at the end of every mail you send, place it in `~/.signature`. diff --git a/qusal/mutt/configure.sls b/qusal/mutt/configure.sls index 00a85e1..5b99f67 100644 --- a/qusal/mutt/configure.sls +++ b/qusal/mutt/configure.sls @@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later include: - dotfiles.copy-x11 - dotfiles.copy-sh + - dotfiles.copy-net - dotfiles.copy-mutt {% endif -%} diff --git a/qusal/mutt/install.sls b/qusal/mutt/install.sls index 77b7e23..d9004a8 100644 --- a/qusal/mutt/install.sls +++ b/qusal/mutt/install.sls @@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later include: - dotfiles.copy-x11 - dotfiles.copy-sh + - dotfiles.copy-net - dotfiles.copy-mutt "{{ slsdotpath }}-updated": @@ -27,10 +28,10 @@ include: - qubes-img-converter - qubes-gpg-split - w3m - - vim - man-db - less # mutt + - vim - mutt - notmuch - notmuch-mutt diff --git a/qusal/qubes-builder/README.md b/qusal/qubes-builder/README.md index 3c5d520..e98e1cd 100644 --- a/qusal/qubes-builder/README.md +++ b/qusal/qubes-builder/README.md @@ -60,6 +60,8 @@ limit the scope, the action is `allowed`, else the action is to `ask`. ## Usage +The builder qube is named `qubes-builder.` + When using the Qubes Executor, configure the builder.yml `dispvm` option to either `dom0` or `dvm-qubes-builder`: ```yaml diff --git a/qusal/reader/README.md b/qusal/reader/README.md index 59f3080..4f3bb39 100644 --- a/qusal/reader/README.md +++ b/qusal/reader/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) * [Credits](#credits) ## Description @@ -30,6 +31,14 @@ qubesctl state.apply reader.create qubesctl --skip-dom0 --targets=tpl-reader state.apply reader.install ``` +## Usage + +The intended usage of this qube is a receiver of incoming files that the call +originator/client did no trust to open in its environment. When you run +`qvm-open-in-dvm` from a qube and it is using the global preferences default +`default_dispvm`, it will open the file to be read in a disposable based on +`dvm-reader`. + ## Credits - [Unman](https://github.com/unman/shaker/tree/main/reader) diff --git a/qusal/remmina/README.md b/qusal/remmina/README.md index 75d27fa..e15208d 100644 --- a/qusal/remmina/README.md +++ b/qusal/remmina/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -29,3 +30,11 @@ qubesctl state.apply remmina.create qubesctl --skip-dom0 --targets=tpl-remmina state.apply remmina.install qubesctl state.apply remmina.appmenus ``` + +## Usage + +You will use Remmina to access remote computers, be it though a login shell +(SSH) or through a desktop connection (VNC, SPICE, HTTP, X2Go). + +You can base your qubes of `dvm-remmina` for disposables or `remmina` for +persistence of data. diff --git a/qusal/signal/README.md b/qusal/signal/README.md index d778d5d..fee6742 100644 --- a/qusal/signal/README.md +++ b/qusal/signal/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -26,3 +27,11 @@ qubesctl state.apply signal.create qubesctl --skip-dom0 --targets=tpl-signal state.apply signal.install qubesctl --skip-dom0 --targets=signal state.apply signal.configure ``` + +## Usage + +You may use different Signal accounts for different identities, such as +personal, work or pseudonym. Maintain the `signal` qube pristine and clone it +to the assigned domain, `personal-signal`, `work-signal`, `anon-signal`. If +you don't maintain the qube pristine, you will have to apply the firewall +rules manually. diff --git a/qusal/signal/create.sls b/qusal/signal/create.sls index b1d9f97..ecc4c51 100644 --- a/qusal/signal/create.sls +++ b/qusal/signal/create.sls @@ -27,6 +27,7 @@ name: {{ slsdotpath }} force: True require: - sls: {{ slsdotpath }}.clone +- qvm: tpl-{{ slsdotpath }} present: - template: tpl-{{ slsdotpath }} - label: yellow diff --git a/qusal/signal/firewall.sls b/qusal/signal/firewall.sls index b5be516..caf5c3f 100644 --- a/qusal/signal/firewall.sls +++ b/qusal/signal/firewall.sls @@ -6,6 +6,8 @@ SPDX-License-Identifier: GPL-3.0-or-later "{{ slsdotpath }}-firewall": cmd.run: + - require: + - qvm: {{ slsdotpath }} - name: | qvm-check -q --running {{ slsdotpath }} && qvm-pause {{ slsdotpath }} qvm-firewall {{ slsdotpath }} reset diff --git a/qusal/signal/install.sls b/qusal/signal/install.sls index 4fe44d4..a861e8e 100644 --- a/qusal/signal/install.sls +++ b/qusal/signal/install.sls @@ -32,7 +32,6 @@ include: - dunst - libatk1.0-0 - libatk-bridge2.0-0 - - libgtk-3-0 - - libcups2 + - libgtk-4-1 {% endif -%} diff --git a/qusal/ssh/README.md b/qusal/ssh/README.md index 2343264..7708098 100644 --- a/qusal/ssh/README.md +++ b/qusal/ssh/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -15,11 +16,6 @@ When saving the SSH configuration is necessary, use the ssh qube. If login in as a one time connection or to an untrusted host use a DispVM based on "dvm-ssh" for disposability. -The client qube can enhanced by being: - -- sys-ssh-agent's client and not storing the SSH keys on the client; or -- sys-git's client and fetching from qubes and push to remote servers. - ## Installation - Top: @@ -35,3 +31,14 @@ qubesctl state.apply ssh.create qubesctl --skip-dom0 --targets=tpl-ssh state.apply ssh.install qubesctl --skip-dom0 --targets=dvm-ssh,ssh state.apply ssh.configure ``` + +## Usage + +Create DispVMs based on the Template for DispVMs "dvm-ssh" for disposable SSH +sessions or create AppVMs based on "tpl-ssh", such as the "ssh" qube for for +preserving the SSH configuration client side. + +The client qube can enhanced by being: + +- sys-ssh-agent's client and not storing the SSH keys on the client; or +- sys-git's client and fetching from qubes and push to remote servers. diff --git a/qusal/sys-cacher/README.md b/qusal/sys-cacher/README.md index 597f74e..67f6fc4 100644 --- a/qusal/sys-cacher/README.md +++ b/qusal/sys-cacher/README.md @@ -5,9 +5,9 @@ * [Description](#description) * [Installation](#installation) * [Usage](#usage) + * [Report Page and Maintenance Tasks](#report-page-and-maintenance-tasks) * [Connect to the cacher via IP instead of Qrexec](#connect-to-the-cacher-via-ip-instead-of-qrexec) * [Non-TemplateVMs integration](#non-templatevms-integration) -* [Upgrade](#upgrade) * [Uninstallation](#uninstallation) * [Credits](#credits) @@ -37,29 +37,54 @@ specify otherwise. - Top ```sh -qubesctl top.enable sys-cacher -qubesctl --targets=tpl-sys-cacher,sys-cacher state.apply -qubesctl top.disable sys-cacher -qubesctl state.apply sys-cacher.tag +qubesctl top.enable sys-cacher browser +qubesctl --targets=tpl-browser,tpl-sys-cacher,sys-cacher,sys-cacher-browser state.apply +qubesctl top.disable sys-cacher browser +qubesctl state.apply sys-cacher.appmenus,sys-cacher.tag ``` - State ```sh qubesctl state.apply sys-cacher.create +qubesctl --skip-dom0 --targets=tpl-browser state.apply browser.install qubesctl --skip-dom0 --targets=tpl-sys-cacher state.apply sys-cacher.install qubesctl --skip-dom0 --targets=sys-cacher state.apply sys-cacher.configure -qubesctl state.apply sys-cacher.tag +qubesctl --skip-dom0 --targets=sys-cacher-browser state.apply sys-cacher.configure-browser +qubesctl state.apply sys-cacher.appmenus,sys-cacher.tag qubesctl --skip-dom0 --templates state.apply sys-cacher.install-client ``` ## Usage +### Report Page and Maintenance Tasks + +The report page is available from `sys-cacher` and `sys-cacher-browser` at +`http://127.0.0.1:8082/acng-report.html` and any other client qube that has +`sys-cacher` as it's update qube. This is apt-cacher-ng limitation and is bad +security wise, every client has administrative access to the cacher qube. You +should add the following to the end of `sys-cacher` rc.local: +```sh +echo "AdminAuth: username:password" | tee /etc/apt-cacher-ng/zzz_security.conf +``` +Where username and password are HTTP Auth strings. + +If you want to view statistics or manage the server through a GUI, open +`sys-cacher` or `sys-cacher-browser` desktop file `cacher-browser.desktop` +from Dom0. Addresses starting with `http` or `https` will be redirected +to `sys-cacher-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. + ### Connect to the cacher via IP instead of Qrexec -Because the sys-cacher qube is listening on port 8082, you can use it from -non-template qubes and qubes that do not have a working Qrexec. Use -the native configuration to set the update proxy using the IP address -of sys-cacher. +Because the `sys-cacher` qube is listening on port `8082`, you can use it from +non-template qubes and qubes that do not have a working Qrexec. Use the native +configuration to set the update proxy using the IP address of `sys-cacher` by +setting the cacher as the netvm of the client qube. ### Non-TemplateVMs integration @@ -85,13 +110,6 @@ sudo /usr/lib/qubes/update-proxy-configs sudo systemctl restart qubes-updates-proxy-forwarder.socket ``` -## Upgrade - -- State -```sh -qubesctl --skip-dom0 --targets=sys-cacher state.apply sys-cacher.configure -``` - ## Uninstallation - Top: diff --git a/qusal/sys-cacher/appmenus.sls b/qusal/sys-cacher/appmenus.sls new file mode 100644 index 0000000..642db38 --- /dev/null +++ b/qusal/sys-cacher/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('tpl-' ~ sls_path) }} + +{% from 'utils/macros/sync-appmenus.sls' import sync_appmenus -%} +{{ sync_appmenus(sls_path ~ '-browser') }} diff --git a/qusal/sys-cacher/appmenus.top b/qusal/sys-cacher/appmenus.top new file mode 100644 index 0000000..26cfe01 --- /dev/null +++ b/qusal/sys-cacher/appmenus.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-cacher.appmenus diff --git a/qusal/sys-cacher/configure-browser.sls b/qusal/sys-cacher/configure-browser.sls new file mode 100644 index 0000000..e53db27 --- /dev/null +++ b/qusal/sys-cacher/configure-browser.sls @@ -0,0 +1,23 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{% if grains['nodename'] != 'dom0' %} + +"{{ slsdotpath }}-browser-rc.local": + file.append: + - name: /rw/config/rc.local + - text: "qvm-connect-tcp 8082:@default:8082" + +"{{ slsdotpath }}-browser-desktop-application": + file.managed: + - name: /home/user/.local/share/applications/cacher-browser.desktop + - source: salt://{{ slsdotpath }}/files/browser/cacher-browser.desktop + - mode: '0644' + - user: user + - group: user + - makedirs: True + +{% endif -%} diff --git a/qusal/sys-cacher/configure-browser.top b/qusal/sys-cacher/configure-browser.top new file mode 100644 index 0000000..19bb4bb --- /dev/null +++ b/qusal/sys-cacher/configure-browser.top @@ -0,0 +1,9 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'sys-cacher-browser': + - sys-cacher.configure-browser diff --git a/qusal/sys-cacher/create.sls b/qusal/sys-cacher/create.sls index ba240d1..30c2b46 100644 --- a/qusal/sys-cacher/create.sls +++ b/qusal/sys-cacher/create.sls @@ -9,6 +9,29 @@ SPDX-License-Identifier: GPL-3.0-or-later include: - .clone +{% load_yaml as defaults -%} +name: tpl-{{ slsdotpath }} +force: True +require: +- sls: {{ slsdotpath }}.clone +prefs: +- vcpus: 1 +- memory: 300 +- maxmem: 500 +- autostart: False +- include_in_backups: False +features: +- disable: + - service.cups + - service.cups-browsed + - service.tracker + - service.evolution-data-server +- set: + - menu-items: "cacher-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" + - default-menu-items: "cacher-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" +{%- endload %} +{{ load(defaults) }} + {% load_yaml as defaults -%} name: {{ slsdotpath }} force: True @@ -20,10 +43,13 @@ present: prefs: - template: tpl-{{ slsdotpath }} - label: gray -- memory: 300 -- maxmem: 600 + ## Disable memory balooning because of HTTP 503: Cannot allocate memory +- maxmem: 0 +- memory: 500 - vcpus: 1 - provides-network: true +- autostart: False +- include_in_backups: True features: - enable: - servicevm @@ -32,6 +58,37 @@ features: - service.cups - service.cups-browsed - service.tinyproxy + - service.meminfo-writer +- set: + - menu-items: "cacher-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: gray +prefs: +- template: tpl-browser +- label: gray +- vcpus: 1 +- netvm: "" +- memory: 300 +- maxmem: 500 +- autostart: False +- include_in_backups: False +features: +- disable: + - service.cups + - service.cups-browsed + - service.tracker + - service.evolution-data-server +- set: + - menu-items: "cacher-browser.desktop qubes-run-terminal.desktop qubes-start.desktop" {%- endload %} {{ load(defaults) }} diff --git a/qusal/sys-cacher/files/admin/policy/default.policy b/qusal/sys-cacher/files/admin/policy/default.policy index 922886d..74f2854 100644 --- a/qusal/sys-cacher/files/admin/policy/default.policy +++ b/qusal/sys-cacher/files/admin/policy/default.policy @@ -4,6 +4,10 @@ ## 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.OpenURL * {{ sls_path }} @default allow target={{ sls_path }}-browser +qubes.OpenURL * {{ sls_path }} @anyvm deny +qubes.ConnectTCP +8082 {{ sls_path }}-browser @default allow target={{ sls_path }} +qubes.ConnectTCP * {{ sls_path }}-browser @anyvm deny qubes.UpdatesProxy * @tag:whonix-updatevm @default allow target=sys-whonix qubes.UpdatesProxy * @tag:whonix-updatevm @anyvm deny qubes.UpdatesProxy * @tag:{{ sls_path }}-updatevm @default allow target={{ sls_path }} diff --git a/qusal/sys-cacher/files/browser/cacher-browser.desktop b/qusal/sys-cacher/files/browser/cacher-browser.desktop new file mode 100644 index 0000000..a003653 --- /dev/null +++ b/qusal/sys-cacher/files/browser/cacher-browser.desktop @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Desktop Entry] +Name=Apt-Cacher-NG Browser +Exec=xdg-open http://127.0.0.1:8082/acng-report.html +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser;FileTransfer;P2P; diff --git a/qusal/sys-cacher/files/server/cacher-browser-general.desktop b/qusal/sys-cacher/files/server/cacher-browser-general.desktop new file mode 100644 index 0000000..5bf36f8 --- /dev/null +++ b/qusal/sys-cacher/files/server/cacher-browser-general.desktop @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Desktop Entry] +Name=Apt-Cacher-NG 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-cacher/files/server/cacher-browser.desktop b/qusal/sys-cacher/files/server/cacher-browser.desktop new file mode 100644 index 0000000..1a3a561 --- /dev/null +++ b/qusal/sys-cacher/files/server/cacher-browser.desktop @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Desktop Entry] +Name=Apt-Cacher-NG Browser +Exec=qvm-open-in-vm -- @default http://127.0.0.1:8082/acng-report.html +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser;FileTransfer;P2P; diff --git a/qusal/sys-cacher/files/server/mimeapps.list b/qusal/sys-cacher/files/server/mimeapps.list new file mode 100644 index 0000000..98fc4bb --- /dev/null +++ b/qusal/sys-cacher/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=cacher-browser-general.desktop +x-scheme-handler/https=cacher-browser-general.desktop diff --git a/qusal/sys-cacher/init.top b/qusal/sys-cacher/init.top index 2755445..5f60ca8 100644 --- a/qusal/sys-cacher/init.top +++ b/qusal/sys-cacher/init.top @@ -12,6 +12,8 @@ base: - sys-cacher.install 'sys-cacher': - sys-cacher.configure + 'sys-cacher-browser': + - sys-cacher.configure-browser 'I@qubes:type:template and not P@nodename:host and not P@nodename:whonix.*': - match: compound - sys-cacher.install-client diff --git a/qusal/sys-cacher/install.sls b/qusal/sys-cacher/install.sls index ff0f80f..63f6373 100644 --- a/qusal/sys-cacher/install.sls +++ b/qusal/sys-cacher/install.sls @@ -28,11 +28,11 @@ SPDX-License-Identifier: GPL-3.0-or-later - anacron - apt-cacher-ng -"{{ slsdotpath }}-disable-systemd-service": +"{{ slsdotpath }}-disable-apt-cacher-ng": cmd.run: - name: systemctl disable apt-cacher-ng -"{{ slsdotpath }}-mask-systemd-service-apt-cacher-ng" +"{{ slsdotpath }}-mask-apt-cacher-ng": service.masked: - name: apt-cacher-ng - runtime: False @@ -74,4 +74,31 @@ SPDX-License-Identifier: GPL-3.0-or-later - group: root - makedirs: True +"{{ slsdotpath }}-desktop-application-browser": + file.managed: + - name: /usr/share/applications/cacher-browser.desktop + - source: salt://{{ slsdotpath }}/files/server/cacher-browser.desktop + - mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-desktop-application-open-general": + file.managed: + - name: /usr/share/applications/cacher-browser-general.desktop + - source: salt://{{ slsdotpath }}/files/server/cacher-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-firewall/README.md b/qusal/sys-firewall/README.md index de6d1c3..5d3ee97 100644 --- a/qusal/sys-firewall/README.md +++ b/qusal/sys-firewall/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -38,3 +39,10 @@ Alternatively, if you prefer to have a disposable firewall: ```sh qubesctl state.apply sys-firewall.prefs-disp ``` + +## Usage + +You should use this qube for handling updates and firewall downstream/client +qubes, in other words, enforce network policy to qubes that have +`sys-firewall` as its `netvm`. Read [upstream firewall +documentation](https://www.qubes-os.org/doc/firewall/). diff --git a/qusal/sys-git/README.md b/qusal/sys-git/README.md index 7a23f4d..04de5e3 100644 --- a/qusal/sys-git/README.md +++ b/qusal/sys-git/README.md @@ -9,6 +9,7 @@ * [Usage](#usage) * [Initialize the server repository](#initialize-the-server-repository) * [Prepare the client](#prepare-the-client) +* [Credits](#credits) ## Description @@ -108,7 +109,7 @@ There are a few constraints regarding repositories: - Must be created under `/home/user/src` in `sys-git`; - Names must have only letters, numbers, hyphen, underscore and dot. Must not - begin with dot, hyphen and underscore. + begin or end with dot, hyphen and underscore. In `sys-git`, create bare repositories under `/home/user/src`. @@ -126,9 +127,10 @@ git init-qrexec ### Prepare the client -Qrexec protocol is supported with the following URL: `qrexec:///`, -where the `` field can be a literal name or token and the `` field -is the name of the repository that exists on `sys-git` under `/home/user/src`. +Qrexec protocol is supported with the following URL format: +`qrexec:///`, where the `` field can be a literal name or +token and the `` field is the name of the repository that exists on +`sys-git` under `/home/user/src`. Clone an existing repository: ```sh @@ -140,17 +142,18 @@ Or Initialize a new repository: git init qubes-doc cd qubes-doc ``` + Add a remote using the Qrexec protocol: ```sh git remote add sg qrexec://@default/qubes-doc ``` -Test fetching: +Test fetching from the newly added remote: ```sh git fetch sg ``` -You can then use that repository as usual, making commits. +Make changes to the git repository as you normally would on any system. Push to the server and set it as the default upstream: ```sh @@ -161,3 +164,7 @@ Following pushes will be simpler: ```sh git push ``` + +## Credits + +- [Unman](https://github.com/unman/shaker/tree/main/git) diff --git a/qusal/sys-mirage-firewall/README.md b/qusal/sys-mirage-firewall/README.md index 7efc7cd..f35bfc7 100644 --- a/qusal/sys-mirage-firewall/README.md +++ b/qusal/sys-mirage-firewall/README.md @@ -19,6 +19,9 @@ 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. +The qube sys-firewall is also the default updatevm. You can't use Mirage +Firewall to be the updatevm, use another qube instead. + ## Installation - Top diff --git a/qusal/sys-net/README.md b/qusal/sys-net/README.md index 4bfb455..d5a89ab 100644 --- a/qusal/sys-net/README.md +++ b/qusal/sys-net/README.md @@ -5,7 +5,6 @@ * [Description](#description) * [Installation](#installation) * [Usage](#usage) - * [Persistent WiFi password in disposable qube](#persistent-wifi-password-in-disposable-qube) ## Description @@ -17,12 +16,18 @@ be a disposable or not. This package takes a different approach, it will create an AppVM "sys-net" and a DispVM "disp-sys-net". By default, the chosen one is "sys-net", but you can choose which qube type -becomes the upstream net qube, the "clockvm" and the fallback target for the -"qubes.UpdatesProxy" service in case no rule matched before, described in the -installation section below. +becomes the upstream net qube "default_netvm", the "clockvm" and the fallback +target for the "qubes.UpdatesProxy" service in case no rule matched before. ## Installation +Before installation, rename your current `sys-net` to another name such as +`sys-net-old`, the old qube will be used to install packages require for the +template. After successful installation and testing the new net qube +capabilities, you can remove the old one. If you want the default net qube +back, just set `sys-net` template to the full template you are using, such as +Debian or Fedora. + - Top: ```sh qubesctl top.enable sys-net @@ -44,27 +49,11 @@ qubesctl state.apply sys-net.prefs-disp ``` You might need to install some firmware on the template for your network -drivers. Check firmware.txt. +drivers. Check files/admin/firmware.txt. ## Usage -### Persistent WiFi password in disposable qube - -The following change must be done on the AppVM that is a template for -disposables, the `dvm-sys-net`, in the `/rw/config/rc.local` (change the SSID -and PASSWORD for the adequate values): -```sh -conn_net(){ - if nm-online -s -x; then - nmcli dev wifi connect SSID password "PASSWORD" - fi -} -while ! systemctl is-active networking.service; do sleep 5; done -case "$(qubesdb-read /type)" in - DispVM|AppVM) - if test -e /run/qubes-service/network-manager; then - conn_net - fi - ;; -esac -``` +A network manager is provided in `sys-net`, from there you can manager Wi-Fi +or Ethernet cable connections. You can also use it for network monitoring. It +should be relied on to hold firewall rules for other qubes, use +`sys-firewall`, `sys-pihole` or `sys-mirage-firewall` for that purpose. diff --git a/qusal/sys-net/create.sls b/qusal/sys-net/create.sls index 5b73eed..c09a083 100644 --- a/qusal/sys-net/create.sls +++ b/qusal/sys-net/create.sls @@ -23,13 +23,12 @@ prefs: - template: tpl-{{ slsdotpath }} - label: red - netvm: "" -- memory: 0 -- maxmem: 400 +- memory: 400 +- maxmem: 0 - vcpus: 1 - virt_mode: hvm - autostart: False - provides-network: True -# - pcidevs: [ '03:00.0', '00:19.0' ] - pcidevs: {{ net_pcidevs|yaml }} - pci_strictreset: False - include_in_backups: False @@ -57,8 +56,8 @@ prefs: - template: tpl-{{ slsdotpath }} - label: red - netvm: "" -- memory: 0 -- maxmem: 400 +- memory: 400 +- maxmem: 0 - vcpus: 1 - virt_mode: hvm - template_for_dispvms: True @@ -91,7 +90,6 @@ prefs: - netvm: "" - autostart: False - provides-network: True -# - pcidevs: [ '03:00.0', '00:19.0' ] - pcidevs: {{ net_pcidevs|yaml }} - pci_strictreset: False - include_in_backups: False diff --git a/qusal/sys-net/firmware.txt b/qusal/sys-net/files/admin/firmware.txt similarity index 100% rename from qusal/sys-net/firmware.txt rename to qusal/sys-net/files/admin/firmware.txt diff --git a/qusal/sys-net/install.sls b/qusal/sys-net/install.sls index 10e82eb..3418544 100644 --- a/qusal/sys-net/install.sls +++ b/qusal/sys-net/install.sls @@ -23,5 +23,6 @@ include: - qubes-core-agent-network-manager - wpasupplicant - gnome-keyring + - notification-daemon {% endif -%} diff --git a/qusal/sys-pgp/README.md b/qusal/sys-pgp/README.md index 31d5590..a495b94 100644 --- a/qusal/sys-pgp/README.md +++ b/qusal/sys-pgp/README.md @@ -59,4 +59,5 @@ qubes.Gpg * @anyvm @anyvm deny ## Usage -Full details are at [www.qubes-os.org/doc/split-gpg](https://www.qubes-os.org/doc/split-gpg/). +Consult [upstream documentation](https://www.qubes-os.org/doc/split-gpg/) on +how to use split-gpg. diff --git a/qusal/sys-pihole/README.md b/qusal/sys-pihole/README.md index 203cc17..3913e21 100644 --- a/qusal/sys-pihole/README.md +++ b/qusal/sys-pihole/README.md @@ -22,6 +22,11 @@ to it. ## Installation +Pi-Hole commits and tags are not signed by individuals, but as they are done +through the web interface, they have GitHub Web-Flow signature. This is the +best verification we can get for Pi-Hole. If you don't trust the hosting +provider however, don't install this package. + - Top: ```sh qubesctl top.enable sys-pihole browser @@ -82,6 +87,12 @@ netvm chaining (will break tor's client stream isolation) as such: - qube -> sys-pihole -> Tor-gateway -> sys-firewall -> sys-net +If you encounter problems with DNS after having upstream netvm route changes, +restart Pi-Hole DNS from `sys-pihole`: +```sh +pihole restartdns +``` + ## Credits - [Patrizio Tufarolo](https://blog.tufarolo.eu/how-to-configure-pihole-in-qubesos-proxyvm/) diff --git a/qusal/sys-pihole/files/browser/pihole-browser.desktop b/qusal/sys-pihole/files/browser/pihole-browser.desktop index 91fb2ff..4613c2e 100644 --- a/qusal/sys-pihole/files/browser/pihole-browser.desktop +++ b/qusal/sys-pihole/files/browser/pihole-browser.desktop @@ -1,6 +1,10 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + [Desktop Entry] Name=Pi-Hole Browser -Exec=xdg-open http://127.0.0.1:80 +Exec=xdg-open http://127.0.0.1:80/admin Icon=web-browser Terminal=false X-MultipleArgs=False diff --git a/qusal/sys-pihole/files/server/keys/5DE3E0509C47EA3CF04A42D34AEE18F83AFDEB23.asc b/qusal/sys-pihole/files/server/keys/5DE3E0509C47EA3CF04A42D34AEE18F83AFDEB23.asc new file mode 100644 index 0000000..e7794c4 --- /dev/null +++ b/qusal/sys-pihole/files/server/keys/5DE3E0509C47EA3CF04A42D34AEE18F83AFDEB23.asc @@ -0,0 +1,33 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFmUaEEBCACzXTDt6ZnyaVtueZASBzgnAmK13q9Urgch+sKYeIhdymjuMQta +x15OklctmrZtqre5kwPUosG3/B2/ikuPYElcHgGPL4uL5Em6S5C/oozfkYzhwRrT +SQzvYjsE4I34To4UdE9KA97wrQjGoz2Bx72WDLyWwctD3DKQtYeHXswXXtXwKfjQ +7Fy4+Bf5IPh76dA8NJ6UtjjLIDlKqdxLW4atHe6xWFaJ+XdLUtsAroZcXBeWDCPa +buXCDscJcLJRKZVc62gOZXXtPfoHqvUPp3nuLA4YjH9bphbrMWMf810Wxz9JTd3v +yWgGqNY0zbBqeZoGv+TuExlRHT8ASGFS9SVDABEBAAHNNUdpdEh1YiAod2ViLWZs +b3cgY29tbWl0IHNpZ25pbmcpIDxub3JlcGx5QGdpdGh1Yi5jb20+wsBiBBMBCAAW +BQJZlGhBCRBK7hj4Ov3rIwIbAwIZAQAAmQEIACATWFmi2oxlBh3wAsySNCNV4IPf +DDMeh6j80WT7cgoX7V7xqJOxrfrqPEthQ3hgHIm7b5MPQlUr2q+UPL22t/I+ESF6 +9b0QWLFSMJbMSk+BXkvSjH9q8jAO0986/pShPV5DU2sMxnx4LfLfHNhTzjXKokws ++8ptJ8uhMNIDXfXuzkZHIxoXk3rNcjDN5c5X+sK8UBRH092BIJWCOfaQt7v7wig5 +4Ra28pM9GbHKXVNxmdLpCFyzvyMuCmINYYADsC848QQFFwnd4EQnupo6QvhEVx1O +j7wDwvuH5dCrLuLwtwXaQh0onG4583p0LGms2Mf5F+Ick6o/4peOlBoZz48= +=HXDP +-----END PGP PUBLIC KEY BLOCK----------BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFmUaEEBCACzXTDt6ZnyaVtueZASBzgnAmK13q9Urgch+sKYeIhdymjuMQta +x15OklctmrZtqre5kwPUosG3/B2/ikuPYElcHgGPL4uL5Em6S5C/oozfkYzhwRrT +SQzvYjsE4I34To4UdE9KA97wrQjGoz2Bx72WDLyWwctD3DKQtYeHXswXXtXwKfjQ +7Fy4+Bf5IPh76dA8NJ6UtjjLIDlKqdxLW4atHe6xWFaJ+XdLUtsAroZcXBeWDCPa +buXCDscJcLJRKZVc62gOZXXtPfoHqvUPp3nuLA4YjH9bphbrMWMf810Wxz9JTd3v +yWgGqNY0zbBqeZoGv+TuExlRHT8ASGFS9SVDABEBAAHNNUdpdEh1YiAod2ViLWZs +b3cgY29tbWl0IHNpZ25pbmcpIDxub3JlcGx5QGdpdGh1Yi5jb20+wsBiBBMBCAAW +BQJZlGhBCRBK7hj4Ov3rIwIbAwIZAQAAmQEIACATWFmi2oxlBh3wAsySNCNV4IPf +DDMeh6j80WT7cgoX7V7xqJOxrfrqPEthQ3hgHIm7b5MPQlUr2q+UPL22t/I+ESF6 +9b0QWLFSMJbMSk+BXkvSjH9q8jAO0986/pShPV5DU2sMxnx4LfLfHNhTzjXKokws ++8ptJ8uhMNIDXfXuzkZHIxoXk3rNcjDN5c5X+sK8UBRH092BIJWCOfaQt7v7wig5 +4Ra28pM9GbHKXVNxmdLpCFyzvyMuCmINYYADsC848QQFFwnd4EQnupo6QvhEVx1O +j7wDwvuH5dCrLuLwtwXaQh0onG4583p0LGms2Mf5F+Ick6o/4peOlBoZz48= +=HXDP +-----END PGP PUBLIC KEY BLOCK----- diff --git a/qusal/sys-pihole/files/server/keys/otrust.txt b/qusal/sys-pihole/files/server/keys/otrust.txt new file mode 100644 index 0000000..28d9d10 --- /dev/null +++ b/qusal/sys-pihole/files/server/keys/otrust.txt @@ -0,0 +1,3 @@ +# List of assigned trustvalues, created Thu 02 Nov 2023 09:43:48 PM UTC +# (Use "gpg --import-ownertrust" to restore them) +5DE3E0509C47EA3CF04A42D34AEE18F83AFDEB23:6: diff --git a/qusal/sys-pihole/files/server/keys/pubring.kbx b/qusal/sys-pihole/files/server/keys/pubring.kbx new file mode 100644 index 0000000..25df668 Binary files /dev/null and b/qusal/sys-pihole/files/server/keys/pubring.kbx differ diff --git a/qusal/sys-pihole/files/server/keys/trustdb.gpg b/qusal/sys-pihole/files/server/keys/trustdb.gpg new file mode 100644 index 0000000..e08b410 Binary files /dev/null and b/qusal/sys-pihole/files/server/keys/trustdb.gpg differ diff --git a/qusal/sys-pihole/files/server/network/50-pihole.conf b/qusal/sys-pihole/files/server/network/50-pihole.conf new file mode 100644 index 0000000..3bb948b --- /dev/null +++ b/qusal/sys-pihole/files/server/network/50-pihole.conf @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +$HTTP["remoteip"] !~ "127.0.0.1" { + $HTTP["url"] =~ "^/admin/" { + url.access-deny = ( "" ) + } +} + +# vim: ft=apache diff --git a/qusal/sys-pihole/files/server/pihole-browser-general.desktop b/qusal/sys-pihole/files/server/pihole-browser-general.desktop index a5971d0..0406b7f 100644 --- a/qusal/sys-pihole/files/server/pihole-browser-general.desktop +++ b/qusal/sys-pihole/files/server/pihole-browser-general.desktop @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + [Desktop Entry] Name=Pi-Hole Browser URL Forwarder Exec=qvm-open-in-vm -- @default %u diff --git a/qusal/sys-pihole/files/server/pihole-browser.desktop b/qusal/sys-pihole/files/server/pihole-browser.desktop index 0094036..5857450 100644 --- a/qusal/sys-pihole/files/server/pihole-browser.desktop +++ b/qusal/sys-pihole/files/server/pihole-browser.desktop @@ -1,6 +1,10 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + [Desktop Entry] Name=Pi-Hole Browser -Exec=qvm-open-in-vm -- @default http://127.0.0.1:80 +Exec=qvm-open-in-vm -- @default http://127.0.0.1:80/admin Icon=web-browser Terminal=false X-MultipleArgs=False diff --git a/qusal/sys-pihole/install.sls b/qusal/sys-pihole/install.sls index abe5517..392e574 100644 --- a/qusal/sys-pihole/install.sls +++ b/qusal/sys-pihole/install.sls @@ -7,6 +7,8 @@ SPDX-License-Identifier: GPL-3.0-or-later {% if grains['nodename'] != 'dom0' %} +{% set pihole_tag = 'v5.17.2' -%} + include: - dotfiles.copy-x11 @@ -17,6 +19,7 @@ include: file.managed: - name: /etc/network/interfaces.d/eth0 - source: salt://{{ slsdotpath }}/files/server/network/eth0 + - mode: '0644' - user: root - group: root - makedirs: True @@ -68,17 +71,25 @@ include: - php-xml - unzip +"{{ slsdotpath }}-disable-external-admin-interface": + file.managed: + - name: /etc/lighttpd/conf-available/50-pihole.conf + - source: salt://{{ slsdotpath }}/files/server/network/50-pihole.conf + - mode: '0644' + - user: root + - group: root + - makedirs: True + +"{{ slsdotpath }}-disable-external-admin-interface-symlink": + file.symlink: + - name: /etc/lighttpd/conf-available/50-pihole.conf + - target: /etc/lighttpd/conf-enabled/50-pihole.conf + - force: True + "{{ slsdotpath }}-disable-systemd-resolved": service.disabled: - name: systemd-resolved -"{{ slsdotpath }}-git-clone": - git.latest: - - name: https://github.com/pi-hole/pi-hole.git - - user: root - - target: /root/pi-hole - - force_fetch: True - "{{ slsdotpath }}-setupVars.conf": file.managed: - name: /etc/pihole/setupVars.conf @@ -87,9 +98,54 @@ include: - group: root - makedirs: True +"{{ slsdotpath }}-git-clone": + git.latest: + - name: https://github.com/pi-hole/pi-hole.git + - user: root + - target: /root/pi-hole + - force_fetch: True + +"{{ slsdotpath }}-gnupg-home-for-pihole": + file.directory: + - name: /root/.gnupg/pihole + - user: root + - group: root + - mode: '0700' + - makedirs: True + +"{{ slsdotpath }}-keyring-and-trustdb": + file.managed: + - user: root + - group: root + - mode: '0600' + - names: + - /root/.gnupg/pihole/pubring.kbx: + - source: salt://{{ slsdotpath }}/files/server/keys/pubring.kbx + - /root/.gnupg/pihole/trustdb.gpg: + - source: salt://{{ slsdotpath }}/files/server/keys/trustdb.gpg + +## The tag is annotated, using verify-commit instead. +"{{ slsdotpath }}-git-verify-tag-pihole": + cmd.run: + - require: + - git: "{{ slsdotpath }}-git-clone" + - name: GNUPGHOME="$HOME/.gnupg/pihole" git verify-commit {{ pihole_tag }} + - cwd: /root/pi-hole + - runas: root + +"{{ slsdotpath }}-git-checkout-tag-{{ pihole_tag }}": + cmd.run: + - name: git checkout {{ pihole_tag }} + - require: + - cmd: "{{ slsdotpath }}-git-verify-tag-pihole" + - cwd: /root/pi-hole + - runas: root + "{{ slsdotpath }}-setup": cmd.run: - name: ./basic-install.sh --unattended + - require: + - cmd: "{{ slsdotpath }}-git-checkout-tag-{{ pihole_tag }}" - cwd: '/root/pi-hole/automated install' - runas: root diff --git a/qusal/sys-rsync/README.md b/qusal/sys-rsync/README.md index d9135b4..9ebbaee 100644 --- a/qusal/sys-rsync/README.md +++ b/qusal/sys-rsync/README.md @@ -42,7 +42,7 @@ 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 +qubesctl --skip-dom0 --targets=TEMPLATE state.apply sys-rsync.install-client ``` The client qube requires the Rsync forwarder service to be enabled: diff --git a/qusal/sys-ssh-agent/README.md b/qusal/sys-ssh-agent/README.md index 2c4efa9..3bf8305 100644 --- a/qusal/sys-ssh-agent/README.md +++ b/qusal/sys-ssh-agent/README.md @@ -7,7 +7,7 @@ * [Installation](#installation) * [Access Control](#access-control) * [Usage](#usage) - * [Agent](#agent) + * [Server](#server) * [Generate keys](#generate-keys) * [Limit key usage](#limit-key-usage) * [Reload agent](#reload-agent) @@ -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=QUBE state.apply sys-ssh-agent.install-client +qubesctl --skip-dom0 --targets=TEMPLATE state.apply sys-ssh-agent.install-client ``` ## Access Control @@ -106,7 +106,7 @@ qusal.SshAgent * @anyvm @anyvm deny ## Usage -### Agent +### Server #### Generate keys diff --git a/qusal/sys-ssh/README.md b/qusal/sys-ssh/README.md index a4c2e3e..1a43209 100644 --- a/qusal/sys-ssh/README.md +++ b/qusal/sys-ssh/README.md @@ -8,8 +8,8 @@ * [Usage](#usage) * [Server](#server) * [Client](#client) - * [Passwordless login](#passwordless-login) - * [Mount the file system](#mount-the-file-system) + * [Enable Passwordless login](#enable-passwordless-login) + * [Mount the server file system](#mount-the-server-file-system) * [Credits](#credits) ## Description @@ -45,7 +45,7 @@ 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 +qubesctl --skip-dom0 --targets=TEMPLATE state.apply sys-ssh.install-client ``` The client qube requires the SSH forwarder service to be enabled: @@ -78,7 +78,7 @@ chroots and access control mechanisms. This is left for the user to configure. ### Client -##### Passwordless login +#### Enable 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. @@ -96,7 +96,7 @@ mkdir -m 0700 ~/.ssh cat ~/QubesIncoming//id_ed25519.pub | tee -a ~/.ssh/authorized_keys ``` -##### Mount the file system +#### Mount the server file system The SSH connection is available with the socket `localhost:1840`. diff --git a/qusal/sys-syncthing/README.md b/qusal/sys-syncthing/README.md index dd2e464..a47abbd 100644 --- a/qusal/sys-syncthing/README.md +++ b/qusal/sys-syncthing/README.md @@ -47,7 +47,7 @@ qubesctl state.apply sys-syncthing.appmenus Install Syncthing on the client template: ```sh -qubesctl --skip-dom0 --targets=QUBE state.apply sys-syncthing.install-client +qubesctl --skip-dom0 --targets=TEMPLATE state.apply sys-syncthing.install-client ``` The client qube requires the split Syncthing service to be enabled: diff --git a/qusal/sys-syncthing/configure-browser.sls b/qusal/sys-syncthing/configure-browser.sls new file mode 100644 index 0000000..394d52c --- /dev/null +++ b/qusal/sys-syncthing/configure-browser.sls @@ -0,0 +1,23 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +{% if grains['nodename'] != 'dom0' %} + +"{{ slsdotpath }}-browser-rc.local": + file.append: + - name: /rw/config/rc.local + - text: "qvm-connect-tcp 8384:@default:8384" + +"{{ slsdotpath }}-browser-desktop-application": + file.managed: + - name: /home/user/.local/share/applications/syncthing-browser.desktop + - source: salt://{{ slsdotpath }}/files/browser/syncthing-browser.desktop + - mode: '0644' + - user: user + - group: user + - makedirs: True + +{% endif -%} diff --git a/qusal/sys-syncthing/configure-browser.top b/qusal/sys-syncthing/configure-browser.top new file mode 100644 index 0000000..ddf3304 --- /dev/null +++ b/qusal/sys-syncthing/configure-browser.top @@ -0,0 +1,9 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + 'sys-syncthing-browser': + - sys-syncthing.configure-browser diff --git a/qusal/sys-syncthing/create.sls b/qusal/sys-syncthing/create.sls index 7904e98..dd52dec 100644 --- a/qusal/sys-syncthing/create.sls +++ b/qusal/sys-syncthing/create.sls @@ -63,7 +63,7 @@ features: {% load_yaml as defaults -%} name: {{ slsdotpath }}-browser -force: True +force: true require: - sls: {{ slsdotpath }}.clone present: diff --git a/qusal/sys-syncthing/files/admin/firewall/in.sh b/qusal/sys-syncthing/files/admin/firewall/in.sh new file mode 100644 index 0000000..c49d315 --- /dev/null +++ b/qusal/sys-syncthing/files/admin/firewall/in.sh @@ -0,0 +1,303 @@ +#!/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/admin/policy/default.policy b/qusal/sys-syncthing/files/admin/policy/default.policy new file mode 100644 index 0000000..794081e --- /dev/null +++ b/qusal/sys-syncthing/files/admin/policy/default.policy @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +## 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.OpenURL * {{ sls_path }} @default allow target={{ sls_path }}-browser +qubes.OpenURL * {{ sls_path }} @anyvm deny +qubes.ConnectTCP +8384 {{ sls_path }}-browser @default allow target={{ sls_path }} +qubes.ConnectTCP * {{ sls_path }}-browser @anyvm deny +qusal.Syncthing * @anyvm @default ask target={{ sls_path }} default_target={{ sls_path }} +qusal.Syncthing * @anyvm @anyvm deny +## vim:ft=qrexecpolicy diff --git a/qusal/sys-syncthing/files/browser/syncthing-browser.desktop b/qusal/sys-syncthing/files/browser/syncthing-browser.desktop new file mode 100644 index 0000000..0bed969 --- /dev/null +++ b/qusal/sys-syncthing/files/browser/syncthing-browser.desktop @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Desktop Entry] +Name=Syncthing Browser +Exec=xdg-open http://127.0.0.1:8384 +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser;FileTransfer;P2P; diff --git a/qusal/sys-syncthing/files/client/systemd/qubes-syncthing-forwarder.service b/qusal/sys-syncthing/files/client/systemd/qubes-syncthing-forwarder.service new file mode 100644 index 0000000..f06fb1e --- /dev/null +++ b/qusal/sys-syncthing/files/client/systemd/qubes-syncthing-forwarder.service @@ -0,0 +1,23 @@ +# 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/syncthing-setup + +[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/files/server/mimeapps.list b/qusal/sys-syncthing/files/server/mimeapps.list new file mode 100644 index 0000000..0426358 --- /dev/null +++ b/qusal/sys-syncthing/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=syncthing-browser-general.desktop +x-scheme-handler/https=syncthing-browser-general.desktop diff --git a/qusal/sys-syncthing/files/server/rpc/qusal.Syncthing b/qusal/sys-syncthing/files/server/rpc/qusal.Syncthing new file mode 100644 index 0000000..55d7f61 --- /dev/null +++ b/qusal/sys-syncthing/files/server/rpc/qusal.Syncthing @@ -0,0 +1,7 @@ +#!/bin/sh + +# SPDX-FileCopyrightText: 2022 unman +# +# SPDX-License-Identifier: GPL-3.0-or-later + +exec socat STDIO TCP:localhost:22000 diff --git a/qusal/sys-syncthing/files/server/syncthing-browser-general.desktop b/qusal/sys-syncthing/files/server/syncthing-browser-general.desktop new file mode 100644 index 0000000..a4d8248 --- /dev/null +++ b/qusal/sys-syncthing/files/server/syncthing-browser-general.desktop @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Desktop Entry] +Name=Syncthing 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-syncthing/files/server/syncthing-browser.desktop b/qusal/sys-syncthing/files/server/syncthing-browser.desktop new file mode 100644 index 0000000..8920532 --- /dev/null +++ b/qusal/sys-syncthing/files/server/syncthing-browser.desktop @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[Desktop Entry] +Name=Syncthing Browser +Exec=qvm-open-in-vm -- @default http://127.0.0.1:8384 +Icon=web-browser +Terminal=false +X-MultipleArgs=False +Type=Application +Keywords=synchronization;interface; +Categories=Network;WebBrowser;FileTransfer;P2P; diff --git a/qusal/sys-syncthing/install-client.sls b/qusal/sys-syncthing/install-client.sls new file mode 100644 index 0000000..286e03c --- /dev/null +++ b/qusal/sys-syncthing/install-client.sls @@ -0,0 +1,51 @@ +{# +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: + - socat + - syncthing + +{% 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 }} + +"{{ slsdotpath }}-set-systemd-qubes-syncthing-forwarder.service": + file.managed: + - name: /usr/lib/systemd/system/qubes-syncthing-forwarder.service + - source: salt://{{ slsdotpath }}/files/client/systemd/qubes-syncthing-forwarder.service + - user: root + - group: root + - mode: '0755' + - makedirs: True + +"{{ slsdotpath }}-enable-qubes-syncthing": + service.enabled: + - name: qubes-syncthing.service + +{% endif -%} diff --git a/qusal/sys-syncthing/install-client.top b/qusal/sys-syncthing/install-client.top new file mode 100644 index 0000000..ca94c09 --- /dev/null +++ b/qusal/sys-syncthing/install-client.top @@ -0,0 +1,9 @@ +{# +SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. + +SPDX-License-Identifier: GPL-3.0-or-later +#} + +base: + '*': + - sys-syncthing.install-client diff --git a/qusal/sys-usb/README.md b/qusal/sys-usb/README.md index bc43a99..6c7b1ab 100644 --- a/qusal/sys-usb/README.md +++ b/qusal/sys-usb/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) * [Credits](#credits) ## Description @@ -46,6 +47,12 @@ If the client requires a FIDO device, install on the client template: qubesctl --skip-dom0 --targets=tpl-QUBE state.apply sys-usb.install-client-fido ``` +## Usage + +Start a USB qube an connect a device to it. USB PCI devices will appear on +the system tray icon `qui-devices`. From there, assign it to the intended +qube. + ## Credits - [Unman](https://github.com/unman/shaker/blob/main/sys-usb) diff --git a/qusal/sys-usb/create.sls b/qusal/sys-usb/create.sls index 730c921..dc2a00b 100644 --- a/qusal/sys-usb/create.sls +++ b/qusal/sys-usb/create.sls @@ -9,7 +9,6 @@ SPDX-License-Identifier: GPL-3.0-or-later include: - .clone - - qvm.hide-usb-from-dom0 {# "{{ slsdotpath }}-updated-dom0": @@ -42,8 +41,8 @@ prefs: - template: tpl-{{ slsdotpath }} - label: red - netvm: "" -- memory: 0 -- maxmem: 400 +- memory: 400 +- maxmem: 0 - vcpus: 1 - virt_mode: hvm - template_for_dispvms: True @@ -53,6 +52,7 @@ features: - servicevm - appmenus-dispvm - disable: + - service.network-manager - service.cups - service.cups-browsed - service.meminfo-writer @@ -60,16 +60,45 @@ features: {%- endload %} {{ load(defaults) }} -## TODO: fix _modules/ext_module_qvm.py {% set usb_pcidevs = salt['grains.get']('pci_usb_devs', []) -%} {% if usb_pcidevs == ['00:14.0', '00:1a.0', '00:1d.0'] -%} - {% set usb_host_model = 'T430' -%} + {% set usb_host_model = 'ThinkPad T430' -%} {% set usbs = ['sys-usb', 'sys-usb-dock', 'sys-usb-left'] -%} {% else -%} {% set usb_host_model = 'unknown' -%} {% set usbs = ['sys-usb'] -%} {% endif -%} +## TODO: salt jinja best practice +## Map different usb controlles to different usb qubes. +## Problems: +## - Random name generator for qubes would be troublesome for the user +## to guess to which qube his usb controller is. Only mapped brands and +## models will work. +## - No grain prints the product_family: $ dmidecode -s system-version +## Questions: +## - How to use jinja array to assign a qube per controller? +## - How to assign UNCATEGORIZED to unregistered products? +{# +{% set usb_pcidevs = { + 'ThinkPad T430': { + 'qubes': ['sys-usb', 'sys-usb-dock', 'sys-usb-left'], + 'pcidevs': ['00:14.0', '00:1a.0', '00:1d.0'], + 'autostart': False, + }, + 'UNCATEGORIZED': { + 'qubes': ['sys-usb'], + 'pcidevs': {{ usb_pcidevs }}, + 'autostart': True, + }, +}.get(salt['smbios.get']('system-version') -%} + +{% for usb in usb_pcidevs.qubes -%} +pcidevs: {{ usb_pcidevs.pcidevs|sequence|yaml }} +autostart: {{ usb_pcidevs.autostart|sequence|yaml }} +{% endfor -%} +#} + {% for usb in usbs -%} {% load_yaml as defaults -%} name: {{ usb }} @@ -84,19 +113,18 @@ prefs: - template: dvm-{{ slsdotpath }} - label: red - netvm: "" -- memory: 0 -- maxmem: 400 +- memory: 400 +- maxmem: 0 - include_in_backups: False - pci_strictreset: False -## TODO: remove this "complex" jinja from yaml and use a best practice -{% if usb_host_model == 'T430' -%} +{% if usb_host_model == 'ThinkPad T430' -%} - autostart: False {% if usb == 'sys-usb-left' -%} -- pcidevs: {{ usb_pcidevs[0]|yaml }} +- pcidevs: {{ [usb_pcidevs[0]]|yaml }} {% elif usb == 'sys-usb' -%} -- pcidevs: {{ usb_pcidevs[1]|yaml }} +- pcidevs: {{ [usb_pcidevs[1]]|yaml }} {% elif usb == 'sys-usb-dock' -%} -- pcidevs: {{ usb_pcidevs[2]|yaml }} +- pcidevs: {{ [usb_pcidevs[2]]|yaml }} {% endif -%} {% else -%} - autostart: True @@ -106,6 +134,7 @@ features: - enable: - servicevm - disable: + - service.network-manager - service.cups - service.cups-browsed - service.meminfo-writer diff --git a/qusal/sys-usb/keyboard.sls b/qusal/sys-usb/keyboard.sls index cfb8c0c..e8b1dbe 100644 --- a/qusal/sys-usb/keyboard.sls +++ b/qusal/sys-usb/keyboard.sls @@ -1,13 +1,17 @@ {# +SPDX-FileCopyrightText: 2018 - 2023 Marmarek Marczykowski-Gorecki SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. SPDX-License-Identifier: GPL-3.0-or-later #} -# Based on 'qvm.usb-keyboard'. +# Based on 'qvm.usb-keyboard', but can't use it because it requires +# 'qvm.sys-usb', which is different from the one we create at create.sls. +# Last known update of 'qvm.usb-keyboard': 2023-08-31 include: - .create + - qvm.hide-usb-from-dom0 "{{ slsdotpath }}-updated-dom0": pkg.uptodate: diff --git a/qusal/terraform/README.md b/qusal/terraform/README.md index 78cddf0..548a48c 100644 --- a/qusal/terraform/README.md +++ b/qusal/terraform/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -25,3 +26,10 @@ qubesctl top.disable terraform qubesctl state.apply terraform.create qubesctl --skip-dom0 --targets=tpl-terraform state.apply terraform.install ``` + +## Usage + +You will be able to run terraform from the "terraform" qube. As simple as +that. + +When using SSH keys, being a split-ssh-agent will facilitate key management. diff --git a/qusal/utils/tools/builder/README.md b/qusal/utils/tools/builder/README.md index 867ac6d..1135bac 100644 --- a/qusal/utils/tools/builder/README.md +++ b/qusal/utils/tools/builder/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -22,3 +23,7 @@ Install documentation tools on templates: ```sh qubesctl --skip-dom0 --targets=TEMPLATEVMS state.apply utils.tools.builder.doc ``` + +## Usage + +Standard builder usage, no extra configuration required. diff --git a/qusal/utils/tools/zsh/README.md b/qusal/utils/tools/zsh/README.md index 90176a8..2e657c5 100644 --- a/qusal/utils/tools/zsh/README.md +++ b/qusal/utils/tools/zsh/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -26,3 +27,7 @@ qubesctl top.disable utils.tools.zsh qubesctl --skip-dom0 --targets=TEMPLATEVMS state.apply utils.tools.zsh.change-shell qubesctl --skip-dom0 --targets=APPVMS state.apply utils.tools.zsh.touch-zshrc ``` + +## Usage + +Standard Zsh usage. No extra configuration required. diff --git a/qusal/whonix/README.md b/qusal/whonix/README.md index 0b934cb..e7d395d 100644 --- a/qusal/whonix/README.md +++ b/qusal/whonix/README.md @@ -4,6 +4,7 @@ * [Description](#description) * [Installation](#installation) +* [Usage](#usage) ## Description @@ -25,3 +26,7 @@ qubesctl state.apply whonix.create qubesctl state.apply qvm.anon-whonix qubesctl state.apply qvm.whonix-ws-dvm ``` + +## Usage + +AppVMs and StandaloneVMs can be based on this template. diff --git a/scripts/update-toc.sh b/scripts/update-toc.sh index 39070bd..4bb34ca 100755 --- a/scripts/update-toc.sh +++ b/scripts/update-toc.sh @@ -34,4 +34,5 @@ for f in "$@"; do echo "Could not find table of contents on file: $f" >&2; exit 1 fi vim -c 'norm zRgg' -c '/^## Table of Contents$' -c 'norm jd}k' -c ':GenTocGFM' -c 'norm ddgg' -c wq -- "${f}" + echo "Updated TOC in file: $f" done