Skip to content
Snippets Groups Projects
Commit c7697591 authored by Martyn Welch's avatar Martyn Welch Committed by Martyn Welch
Browse files

Document hardening techniques


It is frequently important for device manufacturers to harden the devices that
they produce, in order to ensure that their devices continue to comply with
required regulations and protect against compromise by malicious third parties.

Provide documentation highlighting techniques that can be used to harden an
Apertis based device.

Update dictionary to include words and acronyms wrongly picked up as spelling
mistakes.

Signed-off-by: default avatarMartyn Welch <martyn.welch@collabora.com>
parent 206c821a
No related branches found
No related tags found
1 merge request!245Document hardening techniques
Pipeline #256365 passed
+++
title = "Device Hardening"
date = "2021-05-28"
weight = 100
+++
Apertis reference implementation provides packages and images geared towards
development, allowing more flexibility than actual products. This guidance is
targeted towards teams building products with Apertis to aid them with
"hardening" the general-purpose development Apertis image/packages to reduce
the attack surface on products. This document also lightly touches on measures
that can be taken to physically harden a device.
The procedures detailed below reduce the attack surface of the Apertis image
and in some cases will provide improvements to other facets such as storage
optimization and boot performance which are also likely to be important to
product teams.
# General Principles
The aim with hardening is to close off any avenues that may be used to alter
the operation of the device, be that with or without the knowledge and consent
of its owner. This may take the form of malicious hacking by a third party
with the aim of extracting something from the owner or the owner trying to
modify the device to operate in ways that it wasn't designed to and which may
violate legally enforced regulations. In essence this is done by removing or
disabling any functionality that isn't critical to the operation of the device.
{{% notice info %}}
Many of the techniques highlighted below will require thought to be given
during device design. We thus advise that security be considered from early on
and not left too late in the design process, when a lot of the techniques may
not be able to be applied without significant effort and changes to the devices
design.
{{% /notice %}}
During early development of Apertis, research was carried out looking at the
various
[threat models]({{< ref "security.md#security-boundaries-and-threat-model" >}})
which may apply to Apertis, the security solutions adopted by popular platforms
and recommendations of how best to approach this in Apertis.
# Physical security
An adventurous user will not be stopped by "warranty void if broken" stickers
and security or obscure headed screws. Depending on your threat models, it may
be necessary to:
- Ensure the hardware provides functionality to securely store cryptographic.
Many ARM SoCs will have such functionality built in, on x86 systems design in
a TPM chip.
- Don't expose unneeded ports and buses as these might be usable as part of a
compromise.
- Don't route out a serial port for use as a debug interface on the finally
release of the PCB. As this is likely to be very useful for an attacker
trying to break into the device.
- Ball grid array (BGA) Flash parts make it harder to short pins to
block/corrupt reading of the flash. This is a common technique for forcing a
device into a debug mode.
- Ensure the bootstrapping configuration of the SoC is provided and stops
fallback to boot options such as network/USB boot if supported by the
hardware. This can enable the user to provide alternative boot firmware.
- Ensure any One Time Programmable (OTP) Fuses that may be available to limit
boot options and debugging interfaces (such as JTAG) are blown prior to
shipping device.
# Boot Firmware
The boot firmware covers the software that runs after boot and is responsible
for initial hardware configuration and loading the Linux kernel. This is
typically UEFI on x86-based systems and U-Boot on ARM and other architectures.
The boot process needs to be guarded against tampering. The ability for a user
to compromise the boot process would potentially allow them to modify it and
thus gain unwanted access to the device.
Certain common steps can be taken:
- Disable any alternative boot mechanisms to avoid these being used.
- Remove/disable functionality providing interactive control.
- Enable functionality to only run signed binaries.
## ARM Based Systems
There are a large number of boot firmwares available for ARM based systems, but
in Apertis we standardize on U-Boot where possible and hence will discuss that
here.
U-Boot provides an interactive command-line interface enabled. This opens the
door for attacks, such as like with the
[Depthcharge tool](https://research.nccgroup.com/2020/07/22/depthcharge/). The
command-line interface can be disabled by ensuring that the `CONFIG_CMDLINE`
option is not enabled in the U-Boot configuration.
If fully disabling the command-line interface is undesirable and even when
disabling it, consider minimizing the functionality provided by the U-Boot
build to just those that are required to boot the expected configuration. This
reduces the commands that can be leveraged to alter the boot process.
U-Boot can store environment variables in a number of places to allow these to
be changed and saved for later boots. This ability should be disabled with
default environment variables provided by the U-Boot binary to avoid
alterations by attackers.
Likewise, U-Boot can utilize boot scripts or configuration stored on the root
file system to determine how to boot the system, with scanning being performed
to find such scripts or configuration. We advise disabling the ability to boot
using boot scripts, though we suggest that the
[EXTLINUX configuration](https://github.com/u-boot/u-boot/blob/master/doc/README.distro)
should still be used (as this allows for clean separation between kernel and
firmware packaging, with the configuration needed to boot a specific kernel
being provided in the kernel package). The locations scanned for the EXTLINUX
configuration should be tightly controlled to avoid attackers being able to
force the device to boot from alternative locations, such as removable media.
[Secure boot]({{< ref "secure-boot.md" >}}) can be implemented in order to
ensure only the expected binaries are booted. This requires the binaries booted
by the system to be cryptographically signed with a private key that
corresponds to a public key that is securely stored on the device so that it
can't be changed. This functionality is implemented differently by different
ARM vendors and is sometimes known by different names, for example it is known
as High Assurance Boot (HAB) on NXP i.MX processors.
## Intel/x86 Based Systems
Most x86 based systems now utilize UEFI. Such systems:
- Should have the UEFI Shell disabled.
- Consider configuring the device to use Secure Boot so that it will only boot
correctly signed binaries.
# Kernel Hardening
A first step in hardening the Linux kernel is to evaluate the drivers and
features that are enabled (including as modules) and tailor the kernel
configuration to build just what is needed by the device. This reduces or
removes the ability for an attacker to connect extra hardware that could
provide extra unintended access (such as USB network devices that may enable
extra binaries to be uploaded). There are also many features that the kernel
may have enabled to support various workloads, but present a minor security
risk which can be closed if these features are not required. As an added
advantage, disabling unrequired options may make the kernel boot faster (less
to load into memory if nothing else) and will require less storage space.
Beyond this, the kernel provides many configuration settings that can be used
to harden it, protecting against certain attack vectors. Many of these are
detailed as part of the
[Kernel Self Protection Project](https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project/Recommended_Settings),
with further options detailed by the
[kconfig-hardened-check](https://github.com/a13xp0p0v/kconfig-hardened-check/)
tool.
{{% notice warning %}}
Effort should be taken to understand the impact that disabling features or
enabling security features will have on your use case. Many of the security
features will incur runtime overhead and some options that these tools suggest
to be disabled may be required for certain use cases. The device will need to
be tested and characterized after any changes are made to ensure that the
device still performs as expected.
{{% /notice %}}
# Minimize Software
Most if not all software contains bugs, with an industry average of 15 to 50
errors per 1000 lines of code. These bugs typically don't become apparent
during "normal" usage, hence why they manage to escape any testing that is
performed, but can prove to be exploitable by someone looking for ways to break
into a device, by using the code outside of it's normal parameters.
In order to reduce the number of opportunities, it is advisable to minimize the
software installed on a device to that which is necessary.
# Minimize Application Privileges
Some of the software installed on a device may have bugs that can be used to
cause it to perform actions it wouldn't normally perform or for someone that
wouldn't normally perform them for. This is especially problematic where
applications have been given increased privileges, such as being configured to
run with root privileges or being given certain
[capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html), thus
enabling privilege escalation.
This can be mitigated to some degree by not running applications as root and
thus it is advised to not run software as root unless absolutely necessary.
Finer grained privileges can be given to applications via Linux
[capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html),
control of these capabilities can be
[enforced via the systemd](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Capabilities),
specifically the `CapabilityBoundingSet=` and `AmbientCapabilities=` options.
This can sometimes be further enhanced by splitting out privileged
functionality to system services and using
[D-Bus]({{< ref "d-bus_services.md" >}}) to communicate between the privileged
system service and unprivileged user application.
# Authentication
It is important that authentication used to identify the device and users of
the device are kept secret. A need to authenticate may be present in many
aspects of an Apertis based device:
- To authenticate users of the device
- Gaining access to protected download services
- Using online services associated with the device
- Accessing encrypted storage provided by the device
- Signing of binaries as part of trusted boot
These features may have been implemented in Apertis as part of a demo provided
by Apertis and thus will have been signed using a key or password provided for
the purposes of demonstrating the functionality. Such credentials should be
changed to custom values.
Default passwords associated with the device should be unique to each unit
produced and not shared between all units. Such passwords are typically easily
found in the device literature (such as the common "admin, admin" username and
password combination), frequently don't get changed by most users and
this results in lots of devices being let running with poor security. It is far
better to implement better security from the outset.
Where keys need to be stored on the device for authentication with remote
services, these should be stored securely on the device, not hard coded into
the application or left on storage that could become accessible when the device
is attacked. This can be
[encrypting data stored on the device]({{< ref "security.md#data-encryption" >}}),
or more rigorously by using a
[Trusted Execution Environment]({{< ref "op-tee.md" >}}).
Finally, it is not expected that Apertis powered devices will require users to
access the root account. The reference images rely on `sudo` for access to a a
privileged state and thus the root password is locked (the root password field
contains the invalid password `*`, ensuring no one can login using root
directly using a password).
# System-wide Configuration
- Don't leave a terminal available on a serial port, even if this is a hidden
debug port. These can end up providing a way to access the device.
# Storage
Storing user data unencrypted on a device leaves such data open to being
extracted. If sensitive data is expected to be data stored on the device, it is
advised that this data is stored on an
[encrypted partition]({{< ref "security.md#data-encryption-and-removal" >}}).
Unless necessary, disable automounting of USB storage, if this is necessary
(such as part of an offline update mechanism) perform plenty of validation on
the USB storage before trusting anything found on it.
# User setup
- Ensure use of strong user passwords where relevant, the `pam_cracklib.so`
module can be used in the PAM configuration to enforce password requirements.
- If multiple users are expected to use the device, consider the guidance on
[multi-user setups]({{< ref "multiuser.md" >}}).
- Ensure that
[Discretionary Access Control]({{< ref "security.md#mandatory-access-control" >}})
(DAC) is properly configured so that users can't access each others home
directories.
# Sandboxing applications and services
Sandboxing utilizes the features provided by Linux to isolate applications and
services from each other, allowing configuration to be provided to restrict
access by a process to parts of the system or restricting access to only
predefined parts. This reduces the impact that a compromised application or
service can have on the running of the system as a whole.
Apertis provides 2 complementary tools that can be used to configure such
sandboxing:
- Applications can be restricted via the use of
[AppArmor profiles]({{< ref "apparmor.md" >}}), a form of
[Mandatory Access Control]({{< ref "security.md#mandatory-access-control" >}}),
enabling access from specific processes to files, sockets, d-bus
communication and IPC to be restricted.
- systemd provides
[sandboxing functionality](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing)
which can be used to alter the environment in which the process is run.
# Network and firewalls
A network interface provides a potentially large attack surface for an
attacker, it can also prove useful to an attacker even if it's not the primary
route used to access the device. There are a number of measures that can be
taken to protect such interfaces when they form part of the devices
functionality:
- Ensure there are not remote access services running that don't need to be
provided (such as telnet, rlogin, sshd, etc).
- Do not use remote services that require the use of plain text passwords (such
as telnet and ftp).
- Ensure that the network is well firewalled using iptables rules. This should
be done for both the ingress and [egress]({{< ref "egress_filtering.md" >}})
of data to both protect the device and ensure that data from the device can't
be sent back to the attacker should it be compromised.
- Ensure that communications with network services are encrypted to reduce the
risk of leaking sensitive information and to provide authentication between
the device and the service.
# Upgrades
Upgrades should have their authenticity verified before being installed to
guard against attackers crafting modified updates. This is handled as part of
the Apertis [encrypted updates]({{< ref "encrypted-updates.md" >}}) support.
If rollback support is provided, to return to a known working state should an
update seem to fail, logic should be employed to stop rollbacks from being
forced once the update has been marked as successful to stop
[downgrade attacks](https://en.wikipedia.org/wiki/Downgrade_attack). This is
provided by the Apertis [OSTree updates and rollback]({{< ref "ostree.md" >}})
support.
Ensure that devices regularly check for new updates, with either updates being
applied automatically or notify the user of the availability of new updates.
personal_ws-1.1 en 83 utf-8
personal_ws-1.1 en 112 utf-8
ARMv
ATF
Apertis
AppArmor
BGA
CPUs
Collabora
CVE
CVEs
Collabora
DAC
Debos
Depthcharge
EXTLINUX
Flatpak
Flatpaks
GPL
GitLab
GlobalPlatform
HAB
HMI
HTML
HiKey
IPAs
IPC
ISA
JTAG
KVM
LFS
LXC
MAC
MX
NXP
OSTree
OTA
OTP
OpenSSL
PDF
PDFs
......@@ -38,12 +46,15 @@ Rockchip
SDK
SMC
SSD
Sandboxing
SoC
SoCs
TAs
TEE
TEEs
TPM
TrustZone
UEFI
UI
UUID
VM
......@@ -53,6 +64,7 @@ WIP
Xen
YAML
architected
automounting
backport
backported
bootloader
......@@ -62,6 +74,7 @@ chroot
chroots
coprocessor
cryptographic
cryptographically
decrypt
deduplicate
deduplicated
......@@ -70,8 +83,11 @@ deployable
devkit
dockerized
downstreams
firewalled
firmwares
globbing
hotfix
iptables
namespace
natively
ospack
......@@ -81,11 +97,15 @@ proxying
rebase
reproducibility
runtime
sandboxing
shortcode
snapshotted
snapshotting
submitters
systemd
topologies
unencrypted
unrequired
untrusted
upstreamed
virtualized
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment