52 lines
1.9 KiB
Bash
52 lines
1.9 KiB
Bash
#!/bin/bash
|
|
shopt -s nullglob
|
|
|
|
# We want to iterate over all system users, check if they are opted-in to ssh
|
|
# authorized_keys building, and then construct their keyfile
|
|
while read -r user; do
|
|
home="$(eval echo "~$user")" || continue
|
|
link="$(readlink "$home"/.ssh/authorized_keys 2>/dev/null)" || continue
|
|
# Users are only opted-in if they symlink to our well-known directory where
|
|
# the final output of this script lives.
|
|
if [[ $link != "/run/authorized_keys/$user" ]]; then
|
|
echo "Ignoring $user $home/.ssh/authorized_keys" >&2
|
|
continue
|
|
fi
|
|
|
|
echo "Updating $link" >&2
|
|
declare -A basemap=()
|
|
declare -a dirs=(
|
|
"/usr/share/authorized_keys.d/$user"
|
|
"$home/.ssh/authorized_keys.d"
|
|
"/run/authorized_keys.d/$user"
|
|
)
|
|
# Build a map that can be used for sorting directories by their priority
|
|
# and prioritizing the last listed directories over the later ones. We
|
|
# append a counter to ensure that there is a stable sorting mechanism for
|
|
# duplicate filenames. Duplicate filenames will be overridden by higher
|
|
# priority directories.
|
|
# Ex.
|
|
# /usr/share/authorized_keys.d/root/10-key
|
|
# /usr/share/authorized_keys.d/root/15-key
|
|
# /run/authorized_keys.d/root/10-key
|
|
# /run/authorized_keys.d/root/20-key
|
|
# Becomes
|
|
# ["10-key"]="/run/authorized_keys.d/root/10-key"
|
|
# ["15-key"]="/usr/share/authorized_keys.d/root/15-key"
|
|
# ["20-key"]="/run/authorized_keys.d/root/20-key"
|
|
for dir in "${dirs[@]}"; do
|
|
for file in "$dir"/*; do
|
|
basemap["${file##*/}"]="$file"
|
|
done
|
|
done
|
|
rm -f /run/authorized_keys.tmp
|
|
touch /run/authorized_keys.tmp
|
|
for key in $(printf "%s\n" "${!basemap[@]}" | sort -r); do
|
|
echo " Including ${basemap[$key]}" >&2
|
|
cat "${basemap[$key]}" >>/run/authorized_keys.tmp
|
|
done
|
|
mkdir -p /run/authorized_keys
|
|
mv /run/authorized_keys.tmp /run/authorized_keys/"$user"
|
|
chown "$user" /run/authorized_keys/"$user"
|
|
done < <(cut -d':' -f1 /etc/passwd)
|