aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md44
-rw-r--r--keyper.c55
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);
+}