Skip to content

Commit

Permalink
Provide unattended-upgrades configuration via apt package
Browse files Browse the repository at this point in the history
securedrop-config package will provide the configuration for focal only
  • Loading branch information
emkll committed Jan 21, 2021
1 parent 37cf001 commit 6d1d194
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ip_info:
### Used by the install_local_deb_pkgs role ###
local_deb_packages:
- "securedrop-keyring-0.1.4+{{ securedrop_app_code_version }}-amd64.deb"
- "securedrop-config-0.1.3+{{ securedrop_app_code_version }}-amd64.deb"
- "securedrop-config-0.1.3+{{ securedrop_app_code_version }}{{ '+focal' if securedrop_staging_install_target_distro|default('') == 'focal' else '' }}-amd64.deb"
- "securedrop-ossec-agent-3.6.0+{{ securedrop_app_code_version }}-amd64.deb"
- "{{ securedrop_app_code_deb }}.deb"
- "ossec-agent-3.6.0-amd64.deb"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ip_info:
### Used by the install_local_deb_pkgs role ###
local_deb_packages:
- "securedrop-keyring-0.1.4+{{ securedrop_app_code_version }}-amd64.deb"
- "securedrop-config-0.1.3+{{ securedrop_app_code_version }}-amd64.deb"
- "securedrop-config-0.1.3+{{ securedrop_app_code_version }}{{ '+focal' if securedrop_staging_install_target_distro|default('') == 'focal' else '' }}-amd64.deb"
- "securedrop-ossec-server-3.6.0+{{ securedrop_app_code_version }}-amd64.deb"
- ossec-server-3.6.0-amd64.deb

Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,14 @@
---
- name: Install unattended-upgrades package and update-notifier-common
apt:
name: "{{ item }}"
state: present
update_cache: yes
with_items:
- unattended-upgrades
- update-notifier-common
tags:
- apt
- unattended-upgrades
# Configuration for unattended upgrades is almost exclusively managed by the
# securedrop-config package under Focal.

- name: Configure unattended-upgrades to update the packages from sources.list.
copy:
src: 20auto-upgrades
dest: /etc/apt/apt.conf.d/20auto-upgrades
mode: 0644
owner: root
group: root
tags:
- apt
- unattended-upgrades

- name: Configure unattended-upgrades to update the packages from sources.list.
- name: Configure unattended-upgrades to reboot daily at the scheduled time.
template:
src: 50unattended-upgrades.j2
dest: /etc/apt/apt.conf.d/50unattended-upgrades
src: 80securedrop.j2
dest: /etc/apt/apt.conf.d/80securedrop
mode: 0644
owner: root
group: root
tags:
- apt
- unattended-upgrades

- name: Add cron job to indicate to unattended-upgrades that a reboot is required.
cron:
name: Indicate that a reboot is required at the scheduled time.
job: "touch /var/run/reboot-required"
hour: "*/12"
tags:
- cron
- unatted-upgrades
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "{{ daily_reboot_time }}:00";
11 changes: 11 additions & 0 deletions install_files/securedrop-config-focal/DEBIAN/control.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Source: securedrop
Section: web
Priority: optional
Maintainer: SecureDrop Team <securedrop@freedom.press>
Homepage: https://securedrop.org
Package: securedrop-config
Version: 0.1.3+1.7.0~rc1+{{ ansible_distribution_release }}
Depends: unattended-upgrades,update-notifier-common
Architecture: all
Description: Establishes baseline system state for running SecureDrop.
Configures apt repositories.
24 changes: 24 additions & 0 deletions install_files/securedrop-config-focal/DEBIAN/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh
# postinst script for securedrop-config-focal

set -e
set -x

case "$1" in
configure)
# Configuration required for unattended-upgrades
cp /opt/securedrop/20auto-upgrades /etc/apt/apt.conf.d/
cp /opt/securedrop/50unattended-upgrades /etc/apt/apt.conf.d/
cp /opt/securedrop/reboot-flag /etc/cron.d/

;;
abort-upgrade|abort-remove|abort-deconfigure)
;;

*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac

exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[[ $- != *i* ]] && return

which tmux >/dev/null 2>&1 || return

tmux_attach_via_proc() {
# If the tmux package is upgraded during the lifetime of a
# session, attaching with the new binary can fail due to different
# protocol versions. This function attaches using the reference to
# the old executable found in the /proc tree of an existing
# session.
pid=$(pgrep --newest tmux)
if test -n "$pid"
then
/proc/$pid/exe attach
fi
return 1
}

if test -z "$TMUX"
then
(tmux attach || tmux_attach_via_proc || tmux new-session)
fi
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ Unattended-Upgrade::Automatic-Reboot "true";
// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "{{ daily_reboot_time }}:00";
// This is set in a template in the common role under the file 80securedrop

// Automatically reboot even if there are users currently logged in
// when Unattended-Upgrade::Automatic-Reboot is set to true
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";

// Use apt bandwidth limit feature, this example limits the download
// speed to 70kb/sec
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The purpose of this cron is to drop the reboot-required flag every 12 hours
# to ensure the system is rebooted nightly, regardless of updates being installed
# or not.
* */12 * * * touch /var/run/reboot-required
1 change: 1 addition & 0 deletions molecule/builder-focal/playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
- role: build-generic-pkg
tags: securedrop-config
package_name: securedrop-config
package_dirname: securedrop-config-focal
when: ansible_host.endswith("-sd-config") or ansible_host == "localhost"
tags: rebuild

Expand Down
6 changes: 5 additions & 1 deletion molecule/builder-xenial/tests/test_securedrop_deb_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@ def make_deb_paths() -> Dict[str, Path]:
if SECUREDROP_TARGET_PLATFORM == "focal":
grsec_version = grsec_version+"+focal"

config_version = securedrop_test_vars["config_version"]
if SECUREDROP_TARGET_PLATFORM == "focal":
config_version = config_version+"+focal"

substitutions = dict(
securedrop_version=securedrop_test_vars["securedrop_version"],
ossec_version=securedrop_test_vars["ossec_version"],
keyring_version=securedrop_test_vars["keyring_version"],
config_version=securedrop_test_vars["config_version"],
config_version=config_version,
grsec_version=grsec_version,
securedrop_target_platform=securedrop_test_vars["securedrop_target_platform"],
)
Expand Down
47 changes: 35 additions & 12 deletions molecule/testinfra/common/test_automatic_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,16 @@ def test_cron_apt_delete_vanilla_kernels(host):
"""

f = host.file('/etc/cron-apt/action.d/9-remove')
assert f.is_file
assert f.user == "root"
assert f.mode == 0o644
command = str('remove -y'
' linux-image-generic-lts-xenial linux-image-.*generic'
' -o quiet=2')
assert f.contains('^{}$'.format(command))
if host.system_info.codename == "xenial":
assert f.is_file
assert f.user == "root"
assert f.mode == 0o644
command = str('remove -y'
' linux-image-generic-lts-xenial linux-image-.*generic'
' -o quiet=2')
assert f.contains('^{}$'.format(command))
else:
assert not f.exists


def test_cron_apt_repo_config_upgrade(host):
Expand Down Expand Up @@ -198,6 +201,20 @@ def test_unattended_upgrades_config(host):
assert f.contains("origin=SecureDrop,codename=${distro_codename}")


def test_unattended_securedrop_specific(host):
"""
Ensures the 80securedrop config is correct only under Ubuntu Focal
"""
f = host.file('/etc/apt/apt.conf.d/80securedrop')
if host.system_info.codename == "xenial":
assert not f.exists
else:
assert f.is_file
assert f.user == "root"
assert f.mode == 0o644
assert f.contains("Automatic-Reboot-Time")


@pytest.mark.parametrize('option', [
'APT::Periodic::Update-Package-Lists "1";',
'APT::Periodic::Unattended-Upgrade "1";',
Expand Down Expand Up @@ -244,11 +261,17 @@ def test_reboot_required_cron(host):
Here, we ensure that reboot-required flag is dropped twice daily to ensure the system
is rebooted every day at the scheduled time.
"""
if host.system_info.codename != "xenial":
with host.sudo():
cronlist = host.run("crontab -l").stdout
cronjob = "* */12 * * * touch /var/run/reboot-required"
assert cronjob in cronlist
f = host.file('/etc/cron.d/reboot-flag')

if host.system_info.codename == "xenial":
assert not f.exists
else:
assert f.is_file
assert f.user == "root"
assert f.mode == 0o644

line = '^{}$'.format(re.escape("* */12 * * * touch /var/run/reboot-required"))
assert f.contains(line)


def test_all_packages_updated(host):
Expand Down

0 comments on commit 6d1d194

Please sign in to comment.