Ubuntu 20.04を実行するRPi4セット(7個)があります。そのうちの1つはGUIであり、そこからコマンドを実行します。 3人の管理者と3人の従業員がいます(/ etc / hostsの両方が正しく設定されています)。
最初は、すべて同じ名前とパスワードを持つユーザーがいます。
パスワードなしのSSHを使用できるように、gui(gui0)で一度実行される単一のスクリプトでSSHを設定したいと思います。
gui*システムはすべてにアクセスでき、Manager*システムは管理者とワーカーにアクセスでき、ワーカーは他のワーカーにのみアクセスできる必要があります。
その理由は、GlusterFS(およびその他のいくつか)を使用してストレージを設定するため、マシンがそれらの間で通信できる必要があるためです。
私はある程度動作するスクリプトを開発しました。特定のコマンド間で眠る時間に応じて、実際にコピーされるキーは多くなりますが、長い間眠っていて、まだ100%ではありません。
スクリプト:
#!/bin/bash
################################################################################
## source ##
################################################################################
source lib/libalx/sh/sysexits.sh; ## This provides EX_USAGE=64
################################################################################
## 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}";
################################################################################
## 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 ${remote} "
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa;
";
done
}
function distribute_ssh_keys_to()
{
local accessible_machines="$1";
# local ssh_opts="-o PreferredAuthentications=keyboard-interactive";
# ssh_opts="${ssh_opts} -o PubkeyAuthentication=no";
for remote in ${accessible_machines}; do
echo " SSH-COPY-ID $(cat /etc/hostname) ${remote};"
sshpass -e ssh-copy-id -i ~/.ssh/id_rsa.pub ${remote} \
2>&1 | grep -e WARNING -e ERROR -e added;
sleep 60;
done
}
function distribute_ssh_keys_from()
{
# ssh_opts="-o PreferredAuthentications=keyboard-interactive";
# ssh_opts="${ssh_opts} -o PubkeyAuthentication=no";
local machines="$1";
local accessible_machines="$2";
for remote in ${machines}; do
sshpass -e ssh ${remote} "
$(declare -fg);
export SSHPASS=${SSHPASS};
distribute_ssh_keys_to \"${accessible_machines}\";
unset SSHPASS;
";
sleep 300;
done
sleep 300;
}
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 ${remote} "
$(declare -fg);
secure_ssh;
";
sleep 60;
done
}
function secure_ssh()
{
:; ## TODO
}
function create_distribute_ssh_keys()
{
read_ssh_password;
create_ssh_keys;
sleep 300;
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;
出力:
ubuntu@gui0:~$ ./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;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID gui0 manager1;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID gui0 manager2;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID gui0 worker0;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID gui0 worker1;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID gui0 worker2;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID manager0 manager0;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID manager0 manager1;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID manager0 manager2;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
SSH-COPY-ID manager0 worker0;
Number of key(s) added: 1
SSH-COPY-ID manager0 worker1;
SSH-COPY-ID manager0 worker2;
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
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;
追加されたキー数、エラー、または警告を示す行を常に受け取りたいです。ただし、場合によってはINFO行のみを受け取ります(私はgrepを使用してその行をノイズとして削除します)。見てわかるように、最初のいくつかはうまくいきます(最初に実行したものではないので警告が表示されるため、以前の実行でキーがすでにインストールされていますが、大丈夫です)。失敗し、すべての失敗が失敗しました。
眠りにつくと早く失敗し始めます。
grepを使用しないときに何が起こるかの例は次のとおりです。
SSH-COPY-ID manager0; worker0;
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ubuntu/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'worker0'"
and check to make sure that only the key(s) you wanted were added.
SSH-COPY-ID manager0; worker1;
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ubuntu/.ssh/id_rsa.pub"
SSH-COPY-ID manager0; worker2;
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ubuntu/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'worker2'"
and check to make sure that only the key(s) you wanted were added.
なぜそんなに不規則に失敗するのですか?
答え1
私はあなたがなぜそれほど長い言葉を広げたのか理解できずsleep
、私はあなたのプログラムの流れを正しく追跡したと信じていません。ただし、要件に応じて、以下が必要です。
gui* マシンはすべてにアクセスできる必要があり、Manager* マシンは管理者とワーカーにアクセスできる必要があり、ワーカーは他のワーカーにのみアクセスできる必要があります。
だから
- GUI→GUI管理者ワーカー
- 管理者→管理者ワーカー
- 労働者→労働者
それではそうします。あなたは自分の進捗状況の更新と終了ステータスを追加したいと確信していますが、この基本的な要素が役に立ちます。
#!/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
クライアント()によって制御され、このプロセス中に管理者またはワーカーは他のコンピュータにファイルのコピーを開始しません。
答え2
主な理由は、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.