Про бомжей и authentication key

Предполагается, что есть bash скрипт /usr/local/bin/run.sh, который запускает другой bash скрипт на удаленном сервере, и получает его выхлоп:

#!/bin/bash

SSH_USER="root"
SSH_HOST="123.45.67.89"
SSH_KEY="/usr/local/share/ssh_keys/my_node"   # Путь к приватному ключу
REMOTE_SCRIPT="/usr/local/bin/send_node_stat.sh" # месторасположение удаленного скрипта

# проверка наличия ключа необязательна, но неплохо помогает при отладке

if [[ ! -f "$SSH_KEY" ]]; then
    echo "Ошибка: ssh ключ не найден по пути $SSH_KEY"
    exit 1
fi

ssh -i "$SSH_KEY" "$SSH_USER@$SSH_HOST" "$REMOTE_SCRIPT" # собственно само выполнение удалённого скрипта

Но, вся фича в том, что нам его нужно выполнить от непривилегированного пользователя-бомжа, а у бомжей, как известно, нет домашней директории.

# создаем бомжа

useradd -r -s /bin/false bomj
usermod -aG sudo bomj

Так как нам нужно выполнять скрипт на удаленном сервере, справедливо настроить для ssh authentication key.

Но, это нужно сделать в каталоге, к которому будет иметь доступ пользователь bomj (также предполагается, что наш бомжара входит в группу run_scripts). В данном случае создаем от пользователя root:

mkdir -p /usr/local/share/ssh_keys
chown -R root:run_scripts /usr/local/share/ssh_keys
chmod -R 750 /usr/local/share/ssh_keys
chmod g+r /usr/local/share/ssh_keys/
ssh-keygen -t ed25519 -f /usr/local/share/ssh_keys/my_node
ssh-copy-id -i /usr/local/share/ssh_keys/my_node.pub root@123.45.67.89

Вроде бы все норм, в скрипте указан верный ключ, но, если мы попробуем запустить этот скрипт под бездомным пользователем, то каждый раз при запуске будем получать предложение ввести yes.

sudo -u bomj /usr/local/bin/run.sh

The authenticity of host '123.45.67.89 (123.45.67.89)' can't be established.

ED25519 key fingerprint is SHA256:or+sERSXpC0EsZZALxphJFxtN9Lt3tTtgr2KGO/xikI.

This key is not known by any other names.

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Could not create directory '/home/bomj/.ssh' (No such file or directory).

Failed to add the host to the list of known hosts (/home/bomj/.ssh/known_hosts).
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Вся штука в том, что у пользователя bomj нет домашней директории, и он не может сделать запись в /home/bomj/.ssh/known_hosts.

Поэтому рассмотрим возможность хранить known_hosts в альтернативном месте. Для этого воспользуемся утилитой ssh-keyscan, которая идёт в стандартном наборе OpenSSH.

Одна из возможностей ssh-keyscan — автоматическое добавление ssh-ключей в файл known_hosts, избегая ручного подтверждения ключа при первом подключении.

# Первый раз нужно будет явно записать fingerprint во сюда вот:

ssh-keyscan 123.45.67.89 >> /usr/local/share/ssh_keys/known_hosts
chown root:run_scripts /usr/local/share/ssh_keys/known_hosts
chmod 640 /usr/local/share/ssh_keys/known_hosts

И немного подправим изначальный скрипт

#!/bin/bash

SSH_USER="root"
SSH_HOST="123.45.67.89"
SSH_KEY="/usr/local/share/ssh_keys/my_node"
KNOWN_HOSTS_FILE="/usr/local/share/ssh_keys/known_hosts"  # Альтернативный known_hosts
REMOTE_SCRIPT="/usr/local/bin/send_node_stat.sh"

if [[ ! -f "$SSH_KEY" ]]; then
    echo "Ошибка: ключ SSH не найден по пути $SSH_KEY"
    exit 1
fi

# тут проверяем known_hosts, если отсутствует — создадим пустой

if [[ ! -f "$KNOWN_HOSTS_FILE" ]]; then
    touch "$KNOWN_HOSTS_FILE"
    chown root:run_scripts "$KNOWN_HOSTS_FILE"
    chmod 640 "$KNOWN_HOSTS_FILE"
fi

ssh -i "$SSH_KEY" -o UserKnownHostsFile="$KNOWN_HOSTS_FILE" "$SSH_USER@$SSH_HOST" "$REMOTE_SCRIPT"