From ccb2b27a683146237ce402e5b6fd3620adbf21d6 Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Thu, 29 Aug 2019 11:17:52 -0700 Subject: [PATCH 1/2] Exposes Onion URLs (v2 & v3) to webapp We write plaintext files to /var/lib/securedrop so that the application can provide user-facing messaging about upcoming v2 -> v3 Onion URL transitions. For example, if a v3 Source Onion URL exists, but a source is browsing via the v2 URL, we can recommend the v3 URL instead. --- .../ansible-base/roles/app/defaults/main.yml | 6 ++++ .../tasks/copy_tor_url_info_to_app_dir.yml | 36 +++++++++++++++++++ .../ansible-base/roles/app/tasks/main.yml | 2 ++ .../testinfra/staging/app/test_tor_config.py | 21 +++++++++++ 4 files changed, 65 insertions(+) create mode 100644 install_files/ansible-base/roles/app/tasks/copy_tor_url_info_to_app_dir.yml diff --git a/install_files/ansible-base/roles/app/defaults/main.yml b/install_files/ansible-base/roles/app/defaults/main.yml index 217e1b16d8..f6953d364d 100644 --- a/install_files/ansible-base/roles/app/defaults/main.yml +++ b/install_files/ansible-base/roles/app/defaults/main.yml @@ -87,3 +87,9 @@ apache_disabled_modules: securedrop_default_locale: en_US # The subset of the available locales that will be proposed to the user securedrop_supported_locales: [] + +# v2 Tor onion services are on / v3 Tor onion services are off by default for backwards +# compatibility. Note that new installs after 1.0 will have v3 enabled by sdconfig which +# will override these variables. +v2_onion_services: true +v3_onion_services: false diff --git a/install_files/ansible-base/roles/app/tasks/copy_tor_url_info_to_app_dir.yml b/install_files/ansible-base/roles/app/tasks/copy_tor_url_info_to_app_dir.yml new file mode 100644 index 0000000000..8838a01dac --- /dev/null +++ b/install_files/ansible-base/roles/app/tasks/copy_tor_url_info_to_app_dir.yml @@ -0,0 +1,36 @@ +--- +- name: Look up Tor v2 URL info + command: cat /var/lib/tor/services/source/hostname + changed_when: false + register: v2_onion_url_lookup_result + # File may not exist, depending on host config + failed_when: false + when: v2_onion_services + +- name: Look up Tor v3 URL info + command: cat /var/lib/tor/services/sourcev3/hostname + changed_when: false + register: v3_onion_url_lookup_result + # File may not exist, depending on host config + failed_when: false + when: v3_onion_services + +- name: Expose Tor v2 Onion URL info to app + copy: + dest: /var/lib/securedrop/source_v2_url + owner: www-data + group: www-data + mode: "0644" + content: | + {{ v2_onion_url_lookup_result.stdout|default('') }} + when: v2_onion_services + +- name: Expose Tor v3 Onion URL info to app + copy: + dest: /var/lib/securedrop/source_v3_url + owner: www-data + group: www-data + mode: "0644" + content: | + {{ v3_onion_url_lookup_result.stdout|default('') }} + when: v3_onion_services diff --git a/install_files/ansible-base/roles/app/tasks/main.yml b/install_files/ansible-base/roles/app/tasks/main.yml index b5a47374c9..9218f9e57f 100644 --- a/install_files/ansible-base/roles/app/tasks/main.yml +++ b/install_files/ansible-base/roles/app/tasks/main.yml @@ -4,6 +4,8 @@ - include: initialize_securedrop_app.yml +- include: copy_tor_url_info_to_app_dir.yml + # If HTTPS is enabled, certs must land before Apache vhost configs # are written, otherwise the Apache enmod tasks will fail. - include: copy_ssl_certs.yml diff --git a/molecule/testinfra/staging/app/test_tor_config.py b/molecule/testinfra/staging/app/test_tor_config.py index 3e8756a77e..90f54fecc6 100644 --- a/molecule/testinfra/staging/app/test_tor_config.py +++ b/molecule/testinfra/staging/app/test_tor_config.py @@ -1,4 +1,5 @@ import pytest +import re testinfra_hosts = ["app-staging"] sdvars = pytest.securedrop_test_vars @@ -58,3 +59,23 @@ def test_tor_torrc_sandbox(host): # Only `Sandbox 1` will enable, but make sure there are zero occurrances # of "Sandbox", otherwise we may have a regression somewhere. assert not f.contains("^.*Sandbox.*$") + + +def test_tor_v2_onion_url_readable_by_app(host): + v2_url_filepath = "/var/lib/securedrop/source_v2_url" + with host.sudo(): + f = host.file(v2_url_filepath) + assert f.is_file + assert f.user == "www-data" + assert f.mode == 0o644 + assert re.search(r"^[a-z0-9]{16}\.onion$", f.content_string) + + +def test_tor_v3_onion_url_readable_by_app(host): + v3_url_filepath = "/var/lib/securedrop/source_v3_url" + with host.sudo(): + f = host.file(v3_url_filepath) + assert f.is_file + assert f.user == "www-data" + assert f.mode == 0o644 + assert re.search(r"^[a-z0-9]{56}\.onion$", f.content_string) From f6b0a691805ae6ee2fcfc99f7d7ecba924258f95 Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Wed, 28 Aug 2019 18:12:24 -0700 Subject: [PATCH 2/2] Documents running subset of testinfra tests Since testinfra is based on pytest, the pytest env var for passing additional options works just fine. We can use the `-k` option to perform a substring search on test names, and run only those tests matching the selector. --- docs/development/testing_configuration_tests.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/development/testing_configuration_tests.rst b/docs/development/testing_configuration_tests.rst index 75be297edd..a4f9f8b29a 100644 --- a/docs/development/testing_configuration_tests.rst +++ b/docs/development/testing_configuration_tests.rst @@ -32,7 +32,7 @@ For the staging VMs: The VMs will be set up using either the libvirt or virtualbox Vagrant VM provider, depending on your system settings. You'll need to use the appropriate commands below -based on your choice of provider. +based on your choice of provider. Then, to run the tests: @@ -40,7 +40,7 @@ libvirt: ~~~~~~~~ .. code:: sh - + molecule verify -s libvirt-staging virtualbox: @@ -50,12 +50,15 @@ virtualbox: molecule verify -s virtualbox-staging +.. tip:: To run only a single test, set ``PYTEST_ADDOPTS="-k name_of_test"`` + in your environment. + Test failure against any host will generate a report with informative output about the specific test that triggered the error. Molecule will also exit with a non-zero status code. .. note:: To build and test the VMs with one command, use the Molecule ``test`` - action: ``molecule test -s libvirt-staging --destroy=never``, or ``molecule test -s virtualbox-staging --destroy=never``. + action: ``molecule test -s libvirt-staging --destroy=never``, or ``molecule test -s virtualbox-staging --destroy=never``. Updating the Config Tests ------------------------- @@ -75,7 +78,7 @@ than the Ansible playbooks: :: Any variable changes in the Ansible config should have a corresponding entry in these vars files. These vars are dynamically loaded for each -host via the ``molecule/testinfra/staging/conftest.py`` file. Make sure to add +host via the ``molecule/testinfra/staging/conftest.py`` file. Make sure to add your tests to the relevant location for the host you plan to test: :: molecule/testinfra/staging/app/ @@ -105,7 +108,7 @@ Molecule configuration: :: ├── app ├── app-code ├── common - ├── mon + ├── mon ├── ossec └── vars