This commit is contained in:
Ben Grande 2023-11-02 02:09:16 +00:00
parent 55f37133f2
commit 758e152b47
No known key found for this signature in database
GPG Key ID: 00C64E14F51F9E56
145 changed files with 1389 additions and 912 deletions

5
.gitignore vendored
View File

@ -1,13 +1,10 @@
# vim: nospell
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# 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

View File

@ -7,6 +7,17 @@ Files: */README.md
Copyright: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
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 <https://www.qubes-os.org>
Frédéric Pierret <frederic.pierret@qubes-os.org>
Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Simon Gaiser <simon@invisiblethingslab.com>
License: CC0-1.0
Files: qusal/ansible/files/repo/*
Copyright: 2014 Ansible, Inc. <https://ansible.com>
License: CC0-1.0
@ -31,11 +42,4 @@ Files: qusal/terraform/files/repo/*
Copyright: 2023 HashiCorp Inc. <security+packaging@hashicorp.com>
License: CC0-1.0
Files: qusal/qubes-builder/files/keys/*
Copyright: The Qubes OS Project <https://www.qubes-os.org>
Frédéric Pierret <frederic.pierret@qubes-os.org>
Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Simon Gaiser <simon@invisiblethingslab.com>
License: CC0-1.0
# vim: ft=debcopyright

View File

@ -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:

View File

@ -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

View File

@ -0,0 +1,8 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
systemctl unmask ssh
systemctl --no-block start ssh

View File

@ -0,0 +1,7 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
qvm-connect-tcp 22000:@default:22

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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 -%}

View File

@ -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

151
qusal/dom0/files/bin/qubes-update Executable file
View File

@ -0,0 +1,151 @@
#!/usr/bin/python3
# SPDX-FileCopyrightText: 2015 Jason Mehring <https://nrgaway@gmail.com>
# SPDX-FileCopyrightText: 2016 Bahtiar Gadimov <https:/bahtiar.gadimov.de>
# SPDX-FileCopyrightText: 2016 - 2019 Marek Marczykowsk-Gorecki
# <marmarek@invisiblethingslab.com>
# SPDX-FileCopyrightText: 2017 unman <unman@thirdeyesecurity.com>
# SPDX-FileCopyrightText: 2020 Frederic Pierret <https://github.com/fepitre>
# SPDX-FileCopyrightText: 2021 ctrlaltf24
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com
#
# SPDX-License-Identifier: GPL-3.0-or-later
"""
Wrapper argound qubesctl to run the update states more easily.
With qubesctl, you specify the salt update states to run:
qubesctl state.sls update.qubes-dom0
qubesctl --skip-dom0 --templates state.sls update.qubes-vm
qubesctl --skip-dom0 --standalones state.sls update.qubes-vm
qubesctl --skip-dom0 --targets=VMNAME,VMNAME2 state.sls update.qubes-vm
While with qvm-update, it detects the salt update state for you:
qvm-update --dom0
qvm-update --templates
qvm-update --standalones
qvm-update --targets=VMNAME,VMNAME2
To do a full system update, qubesctl requires a very extensive command:
qubesctl state.sls update.qubes-dom0
targets="$(qvm-ls --no-spinner --raw-daata --fields NAME,CLASS | grep -v -e AppVM -e DispVM | cut -d "|" -f 1 | tr "\n" ",")"
qubesctl --skip-dom0 --targets="$targets" state.sls update.qubes-vm
On the other side, qvm-update is plain simple:
qvm-update --all
Note: Full system update: Dom0, TemplateVMs and StandaloneVMs.
Why not use the qvm-update-gui? Its maximum concurrency is fixed at 1.
Developed for R4.1. Can the R4.2 be concurrent?
"""
from __future__ import print_function
import argparse
import sys
import subprocess
import qubessalt
import qubesadmin
import qubesadmin.vm
def main(args=None): # pylint: disable=missing-docstring
parser = argparse.ArgumentParser()
parser.add_argument('--show-output', action='store_true',
help='Show output of management commands')
parser.add_argument('--force-color', action='store_true',
help='Force color output, allow control characters '
'from VM, UNSAFE')
parser.add_argument('--max-concurrency', action='store',
help='Maximum number of VMs configured simultaneously '
'(default: %(default)d)',
type=int, default=4)
group = parser.add_mutually_exclusive_group()
group.add_argument('--targets', action='store',
help='Comma separated list of VMs to target')
group.add_argument('--all', action='store_true',
help='Target all VMs (TemplateVMs, StandaloneVMs, '
'Dom0)')
group.add_argument('--dom0', action='store_true',
help='Target Dom0')
parser.add_argument('--templates', action='store_true',
help='Target all TemplatesVMs')
parser.add_argument('--standalones', action='store_true',
help='Target all StandaloneVMs')
args = parser.parse_args(args)
args.command = ['state.sls']
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)
return 1
app = qubesadmin.Qubes()
targets = []
if args.dom0:
# already handled
return 0
if args.templates:
targets += [vm for vm in app.domains.values()
if vm.klass == 'TemplateVM']
if args.standalones:
targets += [vm for vm in app.domains.values()
if vm.klass == 'StandaloneVM']
if args.all:
targets = [vm for vm in app.domains.values()
if not vm.klass == 'AppVM' and not vm.klass == 'DispVM']
elif args.targets:
names = args.targets.split(',')
targets = [vm for vm in app.domains.values()
if vm.name in names
and not vm.klass == 'AppVM' and not vm.klass == 'DispVM']
if args.show_output and args.force_color:
args.command.insert(0, '--force-color')
exit_code = ''
vms_to_go = targets
if 'dom0' in vms_to_go:
args.command.append('update.qubes-vm')
vms_to_go = [vm for vm in targets
if not vm.name == 'dom0']
runner = qubessalt.ManageVMRunner(app, vms_to_go, args.command,
show_output=args.show_output,
force_color=args.force_color,
max_concurrency=args.max_concurrency)
exit_code = runner.run()
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)
return 1
else:
args.command.append('update.qubes-vm')
# remove dom0 - already handled
targets = [vm for vm in targets if not vm.name == 'dom0']
runner = qubessalt.ManageVMRunner(app, targets, args.command,
show_output=args.show_output,
force_color=args.force_color,
max_concurrency=args.max_concurrency)
exit_code = runner.run()
return exit_code
if __name__ == '__main__':
# --dom0-only is a passthrough to salt-call
if len(sys.argv) > 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())

View File

@ -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 -%}

@ -1 +1 @@
Subproject commit edd1ac0a8a66f3aab4a348d0a9b34e290b536fcf
Subproject commit 60b22d66d248a2083b015e1aab2b8a711fae91cc

View File

@ -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

View File

@ -81,7 +81,7 @@ prefs:
- autostart: False
- include_in_backups: False
features:
- appemenus-dispvm: True
- appmenus-dispvm: True
- disable:
- service.cups
- service.cups-browsed

View File

@ -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'

View File

@ -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'

View File

@ -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:

View File

@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2023 The Qubes OS Project <https://www.qubes-os.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
mount /builder -o dev,suid,remount

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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 %}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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)

View File

@ -0,0 +1,72 @@
{#
SPDX-FileCopyrightText: 2023 unman <unman@thirdeyesecurity.com>
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
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) }}

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-mirage-firewall.create

View File

@ -0,0 +1 @@
833cea063ab8fa87954c56e75e326f0d0ac9b9a2ee8e88a05e2a50af50666ef2 mirage-firewall.tar.bz2

View File

@ -0,0 +1 @@
v0.8.5

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-mirage-firewall.create

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
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') }}

View File

@ -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

View File

@ -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 -%}

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later
#}
base:
'sys-pihole-browser':
- sys-pihole.configure-browser

View File

@ -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) }}

View File

@ -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

View File

@ -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;

View File

@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2023 unman <unman@thirdeyesecurity.org>
#
# 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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 -%}

View File

@ -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":

100
qusal/sys-rsync/README.md Normal file
View File

@ -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)

View File

@ -7,4 +7,4 @@ SPDX-License-Identifier: GPL-3.0-or-later
base:
'dom0':
- match: nodegroup
- sys-sshfs.clone
- sys-rsync.clone

View File

@ -0,0 +1,38 @@
{#
SPDX-FileCopyrightText: 2022 unman <unman@thirdeyesecurity.com>
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
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

View File

@ -5,5 +5,5 @@ SPDX-License-Identifier: GPL-3.0-or-later
#}
base:
'sys-sshfs':
- sys-sshfs.configure
'sys-rsync':
- sys-rsync.configure

View File

@ -7,4 +7,4 @@ SPDX-License-Identifier: GPL-3.0-or-later
base:
'dom0':
- match: nodegroup
- sys-sshfs.create
- sys-rsync.create

View File

@ -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

View File

@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com
#
# SPDX-License-Identifier: GPL-3.0-or-later
[Unit]
Description=Forward connection to Rsync over Qrexec
ConditionPathExists=/var/run/qubes-service/rsync-setup
[Socket]
ListenStream=127.0.0.1:839
BindToDevice=lo
Accept=true
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com
#
# SPDX-License-Identifier: GPL-3.0-or-later
[Unit]
Description=Forward connection to Rsync over Qrexec
[Service]
ExecStart=/usr/bin/qrexec-client-vm @default qusal.Rsync
StandardInput=socket
StandardOutput=inherit

View File

@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com
#
# SPDX-License-Identifier: GPL-3.0-or-later
systemctl unmask rsync
systemctl --no-block restart rsync

View File

@ -4,4 +4,6 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
exec socat STDIO TCP:localhost:22000
set -eu
exec socat STDIO TCP:localhost:873

View File

@ -0,0 +1,36 @@
# rsyncd.conf configuration file
# vim: ft=toml
# SPDX-FileCopyrightText: 2020 unman <unman@thirdeyesecurity.com>
# SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com
#
# SPDX-License-Identifier: GPL-3.0-or-later
# GLOBAL OPTIONS
#motd file=/etc/motd
#log file=/var/log/rsyncd
# for pid file, do not use /var/run/rsync.pid if you are going to run rsync out
# of the init.d script. The init.d script does its own pid file handling, so
# omit the "pid file" line completely in that case.
# pid file=/var/run/rsyncd.pid
#syslog facility=daemon
#socket options=
port = 873
&merge /usr/local/etc/rsync.d
&include /usr/local/etc/rsync.d
# MODULE OPTIONS
[shared]
path = /home/user/shared
comment = Shared read and write area
read only = no
[archive]
path = /home/user/archive
comment = Shared read-only area
read only = yes

14
qusal/sys-rsync/init.top Normal file
View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
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

View File

@ -0,0 +1,36 @@
{#
SPDX-FileCopyrightText: 2022 unman <unman@thirdeyesecurity.com>
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
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 -%}

Some files were not shown because too many files have changed in this diff Show More