0

This question is about the design of a service I want to setup.

Description

My purpose is to provide a client box which connects to a server and provides some features.

The client box is a small computer like OLinuXino or Raspberry-Pi which would contain an embedded system with some files (information like security keys or executable files) I want to protect from being copied.

Server is the centralized part of the service.

Size of the protected files: from 1kB to 500kB.

The client box will contain a Debian (wheezy) system which will be read-only and setup with tmpfs (as shown here).

How I want to secure it

This system will contain some configuration and executable files I want to keep hidden from curious eyes. So they will be strongly encrypted.

As the client box will connect to the server and open a reverse ssh tunnel (from server to client), the server will have the ability to decrypt the files (with a key that is on server-side) after some verification. These files, once decrypted, will stay in client's RAM until shutdown of the client.

This client box will be headless (no screen, no keyboard) and entirely automated, but I am not sure an user will not try to connect screen or keyboard to watch what is happening.

So I would like to make the server checks that no keyboard nor screen is connected to the client. So it would call (remotely through an ssh call from server to client) some commands

  1. to check the serial number, MAC address, some files checksum and other system specific information to verify that the client box was not compromised (nor the whole filesystem copied to another machine)
  2. to detect if a keyboard was plugged and eventually block it.
  3. to close all opened user sessions.
  4. to block any new connection (keyboard, new session, devices)
  5. to detect if a screen was plugged an block any output display.

After this, the server would remotely decrypt the files in RAM.

My first question: do you think this is a secure way to keep my files hidden ? Did I miss something ?

My second question: for items 1, 2 and 3 of the above list, I am pretty sure I will find a way to do this. But for items 4 and 5, I am not sure. Would you have any suggestions ? Or do you think it is not possible at all ?

Any advice (like "don't do this, it's silly" or "go, it will work") is welcome !

  • Thank you for the anonymous downvote. An advice ? Should I post on another site from SE network ? – lauhub Aug 12 '14 at 7:02
  • I also don't like this behavior so I compensated that. If you see some like so, do it as well. – peterh says reinstate Monica Aug 12 '14 at 14:39
0

I think, there are things which you simply can't prevent.

In your place I used 2 partition on the flash drive of the client. The first were used for booting, and to load in a minimal C program. This minimal C program contacted the server, and got the decoding key to the second partition to that. This whole run from initrd.

After the successful decoding, the second, real partition of the system were already usable.

The most important thing is to remove everything from the kernel, and from the userspace software, which could be used against your security.

(p.s. from a similar, but security-centralized viewpoint you could ask some similar on security.stackexchange.com as well)

  • Thanks. The idea to create a small C program is good to me. I'll try to test this (and I already found something here that makes your lead really good: blog.neutrino.es/2011/…) – lauhub Aug 12 '14 at 14:58
0

You'll get better answers if you say what exactly you want to do instead of how you want to do it - in other words: Put down the chocolate-covered banana and step away from the European currency systems.

TL;DR summary

Q: Will it work?
A: It could.
Q: Does it make sense?
A: Only under some very specific assumptions, I'm afraid.

Security is very hard to get right - you might want to ask on the Security SE for general approach.

Long version

If you don't want anybody to interfere with the box via screen or keyboard, just disable the appropriate kernel modules, or even better unsolder the connectors (I mean it). On the other hand, I'm not really sure how attaching a screen could matter if there is no program running on the machine that would display something.

However, the key problem here is trust. As far as I understand, you want to keep the sensitive data (both encrypted E and temporarily the plaintext P as well) on the client and the key K on the server. To be able to decrypt E into P you are going to have K and E on the same machine at some point - and this very moment is the first one where it falls apart: the server doesn't trust the client enough, so it runs some checks - how can you guarantee, that the check results won't be faked? If you are so concerned about somebody connecting a keyboard to the client device, are you not concerned about JTAGging it and watching what's going on there? What if someone copies the client, analyses it then swaps it with his/her own system while spoofing the test results?

The second (more important from my point of view) problem is: what are you going to do with the unencrypted data and why can't you do it on the "server"? The key point here is: if you don't trust the server enough to temporarily hold the data in its RAM (talking about the client requesting decryption from the server here), why do you trust it so much that you are permanently storing the key to the encrypted data there? If you don't trust it enough to put plaintext in its RAM, is it reasonable to load the key data into the very same memory and send it over the network interface?

What if you decide you want to work with the data in, let's say, an editor over an ssh channel? How do you know someone won't snoop the ssh connection data, which will definitely contain the plaintext?

My suggestion would be to look for a solution (preferably an already made one, since rolling out one's own cryptography is usually a disaster) involving a very tight protocol that would:

  1. authenticate both parties, then

  2. authorize the client to request the decryption key from the server

  3. authorize the server to supply the decryption key to the client

  4. forbid any commands emitted on one side of the channel to be run directly on the other - i.e. no things like:

    user@server$ ssh client -c "decrypt -k key < encrypted > plaintext"
    

    Why?

    Generally you don't want to allow the someone running arbitrary commands remotely. You are much better off by setting up a special binary that will let the remote user select one of predefined commands (a little bit like restricted shell, only more restricted). In case your access tokens get compromised, the attacker will only be able to do several actions. Although in your case it might mean stealing the data in the end, it will prevent him from turning the system into a trojan horse. For example sshd (from the OpenSSH suite at least) works exactly like this in the authentication phase: the listening daemon creates a child which immediately drops all (read "root") privileges and handles the authentication as an unprivileged process which requests privileged actions from its parent through a very restricted API. That way any input you feed it will either result in the authentication progressing a bit, or in a crash of an unprivileged application thus eliminating the possibility of a remote root exploit.

The most problematic is the first one. Things like TPM and TXT might help, but in the end you still have to trust somebody. And whether chip and firmware manufacturers are to be trusted is not as clear as one might expect.

  • Thank you for your answer. Why forbidding commands like said in 4. should be forbidden ? Is it because they are visible inside data packets ? – lauhub Sep 3 '14 at 11:34
  • Too long for a comment, see updated answer. – peterph Sep 5 '14 at 8:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.