Это было бы верно, если бы вы установили разрешение для домашнего каталога на 700. Но это не настройка по умолчанию. На сервере Ubuntu домашний каталог нового пользователя получает «drwxr -xr -x». Это дает вескую причину установить некоторые индивидуальные разрешения для ваших файлов и каталогов.
Я не понимаю, почему вы разбросали длинные sleep
операторы, и я не уверен, что правильно отследил поток вашей программы. Однако, глядя на требования, вам нужно
The gui* machines should have access to all; manager* machines should have access to managers and workers; and workers should only be able to access other workers
Итак,
Что-то вроде этого. Я уверен, вы захотите добавить свои собственные обновления прогресса и статус выхода, но этот базовый набор должен заставить вас работать.
#!/bin/bash
#
guis=(gui0)
managers=(manager0 manager1 manager2)
workers=(worker0 worker1 worker2)
# Grab the password
#
IFS= read -rsp "Master password: " sshpass && echo
# First, GUI to everything
#
if [[ ! -f "$HOME/.ssh/id_rsa" ]] || [[ ! -f "$HOME/.ssh/id_rsa.pub" ]]
then
# Start clean
rm -f "$HOME/.ssh/id_rsa" "$HOME/.ssh/id_rsa.pub"
ssh-keygen -t rsa -b 4096 -f "$HOME/.ssh/id_rsa" -P ""
fi
for dst in "${guis[@]}" "${managers[@]}" "${workers[@]}"
do
# Using the password we entered at the beginning, copy the keys everywhere
SSHPASS=$sshpass sshpass -ev ssh-copy-id -o StrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" "$dst"
done
# Now generate a key on each host in turn
#
for dst in "${managers[@]}" "${workers[@]}"
do
# Ensure the target is clean and then generate a new key
ssh -n "$dst" 'rm -f.ssh/id_rsa.ssh/id_rsa.pub'
ssh -n "$dst" 'ssh-keygen -t rsa -b 4096 -f.ssh/id_rsa -P ""'
done
# Grab each host's key pair
#
for src in "${managers[@]}" "${workers[@]}"
do
scp -p "$src:.ssh/id_rsa" "$HOME/.ssh/id_rsa.$src"
scp -p "$src:.ssh/id_rsa.pub" "$HOME/.ssh/id_rsa.$src.pub"
done
# Push each Manager key out to the Managers and Workers
#
for src in "${managers[@]}"
do
for dst in "${managers[@]}" "${workers[@]}"
do
ssh-copy-id -i "$HOME/.ssh/id_rsa.$src" "$dst"
done
done
# Push each Worker key out to the Workers
#
for src in "${workers[@]}"
do
for dst in "${workers[@]}"
do
ssh-copy-id -i "$HOME/.ssh/id_rsa.$src" "$dst"
done
done
# Now fix up the "authenticity of host" warnings by connecting everywhere
#
for src in "${managers[@]}"
do
for dst in "${managers[@]}" "${workers[@]}"
do
ssh -n "$src" ssh -n -o StrictHostKeyChecking=no "$dst" id >/dev/null
done
done
for src in "${workers[@]}"
do
for dst in "${workers[@]}"
do
ssh -n "$src" ssh -n -o StrictHostKeyChecking=no "$dst" id >/dev/null
done
done
# Delete the unwanted key pairs from this host
#
for src in "${managers[@]}" "${workers[@]}"
do
rm -f "$HOME/.ssh/id_rsa.$src" "$HOME/.ssh/id_rsa.$src.pub"
done
# All done
#
exit 0
Обратите внимание, что все управляется с клиента (gui0
), и во время процесса ни один из менеджеров или рабочих не инициирует копирование какого-либо файла на любую другую машину.
Основная причина заключалась в том, что SSH не знал хостов (~/.ssh/known_hosts
), поэтому предлагал добавить новые хосты в файл. Разумеется, сценарий никак не мог на это отреагировать.
Решение было простым, как отметил @roaima в комментарии к своему ответу :ssh... -o StrictHostKeyChecking=no
В моем сценарии было несколько других проблем, которые я исправил (Я также улучшил несколько вещей благодаря коду @roaima ).
Для тех, кому это может понадобиться в будущем, вот мой рабочий скрипт:
#!/bin/bash
set -Eeo pipefail
################################################################################
##
## Set up ssh network
## ==================
##
## Run this script from a guiX machine
##
################################################################################
################################################################################
## source ##
################################################################################
source lib/libalx/sh/sysexits.sh;
################################################################################
## definitions ##
################################################################################
ARGC=0;
guis=(gui0);
managers=(manager0 manager1 manager2);
workers=(worker0 worker1 worker2);
all_machines="${guis[*]} ${managers[*]} ${workers[*]}";
gui_accessible_machines="${all_machines}";
manager_accessible_machines="${managers[*]} ${workers[*]}";
worker_accessible_machines="${workers[*]}";
ssh_opts='-o StrictHostKeyChecking=no';
################################################################################
## functions ##
################################################################################
## XXX: Pair calls to this function with "unset SSHPASS"!!!
function read_ssh_password()
{
echo "This script will set up keyless ssh."
echo "After this script, ssh will not accept passwords again."
echo "Enter the current password for ssh connections."
read -s -p "Password to use: " SSHPASS;
echo;
export SSHPASS;
}
function create_ssh_keys()
{
for remote in ${all_machines}; do
echo " SSH-KEYGEN ${remote};"
sshpass -e ssh ${ssh_opts} ${remote} "
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -P '' ||:;
";
done
}
function distribute_ssh_keys_to()
{
local accessible_machines="$1";
for remote in ${accessible_machines}; do
echo " SSH-COPY-ID $(cat /etc/hostname) ${remote};"
sshpass -e ssh-copy-id -i ~/.ssh/id_rsa.pub ${ssh_opts} \
${remote} \
2>&1 | { grep -e WARNING -e ERROR ||:; };
done
}
function distribute_ssh_keys_from()
{
local machines="$1";
local accessible_machines="$2";
for remote in ${machines}; do
sshpass -e ssh -n ${ssh_opts} ${remote} "
set -Eeo pipefail
$(declare -fg);
export SSHPASS=\"${SSHPASS}\";
ssh_opts=\"${ssh_opts}\";
distribute_ssh_keys_to \"${accessible_machines}\";
unset SSHPASS;
";
done
}
function distribute_ssh_keys()
{
distribute_ssh_keys_from "${guis[*]}" "${gui_accessible_machines}";
distribute_ssh_keys_from "${managers[*]}" "${manager_accessible_machines}";
distribute_ssh_keys_from "${workers[*]}" "${worker_accessible_machines}";
for remote in ${all_machines}; do
ssh -n ${remote} "
$(declare -fg);
secure_ssh;
";
done
}
function secure_ssh()
{
:; ## TODO
}
function create_distribute_ssh_keys()
{
read_ssh_password;
create_ssh_keys;
distribute_ssh_keys;
unset SSHPASS;
}
################################################################################
## main ##
################################################################################
function main()
{
create_distribute_ssh_keys;
}
################################################################################
## run ##
################################################################################
argc=$#;
if [ ${argc} -ne ${ARGC} ]; then
echo "Illegal number of parameters (Requires ${ARGC})";
exit ${EX_USAGE};
fi
main;
################################################################################
## end of file ##
################################################################################
Со следующим выходом:
$./bin/setup_ssh.sh
This script will set up keyless ssh.
After this script, ssh will not accept passwords again.
Enter the current password for ssh connections.
Password to use:
SSH-KEYGEN gui0;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-KEYGEN manager0;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-KEYGEN manager1;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-KEYGEN manager2;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-KEYGEN worker0;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-KEYGEN worker1;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-KEYGEN worker2;
Generating public/private rsa key pair.
/home/ubuntu/.ssh/id_rsa already exists.
Overwrite (y/n)? n
SSH-COPY-ID gui0 gui0;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID gui0 manager0;
SSH-COPY-ID gui0 manager1;
SSH-COPY-ID gui0 manager2;
SSH-COPY-ID gui0 worker0;
SSH-COPY-ID gui0 worker1;
SSH-COPY-ID gui0 worker2;
SSH-COPY-ID manager0 manager0;
SSH-COPY-ID manager0 manager1;
SSH-COPY-ID manager0 manager2;
SSH-COPY-ID manager0 worker0;
SSH-COPY-ID manager0 worker1;
SSH-COPY-ID manager0 worker2;
SSH-COPY-ID manager1 manager0;
SSH-COPY-ID manager1 manager1;
SSH-COPY-ID manager1 manager2;
SSH-COPY-ID manager1 worker0;
SSH-COPY-ID manager1 worker1;
SSH-COPY-ID manager1 worker2;
SSH-COPY-ID manager2 manager0;
SSH-COPY-ID manager2 manager1;
SSH-COPY-ID manager2 manager2;
SSH-COPY-ID manager2 worker0;
SSH-COPY-ID manager2 worker1;
SSH-COPY-ID manager2 worker2;
SSH-COPY-ID worker0 worker0;
SSH-COPY-ID worker0 worker1;
SSH-COPY-ID worker0 worker2;
SSH-COPY-ID worker1 worker0;
SSH-COPY-ID worker1 worker1;
SSH-COPY-ID worker1 worker2;
SSH-COPY-ID worker2 worker0;
SSH-COPY-ID worker2 worker1;
SSH-COPY-ID worker2 worker2;
Тестирование:
ubuntu@gui0:~$ ssh manager0 'ssh worker2 cat /etc/hostname'
worker2
ubuntu@gui0:~$ ssh worker2 'ssh manager1 cat /etc/hostname'
Host key verification failed.