From 6b83b50141e37e2926333dc1aa987bfb50317b5b Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Fri, 23 May 2008 19:01:50 -0400 Subject: major overhaul of rhesus: - much more sophisticated validity checking of keys/uids - broke out more functions - cleaned-up/simplified code - changed to new variable naming standard --- doc/MonkeySpec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/MonkeySpec') diff --git a/doc/MonkeySpec b/doc/MonkeySpec index 7a19df0..c36e7de 100644 --- a/doc/MonkeySpec +++ b/doc/MonkeySpec @@ -102,4 +102,4 @@ Write manpage for gpgkey2ssh gpg private key (start with passwordless) to PEM encoded private key: perl libraries, libopencdk / gnutls, gpgme setup remote git repo think through / plan merging of known_hosts (& auth_keys?) -think about policies and their representation \ No newline at end of file +think about policies and their representation -- cgit v1.2.3 From 491612988f2207deaa479249f5a42c9e916704d1 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 25 May 2008 14:43:39 -0400 Subject: update to MonkeySpec: - i took the liberty to reapportion some of the monkey names to new/different components. some components are no longer needed (eg. marmoset as originally defined is no longer needed since rhesus handles both ssh key file types). i also took the name "howler" and used it for a new component that generates and publishes server gpg keys. - fleshed out the Alice/Bob use case senario with some clarification and more detail. --- doc/MonkeySpec | 187 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 109 insertions(+), 78 deletions(-) (limited to 'doc/MonkeySpec') diff --git a/doc/MonkeySpec b/doc/MonkeySpec index c36e7de..45d6cf6 100644 --- a/doc/MonkeySpec +++ b/doc/MonkeySpec @@ -7,99 +7,130 @@ AGENDA [ ] work [x] jrollins will talk and gesture - in progress +MONKEYNAMES +=========== + +rhesus, marmoset, howler, langur, tamarin, barbary + COMPONENTS ========== -* client-side componants -** "Marmoset": update known_hosts file with public key of server(s): -*** be responsible for removing keys from the file as key revocation happens -*** be responsible for updating a key in the file where there is a key replacement -*** must result in a file that is parsable by the existing ssh client without errors -*** manual management must be allowed without stomping on it -*** provide a simple, intelligible, clear policy for key acceptance -*** questions: should this query keyserver & update known host files? (we already - have awesome tool that queries keyservers and updates a web of trust (gpg) -** "Howler": simple script that could be placed as a trigger function (in your .ssh/config) -*** runs on connection to a certain host -*** triggers update to known_hosts file then makes connection -*** proxy-command | pre-hook script | wrapper script -** "Langur": policy-editor for viewing/editing policies - -* server-side componants -** "Rhesus" updates a per-user authorized_keys file, instead of updating a - known_hosts file from a public key by matching a specified user-id (for given - user: update authkeys file with public keys derived from authorized_uids - file) -*** Needs to operate with the same principles that Marmoset client-side does -** "Tamarin" triggers Rhesus during an attempt to initiate a connection or a scheduler (or both) -** "Barbary" - policy editor / viewer - -* common componants -** Create a ssh keypair from a openpgp keypair - -from ssh_config(5): - LocalCommand - Specifies a command to execute on the local machine after suc‐ - cessfully connecting to the server. The command string extends - to the end of the line, and is executed with /bin/sh. This - directive is ignored unless PermitLocalCommand has been enabled. +(names in "" are code names until we think of better ones.) + +common components +----------------- +* "rhesus": update known_hosts/authorized_keys files: + - be responsible for removing keys from the file as key revocation + happens + - be responsible for updating a key in the file where there is a key + replacement + - must result in a file that is parsable by the existing ssh client + without errors + - manual management must be allowed without stomping on it + - provide a simple, intelligible, clear policy for key acceptance + +* "langur": policy-editor for viewing/editing policies + +* gpg2ssh: utility to convert gpg keys to ssh + known_hosts/authorized_keys lines + +* ssh2gpg: create openpgp keypair from ssh keypair + +server-side components +---------------------- +* "howler": service gpg key generator/publisher + +* "tamarin": script to trigger rhesus during attempt to initiate + connection from client + +client-side components +---------------------- +* "marmoset": script to trigger rhesus during attempt to initiate + connection to server + - runs on connection to a certain host + - triggers update to known_hosts file then makes connection + - proxy-command | pre-hook script | wrapper script + - (ssh_config "LocalCommand" is only run *after* connection) + +USE CASE +======== + +Dramatis Personae: http://en.wikipedia.org/wiki/Alice_and_Bob +Backstory: http://www.conceptlabs.co.uk/alicebob.html + +Bob wants to sign on to the computer "mangabey" via monkeysphere +framework. He doesn't yet have access to the machine, but he knows +Alice, who is the admin of magabey. Alice and Bob, being the +contientious netizens that they are, have already published their +personal gpg keys to the web of trust, and being good friends, have +both signed each other's keys and marked each others keys with "full" +trust. + +Alice uses howler to publish a gpg key for magabey with the special +"ssh://magabey" URI userid. Alice signs magabey's gpg key and +publishes her signature. Alice then creates a user "bob" on magabey, +and puts Bob's userid in the auth_user_ids file for user bob on +magabey. tamarin triggers on magabey, which triggers rhesus, which +takes all userids in bob's auth_user_ids file, look on a keyserver to +find the public keys for each user, converts the gpg public keys into +ssh public keys if the key validity is acceptable, and finally insert +those keys into an authorized_keys file for bob. + +Bob now adds the "ssh://magabey" userid to the auth_host_ids file in +his account on his localhost. Bob now goes to connect to bob@magabey. +Bob's ssh client, which is monkeysphere enabled, triggers marmoset, +which triggers rhesus on Bob's computer, which takes all server +userids in his auth_host_ids file, looks on a keyserver to find the +public key for each server (based on the server's URI), converts the +gpg public keys into ssh public keys if the key validity is +acceptable, and finally insert those keys into Bob's known_hosts file. + +On Bob's side, since mangabey's key had "full" validity (since it was +signed by Alice whom he fully trusts), Bob's ssh client deems magabey +"known" and no further host key checking is required. + +On magabey's side, since Bob's key has "full" validity (since it had +also been signed by Alice whom magabey fully trusts (since Alice told +him to)), Bob is authenticated to log into bob@magabey. NOTES ===== + * Daniel and Elliot lie. -* We will use a distributed VCS, each developer will create their own git repository and publish it publically for others to pull from, mail out +* We will use a distributed VCS, each developer will create their own + git repository and publish it publicly for others to pull from, mail + out * public project page doesn't perhaps make sense yet -* approximate goal - using the web of trust to authenticate ppl for SSH +* approximate goal - using the web of trust to authenticate ppl for + SSH * outline of various components of monkeysphere -* M: what does it mean to be in the monkeysphere? not necessarily a great coder. -* J: interested in seeing project happen, not in actually doing it. anybody can contribute as much as they want. -* J: if we put the structure in place to work on monkeysphere then we don't have to do anything +* M: what does it mean to be in the monkeysphere? not necessarily a + great coder. +* J: interested in seeing project happen, not in actually doing it. + anybody can contribute as much as they want. +* J: if we put the structure in place to work on monkeysphere then we + don't have to do anything * D: we are not creating -* understand gpg's keyring better, understanding tools better, building scripts +* understand gpg's keyring better, understanding tools better, + building scripts * Some debian packages allow automated configuration of config files. - * GENERAL GOAL - use openpgp web-of-trust to authenticate ppl for SSH -* SPECIFIC GOAL - allow openssh to tie into pgp web-of-trust without modifying either openpgp and openssh -* DESIGN GOALS - authentication, use the existing generic OpenSSH client, the admin can make it default, although end-user should be decide to use monkeysphere or not -* DESIGN GOAL - use of monkeysphere should not radically change connecting-to-server experience +* SPECIFIC GOAL - allow openssh to tie into pgp web-of-trust without + modifying either openpgp and openssh +* DESIGN GOALS - authentication, use the existing generic OpenSSH + client, the admin can make it default, although end-user should be + decide to use monkeysphere or not +* DESIGN GOAL - use of monkeysphere should not radically change + connecting-to-server experience * GOAL - pick a monkey-related name for each component -Dramatis Personae: http://en.wikipedia.org/wiki/Alice_and_Bob -Backstory: http://www.conceptlabs.co.uk/alicebob.html +Host identity piece of monkeysphere could be used without buying into +the authorization component. -* Use Case: Bob wants to sign on to the computer "mangabey" via monkeysphere - framework. He doesn't have access to the machine, but he knows Alice, who is - the admin of magabey. Alice creates a user bob and puts bob's userid in the - auth_user_ids file for bob. Tamarin triggers which causes Rhesus to take all - the things in the auth_userids file, takes those users, look son a keyserver - finds the public keys for the users, converts the gpg public keys into ssh - public keys and inserts those into a user_authorized_keys file. Bob goes to - connect, bob's ssh client which is monkeysphere enbaled, howler is triggered - which triggers marmoset which looks out into the web of trust and find an - OpenPGP key that has a userid that matches the URI of magabey. Marmoset checks - to see if this key for mangabey has been signed by any keys that you trust - (based on your policy). Has this key been signed by somebody that you trust? - If yes, connect, if no: abort or fail-through or whatever. Alice has signed - this uid, so Marmoset says "OK, this server has been verified" it then - converts the gpg public key into a ssh public key and then adds this gpg key - to the known_host file. ssh says, "you" are about to connect to magabey and - you know this is magabey because alice says so and you trust alice". The gpg - private key of bob has to be converted (somehow, via agent or something) into - a ssh private_key. SSH connection happens. - -Host identity piece of monkeysphere could be used without buying into the -authorization component. - -Monkeysphere is authentication layer that allows the sysadmin to perform -authorization on user identities instead of on keys, it additionally allows the -sysadmin also to authenticate the server to the end-user. +Monkeysphere is authentication layer that allows the sysadmin to +perform authorization on user identities instead of on keys, it +additionally allows the sysadmin also to authenticate the server to +the end-user. git clone http://git.mlcastle.net/monkeysphere.git/ monkeysphere - -Fix gpgkey2ssh so that the entire key fingerprint will work, accept full fingerprint, or accept a pipe and do the conversion -Write manpage for gpgkey2ssh -gpg private key (start with passwordless) to PEM encoded private key: perl libraries, libopencdk / gnutls, gpgme -setup remote git repo -think through / plan merging of known_hosts (& auth_keys?) -think about policies and their representation -- cgit v1.2.3 From 4eba4e7e66fc7febb1e7255a649f6b6ad240d653 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 25 May 2008 15:59:54 -0400 Subject: expand howler to handle general gpg maintenence tasks for server - add "gen-key", "publish-key", and "trust-uids" functions small tweak to rhesus. update README and MonkeySpec --- doc/MonkeySpec | 5 ++- doc/README | 50 ++++++++++++++++++---- howler/howler | 130 +++++++++++++++++++++++++++++++++++++++------------------ rhesus/rhesus | 8 ++-- 4 files changed, 140 insertions(+), 53 deletions(-) (limited to 'doc/MonkeySpec') diff --git a/doc/MonkeySpec b/doc/MonkeySpec index 45d6cf6..3b565db 100644 --- a/doc/MonkeySpec +++ b/doc/MonkeySpec @@ -38,7 +38,10 @@ common components server-side components ---------------------- -* "howler": service gpg key generator/publisher +* "howler": server gpg maintainer + - generates gpg keys for the server + - publishes server gpg keys + - used to specify userids to trust for user authentication * "tamarin": script to trigger rhesus during attempt to initiate connection from client diff --git a/doc/README b/doc/README index 9dc8753..9034519 100644 --- a/doc/README +++ b/doc/README @@ -1,19 +1,22 @@ Monkeysphere README -------------------- +=================== -Default file locations: +Default files locations (by variable): MS_HOME=~/.config/monkeysphere -STAGING_AREA=$MS_HOME +MS_CONF=$MS_HOME/monkeysphere.conf +AUTH_HOST_FILE=$MS_HOME/auth_host_ids +AUTH_USER_FILE=$MS_HOME/auth_user_ids GNUPGHOME=~/.gnupg -$MS_HOME/monkeysphere.conf -$MS_HOME/auth_host_ids -$MS_HOME/auth_user_ids +STAGING_AREA=$MS_HOME + $STAGING_AREA/host_keys/KEYHASH $STAGING_AREA/known_hosts $STAGING_AREA/user_keys/KEYHASH $STAGING_AREA/authorized_keys +user usage +---------- For a user to update their ms known_hosts file: $ rhesus --known_hosts @@ -22,6 +25,23 @@ For a user to update their ms authorized_keys file: $ rhesus --authorized_keys +server service publication +-------------------------- +To publish a server host key use the "howler" component: + +# howler gen-key +# howler publish-key + +This will generate the key for server with the service URI +(ssh://server.hostname). The server admin should now sign the server +key so that people in the admin's web of trust can authenticate the +server without manual host key checking: + +$ gpg --search ='ssh://server.hostname' +$ gpg --sign-key 'ssh://server.hostname' + +server authorized_keys maintenance +---------------------------------- A system can maintain ms authorized_keys files for it's users. Some different variables need to be defined to help manage this. The way this is done is by first defining a new MS_HOME: @@ -35,10 +55,24 @@ AUTH_USER_FILE="$MS_HOME"/auth_user_ids/"$USER" STAGING_AREA=/var/lib/monkeysphere/stage/$USER GNUPGHOME=$MS_HOME/gnupg -To update the ms authorized_keys file for user "foo", the system would +For each user account on the server, the userids of people authorized +to log into that account would be placed in the AUTH_USER_FILE for +that user. However, in order for users to become authenticated, the +server must determine that the user keys have "full" validity. This +means that the server must fully trust at least one person whose +signature on the connecting users key would validate the user. This +would generally be the server admin. If the server admin's userid is + +"Alice " + +then the server would run: + +# howler trust-uids "Alice " + +To update the ms authorized_keys file for user "bob", the system would then run the following: -# USER=foo MS_HOME=/etc/monkeysphere rhesus --authorized_keys +# USER=bob MS_HOME=/etc/monkeysphere rhesus --authorized_keys To update the ms authorized_keys file for all users on the the system: diff --git a/howler/howler b/howler/howler index 7e33471..d0bb13d 100755 --- a/howler/howler +++ b/howler/howler @@ -1,78 +1,128 @@ #!/bin/sh -# howler: server gpg key generator/publisher +# howler: monkeysphere server gpg generator/publisher/maintainer # # Written by # Jameson Rollins # # Copyright 2008, released under the GPL, version 3 or later -CMD=$(basename $0) +PGRM=$(basename $0) ######################################################################## # FUNCTIONS ######################################################################## +usage() { +cat <&2 exit ${2:-'1'} } -######################################################################## -# MAIN -######################################################################## - -MS_HOME=${MS_HOME:-/etc/monkeysphere} - -. "$MS_HOME"/monkeysphere.conf - -export GNUPGHOME - -KEY_TYPE=${KEY_TYPE:-RSA} -KEY_LENGTH=${KEY_LENGTH:-2048} -KEY_USAGE=${KEY_USAGE:-encrypt,auth} -SERVICE=${SERVICE:-ssh} -HOSTNAME=${HOSTNAME:-$(hostname -f)} +# generate server gpg key +gen_key() { + KEY_TYPE=${KEY_TYPE:-RSA} + KEY_LENGTH=${KEY_LENGTH:-2048} + KEY_USAGE=${KEY_USAGE:-encrypt,auth} + SERVICE=${SERVICE:-ssh} + HOSTNAME_FQDN=${HOSTNAME_FQDN:-$(hostname -f)} -USERID=${USERID:-"$SERVICE"://"$HOSTNAME"} + USERID=${USERID:-"$SERVICE"://"$HOSTNAME_FQDN"} -echo "key parameters:" -cat < /dev/null 2>&1 ; then - failure "key for '$USERID' already exists" -fi + if gpg --list-key ="$USERID" > /dev/null 2>&1 ; then + failure "key for '$USERID' already exists" + fi -echo "generating server key..." -gpg --batch --gen-key < /dev/null | grep '^pub:' | cut -d: -f5) + keyID=$(gpg --list-key --with-colons ="$USERID" 2> /dev/null | grep '^pub:' | cut -d: -f5) -# dummy command so as not to publish fakes keys during testing -# eventually: -#gpg --send-keys --keyserver "$KEYSERVER" "$keyID" -echo "gpg --send-keys --keyserver $KEYSERVER $keyID" + # dummy command so as not to publish fakes keys during testing + # eventually: + #gpg --send-keys --keyserver "$KEYSERVER" "$keyID" + echo "gpg --send-keys --keyserver $KEYSERVER $keyID" +} -echo "done." +# FIXME: need to figure out how to automate this, in a batch mode +# or something. +trust_uids() { + for userID ; do + gpg --keyserver "$KEYSERVER" --search ="$userID" + gpg --edit-key "$userID" + done +} + +######################################################################## +# MAIN +######################################################################## + +# set ms home directory +MS_HOME=${MS_HOME:-/etc/monkeysphere} + +# load configuration file +MS_CONF=${MS_CONF:-"$MS_HOME"/monkeysphere.conf} +[ -e "$MS_CONF" ] && . "$MS_CONF" + +GNUPGHOME=${GNUPGHOME:-"$MS_HOME"/gnupg} +export GNUPGHOME +KEYSERVER=${KEYSERVER:-subkeys.pgp.net} +export KEYSERVER + +COMMAND="$1" +[ "$COMMAND" ] || failure "Type '$PGRM help' for usage." +shift 1 + +case $COMMAND in + 'gen-key') + gen_key + ;; + 'publish-key') + publish_key + ;; + 'trust-uids') + trust_uids "$@" + ;; + 'help') + usage + exit + ;; + *) + failure "Unknown command: '$COMMAND' +Type '$PGRM help' for usage." + ;; +esac diff --git a/rhesus/rhesus b/rhesus/rhesus index dec24a2..7a43fca 100755 --- a/rhesus/rhesus +++ b/rhesus/rhesus @@ -7,7 +7,7 @@ # # Copyright 2008, released under the GPL, version 3 or later -CMD=$(basename $0) +PGRM=$(basename $0) ######################################################################## # FUNCTIONS @@ -15,8 +15,8 @@ CMD=$(basename $0) usage() { cat <