Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple set of bash scripts for uploading public keys to remote servers via GitHub usernames

authorized_keys

A method for managing and giving team members access to remote servers without needing to pass around the master .pem key. Generates and sends authorized key files to a list of hosts based on a set of permissions.

fetch_keys_from_github.sh

Generates a new keys/*.txt file for each user defined in permissions.txt when one doesn't already exist. Gets the list by calling out to https://github.com/<user>.keys. After first fetching a set of keys, the list can be paired down if necessary before running upload_keys.sh.

./fetch_keys_from_github.sh

upload_keys.sh

  1. Runs through each group defined in hosts/. ex:
  2. Reads the permissions.txt file to find out which users have permission to that host
  3. Generates a master authorized keys file for those users using their keys from keys/<user>.txt
  4. Uploads it to ~/.ssh/authorized_keys_sh for each host in that group. This avoids overwriting the server default authorized_keys file.
./upload_keys.sh

permissions.txt

Specifies each user and which groups of hosts they should have permissions for. The format for each line is a GitHub username followed by a dash, then a comma-delimited list of groups they belong to. Each group should correspond to a file with a list of servers in hosts/. Example below:

ifightcrime - web,mygroup,othergroup

keys/*.txt

This directory houses a user specific set of keys for each user defined in permissions.txt.

hosts/*.txt

Each file (group) contains a list of associated hosts that we want to push the keys to. A separate user@host is defined on each line.

Adding support for new hosts

Modify the host's /etc/ssh/sshd_config file to add support for our new authorized_keys_sh file. Change the AuthorizedKeysFile directive to match the following (and uncomment if commented):

AuthorizedKeysFile     %h/.ssh/authorized_keys %h/.ssh/authorized_keys_sh

Don't forget to reload ssh after you make the change.

/etc/init.d/ssh reload
#!/bin/bash
function fetch_keys_from_github () {
for user in $(awk '{print $1}' permissions.txt); do
file="keys/${user}.txt"
# only fetch if the file doesn't exist
if [[ ! -f $file ]] ; then
echo "Fetching ssh keys for ${user}..."
curl -sf https://github.com/${user}.keys > $file
fi
done
}
fetch_keys_from_github
#!/bin/bash
readonly REMOTE_KEY_PATH="~/.ssh/authorized_keys_sh"
function users_for_group () {
# group must start after '-' with space/comma, and end with comma/newline
users=$(grep "\-.*\(\s\|,\)${1}\(,\|$\)" permissions.txt | awk '{print $1;}')
if [[ -z $users ]]; then
echo -e " \e[31mno permissions defined for this group\e[0m" 1>&2
fi
echo $users
}
function generate_key_file () {
key_file=""
for user in $(users_for_group $1); do
file="keys/${user}.txt"
if [[ ! -f $file ]]; then
# skip this user if they have no key file
echo -e " \e[31mkeys for user '${user}' are missing\e[0m" 1>&2
else
key_file="${key_file}\n# ${user}"
key_file="${key_file}\n$(cat $file)\n"
fi
done
# -e and quotes to preserve line breaks
echo -e "$key_file"
}
function send_keys_to_hosts () {
for file in hosts/*.txt; do
group=$(basename ${file%.txt})
echo "Generating key file for '${group}'..."
key_file=$(mktemp /tmp/${group}_${host}.XXXXXX)
echo -e "$(generate_key_file $group)" > $key_file
if [[ -z $(cat $key_file) ]]; then
# generated file is empty, which means there are no keys to send
echo -e " \e[31mno keys generated for this group, skipping...\e[0m" 1>&2
else
for host in $(<${file}); do
echo " uploading to '${host}'"
scp -i ~/.ssh/upcounsel20130307.pem ${key_file} ${host}:${REMOTE_KEY_PATH} > /dev/null
done
fi
rm $key_file
done
}
send_keys_to_hosts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.