diff options
-rw-r--r-- | README.md | 44 | ||||
-rw-r--r-- | keyper.c | 55 |
2 files changed, 99 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..53e3638 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +Keyper +------ + +A very simple program to be used with sshd to transfer keys to authorized +servers. Mostly to be used with the Dracut module `acquire-key-over-ssh` for +machines to acquire their encryption keys securely over ssh from a secure +server. (It technically just is a way to dump a file upon login to an ssh +connection.). + +To set this up, run the following on the keyserver, replacing `<id_rsa.pub>` +with the public key of the authorized user: + +```bash +$ gcc -o keyper keyper.c +$ sudo su +# useradd keyper +# cp keyper /home/keyper +# cd /home/keyper +# chsh -s /home/keyper/keyper keyper +# mkdir .ssh +# echo 'environment="KEYPER_FILE=keyper-key" <id_rsa.pub>' >> .ssh/authorized_keys +# chown -R keyper:keyper .ssh/ +# chmod 700 .ssh +# head -c 512 /dev/urandom | base64 -w0 > keyper-key +``` + +Make sure `PermitUserEnvironment` is set to "yes" in sshd\_config. + +TL;DR this sets up a user, keyper, sets its shell to "keyper", which reads a +file based on an environement variable. Then it sets up an authorized key and +sets the environment based on the authorized ssh key. Thereby multiple different +keys can be served different authorized keys. + +There are some weird things that can happen with a binary key. For example, +carridge returns may be removed, so to avoid these, the above commands +base64-encode the key. + +On the client, run: + +``` +$ ssh keyper@keyserver > /tmp/key +$ sudo luksAddKey /dev/<disk> /tmp/key +$ shred /tmp/key +``` diff --git a/keyper.c b/keyper.c new file mode 100644 index 0000000..a3338c3 --- /dev/null +++ b/keyper.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> + +static int check_fname(const char* fname) +{ + while (*fname) { + if (strchr("/.", *(fname++))) { + return 0; + } + } + return 1; +} + +static int dump_file(const char* fname) +{ + int fd = open(fname, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Failed to open %s\n", fname); + return 1; + } + char buf[1024]; + int buflen; + while ((buflen = read(fd, buf, sizeof(buf))) > 0) { + write(1, buf, buflen); + } + close(fd); + return 0; +} + +int main(int argc, char** argv) +{ + const char* file = getenv("KEYPER_FILE"); + const char* disable_file = getenv("KEYPER_DISABLE_FILE"); + + if (!disable_file) { + disable_file="keyper-disable"; + } + + if (!file) { + fprintf(stderr, "No KEYPER_FILE value.\n"); + return 1; + } + + struct stat statbuf; + if (!stat(disable_file, &statbuf)) { + fprintf(stderr, "Keyper disabled because %s exists.\n", disable_file); + return 127; + } + + return dump_file(file); +} |