Вопрос или проблема
Есть ли способ разумно сделать это:
scp user@host:/path/to/file /dev/tty | openssl [options] | less
без создания файла и без необходимости указывать пароль непосредственно в аргументах?
Проблема в том, что оба процесса запрашивают пароль, но порядок их запуска (и, следовательно, порядок, в котором они запрашивают пароль) неопределен.
Было бы нормально сначала завершить scp
, а затем запустить openssl
, но без временного файла.
Возможные решения на данный момент
- положить вывод
scp
в переменную, а затем из переменной вopenssl
(это будет осуществимо только для небольших файлов, и я подозреваю, что могут возникнуть проблемы с бинарными данными и т.д.) - положить пароли в файлы (не лучший вариант)
- использовать ключи (лучше?)
- использовать именованные каналы
Версия именованных каналов 1
mkfifo pipe && {
scp user@host:/path/to/file pipe # запрашивает пароль, затем ждет
# завершения чтения из канала,
# что произойдет только после того,
# как был введен пароль для openssl
# => нужно ^Z и ввести пароль
# => `pipe: Interrupted system call'
openssl [options] -in pipe | less
}
Версия именованных каналов 2
mkfifo pipe && {
scp user@host:/path/to/file pipe & # запрашивает пароль (и работает, когда
# введен пароль) несмотря на то, что
# помещен в фоновый режим (что? как?
# может кто-то объяснить?)
openssl [options] -in pipe | less # `bad password read'
}
Версия именованных каналов 3
mkfifo pipe && {
scp user@host:/path/to/file pipe | # сначала запрашивает пароль
openssl [options] -in pipe | less # запрашивает пароль после того, как
# был введен пароль от scp
# и все работает нормально
}
Поменять команды местами не помогает.
openssl [options] -in <(scp user@host:/path/to/file /dev/tty) | less
не работает.
Может кто-то
- предложить другое решение,
-
объяснить необычное поведение scp в примере 1 (`Interrupted system call’) (я предполагаю, что это либо ошибка, либо некое “защитное свойство”),
-
объяснить, как работает ввод паролей, например, как задача, которая была запущена в фоновом режиме, может читать из stdin,
- (связано с 3.) объяснить, почему scp в примере 2 выводит запрос пароля, даже если stdout и stderr перенаправлены в
/dev/null
?
scp user@host:/path/to/file /dev/tty
пытается отправить содержимое удаленного файла в tty, а не в канал для openssl
.
Насколько мне известно, ssh/scp не позволяют считывать пароли из stdin, вы можете использовать sshpass
, если не можете воспользоваться более безопасными способами аутентификации. scp
предназначен для копирования файлов, а не для вывода их содержимого. Вы можете использовать ssh cat
вместо этого или даже сжимать данные на лету, чтобы сэкономить трафик.
И sshpass
, и openssl
поддерживают ввод паролей из переменных окружения.
SSHPASS=$password_for_ssh sshpass -e ssh host 'gzip -3 < /path/to/file' |
gunzip |
PASS=$password_for_openssl openssl -passin env:PASS ...
Ответ или решение
Для решения проблемы, связанной с использованием команд scp
и openssl
с запросом пароля из стандартного ввода, можно рассмотреть несколько подходов. Основная цель — обойти необходимость временных файлов и избежать прямого ввода паролей в командной строке.
Возможное решение
Одним из наиболее элегантных и безопасных способов является использование утилиты sshpass
в сочетании с передачей данных через стандартный ввод. Вы можете передать пароли через переменные окружения, что значительно повышает безопасность по сравнению с их явным указанием в командной строке.
Пример команды может выглядеть следующим образом:
SSHPASS='ваш_пароль_для_ssh' sshpass -e ssh user@host 'gzip -c /path/to/file' | \
PASS='ваш_пароль_для_openssl' openssl enc -d -aes-256-cbc -pass env:PASS | less
Пояснение:
-
Использование
sshpass
:- Утилита
sshpass
позволяет передавать пароль для аутентификации SSH, используя переменную окружения или файл. В данном примере используется переменная окружения (-e
), содержащая пароль. - Команда
ssh
подключается к удаленному хосту и передает файл черезgzip
, который сжимает данные и отправляет их в стандартный вывод.
- Утилита
-
openssl
и передача пароля:- Утилита
openssl
позволяет передавать пароль для расшифровки через переменную окружения (-pass env:PASS
). - В данном примере
openssl
ожидает входящие данные отgzip
, которые затем передаются вless
для построчного просмотра.
- Утилита
Объяснения поведения:
-
Необычное поведение
scp
в первом варианте:- Команда
scp
ожидает завершения ввода, иInterrupted system call
может возникать из-за того, что процесс был прерван (например, когда происходит попытка прерывания операции чтения изpipe
). Это поведение может быть связано с особенностями синхронизации между процессами и механикой работы с stdin/stdout.
- Команда
-
Вход пароля из фонового процесса:
- Процессы, запущенные в фоновом режиме, могут все еще взаимодействовать с stdin, если они не полностью отсоединены от терминала. Это может породить путаницу, но соль заключается в том, что
scp
продолжает ожидать ввода, даже если он запущен в фоне.
- Процессы, запущенные в фоновом режиме, могут все еще взаимодействовать с stdin, если они не полностью отсоединены от терминала. Это может породить путаницу, но соль заключается в том, что
-
Вывод
scp
, перенаправленный в/dev/null
:- Программа
scp
выводит запрос пароля в стандартный вывод на tty.h, и, даже если stdout и stderr перенаправлены, её поведение остается прежним — запрос пароля осуществляется через терминал. Такой подход считается стандартным для программ, требующих интерактивного ввода.
- Программа
Использование предложенной схемы с sshpass
и openssl
позволит без труда обойти проблему с вводом пароля и обеспечит надежный способ обработки данных из удаленного хоста без создания временных файлов.