Я использую Ubuntu 11.10. Я использую ssh для подключения ко многим серверам ежедневно, поэтому я поместил их параметры в файл .ssh/config
; например:
Host Home
User netmoon
Port 22
HostName test.com
Есть ли способ поместить пароли в этот файл для каждого соединения? Поэтому, когда сервер запрашивает пароль, терминал передает свой пароль и отправляет его на сервер.
Это потому, что иногда я стою в стороне от компьютера, а когда я возвращаюсь и набираю пароль, и нажимаю ввод, терминал говорит, что СОЕДИНЕНИЕ ЗАКРЫТО.
Обмен безопасности для удобства никогда не заканчивается хорошо ...
Не могли бы вы использовать ssh-copy-id
из пакета openssh-client
?
Из man ssh-copy-id
:
ssh-copy-id - это скрипт, который использует ssh для входа на удаленный компьютер и добавления указанного идентификационного файла в файл ~ / .ssh / authorized_keys этого компьютера.
BLOCKQUOTE>
Если вы на самом деле не хотите использовать пару открытый / закрытый ключ, вы можете написать сценарий expect
для автоматического ввода пароля в зависимости от адреса назначения.
Редактировать: я имею в виду, что у вас может быть сценарий, который, с одной стороны, использует expect
для ввода пароля для вас, а с другой стороны, считывает пароль для данного пользователя и хоста из конфигурации файл. Например, следующий сценарий python будет работать для сценария солнечного дня:
#!/usr/bin/python
import argparse
from ConfigParser import ConfigParser
import pexpect
def main(args):
url = args.url
user, host = url.split('@', 1)
cfg_file = 'ssh.cfg'
cfg = ConfigParser()
cfg.read(cfg_file)
passwd = cfg.get(user, host)
child = pexpect.spawn('ssh {0}'.format(url))
child.expect('password:')
child.sendline(passwd)
child.interact()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Run ssh through pexpect')
parser.add_argument('url')
args = parser.parse_args()
main(args)
и формат файла конфигурации будет следующим:
[user_1]
host1 = passwd_1
host2 = passwd_2
[user_2]
host1 = passwd_1
host2 = passwd_2
Примечание. Как объяснено, python сценарий должен быть намного более сложным, чтобы обрабатывать все возможные ошибки и сообщения с вопросами из ssh и все возможные URL-адреса (в примере предполагается, что это будет что-то вроде user@host
, но пользовательская часть не используется большинство времена), но основная идея была бы все та же. Что касается файла конфигурации, вы можете использовать другой файл конфигурации или использовать .ssh/config
и написать свой собственный код для анализа этого файла и получения пароля для данного пользователя и хоста.
Нет. Боюсь, это невозможно.
Единственная реальная альтернатива - использовать закрытые ключи, но вы сказали, что не хотите (почему бы и нет?).
Отвечая на заданный вопрос, нет, невозможно настроить пароль по умолчанию в файле конфигурации ssh.
Но если действительно, как вы говорите, « Это потому, что иногда я стою в стороне от компьютера, и когда я возвращаюсь и набираю пароль и нажимаю ввод, терминал сказал, что СОЕДИНЕНИЕ ЗАКРЫТО. », то почему бы не предотвратить вместо этого закрывать сессию? SSH может поддерживать связь для вас.
Host Home
User netmoon
Port 22
HostName test.com
ServerAliveInterval 300
ServerAliveCountMax 2
Вы можете создать простую замену сценария ssh в / usr / local / bin:
#!/bin/bash
host=$1
password=`awk "/#Password/ && inhost { print \\\$2 } /Host/ { inhost=0 } /Host $host/ { inhost=1 }" ~/.ssh/config`
if [[ -z "$password" ]]; then
/usr/bin/ssh $*
else
sshpass -p $password /usr/bin/ssh $*
fi
А затем в вашем файле ~ / .ssh / config вы можете использовать
Host foohost
User baruser
#Password foobarpassword
Ответ @BrunoPereira на на этот вопрос показывает альтернативный способ подключения без явного ввода пароля и обхода ключей ssh.
Вы можете создать скрипт, псевдоним или функцию в ~/.bashrc
для быстрого выполнения этой команды.
Очевидно, есть соображения безопасности, которые вы должны принять во внимание при таком подходе.
Спасибо Ареку за вдохновение ...
Вместо запуска другого процесса оболочки это просто функция, выполняемая в текущей оболочке bash. Он запускает один awk, чтобы проанализировать файл конфигурации и выяснить, брать ли пароль из переменной оболочки или из открытого текста пароля в файл конфигурации ssh (с awk в eval, а не description, из-за проблем, с которыми я столкнулся при использовании description). Я пробовал так много способов использовать sshpass напрямую в конфигурационном файле ssh с использованием ProxyCommand, но, похоже, ничего не работало, как ожидалось, за исключением случаев, когда я мог войти в ящик через rsa, но затем мне нужно было отправить пароль, чтобы открыть мой зашифрованный каталог. Тем не менее, моя функция ниже, кажется, работает для меня во всех случаях, даже для Cygwin.
# In your .bash_profile
function ssh(){
host=$1;
unset PASSWORD
unset PASSVAR
eval $(awk "/#[Pp]assvar / && inhost { printf \"PASSVAR=%s\",\$2; exit 1 } /#[Pp]assword / && inhost { printf \"PASSWORD=%s\",\$2; } /^[Hh][oO][sS][tT] / && inhost { inhost=0; exit 1 } /^[Hh][oO][sS][tT] $host\$/ { inhost=1 }" ~/.ssh/config)
if [[ -z "$PASSWORD" ]] && [[ -z "$PASSVAR" ]]; then
/usr/bin/ssh -q $* 2>/dev/null
else
if [[ -n "$PASSVAR" ]]; then
PASSWORD=$(TMP=${!PASSVAR-*};echo ${TMP##*-})
fi
/usr/local/bin/sshpass -p"$PASSWORD" /usr/bin/ssh -q $* 2>/dev/null
fi
}
# and setup your passwords (perhaps in .bashrc instead...)
MYPASS_ENVVAR=SomePassword
MYPASSWD_FROM_FILE=$(</home/me/.passwd_in_file)
Тогда секция ~/.ssh/config
выглядит следующим образом:
Host MyHostname
Port 22
Hostname 2.1.2.2
User merrydan
#Passvar MYPASS_ENVVAR
#Password Some!Password
Если в секции конфигурации существует #Passvar
, это переопределяет #Password
.
$MYPASS_ENVVAR
- это переменная окружения, содержащая ваш пароль.
Наслаждайтесь!
Я использую приложение от VanDyke Software под названием SecureCRT .
http://www.vandyke.com/products/securecrt/
Это не бесплатно, но по очень разумной цене. Я использовал его в течение многих лет (работает на Windows или с помощью Wine) для удаленного доступа, эмуляции терминала и (рассеянного) управления сетью. Наконец, они выпустили собственную версию Linux для этого в начале 2011 года.
Он поддерживает сложные настройки входа (или сценарии), сохраненные пароли (или сертификаты), вкладки нескольких сеансов и т. Д.
При запуске вы можете выбрать, какая удаленная цель (и протокол) из структурированного списка (древовидное представление) сохраненных удаленных (или локальных) машин, или просто создать соединение (которое затем сохраняется).
Я считаю, что это особенно полезно для удаленных сайтов с расширенной аутентификацией, нестандартными портами или согласованием доступа через брандмауэр.
Если вы часто делаете удаленный доступ (часть вашей основной роли), то это приложение оправдывает свои расходы в первый месяц использования.
Как насчет ProxyCommand:
Host Home-raw
HostName test.com
Host Home
User netmoon
Port 22
ProxyCommand sshpass -pmypass ssh netmoon@%h-raw nc localhost %p
Вы также можете использовать ssh -W
вместо nc
:
ProxyCommand sshpass -pmypass ssh netmoon@%h-raw -W localhost:%p
Есть также sshpass
программа для этого. Как использовать: sshpass -p MyPa55word ssh me@myservor.com
Вот мой сложный вариант ответа @ ArekBurdach. Он предлагает следующие расширения:
ssh
; то есть он также поддерживает синтаксис ssh <args> <host> <commands>
ssh
ssh_config
ssh-wrapper
#!/bin/bash
password=$(awk '
BEGIN {
# Collect the SSH arguments as keys of a dictionary, so that we can easily
# check for inclusion.
for (i = 2; i < ARGC; i++) {
sshArgs[ARGV[i]] = 1
}
# Only process the first argument; all others are the command-line arguments
# given to ssh.
ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
if ($2 in sshArgs)
inhost=1
else
inhost=0
}
' ~/.ssh/config "$@")
if [ "$password" ]; then
sshpass -p "$password" "$(which ssh)" "$@"
else
"$(which ssh)" "$@"
fi
scp-wrapper
#!/bin/bash
password=$(awk '
BEGIN {
# Collect the SCP arguments as keys of a dictionary, so that we can easily
# check for inclusion.
for (i = 2; i < ARGC; i++) {
colonIdx = index(ARGV[i], ":")
if (colonIdx > 0) {
scpArgs[substr(ARGV[i], 1, colonIdx - 1)] = 1
}
}
# Only process the first argument; all others are the command-line arguments
# given to scp.
ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
if ($2 in scpArgs)
inhost=1
else
inhost=0
}
' ~/.ssh/config "$@")
if [ "$password" ]; then
sshpass -p "$password" "$(which scp)" "$@"
else
"$(which scp)" "$@"
fi
Определите псевдонимы в ~/.bashrc
]:
alias ssh=ssh-wrapper
alias scp=scp-wrapper
С помощью директивы IgnoreUnknown
ssh
не жалуется на недавно введенную директиву Password
, поэтому (в отличие от ответа @ ArekBurdach), мы можем сделать это «реальной» конфигурацией. Если вам не нравится это, тривиально заменить сценарий обратно на закомментированный.
# Allow specifying passwords for Host entries, to be parsed by ssh-wrapper.
IgnoreUnknown Password
Host foohost
User baruser
Password foobarpassword
Если у вас нет прямого доступа к паре ключей, вы можете зашифровать пароль на своем локальном компьютере.
Способ сделать это - зашифровать ваш пароль с помощью ключа в дополнение к ProxyCommand @Eric Woodruff.
Способ объединения заключается в использовании трубы:
openssl rsautl -decrypt -inkey /path/to/decrypt_key -in /path/to/encrypted_password | sshpass ssh real-destination -tt
где
Host real-destination
Hostname test.com
User netmoon
Существует небольшой вариант пути, описанного в блоге о том, как использовать sshpass
который может быть найден здесь. Учитывая, что у Вас есть gpg зашифрованный пароль (как ot делают это описано в блоге), файл, Вы могли сделать что-то вроде этого:
sshpass -p $(echo $(gpg -d -q .sshpasswd.gpg)) ssh your_desination.xyz
и просто сохраните ту команду как псевдоним в Вашем .bashrc
.
Если Вы хотите туннелировать посредством того соединения, Вы могли бы сделать что-то как
Host actual_dest
Hostname actual.dest.xyz
User username
ProxyCommand sshpass -p $(echo $(gpg -d -q ~/.sshpasswd.gpg)) \
ssh your_destination.xyz nc %h %p
Поскольку я не могу найти документацию о том, как реализовать аутентификацию на основе ключей для сервера Windows ssh, я вынужден использовать аутентификацию по паролю для доступа к файлам и каталогам, размещенным в Windows.
Ниже приведены рабочие версии Python3 программ-оболочек ssh и scp в ответе @IngoKarkat. Это предполагает, что вы храните пароль в ~/.ssh/config
, как он предлагает:
# Allow specifying passwords for Host entries, to be parsed by ssh-wrapper and scp-wrapper.
IgnoreUnknown Password
Host foohost
User baruser
Password foobarpassword
Перед запуском этих программ сначала установите sshconf
библиотеку Python:
$ pip3 install sshconf
Эти программы сначала пытаются найти пароль, и если он недоступен, они возвращаются к аутентификации на основе ключа.
ssh
#!/usr/bin/env python3
from __future__ import print_function
import shutil, subprocess, sys
from sshconf import read_ssh_config
from os.path import expanduser
c: str = read_ssh_config(expanduser("~/.ssh/config"))
if len(sys.argv) == 1:
print(f"Usage: {sys.argv[0]} host [command]")
sys.exit(1)
if shutil.which("sshpass") == None:
print("Please install sshpass and retry.")
sys.exit(2)
host: str = sys.argv[1]
try:
password: str = c.host(host)["password"]
command = [ "sshpass", f"-p{password}", "ssh", host ] + sys.argv[2:]
except KeyError:
command = [ "ssh", host ] + sys.argv[2:]
subprocess.run(command)
scp
#!/usr/bin/env python3
# Python3 version of https://askubuntu.com/a/878335/58760
#
# See https://github.com/sorend/sshconf
#
# pip3 install sshconf
from __future__ import print_function
import shutil, subprocess, sys
from sshconf import read_ssh_config
from os.path import expanduser
c: str = read_ssh_config(expanduser("~/.ssh/config"))
if len(sys.argv) < 3:
print(f"""Usage:
{sys.argv[0]} /dir1 host2:/dir2
{sys.argv[0]} host1:/dir1 /dir2""")
sys.exit(1)
if shutil.which("sshpass") == None:
print("Please install sshpass and retry.")
sys.exit(2)
try:
host = sys.argv[1].rsplit(":", 1)[0]
password: str = c.host(host)["password"]
command = [ "sshpass", f"-p{password}" ]
except KeyError:
try:
host = sys.argv[2].rsplit(":", 1)[0]
password: str = c.host(host)["password"]
command = [ "sshpass", f"-p{password}" ]
except KeyError:
command = [ ]
command = command + [ "scp" ] + sys.argv[1:]
subprocess.run(command)
Я сохранил программы в каталоге ~/.local/bin/
, который рекомендуется Каталог Ubuntu для пользовательских скриптов.
Чтобы использовать программы, сначала сделайте их исполняемыми. Предполагая, что вы сохранили их в ~/.local/bin/sshPass
и ~/.local/bin/scpPass
, введите следующее, чтобы сделать их исполняемыми:
$ chmod a+x ~/.local/bin/sshPass
$ chmod a+x ~/.local/bin/scpPass
Вы можете запустить их вот так:
$ ~/.local/bin/sshPass hostName ls
$ ~/.local/bin/scpPass hostName:fromFile toFile
$ ~/.local/bin/scpPass fromFile hostName:toFile
Вы также можете добавить это в ~/.bash_aliases
, для дистрибутивов *nix, которые это поддерживают, или в ваш стартовый bash-скрипт:
alias ssh=~/.local/bin/sshPass
alias scp=~/.local/bin/scpPass
Вдохновленный ответом @Arek Burdach и другими обертками, я написал оболочку, которая должна быть более надежной, что облегчает синтаксический анализ собственной команды ssh.
ОБНОВЛЕНИЕ 2021-04-26: Исправлена оболочка, когда хост соответствует только префиксу (например, Host is none)
Вот как это работает:
debug1: /home/misty/.ssh/config строка 42: Применение параметров для XXXXXX
. Но ssh выводит журнал ошибок с помощью \r, поэтому мы заменили их перед переходом в grep. Согласно моему тесту, ssh распознает только первый -o ProxyCommand=XXX в командной строке, даже если в командной строке есть второй параметр ProxyCommand или ProxyCommand в ~/.ssh/config, поэтому наш метод будет очень стабильно ;)
Для ssh
#!/usr/bin/env bash
ORISSH=/usr/bin/ssh
ssh_dryrun=$($ORISSH -v -o "ProxyCommand=FAKE_PROXY_STUB %h %p" "$@" 2>&1 | sed -e 's/\r/\n/g')
host=$( grep -oP 'Applying options for \K(.*?)$' <<< $ssh_dryrun | head -n 1 )
if [[ $host == "*" ]]; then
password=''
else
password=`awk "/#Password/ && inhost { print \\\$2 } /^Host/ { inhost=0 } /Host $host$/ { inhost=1 }" ~/.ssh/config`
fi
if [[ -z "$password" ]]; then
$ORISSH "$@"
else
sshpass -p $password $ORISSH "$@"
fi
Для scp:
#!/usr/bin/env bash
ORISCP=/usr/bin/scp
scp_dryrun=$($ORISCP -v -o "ProxyCommand=proxyhost %h %p" "$@" 2>&1 | sed -e 's/\r/\n/g')
host=$( grep -oP 'Applying options for \K(.*?)$' <<< $scp_dryrun | head -n 1 )
if [[ $host == "*" ]]; then
password=""
else
password=`awk "/#Password/ && inhost { print \\\$2 } /^Host/ { inhost=0 } /Host $host$/ { inhost=1 }" ~/.ssh/config`
fi
if [[ -z "$password" ]]; then
$ORISCP "$@"
else
sshpass -p $password $ORISCP "$@"
fi