Qubes dom0-update-guard script

94 views
Skip to first unread message

fiftyfour...@gmail.com

unread,
Aug 7, 2020, 7:22:50 AM8/7/20
to qubes-users
Informed by a recent post, I've decided to start writing a script that takes a Qubes installation's list of packages installed in dom0 and compare them to the list of available packages in the chosen repo (e.g. 'current') to ensure that the update process hasn't been interfered with by an adversary that has taken advantage of Fedora's insecure updating mechanism (detailed in the thread linked earlier). I'm motivated to do this because this seems to be a flaw that can give attackers the key to the kingdom by blocking patches to dom0 or Xen. 

Since I'm not a programmer (I know *basic* Python), this will be a learning experience for me, so stay tuned and please point out any issues/errors you spot in my updates. I'd appreciate it if someone felt charitable enough to point me towards useful commands/functions, but I'd be fine learning the hard way too--I need to start learning programming *somewhere*, and this seems to be a good place to start.

Right now my plan is to take the output of 'rpm -qa' or 'yum list installed' and compare it via some sort of 'match' or 'crosscheck' function to a repo list pulled from somewhere secure (i.e. not tampered with by potential adversaries) and maybe imported into dom0 from a specialized secure appVM, creating a security tradeoff.

awokd

unread,
Aug 7, 2020, 2:56:51 PM8/7/20
to qubes...@googlegroups.com
fiftyfour...@gmail.com:

> Right now my plan is to take the output of 'rpm -qa' or 'yum list
> installed' and compare it via some sort of 'match' or 'crosscheck' function
> to a repo list pulled from somewhere secure (i.e. not tampered with by
> potential adversaries) and maybe imported into dom0 from a specialized
> secure appVM, creating a security tradeoff.
>
"[P]ulled from somewhere secure"- if the concern is someone tampering
with your HTTPS traffic in particular, you will probably want to use a
different method of obtaining the repo list. Tor might work.

--
- don't top post
Mailing list etiquette:
- trim quoted reply to only relevant portions
- when possible, copy and paste text instead of screenshots

Chris Laprise

unread,
Aug 7, 2020, 6:38:38 PM8/7/20
to awokd, qubes...@googlegroups.com
On 8/7/20 2:56 PM, 'awokd' via qubes-users wrote:
> fiftyfour...@gmail.com:
>
>> Right now my plan is to take the output of 'rpm -qa' or 'yum list
>> installed' and compare it via some sort of 'match' or 'crosscheck' function
>> to a repo list pulled from somewhere secure (i.e. not tampered with by
>> potential adversaries) and maybe imported into dom0 from a specialized
>> secure appVM, creating a security tradeoff.
>>
> "[P]ulled from somewhere secure"- if the concern is someone tampering
> with your HTTPS traffic in particular, you will probably want to use a
> different method of obtaining the repo list. Tor might work.

I think this is only properly done via a trusted .onion address, i2p
address, etc... Unless Tor's DNS lookups have been improved since the
last time I checked.

Just for reference here, threat model I'm thinking of here is when an
attacker tries to MiTM while having the cooperation of the certificate
authority.

--
Chris Laprise, tas...@posteo.net
https://github.com/tasket
https://twitter.com/ttaskett
PGP: BEE2 20C5 356E 764A 73EB 4AB3 1DC4 D106 F07F 1886

fiftyfour...@gmail.com

unread,
Aug 8, 2020, 12:07:39 AM8/8/20
to qubes-users
On Saturday, 8 August 2020 06:38:38 UTC+8, Chris Laprise wrote:
I think this is only properly done via a trusted .onion address, i2p
address, etc... Unless Tor's DNS lookups have been improved since the
last time I checked.

Just for reference here, threat model I'm thinking of here is when an
attacker tries to MiTM while having the cooperation of the certificate
authority.

--
Chris Laprise, tas...@posteo.net
https://github.com/tasket
https://twitter.com/ttaskett
PGP: BEE2 20C5 356E 764A 73EB  4AB3 1DC4 D106 F07F 1886

Since dom0 can be updated via tor, is there an onion address? If not, what would it take to make one or convince someone to make one? Without this (since i2p is a whole can of worms I don't want to touch), the whole exercise is meaningless. 

unman

unread,
Aug 8, 2020, 8:51:25 AM8/8/20
to qubes-users
On Fri, Aug 07, 2020 at 09:07:39PM -0700, fiftyfour...@gmail.com wrote:
> On Saturday, 8 August 2020 06:38:38 UTC+8, Chris Laprise wrote:
> >
> > I think this is only properly done via a trusted .onion address, i2p
> > address, etc... Unless Tor's DNS lookups have been improved since the
> > last time I checked.
> >
> > Just for reference here, threat model I'm thinking of here is when an
> > attacker tries to MiTM while having the cooperation of the certificate
> > authority.
> >
> > --
> > Chris Laprise, tas...@posteo.net <javascript:>
> > https://github.com/tasket
> > https://twitter.com/ttaskett
> > PGP: BEE2 20C5 356E 764A 73EB 4AB3 1DC4 D106 F07F 1886
> >
>
> Since dom0 can be updated via tor, is there an onion address? If not, what
> would it take to make one or convince someone to make one? Without this
> (since i2p is a whole can of worms I don't want to touch), the whole
> exercise is meaningless.
>
> --

Onion? Of course.
Check /etc/yum.repos.d/qubes-dom0.repo
Also, it's on mirror list at https://www.qubes-os.org/downloads, and has
been referenced on this list.
The repo is:
http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion

What you should do is grab a few of those mirror sites, and compare the
metadata downloaded through Tor. i.e don't trust *any one* site, but look at
them in the mass .
Just as you would with an iso or pgp key.

unman

fiftyfour...@gmail.com

unread,
Aug 8, 2020, 10:20:16 AM8/8/20
to qubes-users
On Saturday, 8 August 2020 20:51:25 UTC+8, unman wrote:
Onion? Of course.
Check /etc/yum.repos.d/qubes-dom0.repo
Also, it's on mirror list at https://www.qubes-os.org/downloads, and has
been referenced on this list.
The repo is:
http://yum.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion

What you should do is grab a few of those mirror sites, and compare the
metadata downloaded through Tor. i.e don't trust *any one* site, but look at
them in the mass .
Just as you would with an iso or pgp key.

unman

I have Awokd, Chris, *and* Unman replying to my post--I feel pampered.  

So the new overview of the script is: have a dedicated (and hardened?) tor VM --basically, whonix-ws-- download the metadata from a few mirror sites, compare them to the metadata from Tor, and if all checks out, compare the tor version to the packages installed in dom0. If it doesn't check out, alert user and ask whether to proceed. To do this entirely in dom0 (keeping it safe and simple for a newbie at programming), I'm going to use qvm-run with --pass-io somewhere in my script, along with something to read the whonix output and run cross checks.

A concern: I've noticed that a lot of Qubes mirrors are often offline. Would this create vulnerabilities?

awokd

unread,
Aug 8, 2020, 4:22:02 PM8/8/20
to qubes...@googlegroups.com
fiftyfour...@gmail.com:

> I have Awokd, Chris, *and* Unman replying to my post--I feel pampered.

It's an interesting security exercise; but agree, don't think our open
source availability syncs up very often. :)

> So the new overview of the script is: have a dedicated (and hardened?) tor
> VM --basically, whonix-ws-- download the metadata from a few mirror sites,
> compare them to the metadata from Tor, and if all checks out, compare the
> tor version to the packages installed in dom0. If it doesn't check out,
> alert user and ask whether to proceed. To do this entirely in dom0 (keeping
> it safe and simple for a newbie at programming), I'm going to use qvm-run
> with --pass-io somewhere in my script, along with something to read the
> whonix output and run cross checks.

To stay in keeping with Qubes philosophy, at most dom0 should only run
jobs inside VMs and copy files between VMs. You don't want it to parse
results, but you could let dom0 copy/move output files to a separate VM,
then kick off a job to handle the parsing inside the destination VM.

> A concern: I've noticed that a lot of Qubes mirrors are often offline.
> Would this create vulnerabilities?

Probably want your script to alert if under 3 reporting.

fiftyfour...@gmail.com

unread,
Aug 8, 2020, 11:20:04 PM8/8/20
to qubes-users
On Sunday, 9 August 2020 04:22:02 UTC+8, awokd wrote:
To stay in keeping with Qubes philosophy, at most dom0 should only run
jobs inside VMs and copy files between VMs. You don't want it to parse
results, but you could let dom0 copy/move output files to a separate VM,
then kick off a job to handle the parsing inside the destination VM.

--
- don't top post
Mailing list etiquette:
- trim quoted reply to only relevant portions
- when possible, copy and paste text instead of screenshots

So I'll have the users create an offline AppVM based on a clean Debian template, then have users point the script to it. Dom0 will copy the data from its 'rpm -qa' or 'yum list installed' to it, and also copy the Tor repodata from Whonix after it has been cross-checked there. The offline AppVM will then parse and cross-check the dom0 list and the repodata and return a result to dom0. 

Another option is to have the offline AppVM handle cross-checking between Tor and HTTPS repodata as well, so all Whonix does is fetch. Which sounds better?

awokd

unread,
Aug 9, 2020, 3:44:02 PM8/9/20
to qubes...@googlegroups.com
fiftyfour...@gmail.com:

> Another option is to have the offline AppVM handle cross-checking between
> Tor and HTTPS repodata as well, so all Whonix does is fetch. Which sounds
> better?
>
Probably this option, mostly because it seems simpler to copy both data
sources to the same AppVM responsible for cross-checking.

Chris Laprise

unread,
Aug 9, 2020, 4:05:53 PM8/9/20
to fiftyfour...@gmail.com, qubes-users
On 8/8/20 10:20 AM, fiftyfour...@gmail.com wrote:
> So the new overview of the script is: have a dedicated (and hardened?)
> tor VM --basically, whonix-ws-- download the metadata from a few mirror
> sites, compare them to the metadata from Tor, and if all checks out,
> compare the tor version to the packages installed in dom0. If it doesn't
> check out, alert user and ask whether to proceed. To do this entirely in
> dom0 (keeping it safe and simple for a newbie at programming), I'm going
> to use qvm-run with --pass-io somewhere in my script, along with
> something to read the whonix output and run cross checks.

Just an idea: Use the Qubes Security Bulletins as your reference for
checking package versions:

https://www.qubes-os.org/security/pack/

These bulletins are signed txt files, which makes them secure. The
difficult part would be parsing the QSBs themselves but I wonder if
Qubes devs would agree to a standard format going forward to make it
easier + reliable.

>
> A concern: I've noticed that a lot of Qubes mirrors are often offline.
> Would this create vulnerabilities?


--
Chris Laprise, tas...@posteo.net

Andrew David Wong

unread,
Aug 10, 2020, 6:39:53 AM8/10/20
to Chris Laprise, fiftyfour...@gmail.com, qubes-users
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

On 2020-08-09 3:05 PM, Chris Laprise wrote:
> On 8/8/20 10:20 AM, fiftyfour...@gmail.com wrote:
>> So the new overview of the script is: have a dedicated (and
>> hardened?) tor VM --basically, whonix-ws-- download the metadata
>> from a few mirror sites, compare them to the metadata from Tor,
>> and if all checks out, compare the tor version to the packages
>> installed in dom0. If it doesn't check out, alert user and ask
>> whether to proceed. To do this entirely in dom0 (keeping it safe
>> and simple for a newbie at programming), I'm going to use qvm-run
>> with --pass-io somewhere in my script, along with something to
>> read the whonix output and run cross checks.
>
> Just an idea: Use the Qubes Security Bulletins as your reference
> for checking package versions:
>
> https://www.qubes-os.org/security/pack/
>
> These bulletins are signed txt files, which makes them secure. The
> difficult part would be parsing the QSBs themselves but I wonder
> if Qubes devs would agree to a standard format going forward to
> make it easier + reliable.
>

The QSB formats are actually pretty standardized already, though our
expectation has been that they'd be read by humans rather than
programmatically. We use a template [1] for the overall structure, and
in particular, the "Patching" section always follows this format:

```
Patching
=========

The specific packages that resolve the problems discussed in this
bulletin are as follows:

For Qubes <supported_release_1>:
- <package_1>
- <package_2>
- <package_3>
- <package_etc...>

For Qubes <supported_release_2>:
- <package_1>
- <package_2>
- <package_3>
- <package_etc...>

The packages are to be installed in dom0 via the Qube Manager or via
the qubes-dom0-update command as follows:

For updates from the stable repository (not immediately available):
$ sudo qubes-dom0-update

For updates from the security-testing repository:
$ sudo qubes-dom0-update --enablerepo=qubes-dom0-security-testing

A system restart will be required afterwards.

These packages will migrate from the security-testing repository to the
current (stable) repository over the next two weeks after being tested
by the community.

If you use Anti Evil Maid, you will need to reseal your secret
passphrase to new PCR values, as PCR18+19 will change due to the new
Xen binaries.
```

Feel free to take a look at any QSBs for specific examples. [2] I'm sure
it wouldn't be a problem to change the syntax slightly if that would
make things easier, as long as it doesn't harm human readability.


[1] https://www.qubes-os.org/security/bulletins/template/
[2] https://www.qubes-os.org/security/bulletins/

- --
Andrew David Wong (Axon)
Community Manager, Qubes OS
https://www.qubes-os.org

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEZQ7rCYX0j3henGH1203TvDlQMDAFAl8xI+QACgkQ203TvDlQ
MDBOyg//T0/mxeE+pVlF7LIUuShy1B55Fjxxi35JhlkfX9Ws7fLT7hLh6172cxGQ
55E1WXlZ19AE9OZFeIUNX08ov5X6/OelAy8qFdtAmXFI3dEDzdjDVRk8naRpdtu6
hxqsnP4zsHLj0WQEYnsuPyjfgFuIZCy5TfXRlxm8u4l9oorK/IB6sqhBftwnT078
U37Sls/fPlKpnZ0rPJ6Kv/cGbXG1wKpxuui2LAsTis/IY/3TsRpEY8CLa1oIKX53
okQCY8GXnp7ova+8LEyhHBdoDK4iT1Fl8ohfJ+JzekE2SaR/7CnFGO2XrwyiFyXw
Zz9Huu+UIJl+ygIGK80HBBmUNSF+/sSoMSo0SYKZP96JnV0Vka54EEppH5Ctzexy
8yVIpYSwmavHOUO2+GVXh4ykETgkpC0UKg+QLoWacNTRqihT5XTCY3J7SqNLn93Z
21OHE5bAy7/cXNtq0rrnw/BeIzgmrHuaKMrOuW9HExoWIrroyb4a+rpEPbQfsCrb
G09/1A5uOt04ZQXKVhly2UYBA8Zzlld6vh4mKlCYBRBFBzAgJ69yHt3gubWcMAVV
f42Za2qpOZsNharvb6lvHI/7E0XY7FpqvOHZuVfX1c0UiTifTm5ZLwN0IDpGgw0f
1K26/H7GriIU4MZlC4qjToRGGXf40jV6l9zHZUzUzbdSGxEF20A=
=Gs9V
-----END PGP SIGNATURE-----

fiftyfour...@gmail.com

unread,
Aug 10, 2020, 9:13:46 AM8/10/20
to qubes-users
On Monday, 10 August 2020 18:39:53 UTC+8, Andrew David Wong wrote:
The QSB formats are actually pretty standardized already, though our
expectation has been that they'd be read by humans rather than
programmatically. We use a template [1] for the overall structure, and
in particular, the "Patching" section always follows this format:

Chris, Andrew,

I'm grateful for your pointers. As a newcomer to programming, I don't think I'm ready to integrate bulletin parsing and PGP verification into my script. As of right now I'm trying to figure out whether I should use bash, sh, or Python to write the script and using Chris' qubes-scripts and qubes-vm-hardening as reference on how I should proceed. Maybe I'll get around to integrating PGP verification into the process, but for now I want to focus on the basics.

Besides, don't the bulletins cover only a tiny (though critical) portion of the updates dom0 receives? The PGP verification will provide a strong additional layer of assurances, but I think cross-checking 'rpm -qa' against the onion repodata, which itself has been cross-checked with at least three other HTTPS repodata, should suffice for now, given my abilities.

Oh, and if someone more proficient at programming than I am (probably > 90% of the people here) would like to write the script, then by all means--I'll take my time and will likely come up with something substandard and in need of multiple major revisions. I can still practice even though someone else has written it, so please don't think of this little project as 'mine' or anything--I'd hate to get in the way of others improving Qubes' security.

54th Parallel

unread,
Aug 14, 2020, 7:12:13 AM8/14/20
to qubes-users
How does this look?

Outline of qubes-dom0-update-guard

Usage: Use in conjunction with manual dom0 update
    sudo qubes-dom0-update -y && qubes-dom0-update-guard
    
<START SCRIPT>
Prompt 1: "Please enter the name of a clean VM with access to Tor (e.g. anon-whonix): "
    Check if entered name is a VM
        If false, alert and prompt again
        If true, proceed
    Check if VM has Tor access
        If Tor inaccessible, alert and prompt again
        If Tor accessible, enter input into variable 'VM1' and proceed

Prompt 2: "Please enter the name of a clean, Debian-based disposable VM template with no assigned NetVM: "
    Check if enter name is a VM
        If false, alert and prompt again
        If true, proceed
    Check if VM is a disposable VM template (via qvm-prefs)
        If false, alert and prompt again
        If true, proceed
    Check if VM is based on Debian (via qvm-prefs)
        If false, alert and prompt again
        If true, proceed
    Check if VM has no NetVM assigned (via qvm-prefs)
        If false, alert and prompt again
        If true, enter input into variable 'VM1' and proceed

Start VM1
    Retreive repodata from Onion and HTTPS mirrors
    Alert if less than 3 mirrors accessible
        Maybe halt process or give choice to continue?
        Maybe instead alert if low proportion (predefined) of mirrors available
            Since that might indicate trouble
    Move repodata files to VM2 (starts VM2)

In VM2
    Cross-check Onion and HTTPS repodata
        If any are different, alert, list differences, <EXIT SCRIPT>
        If all match, proceed
        
Write output of dom0 'rpm -qa' or 'yum list installed' to a file, overwriting old version
    Copy into VM2 (same folder as repodata)
    
In VM2, parse and re-write cross-checked Onion repodata into same format as 'rpm -qa' or 'yum list installed' output
    Include newest version of each package only
    Cross-check output against dom0 output using same method for repodata
        If one or more differences, alert (loudly) and list differences, then <END SCRIPT>
        If both match, notify and <END SCRIPT>
        
        
I think the part that will pose the biggest challenge to my almost non-existence programming skills is the last part, where I have to write a program that will parse and repackage Onion repodata into a list of most recent packages. The rest seems workable, especially since I'm using Chris' qubes4-multi-update as reference for the script, which will be in Python.

disrupt_the_flow

unread,
Aug 14, 2020, 7:24:11 AM8/14/20
to qubes...@googlegroups.com
I am so confused. Please explain what you want to do, but no like in a pseudo-script method.
pEpkey.asc

54th Parallel

unread,
Aug 14, 2020, 10:38:33 AM8/14/20
to qubes-users
On Friday, 14 August 2020 at 19:24:11 UTC+8 disrupt_the_flow wrote:
I am so confused. Please explain what you want to do, but no like in a pseudo-script method.

The thread above contains all the pertinent information--if you're using Google Groups, try 'expanding all' and reading through them. 

54th Parallel

unread,
Aug 18, 2020, 1:05:52 AM8/18/20
to qubes-users
While working on the script, I realized that a much simpler way of achieving the goal of verifying that repomd hasn't been tampered with is to just verify that the repomd.xml used for updating matches the onion version (itself cross-checked against multiple HTTPS copies) before the update, instead of comparing a list of installed packages against a parsed list of available packages. This means I won't have to write something to parse that list and makes the script much more compact. 

Unfortunately, this seems to mean tinkering with qubes-dom0-update itself and mandating the use of sys-whonix as the dom0 update VM instead of writing a separate script to be run after the fact.

Reply all
Reply to author
Forward
0 new messages