feat: add Print formula

This commit is contained in:
Ben Grande 2024-05-24 15:39:22 +02:00
parent cbf61e674e
commit b09ecdceb9
No known key found for this signature in database
GPG Key ID: 00C64E14F51F9E56
20 changed files with 487 additions and 0 deletions

114
salt/sys-print/README.md Normal file
View File

@ -0,0 +1,114 @@
# sys-print
Printer environment in Qubes OS.
## Table of Contents
* [Description](#description)
* [Security](#security)
* [Installation](#installation)
* [Access Control](#access-control)
* [Usage](#usage)
* [Add a printer](#add-a-printer)
* [Print](#print)
* [Credits](#credits)
## Description
Creates a print server named "sys-print" and a named disposable
"disp-sys-print" qube for sending files to your configured printer, which can
be done over the network or with IPP-over-USB.
## Security
The client does not have CUPS, does not need internet connection and does not
have USB devices connected.
Using CUPS in a dedicated qube reduces attack surface and has a better
usability as you only need to configure the printer in one qube and other
qubes will have access through Qrexec.
If the devices connected to the server qube can attack the CUPS server, it can
escalate the attack to the client qube. Usage of disposables servers does not
prevent this from happening, it just avoids persistent infection on the
server, where you could attribute different printers to different levels of
trust.
Sending files to the print server with `qvm-copy` is always safer than
allowing a direct connection from the qube that wants to print files to the
qube that has access to the printer.
## Installation
- Top:
```sh
sudo qubesctl top.enable sys-print
sudo qubesctl --targets=tpl-sys-print,sys-print state.apply
sudo qubesctl top.disable sys-print
sudo qubesctl state.apply sys-print.appmenus
```
- State:
<!-- pkg:begin:post-install -->
```sh
sudo qubesctl state.apply sys-print.create
sudo qubesctl --skip-dom0 --targets=tpl-sys-print state.apply sys-print.install
sudo qubesctl --skip-dom0 --targets=dvm-sys-print,sys-print state.apply sys-print.configure
sudo qubesctl state.apply sys-print.appmenus
```
<!-- pkg:end:post-install -->
If you want to install all printer drivers:
```sh
sudo qubesctl --skip-dom0 --targets=tpl-sys-print state.apply sys-print.install-driver-all
```
On the client template:
```sh
sudo qubesctl --skip-dom0 --targets=tpl-QUBE -print state.apply sys-print.install-client
```
The client qube requires the split Print service to be enabled:
```sh
qvm-features QUBE service.print-setup 1
```
## Access Control
_Default policy_: `ask` `all` requests requesting to use the
`qusal.Print` RPC service.
`Asking` can spawn multiple requests depending on the client, usage of `allow`
is recommended for trusted clients.
Allow access to the specified printing agent based on the qube tag:
```qrexecpolicy
qusal.Print * @tag:print-client @default allow target=sys-print
```
Always recommended to end with an explicit deny rule:
```qrexecpolicy
qusal.Print * @anyvm @anyvm deny
```
## Usage
### Add a printer
You will configure your printer from `sys-print` or `disp-sys-print`, it can
connect over the network or USB. If you do not want to save printing
configuration, use `disp-sys-print`.
On `sys-print` or `disp-sys-print`, add your printer:
```sh
system-config-printer
```
### Print
On the client, select the file to print, open it with an editor, viewer or
browser and target the desired printer.
## Credits
- [Unman](https://github.com/unman/shaker/tree/main/sys-print)

View File

@ -0,0 +1,8 @@
{#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% from 'utils/macros/sync-appmenus.sls' import sync_appmenus -%}
{{ sync_appmenus('tpl-' ~ sls_path) }}

View File

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

8
salt/sys-print/clone.sls Normal file
View File

@ -0,0 +1,8 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% from 'utils/macros/clone-template.sls' import clone_template -%}
{{ clone_template('debian-minimal', sls_path) }}

10
salt/sys-print/clone.top Normal file
View File

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

View File

@ -0,0 +1,24 @@
{#
SPDX-FileCopyrightText: 2022 - 2023 unman <unman@thirdeyesecurity.org>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
"{{ slsdotpath }}-bind-dirs":
file.managed:
- name: /rw/config/qubes-bind-dirs.d/50-sys-print.conf
- source: salt://{{ slsdotpath }}/files/server/qubes-bind-dirs.d/50-sys-print.conf
- mode: '0644'
- user: root
- group: root
- makedirs: True
"{{ slsdotpath }}-rpc":
file.managed:
- name: /etc/qubes-rpc/qusal.Print
- source: salt://{{ slsdotpath }}/files/server/rpc/qusal.Print
- mode: '0755'
- user: root
- group: root
- makedirs: True

View File

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

127
salt/sys-print/create.sls Normal file
View File

@ -0,0 +1,127 @@
{#
SPDX-FileCopyrightText: 2022 - 2023 unman <unman@thirdeyesecurity.org>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{%- from "qvm/template.jinja" import load -%}
include:
- .clone
{% load_yaml as defaults -%}
name: tpl-{{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
prefs:
- audiovm: ""
features:
- set:
- default-menu-items: "system-config-printer.desktop qubes-run-terminal.desktop qubes-open-file-manager.desktop qubes.start.desktop"
- menu-items: "system-config-printer.desktop qubes-run-terminal.desktop qubes-open-file-manager.desktop qubes.start.desktop"
{%- endload %}
{{ load(defaults) }}
{% load_yaml as defaults -%}
name: dvm-{{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
present:
- template: tpl-{{ slsdotpath }}
- label: red
prefs:
- template: tpl-{{ slsdotpath }}
- label: red
- netvm: "*default*"
- audiovm: ""
- vcpus: 1
- memory: 300
- maxmem: 400
- autostart: False
- template_for_dispvms: True
- include_in_backups: True
features:
- enable:
- servicevm
- service.cups
- appmenus-dispvm
- disable:
- service.cups-browsed
- service.tinyproxy
- service.tracker
- service.evolution-data-server
- set:
- menu-items: "system-config-printer.desktop qubes-run-terminal.desktop qubes-open-file-manager.desktop qubes.start.desktop"
{%- endload %}
{{ load(defaults) }}
{% load_yaml as defaults -%}
name: disp-{{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
present:
- template: dvm-{{ slsdotpath }}
- label: red
- class: DispVM
prefs:
- template: dvm-{{ slsdotpath }}
- label: red
- netvm: "*default*"
- audiovm: ""
- vcpus: 1
- memory: 300
- maxmem: 400
- autostart: False
- include_in_backups: True
features:
- enable:
- servicevm
- service.cups
- disable:
- service.cups-browsed
- service.tinyproxy
- service.tracker
- service.evolution-data-server
- set:
- menu-items: "system-config-printer.desktop qubes-run-terminal.desktop qubes-open-file-manager.desktop qubes.start.desktop"
{%- endload %}
{{ load(defaults) }}
{% load_yaml as defaults -%}
name: {{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
present:
- template: tpl-{{ slsdotpath }}
- label: red
prefs:
- template: tpl-{{ slsdotpath }}
- label: red
- netvm: "*default*"
- audiovm: ""
- vcpus: 1
- memory: 300
- maxmem: 400
- autostart: False
- include_in_backups: True
features:
- enable:
- servicevm
- service.cups
- disable:
- service.cups-browsed
- service.tinyproxy
- service.tracker
- service.evolution-data-server
- set:
- menu-items: "system-config-printer.desktop qubes-run-terminal.desktop qubes-open-file-manager.desktop qubes.start.desktop"
{%- endload %}
{{ load(defaults) }}
{% from 'utils/macros/policy.sls' import policy_set with context -%}
{{ policy_set(sls_path, '80') }}

10
salt/sys-print/create.top Normal file
View File

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

View File

@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# SPDX-License-Identifier: AGPL-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`.
qusal.Print * @anyvm @default ask default_target=sys-print
qusal.Print * @anyvm @anyvm deny
## vim:ft=qrexecpolicy

View File

@ -0,0 +1,23 @@
# SPDX-FileCopyrightText: 2023 unman <unman@thirdeyesecurity.org>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
[Unit]
Description=Print over Qrexec
After=qubes-qrexec-agent.service
ConditionPathExists=/var/run/qubes-service/print-setup
[Service]
ExecStart=/usr/bin/socat TCP4-LISTEN:631,reuseaddr,fork,end-close EXEC:"qrexec-client-vm @default qusal.Print"
Restart=on-failure
RestartSec=3
# Hardening
ProtectSystem=full
PrivateTmp=true
SystemCallArchitectures=native
MemoryDenyWriteExecute=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2023 unman <unman@thirdeyesecurity.org>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
binds+=('/etc/cups')
# vim: ft=bash

View File

@ -0,0 +1,7 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2023 unman <unman@thirdeyesecurity.org>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
set -eu
exec socat STDIO TCP:localhost:631

14
salt/sys-print/init.top Normal file
View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-print.create
'tpl-sys-print':
- sys-print.install
'dvm-sys-print,sys-print':
- sys-print.configure

View File

@ -0,0 +1,15 @@
{#
SPDX-FileCopyrightText: 2022 - 2023 unman <unman@thirdeyesecurity.org>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
"{{ slsdotpath }}-systemd-print-forwarder":
file.managed:
- name: /usr/lib/systemd/system/qubes-print-forwarder.service
- source: salt://{{ slsdotpath }}/files/client/systemd/qubes-print-forwarder.service
- mode: '0644'
- user: root
- group: root
- makedirs: True

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'*':
- sys-print.install-client

View File

@ -0,0 +1,21 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- sys-print.install
"{{ slsdotpath }}-installed":
pkg.installed:
- require:
- sls: utils.tools.common.update
- install_recommends: False
- skip_suggestions: True
- pkgs:
- printer-driver-all-enforce
{% endif -%}

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'tpl-sys-print':
- sys-print.install-driver-all

View File

@ -0,0 +1,44 @@
{#
SPDX-FileCopyrightText: 2022 - 2023 unman <unman@thirdeyesecurity.org>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- utils.tools.common.update
- dev.home-cleanup
- dotfiles.copy-sh
- dotfiles.copy-x11
- sys-usb.install-client
"{{ slsdotpath }}-installed":
pkg.installed:
- require:
- sls: utils.tools.common.update
- install_recommends: False
- skip_suggestions: True
- pkgs:
## Discovery
- qubes-core-agent-networking
- cups
- ipp-usb
## Print
- printer-driver-cups-pdf
- system-config-printer
## Scan
## TODO: simple-scan did not detect my scanner, but detected printer.
- simple-scan
- sane
- sane-utils
- sane-airscan
"{{ slsdotpath }}-add-user-to-lpadmin-group":
group.present:
- name: lpadmin
- addusers:
- user
{% endif -%}

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'tpl-sys-print':
- sys-print.install