-
Notifications
You must be signed in to change notification settings - Fork 689
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4814 from freedomofpress/backport-4801
[1.0.0] backport #4801 Rework Ansible restore role to detect Onion service version mismatch
- Loading branch information
Showing
4 changed files
with
148 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
install_files/ansible-base/roles/restore/files/compare_torrc.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python | ||
|
||
# | ||
# Compares Tor configurations on the app server and from a backup. If | ||
# restoring the backup would alter the server's Tor configuration, | ||
# print a warning and exit. | ||
# | ||
|
||
from __future__ import print_function | ||
|
||
import os | ||
import re | ||
import sys | ||
|
||
|
||
def get_tor_versions(path): | ||
""" | ||
Determine which service versions are offered in the given torrc. | ||
""" | ||
service_re = re.compile(r"HiddenServiceDir\s+(?:.*)/(.*)") | ||
versions = set([]) | ||
with open(path) as f: | ||
for line in f: | ||
m = service_re.match(line) | ||
if m: | ||
service = m.group(1) | ||
if "v3" in service: | ||
versions.add(3) | ||
else: | ||
versions.add(2) | ||
|
||
return versions | ||
|
||
|
||
def strset(s): | ||
""" | ||
Sort the given set and join members with "and". | ||
""" | ||
return " and ".join(str(v) for v in sorted(s)) | ||
|
||
|
||
if __name__ == "__main__": | ||
tempdir = sys.argv[1] | ||
|
||
server_versions = get_tor_versions(os.path.join(tempdir, "app/etc/tor/torrc")) | ||
backup_versions = get_tor_versions(os.path.join(tempdir, "backup/etc/tor/torrc")) | ||
|
||
if server_versions == backup_versions: | ||
print("The Tor configuration in the backup matches the server.") | ||
sys.exit(0) | ||
|
||
print( | ||
"The Tor configuration on the app server offers version {} services.".format( | ||
strset(server_versions) | ||
) | ||
) | ||
|
||
print( | ||
"The Tor configuration in this backup offers version {} services.".format( | ||
strset(backup_versions) | ||
) | ||
) | ||
|
||
print("\nRestoring a backup with a different Tor configuration than the server ") | ||
print("is currently unsupported. If you require technical assistance, please ") | ||
print("contact the SecureDrop team via the support portal or at ") | ||
print("[email protected].") | ||
|
||
sys.exit(1) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,81 @@ | ||
--- | ||
- name: Copy restore script to Application Server. | ||
copy: | ||
src: restore.py | ||
dest: /tmp/ | ||
owner: root | ||
mode: "0770" | ||
|
||
- name: Copy backup tarball of config info to Application Server. | ||
copy: | ||
- name: Create temporary directory for Tor configuration check | ||
connection: local | ||
become: no | ||
tempfile: | ||
state: directory | ||
register: torrc_check_dir | ||
|
||
- name: Fetch current Tor configuration from app server | ||
become: no | ||
fetch: | ||
src: /etc/tor/torrc | ||
dest: "{{ torrc_check_dir.path }}" | ||
|
||
- name: Create directory to hold the Tor configuration from the backup | ||
connection: local | ||
become: no | ||
file: | ||
path: "{{ torrc_check_dir.path }}/backup" | ||
state: directory | ||
|
||
- name: Extract Tor configuration from backup | ||
connection: local | ||
become: no | ||
unarchive: | ||
dest: "{{ torrc_check_dir.path }}/backup/" | ||
src: "{{ restore_file }}" | ||
dest: /tmp/{{ restore_file }} | ||
extra_opts: | ||
- "etc/tor/torrc" | ||
|
||
- name: Run the restore script (can be slow). | ||
command: /tmp/restore.py /tmp/{{ restore_file }} | ||
async: 3600 | ||
poll: 10 | ||
- name: Check for Tor configuration differences between the backup and server | ||
connection: local | ||
become: no | ||
command: "python {{ role_path }}/files/compare_torrc.py {{ torrc_check_dir.path }}" | ||
|
||
- name: Delete the restore file to save disk space. | ||
- name: Remove temporary directory for Tor configuration check | ||
connection: local | ||
become: no | ||
file: | ||
path: /tmp/{{ restore_file }} | ||
path: "{{ torrc_check_dir.path }}" | ||
state: absent | ||
when: torrc_check_dir.path is defined | ||
|
||
- name: Copy backup to application server | ||
synchronize: | ||
src: "{{ restore_file }}" | ||
dest: /tmp/{{ restore_file }} | ||
partial: yes | ||
|
||
- name: Extract backup | ||
unarchive: | ||
dest: / | ||
remote_src: yes | ||
src: "/tmp/{{ restore_file}}" | ||
|
||
- name: Reconfigure securedrop-app-code | ||
command: dpkg-reconfigure securedrop-app-code | ||
|
||
- name: Reconfigure securedrop-config | ||
command: dpkg-reconfigure securedrop-config | ||
|
||
- name: Reload Apache service | ||
service: | ||
name: apache2 | ||
state: reloaded | ||
|
||
- name: Reload Tor service | ||
service: | ||
name: tor | ||
state: reloaded | ||
async: 60 | ||
poll: 0 | ||
register: tor_reload_job | ||
|
||
- name: Wait for Tor reload | ||
async_status: | ||
jid: "{{ tor_reload_job.ansible_job_id }}" | ||
register: tor_reload | ||
until: tor_reload.finished | ||
retries: 6 | ||
delay: 10 |