Как использовать sshpass?


28

Мне нужно использовать sshpassдля запуска удаленной команды через SSH из кода Java.

Если я вручную наберу в консоли:

ssh -p 22 user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'

работает отлично, но просит пароль. Итак, я попытался запустить sshpass:

sshpass -p mypass ssh -p 22 user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh -l user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh -t user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh user@ipaddress echo 'OK'

и никто из них не работает.

Ответы:


28

Это может быть вызвано проверками ключа хоста, выполненными ssh. Похоже , sshpassне умалчивает о недействительных ключах хоста (не выводят на ни stderrни stdout) и существует с код_состоянием 6. На момент написания этой статьи это была ревизия 50, и в коде есть константа соответствия RETURN_HOST_KEY_UNKNOWN, которая указывает на эту ошибку.

Ваш код ошибки может отличаться, и просмотр приведенного выше кода может дать вам некоторое представление.

Если ваша проблема заключается в неверном ключе хоста, вам следует дважды подумать о переопределении ошибки с помощью параметра CLI. Ваша машина может быть взломана или вы можете подвергнуться атаке MITM! Если вы на 100% уверены, что это не так, и если у вас нет средств для обновления проверенных ключей хоста, вы можете использовать команду, подобную этой:

sshpass -pfoobar ssh -o StrictHostKeyChecking=no user@host command_to_run

2
При установке brew после -p требуется пространство. github.com/hudochenkov/homebrew-sshpass
AnneTheAgile

ВНИМАНИЕ: Каждый должен помнить, что безопаснее использовать парольные SSH Host Keys, когда это возможно! По определению использование SSHPass менее безопасно.
Вопросительный

@Questionmark, хотя это так, существуют крайние случаи, когда удаленная конечная точка не поддерживает аутентификацию с помощью ключа. Вот где пригодится
sshpass

Да, я знаю. Вот почему я сказал «по возможности» ...
Вопросительный

1
С новым достаточно SSH, есть StrictHostKeyChecking=accept-new.
Муру

5

sshpassработает только в том случае, если запрос пароля заканчивается assword:.

Если ваша подсказка пароля отличается, вам, возможно, придется изменить исходный код, sshpassчтобы распознать вашу подсказку.

Я видел пароли, как Password for user@host:в некоторых системах, возможно, это ваша проблема.


1
извиняюсь? -P prompt Which string should sshpass search for to detect a password prompt
m3nda

2
Эта новая опция (требуется как минимум v1.0.6 sshpass) решает эту проблему.
rjs

Ой, извини. Такого рода проблема (решение?) Возникает так часто, старые вопросы, которые уже исправлены в новых версиях. Спасибо.
m3nda

2

Я думаю, что вы хотите что-то вроде:

sshpass -p yourpassword ssh user@ipaddress somecommand

Например, это работает для меня:

sshpass -p mypassword ssh username@10.0.0.9 touch foo

1

Вы установили логин без пароля?

Вход в систему без пароля с OpenSSH http://www.debian-administration.org/articles/152


Я бы предпочел придерживаться sshpass из-за неудобств, связанных с включением входа без пароля на предприятии
Roman Rdgz

Вы пробовали это: sshpass -p 'mypass' ssh username@server.example.com
koni_raid

Я сделал, не имеет значения, использую ли я «mypass» или mypass. Он начинает ждать вечно
Roman Rdgz

sshpass -V работает?
koni_raid

На нем напечатано: «Эта программа является свободным программным обеспечением и может распространяться в соответствии с условиями лицензии GPL. Для получения дополнительной информации см. Файл COPYING». А затем завершает свое выполнение и больше ничего не делает (я попытался добавить -V в начало команды, которую я обрабатывал, а не просто набрать sshpass -V)
Roman Rdgz

1

Есть много способов сделать это, вот мое предлагаемое решение:

Прежде всего, хранение вашего пароля в переменной дает вам более гибкие команды. sshpassесть вариант для этого:

-e: эта опция позволяет читать пароль из $SSHPASSпеременной окружения

У вас есть два способа установить эту переменную:

  1. Установите прямо в своем коде:

    export SSHPASS='your_pass'
    
  2. Или попросить об этом:

    readPassword () {
      echo Ssh Password: 
      read -s SSHPASS
      eval "export SSHPASS='""$SSHPASS""'"
    }
    
    # read password
    
    readPassword
    

Чем выполнить вашу команду;

  1. Если ваша команда статическая, запустите ее напрямую:

    sshpass -e ssh user@host << EOF
    mplayer '/media/data/myFavouriteSong.mp3'
    command2 parameter1 parameter2 parameter3 ...
    command3 parameter1 parameter2 parameter3 ...
    ...
    EOF
    
  2. Если ваша команда будет динамической, используйте вот так:

    DYN_FILE_LOC='/media/data/myFavouriteSong.mp3'
    
    eval 'sshpass -e ssh user@host << EOF
    mplayer "$DYN_FILE_LOC"
    command2 parameter1 parameter2 parameter3 ...
    command3 parameter1 parameter2 parameter3 ...
    ...
    EOF'
    

надеюсь, это поможет кому-то.


В вашей функции readPassword вы не можете просто сделать экспорт SSHPASS?
kutschkem

@kutschkem, я верю, но моя идея, что я думаю здесь; я не хочу писать свой пароль в статическом файле, но вместо того, чтобы снова и снова писать пароль для большого количества серверов (7+), я пишу один раз :) Вам не нужно использовать readPasswordфункцию, вы можете просто написать свой пароль, это должен работать :) Только я хочу поделиться своим кодом, который показывает пример использования sshpassдля динамических команд: D
veysiertekin

Нет, я просто имею в виду, что eval не нужен после чтения, экспорт не требует назначения. ss64.com/bash/export.html
kutschkem,

проблема с -e в том, что экспорт будет указан в вашей истории
ejaenv

0

sshpassиспользует псевдотерминалы, и manстраница содержит извинения за случайные нарушения. Вы также можете попробовать fd0ssh. Это работает, если вам не нужно отправлять stdinпроцесс на удаленную машину. Это работает, если вы просто выполните команду и получите результат.


0

синтаксис sshpass

sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments

Обратите внимание, что между -p и паролем нет пробела.

Также я заметил, что вам необходимо хотя бы один раз подключиться к ssh вручную, чтобы получить ключ RSA компьютера, к ~/.ssh/known_hostsкоторому вы подключаетесь , чтобы войти в файл, прежде чем sshpass позволит вам подключиться.

поэтому после получения записи в файле known_hosts я могу выполнить команду, такую ​​как

sshpass -ffilename_with_password_in_it ssh user@server uname -a

и он выполнит команду uname -aна удаленном сервере и выведет результаты на стандартный выход на локальном компьютере.


0

Что вам нужно -f -t -t -t

sshpass -p$PASS ssh -f -t -t -t $USER@$HOST $COMMAND

Кроме того, вам может потребоваться удалить «requiretty» из конфигурации sudo (/ etc / sudoers) на удаленной машине.


0
  1. сделать ключ

    ssh-keygen -t rsa

  2. создайте папку .ssh на удаленном сервере, он попросит пароль

    ssh $USER@SEVERNAME mkdir -p .ssh

  3. скопировать ключ на удаленный сервер

    cat .ssh/id_rsa.pub | ssh $USER@SERVER 'cat >> .ssh/authorized_keys'


Проверьте, запрашивает ли он пароль, если нет, он должен работать.

ssh $USER@SEVERNAME 'command'

0

У @exhuma был пример, который привел меня к работе.

Пароль должен быть в форме -pPassword(без пробела)

Также могут быть необходимы кавычки: sshpass -p'Password&0' user@hostname

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.