Signed executables under Linux

Viewed 42396

For security reasons, it is desirable to check the integrity of code before execution, avoiding tampered software by an attacker. So, my question is

How to sign executable code and run only trusted software under Linux?

I have read the work of van Doom et al., Design and implementation of signed executables for Linux, and the IBM's TLC (Trusted Linux Client) by Safford & Zohar. TLC uses TPM controller, what is nice, but the paper is from 2005 and I was unable to find current alternatives.

Do you know another options?

UPDATE: And about other OS's? OpenSolaris? BSD family?

10 Answers

I like to think to security as a chain. The weaker link of the chain can compromise the whole system. So the whole thing become "preventing an unauthorized user from obtaining the root password".

As suggested by @DanMoulding the source of the software is also important and in the future probably official OS application stores will be the standard. Think about Play Store, Apple or Microsoft stores.

I think installation and distribution of covert malicious code is the far more insidious problem. After all, in order to load bad code it's got to first be installed on the system somewhere. More layers of security are usually better, of course. The question is: is it worth the cost?

In my opinion the answer is "it depends". You can reduce the risk by adopting a set of security policies as suggested by @sleblanc. You can encrypt your file system (https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup), use read-only file systems for the binaries or use a mechanism to sign and verify the binaries.

However whatever mechanism you use there is nothing you can do once the root access is obtained by an attacker. The signature verification tools can be replaced with a tampered version or just disabled and it doesn't really matter if the tools run in user-space or kernel-space once that the machine has been compromised (although the latter would be more secure of course).

So it would be nice if the Linux kernel could embeds a signature verification module and another security layer between the root user and the operating system.

For example this is the approach adopted on the recent macOS versions. Some file can't be modified (and sometimes read) even by the root account and there are restrictions also on the policies and kernel modules (e.g. only signed or authorized kext can be loaded on the system). Windows adopted more or less the same approach with AppLocker.

I agree that the philosophy surrounding Linux, GNU et al. revolves around tinkering. On the other hand, I also believe that some systems deserve protection against vulnerabilities such as software tampering, which can undermine the privacy and integrity of a system's users.

Kernel implementations cannot keep up with the rapid development cycle of the kernel itself. I recommend instead to implement a form of executable file signature verification using userspace tools. Place executables in an archive or filesystem image and sign the image using a private key; if that private key stays on your development machines (private), when your server gets hacked, attackers still have no way to sign their own images and inject their code without tricking the system to mount unsigned images. It extends further along the chain:

  • have your services contained into runtime-mounted read-only images;
  • have the machine run off of a signed, read-only filesystem;
  • implement secure boot on your machines, running a bootloader that enforces the integrity of the boot media;
  • trust that the people in your organization will not tamper with your machines.

Getting everything right is a hard endeavor. It is much simpler to work around it all by designing your system under another approach:

  • quarantine users from the system. Do not introduce means for users to execute commands on your system. Avoid shelling out from inside the programs that rely on user-fed data.
  • design your deployment procedures using configuration management and ensure that your deployments are "repeatable", meaning that they lead to the same functional result when you deploy them several times. This allows you to "nuke from orbit" machines that you suspect have been compromised.
  • treat your machines as if they were compromised: regularly run audits to verify the integrity of your systems. Save your data on separate images and redeploy systems regularly. Sign images and have systems reject unsigned images.
  • use certificates: favor a "certificate pinning" approach. Do deploy a root certificate for your applications (which will provide automatic rejection of signatures that have not been certified by your organization) but at the very least have the system manage fingerprints of current images and notify administrators when fingerprints have changed. Although it is possible to implement all this using chains of keys, certificate-based authentication has been designed for this exact application.
Related