Add user public keys to admin user on the server
This only adds the admin user authorized_keys file, not the master one
This commit is contained in:
3
.shellcheckrc
Normal file
3
.shellcheckrc
Normal file
@@ -0,0 +1,3 @@
|
||||
shell=bash
|
||||
# source-path=config
|
||||
external-sources=true
|
||||
186
bin/user-add-ssh-key.sh
Normal file
186
bin/user-add-ssh-key.sh
Normal file
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Add user key to admin SSH KEY LIST
|
||||
|
||||
# base folder for all data
|
||||
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
||||
# config folder
|
||||
CONFIG_BASE="${BASE_FOLDER}../config/";
|
||||
# current public key folder for user
|
||||
SSH_PUBLIC_KEYS_CURRENT="${BASE_FOLDER}../ssh-public-keys/user-current/";
|
||||
|
||||
DRY_RUN=0;
|
||||
GO=0;
|
||||
HOST_ONLY="";
|
||||
USER_ONLY="";
|
||||
USER_PUBLIC_KEY="";
|
||||
#
|
||||
while getopts ":h:u:k:ng" opt; do
|
||||
case "${opt}" in
|
||||
h) # hostname
|
||||
HOST_ONLY="${OPTARG}";
|
||||
;;
|
||||
u) # username
|
||||
USER_ONLY="${OPTARG}";
|
||||
;;
|
||||
k) # user public key
|
||||
USER_PUBLIC_KEY="${OPTARG}";
|
||||
;;
|
||||
n) # dry-run
|
||||
DRY_RUN=1;
|
||||
;;
|
||||
g) # go
|
||||
GO=1;
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "-h override single host name";
|
||||
echo "-u override user name for a host";
|
||||
echo "-k public key file to add";
|
||||
echo "-n dry run";
|
||||
echo "-g flag for actual change call";
|
||||
echo ""
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# the public key file for the user
|
||||
SSH_KEY_PUB_FILE="${SSH_PUBLIC_KEYS_CURRENT}${USER_PUBLIC_KEY}" ;
|
||||
|
||||
# no current public key file with given name
|
||||
if [ ! -f "${SSH_KEY_PUB_FILE}" ]; then
|
||||
echo "Missing user ssh public key file to add: ${SSH_KEY_PUB_FILE}";
|
||||
exit;
|
||||
else
|
||||
# validate key
|
||||
SSH_PUBLIC_KEY_VALIDATE="ssh-keygen -l -f";
|
||||
# message=$(${SSH_PUBLIC_KEY_VALIDATE} "${SSH_KEY_PUB_FILE}");
|
||||
if ! message=$(${SSH_PUBLIC_KEY_VALIDATE} "${SSH_KEY_PUB_FILE}" 2>&1); then
|
||||
echo "Failed to parse ssh public key: ${message}";
|
||||
exit;
|
||||
fi;
|
||||
fi
|
||||
|
||||
# load config
|
||||
if [ ! -f "${CONFIG_BASE}settings.ini" ]; then
|
||||
echo "Missing 'settings.ini' file in ${CONFIG_BASE}";
|
||||
exit;
|
||||
fi
|
||||
# shellcheck source=../config/settings.ini
|
||||
# shellcheck disable=SC1094
|
||||
source <(grep "=" "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
|
||||
if [ -z "${server_list}" ]; then
|
||||
echo "No server list is defined in the settings";
|
||||
exit;
|
||||
fi;
|
||||
# we must have "server_list" set and file must be in config folder
|
||||
if [ ! -f "${CONFIG_BASE}${server_list}" ]; then
|
||||
echo "Cannot find ${server_list} file in the config folder";
|
||||
exit
|
||||
fi
|
||||
# abort if go not set
|
||||
if [ ${GO} -eq 0 ] && [ ${DRY_RUN} -eq 1 ]; then
|
||||
GO=1;
|
||||
elif [ ${GO} -eq 0 ]; then
|
||||
echo "No -g (go) parameter set. aborting. For testing set -n for dry run"
|
||||
exit;
|
||||
fi
|
||||
|
||||
# default ssh command
|
||||
# -t is needed for systens when "Defaults requiretty" is set
|
||||
SSH="ssh -a -x -n";
|
||||
|
||||
# Add the SSH Key to an auth file if it does not exist yet and the auth file does exist
|
||||
# Build bash command to run this
|
||||
# @Params
|
||||
# AUTH_KEY_FILE {1}: the auth key file where to add the key
|
||||
# PUB_KEY_FILE {2}: Public key file name
|
||||
add_ssh_key() {
|
||||
AUTH_KEY_FILE="${1}";
|
||||
PUB_KEY_FILE="${2}";
|
||||
AUTH_KEY_SETTINGS="${3}";
|
||||
RMV_CHATTR_I="chattr -i"
|
||||
ADD_CHATTR_I="chattr +i"
|
||||
RMV_CHMOD_UW="chmod u-w"
|
||||
ADD_CHMOD_UW="chmod u+w"
|
||||
# check if the auth file exists and the key is not yet in the auth file
|
||||
# the -z `tail ...` checks for a trailing newline. The echo adds one if was missing (from ssh-copy-id)
|
||||
# PROBLEM:
|
||||
# for grep from pipe, the left data is removed. we also can't cat from pipe
|
||||
# into a var as that would go through a pipe and not be visible
|
||||
# so we get the pub key file name and read it here
|
||||
pub_key=$(cat "${PUB_KEY_FILE}");
|
||||
# if we have auth key settings, prefix them to the pub key
|
||||
# Note that the check key "pub_key" ignores any prefixes, but we add with settings prefix
|
||||
if [ -n "${AUTH_KEY_SETTINGS}" ]; then
|
||||
pub_key_write="${AUTH_KEY_SETTINGS} ${pub_key}";
|
||||
else
|
||||
pub_key_write="${pub_key}";
|
||||
fi
|
||||
INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
|
||||
if [ -f "${AUTH_KEY_FILE}" ] && ! grep "${pub_key}" "${AUTH_KEY_FILE}" >> /dev/null; then
|
||||
${RMV_CHATTR_I} "${AUTH_KEY_FILE}";
|
||||
${ADD_CHMOD_UW} "${AUTH_KEY_FILE}";
|
||||
{ [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] ||
|
||||
echo >> "${AUTH_KEY_FILE}" || exit 1; } &&
|
||||
echo "${pub_key_write}" >> "${AUTH_KEY_FILE}" || exit 1;
|
||||
${RMV_CHMOD_UW} "${AUTH_KEY_FILE}";
|
||||
${ADD_CHATTR_I} "${AUTH_KEY_FILE}";
|
||||
fi;
|
||||
EOF
|
||||
);
|
||||
# to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
|
||||
printf "exec sudo sh -c '%s'" "${INSTALLKEYS_SH}"
|
||||
}
|
||||
|
||||
# install call
|
||||
# @Params
|
||||
# HOSTNAME {1} hostname to access
|
||||
# USERNAME {2} username to use
|
||||
# PUB_KEY_FILE {3} public key file to add
|
||||
# AUTH_KEY_FILE {4} auth key file where to add the public key
|
||||
install_ssh_key() {
|
||||
HOSTNAME="${1}";
|
||||
USERNAME="${2}";
|
||||
PUB_KEY_FILE="${3}";
|
||||
AUTH_KEY_FILE="${4}";
|
||||
AUTH_KEY_SETTINGS="${5}";
|
||||
echo "[.] Add to auth file: ${AUTH_KEY_FILE}";
|
||||
if [ ${DRY_RUN} -eq 0 ]; then
|
||||
${SSH} "${USERNAME}"@"${HOSTNAME}" "$(add_ssh_key "${AUTH_KEY_FILE}" "${PUB_KEY_FILE}" "${AUTH_KEY_SETTINGS}")"
|
||||
else
|
||||
echo "${SSH} \"${USERNAME}\"@\"${HOSTNAME}\" \"\$(add_ssh_key \"${AUTH_KEY_FILE}\" \"${PUB_KEY_FILE}\" \"${AUTH_KEY_SETTINGS}\")\"";
|
||||
fi
|
||||
}
|
||||
|
||||
while read -r line; do
|
||||
if [[ "${line}" =~ ^\# ]]; then
|
||||
continue;
|
||||
fi
|
||||
# hostname is on pos 1
|
||||
hostname=$(echo "${line}" | cut -d "," -f 1);
|
||||
# if hostname opt set and not matching skip
|
||||
if [ -n "${HOST_ONLY}" ] && [ "${HOST_ONLY}" != "${hostname}" ]; then
|
||||
continue;
|
||||
fi
|
||||
# login user name
|
||||
username=$(echo "${line}" | cut -d "," -f 2);
|
||||
# if username opt set and not matching skip
|
||||
if [ -n "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
echo "[+] Add new public key '${SSH_KEY_PUB_FILE}' to: ${username}@${hostname}";
|
||||
|
||||
# flags: (not used at the moment)
|
||||
# Possible: U (add to .ssh/authorized_keys)
|
||||
# flags=$(echo "${line}" | cut -d "," -f 3);
|
||||
# auth key settings (in front of auth key)
|
||||
auth_key_settings=$(echo "${line}" | cut -d "," -f 4);
|
||||
install_ssh_key "${hostname}" "${username}" "${SSH_KEY_PUB_FILE}" "/etc/ssh/authorized_keys/${username}" "${auth_key_settings}";
|
||||
|
||||
echo "[=] ............... DONE";
|
||||
done <<<"$(sed 1d "${CONFIG_BASE}${server_list}")";
|
||||
|
||||
# __END__
|
||||
157
bin/user-remove-ssh-key.sh
Normal file
157
bin/user-remove-ssh-key.sh
Normal file
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Remove user key to admin SSH KEY LIST
|
||||
|
||||
# base folder for all data
|
||||
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
||||
# config folder
|
||||
CONFIG_BASE="${BASE_FOLDER}../config/";
|
||||
# current public key folder for user
|
||||
SSH_PUBLIC_KEYS_PREVIOUS="${BASE_FOLDER}../ssh-public-keys/user-previous/";
|
||||
|
||||
DRY_RUN=0;
|
||||
GO=0;
|
||||
HOST_ONLY="";
|
||||
USER_ONLY="";
|
||||
USER_PUBLIC_KEY="";
|
||||
#
|
||||
while getopts ":h:u:k:ng" opt; do
|
||||
case "${opt}" in
|
||||
h) # hostname
|
||||
HOST_ONLY="${OPTARG}";
|
||||
;;
|
||||
u) # username
|
||||
USER_ONLY="${OPTARG}";
|
||||
;;
|
||||
k) # user public key
|
||||
USER_PUBLIC_KEY="${OPTARG}";
|
||||
;;
|
||||
n) # dry-run
|
||||
DRY_RUN=1;
|
||||
;;
|
||||
g) # go
|
||||
GO=1;
|
||||
;;
|
||||
\?)
|
||||
echo -e "\n Option does not exist: ${OPTARG}\n";
|
||||
echo "-h override single host name";
|
||||
echo "-u override user name for a host";
|
||||
echo "-k public key file to remove";
|
||||
echo "-n dry run";
|
||||
echo "-g flag for actual change call";
|
||||
echo ""
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# the public key file for the user
|
||||
SSH_KEY_PUB_FILE="${SSH_PUBLIC_KEYS_PREVIOUS}${USER_PUBLIC_KEY}" ;
|
||||
|
||||
# no current public key file with given name
|
||||
if [ ! -f "${SSH_KEY_PUB_FILE}" ]; then
|
||||
echo "Missing user ssh public key file to remove: ${SSH_KEY_PUB_FILE}";
|
||||
exit;
|
||||
else
|
||||
# validate key
|
||||
SSH_PUBLIC_KEY_VALIDATE="ssh-keygen -l -f";
|
||||
# message=$(${SSH_PUBLIC_KEY_VALIDATE} "${SSH_KEY_PUB_FILE}");
|
||||
if ! message=$(${SSH_PUBLIC_KEY_VALIDATE} "${SSH_KEY_PUB_FILE}" 2>&1); then
|
||||
echo "Failed to parse ssh public key: ${message}";
|
||||
exit;
|
||||
fi;
|
||||
fi
|
||||
|
||||
# load config
|
||||
if [ ! -f "${CONFIG_BASE}settings.ini" ]; then
|
||||
echo "Missing 'settings.ini' file in ${CONFIG_BASE}";
|
||||
exit;
|
||||
fi
|
||||
# shellcheck source=../config/settings.ini
|
||||
# shellcheck disable=SC1094
|
||||
source <(grep "=" "${CONFIG_BASE}settings.ini" | sed 's/ *= */=/g')
|
||||
if [ -z "${server_list}" ]; then
|
||||
echo "No server list is defined in the settings";
|
||||
exit;
|
||||
fi;
|
||||
# we must have "server_list" set and file must be in config folder
|
||||
if [ ! -f "${CONFIG_BASE}${server_list}" ]; then
|
||||
echo "Cannot find ${server_list} file in the config folder";
|
||||
exit
|
||||
fi
|
||||
# abort if go not set
|
||||
if [ ${GO} -eq 0 ] && [ ${DRY_RUN} -eq 1 ]; then
|
||||
GO=1;
|
||||
elif [ ${GO} -eq 0 ]; then
|
||||
echo "No -g (go) parameter set. aborting. For testing set -n for dry run"
|
||||
exit;
|
||||
fi
|
||||
|
||||
# default ssh command
|
||||
# -t is needed for systens when "Defaults requiretty" is set
|
||||
SSH="ssh -a -x -n";
|
||||
|
||||
remove_ssh_key() {
|
||||
AUTH_KEY_FILE="${1}";
|
||||
PUB_KEY_FILE="${2}";
|
||||
RMV_CHATTR_I="chattr -i"
|
||||
ADD_CHATTR_I="chattr +i"
|
||||
RMV_CHMOD_UW="chmod u-w"
|
||||
ADD_CHMOD_UW="chmod u+w"
|
||||
pub_key=$(cat "${PUB_KEY_FILE}");
|
||||
# we need to escape for sed
|
||||
pub_key_escaped=$(printf '%s\n' "$pub_key" | sed -e 's/[]\/$*.^[]/\\&/g');
|
||||
# the -z `tail ...` checks for a trailing newline. The echo adds one if was missing (from ssh-copy-id)
|
||||
UNINSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
|
||||
if [ -f "${AUTH_KEY_FILE}" ] && grep "${pub_key}" "${AUTH_KEY_FILE}" >> /dev/null; then
|
||||
${RMV_CHATTR_I} "${AUTH_KEY_FILE}";
|
||||
${ADD_CHMOD_UW} "${AUTH_KEY_FILE}";
|
||||
sed -i "/${pub_key_escaped}/d" "${AUTH_KEY_FILE}";
|
||||
${RMV_CHMOD_UW} "${AUTH_KEY_FILE}";
|
||||
${ADD_CHATTR_I} "${AUTH_KEY_FILE}";
|
||||
fi;
|
||||
EOF
|
||||
);
|
||||
# to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
|
||||
printf "exec sudo sh -c '%s'" "${UNINSTALLKEYS_SH}"
|
||||
}
|
||||
|
||||
uninstall_ssh_key() {
|
||||
HOSTNAME="${1}";
|
||||
USERNAME="${2}";
|
||||
PUB_KEY_FILE="${3}";
|
||||
AUTH_KEY_FILE="${4}";
|
||||
echo "[.] Remove from auth file: ${AUTH_KEY_FILE}";
|
||||
if [ ${DRY_RUN} -eq 0 ]; then
|
||||
# find the pub key in the file and remove this line only
|
||||
${SSH} "${USERNAME}"@"${HOSTNAME}" "$(remove_ssh_key "${AUTH_KEY_FILE}" "${PUB_KEY_FILE}")"
|
||||
else
|
||||
echo "${SSH} \"${USERNAME}\"@\"${HOSTNAME}\" \"\$(remove_ssh_key \"${AUTH_KEY_FILE}\" \"${PUB_KEY_FILE}\")\"";
|
||||
fi
|
||||
}
|
||||
|
||||
while read -r line; do
|
||||
if [[ "${line}" =~ ^\# ]]; then
|
||||
continue;
|
||||
fi
|
||||
# hostname is on pos 1
|
||||
hostname=$(echo "${line}" | cut -d "," -f 1);
|
||||
# if hostname opt set and not matching skip
|
||||
if [ -n "${HOST_ONLY}" ] && [ "${HOST_ONLY}" != "${hostname}" ]; then
|
||||
continue;
|
||||
fi
|
||||
# login user name
|
||||
username=$(echo "${line}" | cut -d "," -f 2);
|
||||
# if username opt set and not matching skip
|
||||
if [ -n "${USER_ONLY}" ] && [ "${USER_ONLY}" != "${username}" ]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
echo "[-] Remove public key '${SSH_KEY_PUB_FILE}' from: ${username}@${hostname}";
|
||||
|
||||
uninstall_ssh_key "${hostname}" "${username}" "${SSH_KEY_PUB_FILE}" "/etc/ssh/authorized_keys/${username}"
|
||||
|
||||
echo "[=] ............... DONE";
|
||||
done <<<"$(sed 1d "${CONFIG_BASE}${server_list}")";
|
||||
|
||||
# __END__
|
||||
2
ssh-public-keys/user-current/.gitignore
vendored
Normal file
2
ssh-public-keys/user-current/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
2
ssh-public-keys/user-previous/.gitignore
vendored
Normal file
2
ssh-public-keys/user-previous/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
Reference in New Issue
Block a user