From 77d2944c9f3475680416bc16db93abe9332f323f Mon Sep 17 00:00:00 2001 From: Pig Monkey Date: Mon, 18 Jan 2016 19:01:05 -0800 Subject: [PATCH] refactor trusted network framework Previously, services would be killed anytime an interface was deactivated, even if another interface was still connected to a trusted network. Now we check all active connections against the trusted list and take the appropriate action. It's also more modular, and allows the user to more easily activate/deactive services directly without stopping/starting networking if for some reason the dispatcher didn't run correctly. --- README.md | 61 +++++++++++-------- roles/backup/tasks/tarsnap.yml | 6 +- .../templates/tarsnapper_dispatcher.sh.j2 | 17 ------ roles/chat/tasks/bitlbee.yml | 4 +- roles/chat/templates/bitlbee_dispatcher.sh.j2 | 17 ------ roles/mail/tasks/mailsync.yml | 6 +- .../mail/templates/mailsync_dispatcher.sh.j2 | 17 ------ roles/network/files/toggle_units.sh | 34 +++++++++++ roles/network/files/trust_dispatcher.sh | 14 +++++ roles/network/tasks/main.yml | 9 +++ 10 files changed, 104 insertions(+), 81 deletions(-) delete mode 100644 roles/backup/templates/tarsnapper_dispatcher.sh.j2 delete mode 100644 roles/chat/templates/bitlbee_dispatcher.sh.j2 delete mode 100644 roles/mail/templates/mailsync_dispatcher.sh.j2 create mode 100755 roles/network/files/toggle_units.sh create mode 100755 roles/network/files/trust_dispatcher.sh diff --git a/README.md b/README.md index 1d6d63c..7cef585 100644 --- a/README.md +++ b/README.md @@ -89,19 +89,27 @@ to `False`. Trusted networks are defined using their NetworkManager UUIDs, configured in the `network.trusted_uuid` list. NetworkManager UUIDs may be discovered using -`nmcli con`. +`nmcli con`. The list of trusted networks is made available at +`/usr/local/etc/trusted_networks`. -The list of trusted networks is made available at -`/usr/local/etc/trusted_networks`. In conjunction with NetworkManager -dispatchers, this list is used to start and stop certain services when -connecting to trusted or untrusted networks. This helps to avoid leaking -personal information on untrusted networks, by ensuring that certain network -tasks are not running in the background. +A list of systemd units which should be enabled when connected to a trusted +network, but disabled when there is no network or any time a connection to an +untrusted network is established, is maintained at +`/usr/local/etc/trusted_units`. A script, `toggle_units` is provided to analyze +the current network connections and toggle the trusted units as appropriate. +Finally, a NetworkManager dispatcher is installed to call this script anytime a +network interface has been activated or deactivated. +This design helps to avoid leaking personal information on untrusted networks, +by ensuring that certain network tasks are not running in the background. Currently, this is implemented for mail syncing (see the section below on Syncing and Scheduling Mail), Tarsnap backups (see the section below on -Scheduling Tarsnap), the git-annex assistant (see the section below on -git-annex), and BitlBee (see the section below on BitlBee). +Scheduling Tarsnap), and BitlBee (see the section below on BitlBee). The +git-annex assistant is also toggled based on the state of the trusted network, +but does not use the same dispatcher or `toggle_units` script as the other +units due to its slightly different requirements (see the section below on +git-annex). + ## Mail @@ -141,10 +149,11 @@ A [systemd timer][15] is also included to periodically call `mailsync`. The timer is set to sync every 10 minutes (configurable through the `mail.sync_time` variable). -The timer is not started or enabled by default. Instead, a NetworkManager -dispatcher is installed, which activates the timer whenever a connection is -established to a trusted network. The timer is stopped when the network goes -down. +The timer is not started or enabled by default. Instead, the timer is added to +`/usr/local/etc/trusted_units`, causing the NetworkManager trusted unit +dispatcher to activate the timer whenever a connection is established to a +trusted network. The timer is stopped whenever the network goes down or a +connection is established to an untrusted network. To have the timer activated at boot, change the `mail.sync_on` variable from `trusted` to `all`. @@ -173,9 +182,10 @@ details. A systemd unit file and timer are included for Tarsnapper. The timer is set to execute Tarsnapper hourly (configurable through the `tarsnapper.timer.schedule` variable). However, as with `mailsync` this timer is not started or enabled by -default. Instead, a NetworkManager dispatcher is installed, which activates the -timer whenever a connection is established to a trusted network. The timer is -stopped when the network goes down. +default. Instead, the timer is added to `/usr/local/etc/trusted_units`, causing +the NetworkManager trusted unit dispatcher to activate the timer whenever a +connection is established to a trusted network. The timer is stopped whenever +the network goes down or a connection is established to an untrusted network. To have the timer activated at boot, change the `tarsnapper.timer.run_on` variable from `trusted` to `all`. @@ -187,9 +197,10 @@ If the `tarsnapper.tarsnap.run_on` variable is set to anything other than [BitlBee][19] and [WeeChat][20] are used to provide chat services. A systemd service unit for BitlBee is installed, but not enabled or started by default. -Instead, a NetworkManager dispatcher is installed, which activates the service -when a connection is established to a trusted network. The service is stopped -when the network goes down. +Instead, the service is added to `/usr/local/etc/trusted_units`, causing the +NetworkManager trusted unit dispatcher to activate the service whenever a +connection is established to a trusted network. The service is stopped whenever +the network goes down or a connection is established to an untrusted network. To have the service activated at boot, change the `bitlbee.run_on` variable from `trusted` to `all`. @@ -207,12 +218,12 @@ NetworkManager dispatchers are installed to stop the service when connecting to untrusted networks. Note that this behaviour is slightly different than that of the NetworkManager -dispatchers included for syncing mail and performing Tarsnap backups. Those -timers are disabled by default, only started *after* a connection to a trusted -network has been established, and immediately stopped after disconnecting from -any network. Conversely, the git-annex assistant is started by default, -stopped *before* connecting to an untrusted network, and immediately started -after disconnecting from any network. +dispatcher used for syncing mail, performing Tarsnap backups, and toggling +BitlBee. Those units are disabled by default, only started *after* a connection +to a trusted network has been established, and immediately stopped after +disconnecting from any network. Conversely, the git-annex assistant is started +by default, stopped *before* connecting to an untrusted network, and +immediately started after disconnecting from any network. If the `gitannex.stopped_on` variable is set to anything other than `untrusted`, the NetworkManager dispatchers will not be installed, resulting in diff --git a/roles/backup/tasks/tarsnap.yml b/roles/backup/tasks/tarsnap.yml index 9cea035..3490a82 100644 --- a/roles/backup/tasks/tarsnap.yml +++ b/roles/backup/tasks/tarsnap.yml @@ -61,8 +61,10 @@ tags: - tarsnap -- name: Push dispatcher to activate Tarsnapper timer on trusted networks - template: src=tarsnapper_dispatcher.sh.j2 dest=/etc/NetworkManager/dispatcher.d/10tarsnapper mode=0755 +- name: Add tarsnapper to trusted unit list + lineinfile: dest=/usr/local/etc/trusted_units + state=present + line=tarsnapper.timer when: tarsnapper.timer.run_on == "trusted" tags: - tarsnap diff --git a/roles/backup/templates/tarsnapper_dispatcher.sh.j2 b/roles/backup/templates/tarsnapper_dispatcher.sh.j2 deleted file mode 100644 index 4370053..0000000 --- a/roles/backup/templates/tarsnapper_dispatcher.sh.j2 +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# {{ ansible_managed }} - -action="$2" - -case $action in - up) - if grep -q \^$CONNECTION_UUID\$ /usr/local/etc/trusted_networks; then - systemctl start tarsnapper.timer - fi - ;; - down) - systemctl stop tarsnapper.timer - ;; -esac - -exit 0 diff --git a/roles/chat/tasks/bitlbee.yml b/roles/chat/tasks/bitlbee.yml index 0cb014e..ad07c71 100644 --- a/roles/chat/tasks/bitlbee.yml +++ b/roles/chat/tasks/bitlbee.yml @@ -38,7 +38,9 @@ - bitlbee - name: Push dispatcher to activate Bitlbee on trusted networks - template: src=bitlbee_dispatcher.sh.j2 dest=/etc/NetworkManager/dispatcher.d/10bitlbee mode=0755 + lineinfile: dest=/usr/local/etc/trusted_units + state=present + line=bitlbee.service when: bitlbee.run_on == "trusted" tags: - bitlbee diff --git a/roles/chat/templates/bitlbee_dispatcher.sh.j2 b/roles/chat/templates/bitlbee_dispatcher.sh.j2 deleted file mode 100644 index e825db7..0000000 --- a/roles/chat/templates/bitlbee_dispatcher.sh.j2 +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# {{ ansible_managed }} - -action="$2" - -case $action in - up) - if grep -q \^$CONNECTION_UUID\$ /usr/local/etc/trusted_networks; then - systemctl start bitlbee.service - fi - ;; - down) - systemctl stop bitlbee.service - ;; -esac - -exit 0 diff --git a/roles/mail/tasks/mailsync.yml b/roles/mail/tasks/mailsync.yml index fb4fbfd..6f62640 100644 --- a/roles/mail/tasks/mailsync.yml +++ b/roles/mail/tasks/mailsync.yml @@ -20,8 +20,10 @@ tags: - mailsync -- name: Push dispatcher to activate mailsync timer on trusted networks - template: src=mailsync_dispatcher.sh.j2 dest=/etc/NetworkManager/dispatcher.d/10mailsync mode=0755 +- name: Add mailsync to trusted unit list + lineinfile: dest=/usr/local/etc/trusted_units + state=present + line="mailsync@{{ user.name }}.timer" when: mail.sync_on == "trusted" tags: - mailsync diff --git a/roles/mail/templates/mailsync_dispatcher.sh.j2 b/roles/mail/templates/mailsync_dispatcher.sh.j2 deleted file mode 100644 index 16a0c6c..0000000 --- a/roles/mail/templates/mailsync_dispatcher.sh.j2 +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# {{ ansible_managed }} - -action="$2" - -case $action in - up) - if grep -q \^$CONNECTION_UUID\$ /usr/local/etc/trusted_networks; then - systemctl start mailsync@{{ user.name }}.timer - fi - ;; - down) - systemctl stop mailsync@{{ user.name }}.timer - ;; -esac - -exit 0 diff --git a/roles/network/files/toggle_units.sh b/roles/network/files/toggle_units.sh new file mode 100755 index 0000000..6833b9a --- /dev/null +++ b/roles/network/files/toggle_units.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +start() { + echo "starting all the things" + systemctl start $(cat /usr/local/etc/trusted_units) + exit $? +} + +stop() { + echo "stopping all the things" + systemctl stop $(cat /usr/local/etc/trusted_units) + exit $? +} + +# Get all active connections. +connections=($(nmcli --terse -f uuid conn show --active)) + +# If there are no active connections, the trusted units should be stopped. +if [ ${#connections[@]} -eq 0 ]; then + echo "there are no active connections" + stop +# If there are active connections, and any of them are untrusted, the +# trusted units should be stopped. +else + for uuid in "${connections[@]}"; do + grep -q \^"$uuid"\$ /usr/local/etc/trusted_networks + if [ "$?" -ne 0 ]; then + echo "$uuid is untrusted" + stop + fi + done +fi +# If we're still here, the trusted units should be started +start diff --git a/roles/network/files/trust_dispatcher.sh b/roles/network/files/trust_dispatcher.sh new file mode 100755 index 0000000..2563fa4 --- /dev/null +++ b/roles/network/files/trust_dispatcher.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +action="$2" + +case $action in + up) + /usr/local/bin/toggle_units + ;; + down) + /usr/local/bin/toggle_units + ;; +esac + +exit $? diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml index 5131880..e05e32e 100644 --- a/roles/network/tasks/main.yml +++ b/roles/network/tasks/main.yml @@ -2,6 +2,15 @@ - name: Push trusted network list template: src=trusted_networks.j2 dest=/usr/local/etc/trusted_networks +- name: Verify trusted unit list exists + file: path=/usr/local/etc/trusted_units state=touch + +- name: Push trusted unit toggler + copy: src=toggle_units.sh dest=/usr/local/bin/toggle_units mode=0755 + +- name: Push network trust dispatcher + copy: src=trust_dispatcher.sh dest=/etc/NetworkManager/dispatcher.d/10trust mode=0755 + - name: Install OpenVPN pacman: name=openvpn state=present