diff --git a/install_files/ansible-base/roles/restore/tasks/cleanup_v2.yml b/install_files/ansible-base/roles/restore/tasks/cleanup_v2.yml new file mode 100644 index 0000000000..cd90f5d0e2 --- /dev/null +++ b/install_files/ansible-base/roles/restore/tasks/cleanup_v2.yml @@ -0,0 +1,40 @@ +--- +- name: Copy disable_v2.py script + copy: + src: "{{ role_path }}/files/disable_v2.py" + dest: /opt/disable_v2.py + when: ("V3 services only" in compare_result.stdout) + +- name: Execute disable_v2 script + command: python3 /opt/disable_v2.py /etc/tor/torrc /etc/tor/torrc + when: ("V3 services only" in compare_result.stdout) + +- name: Remove v2 tor source directory + file: + state: absent + path: /var/lib/tor/services/source + when: ("V3 services only" in compare_result.stdout) + +- name: Remove v2 tor journalist directory + file: + state: absent + path: /var/lib/tor/services/journalist + when: ("V3 services only" in compare_result.stdout) + +- name: Remove v2 tor ssh directory + file: + state: absent + path: /var/lib/tor/services/ssh + when: ("V3 services only" in compare_result.stdout) + +- name: Remove v2 source_url application file + file: + state: absent + path: /var/lib/securedrop/source_v2_url + when: ("V3 services only" in compare_result.stdout) + +- name: Remove disable_v2.py script + file: + state: absent + path: /opt/disable_v2.py + when: ("V3 services only" in compare_result.stdout) diff --git a/install_files/ansible-base/roles/restore/tasks/main.yml b/install_files/ansible-base/roles/restore/tasks/main.yml index 3cd847b6de..a6e3eb89fe 100644 --- a/install_files/ansible-base/roles/restore/tasks/main.yml +++ b/install_files/ansible-base/roles/restore/tasks/main.yml @@ -1,159 +1,11 @@ --- -- name: Create temporary directory for Tor configuration check - connection: local - become: no - tempfile: - state: directory - register: torrc_check_dir +- name: Apply backup to Application Server + include: perform_restore.yml -- 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 }}" - extra_opts: - - "etc/tor/torrc" - -- 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 }}" - ignore_errors: yes - register: compare_result - -- name: Remove temporary directory for Tor configuration check - connection: local - become: no - file: - path: "{{ torrc_check_dir.path }}" - state: absent - when: torrc_check_dir.path is defined - -- name: Verify that the backup Tor config is compatible with the server Tor config - assert: - that: - - "'Valid configuration' in compare_result.stdout" - fail_msg: - - "This backup's tor configuration cannot be applied on this server." - - "A data-only restore can be applied using the --preserve-tor-config argument" - - "More info: {{ compare_result.stdout }}" +- name: Remove deprecated v2 onion service configuration + include: cleanup_v2.yml when: not restore_skip_tor -- 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}}" - when: (not restore_skip_tor) and - ("V3 services only" not in compare_result.stdout) - -- name: Extract backup, using v3 services only - unarchive: - dest: / - remote_src: yes - src: "/tmp/{{ restore_file}}" - exclude: "var/lib/tor/services/source,var/lib/tor/services/journalist,var/lib/tor/services/ssh" - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Extract backup, skipping tor service configuration - unarchive: - dest: / - remote_src: yes - src: "/tmp/{{ restore_file}}" - exclude: "var/lib/tor,etc/tor/torrc" - when: restore_skip_tor - -- 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: Copy disable_v2.py script - copy: - src: "{{ role_path }}/files/disable_v2.py" - dest: /opt/disable_v2.py - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Execute disable_v2 script - command: python3 /opt/disable_v2.py /etc/tor/torrc /etc/tor/torrc - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Remove v2 tor source directory - file: - state: absent - path: /var/lib/tor/services/source - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Remove v2 tor journalist directory - file: - state: absent - path: /var/lib/tor/services/journalist - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Remove v2 tor ssh directory - file: - state: absent - path: /var/lib/tor/services/ssh - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Remove v2 source_url application file - file: - state: absent - path: /var/lib/securedrop/source_v2_url - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- name: Remove disable_v2.py script - file: - state: absent - path: /opt/disable_v2.py - when: (not restore_skip_tor) and - ("V3 services only" in compare_result.stdout) - -- 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 +- name: Restart Tor + include: update_tor.yml + when: not restore_skip_tor diff --git a/install_files/ansible-base/roles/restore/tasks/perform_restore.yml b/install_files/ansible-base/roles/restore/tasks/perform_restore.yml new file mode 100644 index 0000000000..2da23dca7d --- /dev/null +++ b/install_files/ansible-base/roles/restore/tasks/perform_restore.yml @@ -0,0 +1,102 @@ +--- +- 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 }}" + extra_opts: + - "etc/tor/torrc" + +- 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 }}" + ignore_errors: yes + register: compare_result + +- name: Remove temporary directory for Tor configuration check + connection: local + become: no + file: + path: "{{ torrc_check_dir.path }}" + state: absent + when: torrc_check_dir.path is defined + +- name: Verify that the backup Tor config is compatible with the server Tor config + assert: + that: + - "'Valid configuration' in compare_result.stdout" + fail_msg: + - "This backup's tor configuration cannot be applied on this server." + - "A data-only restore can be applied using the --preserve-tor-config argument" + - "More info: {{ compare_result.stdout }}" + when: not restore_skip_tor + +- 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}}" + exclude: + - "var/lib/tor/services/ssh" + - "var/lib/tor/services/sshv3" + when: (not restore_skip_tor) and + ("V3 services only" not in compare_result.stdout) + +- name: Extract backup, using v3 services only + unarchive: + dest: / + remote_src: yes + src: "/tmp/{{ restore_file}}" + exclude: + - "var/lib/tor/services/source,var/lib/tor/services/journalist" + - "var/lib/tor/services/ssh" + - "var/lib/tor/services/sshv3" + when: (not restore_skip_tor) and + ("V3 services only" in compare_result.stdout) + +- name: Extract backup, skipping tor service configuration + unarchive: + dest: / + remote_src: yes + src: "/tmp/{{ restore_file}}" + exclude: "var/lib/tor,etc/tor/torrc" + when: restore_skip_tor + +- 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 diff --git a/install_files/ansible-base/roles/restore/tasks/update_tor.yml b/install_files/ansible-base/roles/restore/tasks/update_tor.yml new file mode 100644 index 0000000000..9d24c23363 --- /dev/null +++ b/install_files/ansible-base/roles/restore/tasks/update_tor.yml @@ -0,0 +1,16 @@ +--- +- 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