Skip to content

Commit

Permalink
Merge pull request #7 from jhampson-dbre/6-harden-ssh
Browse files Browse the repository at this point in the history
Add role to harden os
  • Loading branch information
jhampson-dbre authored Dec 27, 2020
2 parents bdb8884 + 15bb846 commit 739d830
Show file tree
Hide file tree
Showing 10 changed files with 319 additions and 0 deletions.
78 changes: 78 additions & 0 deletions roles/harden_os/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
harden_os
=========

Improve security of Debian 10 OS running Home Assistant Supervised on Raspberry Pi 4

This role can perform the following hardening:

1. Harden SSH

- Disable root SSH login
- Disable SSH password authentication
- Only allow SSH key authentication

1. Enable Automatic Security Updates

- Install and configure unattended-upgrades


Requirements
------------

This role must be ran as the root user or with `become` enabled.

Additional considerations:

- Harden SSH

You should ensure that you have a non-root user with sudo priviledges and an SSH key configured before running this role. This can be completed accomplished by running the `jhampson_dbre.home_assistant.preinstall_config` role that is available in the collection.

- Automatic Security Updates

If automatic reboots are enabled, ensure the time is set correctly on the Raspberry Pi to ensure reboots happen at the expectd time.

Role Variables
--------------

The following variables are set in `defaults/main.yml`

```yaml
# Lock down SSH, including disabling SSH root log in
harden_ssh: true

# Configure automatic installation of security updates
enable_automatic_security_updates: true

## Automatic Security Patching options

# Reboot automatically if reboot is required for installed patches
enable_patching_reboot: "true"

# The time to reboot at if automatic reboot is enabled
patching_reboot_time: "04:00"
```
Dependencies
------------
none
Example Playbook
----------------
```yaml

- hosts: pi
roles:
- role: jhampson_dbre.home_assistant.harden_os
```
License
-------
MIT
Author Information
------------------
@jhampson-dbre
8 changes: 8 additions & 0 deletions roles/harden_os/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Configure which areas to harden
harden_ssh: true
enable_automatic_security_updates: true

# Automatic Security Patching options
enable_patching_reboot: "true"
patching_reboot_time: "04:00"
5 changes: 5 additions & 0 deletions roles/harden_os/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: restart sshd
service:
name: sshd
state: restarted
22 changes: 22 additions & 0 deletions roles/harden_os/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
galaxy_info:
author: Jared Hampson
description: Improve OS security after Home Assistant Suprvised is installed

license: MIT

min_ansible_version: 2.9

platforms:
- name: Debian
versions:
- buster

galaxy_tags:
- home
- assistant
- supervised
- raspberry
- pi
- hassio

dependencies: []
8 changes: 8 additions & 0 deletions roles/harden_os/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: import ssh tasks
import_task: ssh.yml
when: harden_ssh|bool

- name: import patching tasks
import_task: patching.yml
when: enable_automatic_security_updates|bool
24 changes: 24 additions & 0 deletions roles/harden_os/tasks/patching.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- name: install unattended-upgrades package
apt:
name:
- unattended-upgrades
- apt-listchanges
state: present

- name: Ensure the apt auto-upgrades configuration stub is created
shell: >
echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true
| debconf-set-selections
dpkg-reconfigure -f noninteractive unattended-upgrades
args:
warn: no

- name: Configure unattended upgrades
template:
src: 50unattended-upgrades.j2
dest: /etc/apt/apt.conf.d/50unattended-upgrades
owner: root
group: root
mode: '0644'
36 changes: 36 additions & 0 deletions roles/harden_os/tasks/ssh.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
- name: Harden SSH
block:
- name: Disable root SSH login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
state: present
validate: /usr/sbin/sshd -T -f %s

- name: Disable SSH password authentication
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PasswordAuthentication'
line: 'PasswordAuthentication no'
state: present
validate: /usr/sbin/sshd -T -f %s

- name: Enable sandbox for SSH privilege seperation
lineinfile:
path: /etc/ssh/sshd_config
regex: '^UsePrivilegeSeparation'
line: 'UsePrivilegeSeparation sandbox'
state: present
validate: /usr/sbin/sshd -T -f %s

- name: Only allow SSH key authentication
lineinfile:
path: /etc/ssh/sshd_config
regex: '^AuthenticationMethods'
line: 'AuthenticationMethods publickey'
state: present
validate: /usr/sbin/sshd -T -f %s
notify:
- restart sshd
131 changes: 131 additions & 0 deletions roles/harden_os/templates/50unattended-upgrades.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Automatically upgrade packages from these (origin:archive) pairs
//
// Note that in Ubuntu security updates may pull in new dependencies
// from non-security sources (e.g. chromium). By allowing the release
// pocket these get automatically pulled in.
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};

// Python regular expressions, matching packages to exclude from upgrading
Unattended-Upgrade::Package-Blacklist {
// The following matches all packages starting with linux-
// "linux-";

// Use $ to explicitely define the end of a package name. Without
// the $, "libc6" would match all of them.
// "libc6$";
// "libc6-dev$";
// "libc6-i686$";

// Special characters need escaping
// "libstdc\+\+6$";

// The following matches packages like xen-system-amd64, xen-utils-4.1,
// xenstore-utils and libxenstore3.0
// "(lib)?xen(store)?";

// For more information about Python regular expressions, see
// https://docs.python.org/3/howto/regex.html
};

// This option controls whether the development release of Ubuntu will be
// upgraded automatically. Valid values are "true", "false", and "auto".
Unattended-Upgrade::DevRelease "false";

// This option allows you to control if on a unclean dpkg exit
// unattended-upgrades will automatically run
// dpkg --force-confold --configure -a
// The default is true, to ensure updates keep getting installed
//Unattended-Upgrade::AutoFixInterruptedDpkg "true";

// Split the upgrade into the smallest possible chunks so that
// they can be interrupted with SIGTERM. This makes the upgrade
// a bit slower but it has the benefit that shutdown while a upgrade
// is running is possible (with a small delay)
//Unattended-Upgrade::MinimalSteps "true";

// Install all updates when the machine is shutting down
// instead of doing it in the background while the machine is running.
// This will (obviously) make shutdown slower.
// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
// This allows more time for unattended-upgrades to shut down gracefully
// or even install a few packages in InstallOnShutdown mode, but is still a
// big step back from the 30 minutes allowed for InstallOnShutdown previously.
// Users enabling InstallOnShutdown mode are advised to increase
// InhibitDelayMaxSec even further, possibly to 30 minutes.
//Unattended-Upgrade::InstallOnShutdown "false";

// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "[email protected]"
//Unattended-Upgrade::Mail "";

// Set this value to one of:
// "always", "only-on-error" or "on-change"
// If this is not set, then any legacy MailOnlyOnError (boolean) value
// is used to chose between "only-on-error" and "on-change"
//Unattended-Upgrade::MailReport "on-change";

// Remove unused automatically installed kernel-related packages
// (kernel images, kernel headers and kernel version locked tools).
//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

// Do automatic removal of newly unused dependencies after the upgrade
//Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

// Do automatic removal of unused packages after the upgrade
// (equivalent to apt-get autoremove)
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// Automatically reboot *WITHOUT CONFIRMATION* if
// the file /var/run/reboot-required is found after the upgrade
Unattended-Upgrade::Automatic-Reboot "{{ patching_reboot_enabled }}";

// 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";

// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "{{ patching_reboot_time }}";

// Use apt bandwidth limit feature, this example limits the download
// speed to 70kb/sec
//Acquire::http::Dl-Limit "70";

// Enable logging to syslog. Default is False
// Unattended-Upgrade::SyslogEnable "false";

// Specify syslog facility. Default is daemon
// Unattended-Upgrade::SyslogFacility "daemon";

// Download and install upgrades only on AC power
// (i.e. skip or gracefully stop updates on battery)
// Unattended-Upgrade::OnlyOnACPower "true";

// Download and install upgrades only on non-metered connection
// (i.e. skip or gracefully stop updates on a metered connection)
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";

// Verbose logging
// Unattended-Upgrade::Verbose "false";

// Print debugging information both in unattended-upgrades and
// in unattended-upgrade-shutdown
// Unattended-Upgrade::Debug "false";

// Allow package downgrade if Pin-Priority exceeds 1000
// Unattended-Upgrade::Allow-downgrade "false";
2 changes: 2 additions & 0 deletions roles/harden_os/tests/inventory
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
localhost

5 changes: 5 additions & 0 deletions roles/harden_os/tests/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- hosts: localhost
remote_user: root
roles:
- harden_os

0 comments on commit 739d830

Please sign in to comment.