Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check remote user on install task #22

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,17 +321,43 @@ def install(c: Any, alias) -> None:
if ask != "y":
return

# Check ssh and remote user
try:
remote_user = h.run(cmd="whoami", stdout=subprocess.PIPE).stdout.strip()
local_user = exec_cmd("whoami").stdout.strip()
if remote_user and local_user and remote_user != local_user:
LOG.warning(
"Remote user '%s' is not your current local user. "
"You will likely not be able to login to the remote host '%s' "
"after nixos-anywhere installation. Consider adding your local "
"user to the remote host and make sure user '%s' "
"also has access to remote host after nixos-anywhere installation "
"by adding your local user as a user to nixos configuration '%s'. "
"Hint: you might want to try the helper script at "
"'terraform/scripts/add-remote-user.sh' to add your current local "
"user to the remote host.",
remote_user,
_get_target(alias).hostname,
local_user,
_get_target(alias).nixosconfig,
)
ask = input("Still continue? [y/N] ")
if ask != "y":
sys.exit(1)
except subprocess.CalledProcessError:
LOG.fatal("No ssh access to the remote host")
sys.exit(1)
# Check sudo nopasswd
try:
h.run("sudo -nv", become_root=True)
h.run("sudo -n true", become_root=True)
except subprocess.CalledProcessError:
LOG.warning(
"sudo on '%s' needs password: installation will likely fail", h.host
)
ask = input("Still continue? [y/N] ")
if ask != "y":
sys.exit(1)
# Check static ip
# Check dynamic ip
try:
h.run("ip a | grep dynamic")
except subprocess.CalledProcessError:
Expand Down
119 changes: 119 additions & 0 deletions terraform/scripts/add-remote-user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/usr/bin/env bash

# SPDX-FileCopyrightText: 2023 Technology Innovation Institute (TII)
#
# SPDX-License-Identifier: Apache-2.0

################################################################################

MYNAME=$(basename "$0")
usage () {
echo "Usage: $MYNAME [-u USER] -s SSH_OPTS -k PUB_KEY_PATH"
echo ""
echo "Add a USER to the remote host using SSH_OPTS for the initial login, adding "
echo "public key PUB_KEY_PATH to the USER's authorized_keys on the remote host."
echo ""
echo "Options:"
echo " -h Print this help message"
echo " -u Username to be added to the remote host (default=\$USER)"
echo " -s SSH options used for the initial login to the remote host"
echo " -k Path to the public key that will be added to remote USER's authorized_keys"
echo ""
echo "Example:"
echo ""
echo " Following command adds user new_user to host remote_host allowing "
echo " new_user ssh login to remote_host with key that matches the public "
echo " key ~/.ssh/id_new_user.pub. For the initial login, the command uses "
echo " admin@remote_host -i admin_key:"
echo ""
echo " $MYNAME -s 'admin@remote_host -i admin_key' -u new_user -k ~/.ssh/id_new_user.pub"
echo ""
}

################################################################################

OPTIND=1; OPT_u=""; OPT_s=""; OPT_k=""
while getopts "hu:s:k:" copt; do
case "${copt}" in
h)
usage; exit 0 ;;
u)
OPT_u="$OPTARG" ;;
s)
OPT_s="$OPTARG" ;;
k)
OPT_k="$OPTARG" ;;
*)
echo "Error: unrecognized option"; usage; exit 1 ;;
esac
done
shift $((OPTIND-1))
if [ -n "$*" ]; then
echo "Error: unsupported positional argument(s): '$*'"; exit 1
fi
if [ -z "$OPT_s" ] || [ -z "$OPT_k" ]; then
echo "Error: missing mandatory option(s)"; usage; exit 1
fi
if [ -z "$OPT_u" ]; then
if [ -z "$USER" ]; then
echo "Error: '-u USER' not defined and missing environment variable \$USER"
exit 1;
fi
OPT_u="$USER"
fi

################################################################################

exit_unless_file_exists () {
if ! [ -f "$1" ]; then
echo "Error: File not found: \"$1\""
exit 1
fi
}

test_remote_sudo () {
# shellcheck disable=SC2086 # intented word splitting of $OPT_s
if ! ssh -o ConnectTimeout=5 $OPT_s "sudo -n true"; then
echo "Error: sudo on remote host failed"
exit 1
fi
}

# shellcheck disable=SC2086 # intented word splitting of $OPT_s
# shellcheck disable=SC2029 # intented client side expansion of $OPT_u
add_remote_user () {
if ! ssh $OPT_s "\
sudo useradd -m -d /home/$OPT_u $OPT_u; \
sudo grep -q '$OPT_u ALL=(ALL) NOPASSWD: ALL' /etc/sudoers || \
sudo sh -c \"printf '$OPT_u ALL=(ALL) NOPASSWD: ALL\n' >>/etc/sudoers\"; \
sudo mkdir -p /home/$OPT_u/.ssh; \
sudo touch /home/$OPT_u/.ssh/authorized_keys; \
sudo chown -R $OPT_u:$OPT_u /home/$OPT_u/.ssh; \
sudo chmod 700 /home/$OPT_u/.ssh; \
sudo chmod 600 /home/$OPT_u/.ssh/authorized_keys; \
sudo tee -a /home/$OPT_u/.ssh/authorized_keys; \
" < "$OPT_k";
then
echo "Error: failed adding user to remote host"
exit 1
fi
if ! ssh $OPT_s "\
sudo sort -u /home/$OPT_u/.ssh/authorized_keys -o /home/$OPT_u/.ssh/authorized_keys;";
then
echo "Warning: failed removing duplicates from remote authorized_keys"
fi
}

################################################################################

main () {
exit_unless_file_exists "$OPT_k"
test_remote_sudo
add_remote_user
echo ""
echo "You can now login to remote host as user '$OPT_u' with key '$OPT_k'"
}

main "$@"

################################################################################