-
Notifications
You must be signed in to change notification settings - Fork 46
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
Uploads dom0 RPM package for securedrop-workstation template #251
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# ignore everything | ||
** | ||
# whitelist just the pubkey, used for verifying sigs | ||
!sd-workstation/apt-test-pubkey.asc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[[source]] | ||
url = "https://pypi.org/simple" | ||
verify_ssl = true | ||
name = "pypi" | ||
|
||
[dev-packages] | ||
|
||
[packages] | ||
awscli = "*" | ||
|
||
[requires] | ||
python_version = "3.5" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -304,15 +304,22 @@ Be aware that running tests *will* power down running SecureDrop VMs, and may re | |
|
||
## Building the Templates | ||
|
||
1. Create a `fedora-29` AppVM for building | ||
2. Increase the disk size to at least 15GB (as the build uses over 10GB) | ||
1. Create a `fedora-29` AppVM for building the templates. It's going | ||
to need Docker and several other packages every time you use it, so | ||
it might be worth creating another template derived from | ||
`fedora-29`, into which you can install those extras, and basing | ||
the builder VM on that, or just using a StandaloneVM to save time | ||
and repetition. | ||
2. Increase the disk size to at least 15GB (as the build uses over | ||
10GB): `qvm-volume extend sd-template-builder:private 15GB` (if | ||
your VM is not named `sd-template-builder`, adjust that command) | ||
3. Import the QubesOS master key and the GPG key used to sign tags (see https://www.qubes-os.org/security/verifying-signatures/) | ||
4. Run `make template` in the top-level of this repository. | ||
5. Copy the rpm generated in `/home/user/src/securedrop-workstation/builder/qubes-builder/qubes-src/linux-template-builder/rpm/` to `dom0` | ||
6. Install the template in `dom0` : `sudo rpm -i <file>.rpm` (this takes a few minutes) | ||
7. Create a new VM based on this template: | ||
``` | ||
qvm-create --template grsec-workstation test-grsec-kernels --class AppVM --property virt_mode=hvm --property kernel='' --label green | ||
qvm-create --template securedrop-workstation test-securedrop-workstation --class AppVM --property virt_mode=hvm --property kernel='' --label green | ||
``` | ||
|
||
## Building workstation deb packages | ||
|
@@ -369,7 +376,7 @@ and `rpm -qi <file>.rpm` will indicate an empty Signature field. Set up your env | |
|
||
``` | ||
sudo dnf install rpm-build rpm-sign # install required packages | ||
echo "QUBES_GPG_DOMAIN=vault" | sudo tee /rw/config/gpg-split-domain # edit 'vault' as required | ||
echo "vault" | sudo tee /rw/config/gpg-split-domain # edit 'vault' as required | ||
cat << EOF > ~/.rpmmacros | ||
%_signature gpg | ||
%_gpg_name <gpg_key_id> | ||
|
@@ -382,16 +389,38 @@ Now we'll sign the RPM: | |
``` | ||
rpm --resign <rpm>.rpm # --addsign would allow us to apply multiple signatures to the RPM | ||
rpm -qi<file.rpm> # should now show that the file is signed | ||
rpm -Kv # will complain that signature is not OK: "Digests SIGNATURES NOT OK" | ||
rpm -Kv # should contain NOKEY errors in the lines containing Signature | ||
# This is because the the (public) key of the RPM signing key is not present, | ||
# and must be added to the RPM client config to verify the signature: | ||
sudo rpm --import <publicKey>.asc | ||
rpm -Kv # will now say signatures are OK: "Digests signatures OK" | ||
rpm -Kv # Signature lines will now contain OK instead of NOKEY | ||
``` | ||
|
||
You can then proceed with distributing the package, via the "test" or "prod" repo, | ||
as appropriate. | ||
|
||
## Distributing packages | ||
|
||
For the Debian packages, see https://github.com/freedomofpress/securedrop-debian-packaging/. | ||
For the RPM packages, such as the `securedrop-workstation` TemplateVM package, first | ||
build the package (e.g. `make template`), then sign the RPM, as outlined above. | ||
|
||
To upload the package to S3, you'll need valid AWS credentials. Talk to a member of the ops team. | ||
Once you have valid credentials configured, install the dependencies (`pipenv install`), then run: | ||
|
||
``` | ||
./scripts/publish-rpm | ||
``` | ||
|
||
The RPM will immediately be available in dom0. Provided you've run the Salt configurations, | ||
find it via: | ||
|
||
``` | ||
sudo qubes-dom0-update --action=search qubes-template-securedrop-workstation | ||
``` | ||
|
||
You can then install it directly. | ||
|
||
## Threat model | ||
|
||
This section outlines the threat model for the *SecureDrop Workstation*, and should complement [SecureDrop's threat model](https://docs.securedrop.org/en/stable/threat_model/threat_model.html). This document is always a work in progress, if you have any questions or comments, please open an issue on [GitHub](https://github.com/freedomofpress/securedrop-workstation) or send an email to [[email protected]](mailto:[email protected]). | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# fedora:29 2019-04-15 | ||
FROM fedora@sha256:8ee55e140e8751492ab2cfa4513c82093cd2716df9311ea6f442f1f1259cbb3e | ||
LABEL maintainer="Freedom of the Press Foundation" | ||
RUN dnf update -y && \ | ||
dnf install -y \ | ||
createrepo_c | ||
|
||
COPY sd-workstation/apt-test-pubkey.asc /tmp/apt-test-pubkey.asc | ||
RUN rpm --import /tmp/apt-test-pubkey.asc | ||
|
||
RUN mkdir /repo | ||
WORKDIR /repo |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,68 @@ | |
# over time. These scripts should be ported to an RPM package. | ||
## | ||
|
||
dom0-rpm-test-key: | ||
file.managed: | ||
# We write the pubkey to the repos config location, because the repos | ||
# config location is automatically sent to dom0's UpdateVM. Otherwise, | ||
# we must place the GPG key inside the fedora-29 TemplateVM, then | ||
# restart sys-firewall. | ||
- name: /etc/pki/rpm-gpg/RPM-GPG-KEY-securedrop-workstation-test | ||
- source: "salt://sd/sd-workstation/apt-test-pubkey.asc" | ||
- user: root | ||
- group: root | ||
- mode: 644 | ||
|
||
dom0-rpm-test-key-import: | ||
cmd.run: | ||
- name: sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-securedrop-workstation-test | ||
- require: | ||
- file: dom0-rpm-test-key | ||
|
||
dom0-rpm-test-key-sys-firewall: | ||
cmd.run: | ||
# Pass in the pubkey directly to sys-firewall, so it's available on the | ||
# UpdateVM for dom0 while we're configuring dom0 repos. | ||
- name: > | ||
qvm-run -p sys-firewall ' | ||
sudo tee /etc/pki/rpm-gpg/RPM-GPG-KEY-securedrop-workstation-test' | ||
< /srv/salt/sd/sd-workstation/apt-test-pubkey.asc | ||
|
||
dom0-rpm-test-key-sys-firewall-import: | ||
cmd.run: | ||
- name: > | ||
qvm-run --no-gui sys-firewall ' | ||
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-securedrop-workstation-test' | ||
- require: | ||
- cmd: dom0-rpm-test-key-sys-firewall | ||
|
||
dom0-workstation-rpm-repo: | ||
# We use file.managed rather than pkgrepo.managed, because Qubes dom0 | ||
# settings write new repos to /etc/yum.real.repos.d/, but only /etc/yum.repos.d/ | ||
# is copied to the UpdateVM for fetching dom0 packages. | ||
file.managed: | ||
- name: /etc/yum.repos.d/securedrop-workstation-dom0.repo | ||
- user: root | ||
- group: root | ||
- mode: 644 | ||
- contents: | | ||
[securedrop-workstation-dom0] | ||
gpgcheck=1 | ||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-securedrop-workstation-test | ||
enabled=1 | ||
baseurl=https://dev-bin.ops.securedrop.org/dom0-rpm-repo/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @conorsch - you probably want an over-ride variable here, we dont want to target There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, we only need dev support, but you're right that we'll eventually want to flip this to dev—and preserve the ability for developers to override. Any thoughts on how to do that cleanly in Salt? We're not currently using any vars-based configuration, as we do heavily over in SecureDrop core (https://github.com/freedomofpress/securedrop/). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea @conorsch - look into pillars here. Variable interpolation uses the jinja syntax and you can inject complex jinja logic where-ever (one of the pros/cons in using salt v. ansible). |
||
name=SecureDrop Workstation Qubes dom0 repo | ||
- require: | ||
- file: dom0-rpm-test-key | ||
|
||
# Not installing automatically, since we have more testing to do | ||
# dom0-install-securedrop-workstation-template: | ||
# pkg.installed: | ||
# - pkgs: | ||
# - qubes-template-securedrop-workstation | ||
# - require: | ||
# - file: dom0-workstation-rpm-repo | ||
# - cmd: dom0-rpm-test-key-sys-firewall | ||
|
||
# Copy script to system location so admins can run ad-hoc | ||
dom0-update-securedrop-script: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/bin/bash | ||
# Creates a local RPM repo, then pushes its contents to S3, for serving. | ||
set -e | ||
set -u | ||
set -o pipefail | ||
|
||
|
||
REPO_ROOT="$(git rev-parse --show-toplevel)" | ||
RPM_LOCAL_DIR="${REPO_ROOT}/rpm-repo" | ||
|
||
|
||
function list_rpms() { | ||
find "$RPM_LOCAL_DIR" | grep '\.rpm$' | ||
} | ||
|
||
function container_run() { | ||
docker run --rm \ | ||
--network=none \ | ||
-v "$RPM_LOCAL_DIR:/repo" \ | ||
fpf.local/createrepo \ | ||
$@ | ||
} | ||
|
||
# Check that we have local RPMs to build a repo for | ||
if [[ -z "$(list_rpms)" ]]; then | ||
echo "No RPM files found in $RPM_LOCAL_DIR" | ||
echo "Build RPMs and place in that directory, then rerun the publish action." | ||
exit 1 | ||
fi | ||
|
||
# Ensure we have 'aws' installed, otherwise we cannot push to S3 | ||
if ! hash aws > /dev/null 2>&1 ; then | ||
echo "'aws' CLI not found, install requirements" | ||
exit 2 | ||
fi | ||
|
||
# Build container for preparing repo | ||
docker build -t fpf.local/createrepo -f docker/CreateRepoRPM/Dockerfile . | ||
|
||
# TODO: In order to manage state over time, we'll need to *pull* from S3, | ||
# populating the existing local dir with the current state of what's in S3. | ||
# That's a bandwidth-intensive operation, so skipping for now. | ||
# aws --profile sdpackager s3 sync "s3://dev-bin.ops.securedrop.org/dom0-rpm-repo/ ${RPM_LOCAL_DIR}/" | ||
|
||
# Sanity check that we have RPMs locally to upload, and they're already | ||
# signed. | ||
echo "Validating RPM signatures..." | ||
while read -r f; do | ||
fname="$(basename "$f")" | ||
sig_results="$(container_run rpm -Kv "$fname")" | ||
if ! grep -qP '^\s+V4 RSA/SHA256 Signature, key ID \w+: OK$' <<< "$sig_results"; then | ||
echo "Failed to validate signature on $fname" | ||
echo "Is the RPM signed? rpm -Kv showed:" | ||
echo "$sig_results" | ||
exit 3 | ||
fi | ||
done <<< "$(list_rpms)" | ||
|
||
# Use local container for creating repo metadata | ||
container_run createrepo_c . | ||
|
||
# Push created repo dirtree to S3 | ||
aws --profile sdpackager s3 sync \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do you feel about making explicit STS calls (assumerole) here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The hardcoded There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great feedback, let's aim to clean this up next time another team member runs through the process. Not opposed to adding a CLI flag to the existing script, but we may want to migrate to a more robust Python script in the near future. |
||
--exclude ".empty" \ | ||
"${RPM_LOCAL_DIR}/" s3://dev-bin.ops.securedrop.org/dom0-rpm-repo/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I don't bother to install docker inside the
sd-template-builder
VM; I simplyqvm-move <rpm>
the artifact back to mysd-dev
environment for upload. Either way, your docs are certainly clearer than what we've had. Let's continue to discuss the optimal workflows here, and improve the docs as we go.