diff --git a/Makefile b/Makefile index 0ef9eac5..d14fe752 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,12 @@ sd-export: prep-salt ## Provisions SD Export VM sudo qubesctl --show-output --targets sd-export-template state.highstate sudo qubesctl --show-output --targets sd-export-export-dvm state.highstate +sd-log: prep-salt ## Provisions SD logging VM + sudo qubesctl top.enable sd-log + sudo qubesctl top.enable sd-log-template-files + sudo qubesctl --show-output --targets sd-log-template state.highstate + sudo qubesctl --show-output --targets sd-log state.highstate + clean-salt: assert-dom0 ## Purges SD Salt configuration from dom0 @echo "Purging Salt config..." @sudo rm -rf /srv/salt/sd @@ -89,6 +95,9 @@ remove-sd-export: assert-dom0 ## Destroys SD EXPORT VMs @./scripts/destroy-vm sd-export-usb @./scripts/destroy-vm sd-export-usb-dvm +remove-sd-log: assert-dom0 ## Destroys SD logging VM + @./scripts/destroy-vm sd-log + clean: assert-dom0 destroy-all clean-salt ## Destroys all SD VMs sudo dnf -y -q remove securedrop-workstation-dom0-config 2>/dev/null || true sudo rm -f /usr/bin/securedrop-update \ diff --git a/dom0/sd-log-template-files.sls b/dom0/sd-log-template-files.sls new file mode 100644 index 00000000..59e5a353 --- /dev/null +++ b/dom0/sd-log-template-files.sls @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +# We should package this so we can easily update +sd-log-script: + file.managed: + - name: /usr/sbin/oqubes-logging + - source: salt://sd/sd-log/oqubes-logging + - user: root + - group: root + - mode: 755 + +sd-log-qrexec: + file.managed: + - name: /etc/qubes-rpc/oqubes.Logging + - source: salt://sd/sd-log/oqubes.Logging + - user: root + - group: root + - mode: 755 diff --git a/dom0/sd-log-template-files.top b/dom0/sd-log-template-files.top new file mode 100644 index 00000000..32d0a1df --- /dev/null +++ b/dom0/sd-log-template-files.top @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +base: + sd-log-template: + - sd-log-template-files diff --git a/dom0/sd-log.sls b/dom0/sd-log.sls new file mode 100644 index 00000000..a8247189 --- /dev/null +++ b/dom0/sd-log.sls @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +# +# Installs 'sd-log' AppVM for collecting and storing logs +# from all SecureDrop related VMs. +# This VM has no network configured. +## +include: + - sd-workstation-template + +sd-log-template: + qvm.vm: + - name: sd-log-template + - clone: + - source: securedrop-workstation + - label: red + - tags: + - add: + - sd-workstation + - require: + - sls: sd-workstation-template + +sd-log: + qvm.vm: + - name: sd-log + - present: + - template: sd-log-template + - label: red + - prefs: + - netvm: "" + - autostart: true + - tags: + - add: + - sd-workstation + - features: + - enable: + - service.paxctld + - require: + - qvm: sd-log-template + +# Allow any SecureDrop VM to log to the centralized log VM +sd-log-dom0-oqubes.Logging: + file.prepend: + - name: /etc/qubes-rpc/policy/oqubes.Logging + - text: | + @tag:sd-workstation sd-log allow + @anyvm @anyvm deny diff --git a/dom0/sd-log.top b/dom0/sd-log.top new file mode 100644 index 00000000..a0e6fa3c --- /dev/null +++ b/dom0/sd-log.top @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +base: + dom0: + - sd-log diff --git a/scripts/list-vms b/scripts/list-vms index 2407f822..d5a52b5f 100755 --- a/scripts/list-vms +++ b/scripts/list-vms @@ -21,6 +21,8 @@ declare -a sd_workstation_vm_names=( sd-export-usb sd-export-usb-dvm sd-export-template + sd-log + sd-log-template ) for vm in "${sd_workstation_vm_names[@]}" ; do diff --git a/scripts/prep-salt b/scripts/prep-salt index fd3f4450..ae1dc287 100755 --- a/scripts/prep-salt +++ b/scripts/prep-salt @@ -19,6 +19,7 @@ if [[ ! -d "$SDW_SALT_DIR" ]]; then sudo mkdir -p /srv/salt/sd sudo cp -r sd-proxy /srv/salt/sd sudo cp -r sd-svs /srv/salt/sd + sudo cp -r sd-log /srv/salt/sd sudo cp -r sd-workstation /srv/salt/sd sudo cp -r sys-firewall /srv/salt/sd sudo cp dom0/* /srv/salt/ diff --git a/sd-log/oqubes.Logging b/sd-log/oqubes.Logging new file mode 100644 index 00000000..abc91aa7 --- /dev/null +++ b/sd-log/oqubes.Logging @@ -0,0 +1 @@ +/usr/sbin/oqubes-logging diff --git a/tests/base.py b/tests/base.py index 4f69cb25..bd8d3a10 100644 --- a/tests/base.py +++ b/tests/base.py @@ -8,6 +8,7 @@ # Reusable constant for DRY import across tests WANTED_VMS = [ "sd-gpg", + "sd-log", "sd-proxy", "sd-svs", "sd-svs-disp", diff --git a/tests/test_log_vm.py b/tests/test_log_vm.py new file mode 100644 index 00000000..ea3b26e0 --- /dev/null +++ b/tests/test_log_vm.py @@ -0,0 +1,18 @@ +import unittest + +from base import SD_VM_Local_Test + + +class SD_Log_Tests(SD_VM_Local_Test): + def setUp(self): + self.vm_name = "sd-log" + super(SD_Log_Tests, self).setUp() + + def test_log_utility_installed(self): + self.assertTrue(self._fileExists("/usr/sbin/oqubes-logging")) + self.assertTrue(self._fileExists("/etc/qubes-rpc/oqubes.Logging")) + + +def load_tests(loader, tests, pattern): + suite = unittest.TestLoader().loadTestsFromTestCase(SD_Log_Tests) + return suite diff --git a/tests/test_vms_exist.py b/tests/test_vms_exist.py index 8d80b560..b0051756 100644 --- a/tests/test_vms_exist.py +++ b/tests/test_vms_exist.py @@ -102,6 +102,19 @@ def test_sd_gpg_config(self): self._check_kernel(vm) self.assertTrue('sd-workstation' in vm.tags) + def test_sd_log_config(self): + vm = self.app.domains["sd-log"] + nvm = vm.netvm + self.assertTrue(nvm is None) + self.assertTrue(vm.template == "sd-log-template") + self.assertTrue(vm.autostart is True) + self.assertFalse(vm.provides_network) + self.assertFalse(vm.template_for_dispvms) + self._check_kernel(vm) + self._check_service_running(vm, "paxctld") + self.assertFalse(vm.template_for_dispvms) + self.assertTrue('sd-workstation' in vm.tags) + def test_sd_workstation_template(self): vm = self.app.domains["securedrop-workstation"] nvm = vm.netvm @@ -156,6 +169,14 @@ def sd_export(self): self.assertTrue('sd-workstation' in vm.tags) self._check_kernel(vm) + def sd_log_template(self): + vm = self.app.domains["sd-log-template"] + nvm = vm.netvm + self.assertTrue(nvm is None) + self.assertTrue('sd-workstation' in vm.tags) + self.assertFalse(vm.template_for_dispvms) + self._check_kernel(vm) + def load_tests(loader, tests, pattern): suite = unittest.TestLoader().loadTestsFromTestCase(SD_VM_Tests)