Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sd-export VMs and basic export flow #259

Merged
merged 14 commits into from
Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[flake8]
ignore: W605
max-line-length = 99
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ sd-svs-disp: prep-salt ## Provisions SD Submission Viewing VM
sudo qubesctl --show-output --targets sd-svs-disp-template state.highstate
sudo qubesctl --show-output --targets sd-svs-disp state.highstate

sd-export: prep-salt ## Provisions SD Export VM
sudo qubesctl top.enable sd-export
sudo qubesctl top.enable sd-export-files
sudo qubesctl --show-output --targets sd-export-template state.highstate
sudo qubesctl --show-output --targets sd-export-export-dvm state.highstate

clean-salt: assert-dom0 ## Purges SD Salt configuration from dom0
@echo "Purging Salt config..."
@sudo rm -rf /srv/salt/sd
Expand All @@ -78,6 +84,12 @@ remove-sd-svs: assert-dom0 ## Destroys SD SVS VM
remove-sd-gpg: assert-dom0 ## Destroys SD GPG keystore VM
@./scripts/destroy-vm sd-gpg

remove-sd-export: assert-dom0 ## Destroys SD EXPORT VMs
@qvm-kill sd-export-usb || true
@qvm-usb detach sd-export-usb || true
@./scripts/destroy-vm sd-export-usb
@./scripts/destroy-vm sd-export-usb-dvm

clean: assert-dom0 destroy-all clean-salt ## Destroys all SD VMs
sudo dnf -y -q remove securedrop-workstation-dom0-config || true
sudo rm -f /usr/bin/securedrop-update \
Expand Down
91 changes: 80 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,32 +161,101 @@ Replies and Source Deletion will be added in the next major release of the *Secu

**WARNING:** Opening files from an unknown origin presents certain risks (malware, fingerprinting). While the workstation helps reduce these risks by offering VM-level isolation, transferring documents to another host without the same level of isolation may expose you to these risks. Using tools to sanitize submitted documents, such as right-clicking a .pdf and selecting "Convert to trusted PDF" in Qubes OS, may help mitigate some of these risks. Further mitigating these risks will be a focus of future development.

##### Manual export flow

Exporting documents directly from within the *SecureDrop Client* is not currently supported, but you can export documents manually via USB by following these steps:

1. Create an export VM based on the `securedrop-workstation` template.
1. Click the Qubes menu in the upper left of the screen.
2. Click **Create Qubes VM**
3. Name the VM `sd-export`
4. Set the template as `securedrop-workstation`
5. Set networking to (none).
6. Click **OK** to create the VM.
2. Start the VM. Again from the Qubes menu:
1. Start the `sd-export-usb` VM. Again from the Qubes menu:
1. Select "Domain: sd-export"
2. Click "export: Files". This will launch the file manager in the export VM.
3. Insert your USB drive into the workstation. A notification will pop up indicating the name of your USB device, e.g. "Innostor_PenDrive".
4. In the upper right hand side of your screen, there is a small icon in the system tray with a USB drive. Click that icon.
5. Select the name of your USB drive.
6. Click the **+** icon next to the `sd-export` VM.
6. Click the **+** icon next to the `sd-export-usb` VM.
3. You can use the command line in `sd-svs` to manually move selected files:

```
qvm-copy-to-vm sd-export ~/.securedrop_client/data/name-of-file
qvm-copy-to-vm sd-export-usb ~/.securedrop_client/data/name-of-file
```

4. You may now use the File manager that you opened in `sd-export` to move files from `~/QubesIncoming/sd-svs` to the USB drive. Delete the original file from `~/QubesIncoming/sd-svs` once it has been moved. Note that the drive and files are not encrypted, so ensure that the key is properly erased and/or destroyed after use.
4. You may now use the File manager that you opened in `sd-export-usb` to move files from `~/QubesIncoming/sd-svs` to the USB drive. Delete the original file from `~/QubesIncoming/sd-svs` once it has been moved. Note that the drive and files are not encrypted, so ensure that the key is properly erased and/or destroyed after use.

The development plan is to provide functionality in the *SecureDrop Client* that automates step 3, and assists the user in taking these steps via GUI prompts. Eventually we plan to provide other methods for export, such as [OnionShare](https://onionshare.org/) (this will require the attachment of a NetVM), using a dedicated export VM template with tools such as OnionShare and Veracrypt. The next section includes instructions to approximate the OnionShare sharing flow.

##### Automated export flow (Work in progress, client integration TBD)

The SecureDrop Workstation can automatically export to a luks-encrypted USB device provided the correct format. The file extension of the tar archive must be `.sd-export`, containing the following structure:

```
.
├── metadata.json
└── export_data
├── file-to-export-1.txt
├── file-to-export-2.pdf
├── file-to-export-3.doc
[...]
```

The folder `export_data` contains all the files that will be exported to the disk, and the file `metadata.json` contains the encryption passphrase and method for the USB Transfer Device (only LUKS is supported at the moment). The file should be formatted as follows:

```
{
"encryption-method": "luks"
"encryption-key": "Your encryption passhrase goes here"
}
```

###### Create the transfer device

You can find instructions to create a luks-encrypted transfer device in the [SecureDrop docs](https://docs.securedrop.org/en/latest/set_up_transfer_device.html).

###### Install-time configuration

A single USB port will be assigned to the exporting feature. Qubes will automatically attach any USB device to the Export VM. It should be labeled and only used for exporting purposes. You will be able to use different USB Transfer Devices, but they will always need to be plugged into the same port. Note that a USB stick must be connected during the entirety of the provisioning process. If you forget, you can run `make sd-export` after the install.


1. Connect the USB device to the port you would like to use. Then in `dom0`, run the following command:

```
qvm-usb
```

2. Take note of the device ID (e.g. `sys-usb:3-4`) used by your USB Transfer Device
3. Populate `config.json` with this value
4. Run the configuration of the sd-export feature.
1. If this is a new install, you can run, in `dom0`:

```
make all
```

2. If the workstation has already been properly configured and you wish to reconfigure the USB export functionality, run the following commands in `dom0`:

```
make remove-sd-export
make sd-export
```

###### Exporting

1. Plug in the USB drive into the dedicated export port on your workstation.
2. In `sd-svs`, run the following command:

```
qvm-open-in-vm sd-export-usb <name-of-file>
```

###### Troubleshooting

If you are experiencing issues with the export flow, or would like to use a different port, you can re-run the configuration steps and apply the configuration to the VMs.
In `dom0`, ensure your config.json contains the correct usb device identifier (see above) and rebuild the export machines (with the USB device attached):

```
make remove-sd-export
make sd-export
```


##### Transferring files via OnionShare
1. Create an `sd-onionshare-template` VM based on `fedora-29`:
1. Click on the Qubes menu in the upper left, select "Template: Fedora 29", click on "fedora-29: Qube Settings", and click on **Clone Qube**
Expand Down
3 changes: 3 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"hidserv": {
"hostname": "avgfxawdn6c3coe3.onion",
"key": "Il8Xas7uf6rjtc0LxYwhrx"
},
"usb": {
"device": "sys-usb:2-4"
}
}
2 changes: 1 addition & 1 deletion docs/images/data-flow-diagram.draw

Large diffs are not rendered by default.

Binary file modified docs/images/data-flow-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions dom0/sd-dom0-qvm-rpc.sls
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dom0-rpc-qubes.OpenInVM:
- marker_end: "### END securedrop-workstation ###"
- content: |
sd-svs $dispvm:sd-svs-disp allow
sd-svs sd-export-usb allow
$anyvm $tag:sd-workstation deny
dom0-rpc-qubes.OpenURL:
file.blockreplace:
Expand Down
53 changes: 53 additions & 0 deletions dom0/sd-export-files.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :

##
# sd-export-files
# ========
#
# Moves files into place on sd-export
#
##
include:
- fpf-apt-test-repo

sd-export-template-install-cryptsetup:
pkg.installed:
- pkgs:
- cryptsetup

sd-export-send-to-usb-script:
file.managed:
- name: /usr/bin/send-to-usb
- source: salt://sd/sd-export/send-to-usb
- user: root
- group: root
- mode: 755
- makedirs: True

sd-export-desktop-file:
file.managed:
- name: /usr/share/applications/send-to-usb.desktop
- source: salt://sd/sd-export/send-to-usb.desktop
- user: root
- group: root
- mode: 644
- makedirs: True
cmd.run:
- name: sudo update-desktop-database /usr/share/applications
- require:
- file: sd-export-desktop-file

sd-export-file-format:
file.managed:
- name: /usr/share/mime/packages/application-x-sd-export.xml
- source: salt://sd/sd-export/application-x-sd-export.xml
- user: root
- group: root
- mode: 644
- makedirs: True
cmd.run:
- name: sudo update-mime-database /usr/share/mime
- require:
- file: sd-export-file-format
- file: sd-export-desktop-file
6 changes: 6 additions & 0 deletions dom0/sd-export-files.top
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :

base:
sd-export-template:
- sd-export-files
77 changes: 77 additions & 0 deletions dom0/sd-export.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :

#
# Installs 'sd-export' AppVM, to persistently store SD data
# This VM has no network configured.
##
include:
- sd-workstation-template

sd-export-template:
qvm.vm:
- name: sd-export-template
- clone:
- source: securedrop-workstation
- label: red
- tags:
- add:
- sd-workstation
- require:
- sls: sd-workstation-template

sd-export-usb-dvm:
qvm.vm:
- name: sd-export-usb-dvm
- present:
- template: sd-export-template
- label: red
- prefs:
- netvm: ""
- template_for_dispvms: True
- tags:
- add:
- sd-workstation
- require:
- qvm: sd-export-template

# Ensure the Qubes menu is populated with relevant app entries,
# so that Nautilus/Files can be started via GUI interactions.
sd-export-template-sync-appmenus:
cmd.run:
- name: >
qvm-start --skip-if-running sd-export-template &&
qvm-sync-appmenus sd-export-template
- require:
- qvm: sd-export-template
- onchanges:
- qvm: sd-export-template

# Here we must create as the salt stack does not appear to allow us to create
# VMs with the class DispVM and attach the usb device specified in the config
# permanently to this VM
sd-export-create-named-dispvm:
cmd.run:
- name: >
qvm-check sd-export-usb ||
qvm-create --class DispVM --template sd-export-usb-dvm --label red sd-export-usb
- require:
- qvm: sd-export-usb-dvm

{% import_json "sd/config.json" as d %}

sd-export-named-dispvm-permanently-attach-usb:
cmd.run:
- name: >
qvm-usb attach --persistent sd-export-usb {{ d.usb.device }} || true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous iterations of this step would be run after qvm-usb detach on the sd-export-usb domain this is because when running make sd-export using more than once, with different values for usb.device will result in an error while starting the sd-export-usb vm (see screenshot below)
sd-export-error

- require:
- cmd: sd-export-create-named-dispvm

sd-export-named-dispvm-add-tags:
qvm.vm:
- name: sd-export-usb
- tags:
- add:
- sd-workstation
- require:
- cmd: sd-export-create-named-dispvm
6 changes: 6 additions & 0 deletions dom0/sd-export.top
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :

base:
dom0:
- sd-export
5 changes: 5 additions & 0 deletions scripts/list-vms
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ set -u
set -o pipefail


# When adding new VMs, ensure the template is listed *after* the AppVMs that
# use it.
declare -a sd_workstation_vm_names=(
sd-gpg
sd-proxy
Expand All @@ -16,6 +18,9 @@ declare -a sd_workstation_vm_names=(
sd-whonix
sd-svs-disp
sd-svs-disp-template
sd-export-usb-dvm
sd-export-usb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's prefer sd-export-usb to sd-export in all cases, since we also plan to support export methods other than USB. So these lines would become:

  • sd-export-usb-template
  • sd-export-usb-dvm
  • sd-export-usb

And the relevant config lines referring to these VMs should be updated, as well. Discussion in the motivating ticket (#84) indicates that we may want to consolidate all export functionality into a single stateless VM. Given the disparate config needs (such as net/no-net) between just USB export and e.g. Onionshare, let's plan to name explicitly from the start, and consolidate if and only if we identify a sound method of doing so.

Copy link
Contributor Author

@emkll emkll May 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed sd-export-dvm to sd-export-usb-dvm. I think this makes sense, we want a DispVM template AppVM to not have network access.

In an attempt to minimize the total amount of templates, I think it might make sense to use the same template for USB exports and other exports(networked, OnionShare exports), as to reduce the time to upgrade templates (which is already quite long, as each template must be updated independently). Since we will likely be creating a AppVM/DispVM template for network-specific exports, I think it might make sense for them to share templates.

I don't feel strongly about sharing the template, happy to break up the template further if you think it's warranted.

sd-export-template
)

for vm in "${sd_workstation_vm_names[@]}" ; do
Expand Down
1 change: 1 addition & 0 deletions scripts/prep-salt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ if [[ ! -d "$SDW_SALT_DIR" ]]; then
sudo cp -r sd-proxy /srv/salt/sd
sudo cp -r sd-svs /srv/salt/sd
sudo cp -r sd-workstation /srv/salt/sd
sudo cp -r sd-export /srv/salt/sd
sudo cp dom0/* /srv/salt/
fi

Expand Down
7 changes: 7 additions & 0 deletions sd-export/application-x-sd-export.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-sd-export">
<comment>Archive for transfering files from the SecureDrop workstation to an external USB device.</comment>
<glob pattern="*.sd-export"/>
</mime-type>
</mime-info>
Loading