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

Configures Tails workstations via Ansible #1803

Merged
merged 10 commits into from
Jun 14, 2017
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 7 additions & 3 deletions install_files/ansible-base/inventory-dynamic
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,18 @@ def lookup_tor_hostname(hostname):
with open(aths_path, 'r') as f:
tor_config = f.readline().rstrip().split()
try:
# Regardless of THS/ATHS, Onion URL will be first item.
# That's all we care about to get the address.
return tor_config[0]
# Ordinarily the Onion URL would be the first field in the file,
# assuming the file is a raw `hostname` file generated by tor,
# but the SD playbooks format the line with `HidServAuth` prefix,
# so it can be concatenated into the torrc file on Tails.
tor_hostname = tor_config[1]
except IndexError:
msg = ("Tor config file for '{}' ",
"appears to be empty").format(hostname)
raise Exception(msg=msg)

return tor_hostname


def lookup_ssh_address(hostname):
"""
Expand Down
43 changes: 43 additions & 0 deletions install_files/ansible-base/roles/tails-config/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
# Locations for SecureDrop-specific dotfiles, for Tails persistence.
tails_config_amnesia_home: /home/amnesia
tails_config_amnesia_persistent: "{{ tails_config_amnesia_home }}/Persistent"

# Directory containing Ansible config, including site-specific customizations.
tails_config_ansible_base: "{{ tails_config_amnesia_persistent }}/securedrop/install_files/ansible-base"

# Custom persistence directory whence site-specific configs will be copied
# on every login under Tails.
tails_config_securedrop_dotfiles: "{{ tails_config_amnesia_persistent }}/.securedrop"

# Locations for Tails persistence settings, used to bootstrap SecureDrop config
tails_config_live_persistence: /live/persistence/TailsData_unlocked
tails_config_live_dotfiles: "{{ tails_config_live_persistence }}/dotfiles"

# Destination directories for storing the SecureDrop desktop icons, which
# provide a user-friendly method of accessing the Onion URLs in a browser.
tails_config_desktop_icon_directories:
- "{{ tails_config_securedrop_dotfiles }}"
- "{{ tails_config_live_dotfiles }}"
- "{{ tails_config_amnesia_home }}/Desktop"
- "{{ tails_config_live_dotfiles }}/Desktop"
- "{{ tails_config_amnesia_home }}/.local/share/applications"
- "{{ tails_config_live_dotfiles }}/.local/share/applications"

# Path for storing site-specific ATHS info for connecting to Journalist Interface.
tails_config_torrc_additions: "{{ tails_config_securedrop_dotfiles }}/torrc_additions"

# Location for NetworkManager hooks, used to activate ATHS info.
tails_config_network_manager_dispatcher: /etc/NetworkManager/dispatcher.d

# Parent directories for joining with the config_files below,
# to ensure absence from all locations succinctly.
tails_config_deprecated_directories:
- "{{ tails_config_live_persistence }}"
- "{{ tails_config_securedrop_dotfiles }}"
- "{{ tails_config_network_manager_dispatcher }}"
- "{{ tails_config_network_manager_dispatcher }}/custom-nm-hooks"

tails_config_deprecated_config_files:
- 70-tor-reload.sh
- 99-tor-reload.sh
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Logic like these legacy cleanup tasks isn't strictly necessary, since we're requiring Admins to install Tails 3 on a fresh stick during upgrade to 0.4. Depending on how they copy the dotfiles over, though, it's conceivable something could be dangling, so I figured better safe than sorry. Also, we know have a dedicated task list for handling legacy cleanup tasks on Tails in the future.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
# Run the SecureDrop init script, which implements the torrc additions
# so the ATHS Onion URLs are accessible. See `securedrop_init.py` for details.
- name: run securedrop network hook
# Writes files to /etc, so elevated privileges are required.
become: yes
command: /usr/bin/python "{{ tails_config_securedrop_dotfiles }}/securedrop_init.py"
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
# Legacy changes handler to ensure backwards-compatibility. If an Admin runs
# this config after already having set up SecureDrop before, any outdated
# items will be handled and updated accordingly.

- name: Remove deprecated network hook config files.
file:
path: "{{ item.0 }}/{{ item.1 }}"
state: absent
with_nested:
- "{{ tails_config_deprecated_directories }}"
- "{{ tails_config_deprecated_config_files }}"

- name: Remove deprecated xsessionrc file.
file:
path: "{{ tails_config_live_persistence }}/dotfiles/.xsessionrc"
state: absent

- name: Remove deprecated Document Interface desktop icons.
file:
state: absent
path: "{{ item }}"
with_items:
- "{{ tails_config_amnesia_home }}/Desktop/document.desktop"
- "{{ tails_config_amnesia_home }}/.local/share/applications/document.desktop"
Copy link
Contributor

Choose a reason for hiding this comment

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

I would add that you should also remove Report_an_error.desktop and tails-documentation.desktop. These icons clutter the desktop and our users are likely hitting errors with SD --- if anything I would add a link to OUR website and OUR docs. That second part can be a new PR (up to you) but I think the removal of existing icons should go in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great idea. Will need to confirm that one-time removal sticks after rebooting. If that's the case, will push up changes.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- name: Enable persistence for NetworkManager hooks.
# Elevated privileges are required for writing to persistence config.
become: yes
lineinfile:
dest: "{{ tails_config_live_persistence }}/persistence.conf"
regexp: '^/etc/NetworkManager'
line: "{{ tails_config_network_manager_dispatcher }} source=custom-nm-hooks,link"

- name: Copy NetworkManager hook for managing SecureDrop interfaces.
become: yes
copy:
src: 65-configure-tor-for-securedrop.sh
dest: "{{ item }}/"
owner: root
group: root
mode: "0755"
with_items:
- "{{ tails_config_live_persistence }}/custom-nm-hooks"
- "{{ tails_config_network_manager_dispatcher }}"
notify: run securedrop network hook

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- name: Find Tor ATHS info for SecureDrop interfaces.
find:
paths:
- "{{ tails_config_ansible_base }}"
patterns:
# Collect all files that end in `-aths`, since only ATHS services
# contain HidServAuth info that must be added to torrc.
- '*-aths'
register: find_aths_info_result

# We need at least one ATHS value, for the Journalist Interface.
# Admin Workstations will have three, including the two SSH interfaces.
# This task simply validates that at least one suitable file was found;
# if not, then the playbooks haven't been run, so fail with instructions.
- name: Confirm ATHS info was found.
assert:
that:
- find_aths_info_result.matched >= 1
msg: >-
Failed to find ATHS info locally. Make sure you've installed SecureDrop
on the servers, and that the `-aths` files are located in:
`{{ tails_config_ansible_base }}/`.

- name: Assemble ATHS info into torrc additions.
become: yes
assemble:
src: "{{ tails_config_ansible_base }}"
regexp: '.*-aths$'
dest: "{{ tails_config_torrc_additions }}"
owner: root
group: root
mode: "0400"
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- name: Create SecureDrop-specific dotfiles directory for Tails persistence.
file:
path: "{{ tails_config_securedrop_dotfiles }}"
state: directory
mode: "0755"

- name: Copy SecureDrop logo for desktop icons to dotfiles directory.
copy:
src: securedrop_icon.png
dest: "{{ tails_config_securedrop_dotfiles }}/"

# Script used to append torrc additions. Triggered by NetworkManager hook.
# Resides in dotfiles in order to achieve persistence.
- name: Copy SecureDrop network hook for Tor config.
# Elevated privileges for root:root ownership, so only the system can
# execute, in the context of the NetworkManager hook, which calls it.
become: yes
copy:
src: securedrop_init.py
dest: "{{ tails_config_securedrop_dotfiles }}/"
owner: root
group: root
mode: "0700"
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
# Read the Onion URL from the Tor info files that were fetched back during
# installation. On the Admin Workstation, these files will be present
# after running the playbooks, but on the Journalist Workstation, they must
# be copied manually by the Admin.
- name: Look up Source Interface URL.
command: grep -Po '.{16}\.onion' app-source-ths
changed_when: false
register: source_interface_lookup_result

- name: Look up Journalist Interface URL.
command: grep -Po '.{16}\.onion' app-journalist-aths
changed_when: false
register: journalist_interface_lookup_result

- name: Create desktop shortcut parent directories.
file:
state: directory
path: "{{ item }}"
with_items: "{{ tails_config_desktop_icon_directories }}"

# Storing as host fact so we can loop over the data in one task.
- name: Assemble desktop icon info.
set_fact:
_securedrop_desktop_icon_info:
- name: SecureDrop Source Interface
filename: source.desktop
onion_url: "{{ source_interface_lookup_result.stdout }}"
- name: SecureDrop Journalist Interface
filename: journalist.desktop
onion_url: "{{ journalist_interface_lookup_result.stdout }}"

- name: Create SecureDrop interface desktop icons.
template:
src: desktop-icon.j2
dest: "{{ item.1 }}/{{ item.0.filename }}"
mode: "0700"
with_nested:
- "{{ _securedrop_desktop_icon_info }}"
- "{{ tails_config_desktop_icon_directories }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Read the Onion URL from the Tor info files that were fetched back during
# installation. On the Admin Workstation, these files will be present
# after running the playbooks, but on the Journalist Workstation, they must
# be copied manually by the Admin.

- name: Look up Application Server SSH Onion URL.
command: grep -Po '.{16}\.onion' app-ssh-aths
changed_when: false
register: app_ssh_lookup_result

- name: Look up Monitor Server SSH Onion URL.
command: grep -Po '.{16}\.onion' mon-ssh-aths
changed_when: false
register: mon_ssh_lookup_result

- name: Create SSH config directory.
file:
state: directory
path: "{{ tails_config_amnesia_home }}/.ssh"
mode: "0700"

- name: Create SSH alias
template:
src: ssh_config.j2
dest: "{{ item }}"
mode: "0600"
with_items:
- "{{ tails_config_securedrop_dotfiles }}/ssh_config"
- "{{ tails_config_amnesia_home }}/.ssh/config"
18 changes: 18 additions & 0 deletions install_files/ansible-base/roles/tails-config/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
# Reuse validation logic.
- include: "{{ role_path }}/../validate/tasks/validate_tails_environment.yml"

- include: cleanup_legacy_artifacts.yml

- include: copy_dotfiles.yml

- include: configure_torrc_additions.yml

- include: create_desktop_shortcuts.yml

- include: configure_network_hook.yml

- include: create_ssh_aliases.yml
# Only Admin Workstation will have ATHS values for SSH, in addition
# to ATHS value for the Journalist Interface.
when: find_aths_info_result.matched > 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env xdg-open

[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Categories=Network;
Name[en_US]={{ item.0.name }}
Icon[en_US]={{ tails_config_securedrop_dotfiles }}/securedrop_icon.png
Name={{ item.0.name }}
Icon={{ tails_config_securedrop_dotfiles }}/securedrop_icon.png
Exec=/usr/local/bin/tor-browser {{ item.0.onion_url }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Host app
Hostname {{ app_ssh_lookup_result.stdout }}
Host mon
Hostname {{ mon_ssh_lookup_result.stdout }}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
with_items:
- /live/persistence/TailsData_unlocked/persistence.conf
- /live/persistence/TailsData_unlocked/openssh-client
- /home/amnesia/Persistent/securedrop

- name: Confirm persistence volume is configured.
assert:
Expand All @@ -22,4 +23,6 @@
msg: >-
Persistence must configured on the Tails device for the Admin
Workstation, and the SSH option for persistent dotfiles must be enabled.
The SecureDrop git repository should be cloned
to `~/Persistent/securedrop`.
with_items: "{{ tails_persistence_check_result.results }}"
23 changes: 23 additions & 0 deletions install_files/ansible-base/securedrop-tails.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env ansible-playbook
---
# Configures SecureDrop dotfiles persistence on Admin and Journalist
# Workstations. Should be run after the servers have been installed.
- name: Configure Tails workstation.
hosts: localhost
connection: local
gather_facts: yes
roles:
- role: tails-config
tags: tails-config
tasks:
- name: Configuration complete.
debug:
msg: >-
Successfully configured Tor and set up desktop bookmarks for SecureDrop!
Copy link
Contributor

Choose a reason for hiding this comment

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

so one issue i hit was that my desktop icons didnt show up right away -- i know thats not a new issue and cant find a specific fix online (gnome's refresh alt+f2 --> r) didnt resolve it for me. rebooting did tho. so i dunno if we want to say hey if your icons arent showing up on desktop, please reboot

@conorsch responded in chat: i noticed that too mike, you can quote my observation when you comment on github. my gut tells me there's some handler we can run to refresh the desktop, bu ti don't know what it is

You will see a notification appear on your screen when Tor is ready.

The Journalist Interface's Tor onion URL is: http://{{ journalist_interface_lookup_result.stdout }}
The Source Interfaces's Tor onion URL is: http://{{ source_interface_lookup_result.stdout }}
{% if find_aths_info_result.matched > 1 %}
SSH aliases are set up. You can use them with 'ssh app' and 'ssh mon'.
{% endif %}
7 changes: 5 additions & 2 deletions securedrop-admin
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,11 @@ def install_securedrop(args):

def run_tails_config(args):
"""Configure Tails environment post SD install"""
subprocess.check_call(['sudo',
os.path.join(SD_DIR, 'tails_files/install.sh')])
activate_venv()
subprocess.check_call([os.path.join(ANSIBLE_PATH, 'securedrop-tails.yml'),
Copy link

Choose a reason for hiding this comment

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

shouldn't there be an ['ansible'... before os.path.join ? Or is there some magic making the .yml executable ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

Nice :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm actually not much of a fan of the executable playbook pragma, simply because it's not common in the Ansible community. Added it here to be consistent with the tooling changes as of #1781.

"--ask-become-pass",
],
cwd=ANSIBLE_PATH)


if __name__ == "__main__":
Expand Down
3 changes: 0 additions & 3 deletions tails_files/README.md

This file was deleted.

Loading