Как заставить только удаленные операции git вызывать событие ssh-add для ssh-agent?

Недавно я задал вопрос на AskUbuntu о том, как заставить ssh-agent автоматически сохранять мой ключ, защищенный парольной фразой, для последующего повторного использования без необходимости повторного ввода парольной фразы во время входа в систему bash (без GUI/Gnome). В ответ я получил хороший bash-скрипт, но, к сожалению, он срабатывает, чтобы запросить парольную фразу независимо от операции git. Я хочу получить запрос только в том случае, если ключ еще не находится в ssh-agent и выполняется удаленная операция git.

Это связано с тем, что я использую $(__git_ps1 "[%s]") в командной строке bash для отображения ветки git текущего рабочего каталога (pwd). Поэтому, когда я подключаюсь к машине по ssh, она сразу же запрашивает ключевую фразу, прежде чем сможет отобразить приглашение bash!

Текущий скрипт из ответа на мой вопрос на AskUbuntu выглядит так:

In ~/.bash_profile:

# File: ~/.bash_profile

# source ~/.profile, if available
if [[ -r ~/.profile ]]; then
  . ~/.profile
fi

# start agent and set environment variables, if needed
agent_started=0
if ! env | grep -q SSH_AGENT_PID >/dev/null; then
  echo "Starting ssh agent"
  eval $(ssh-agent -s)
  agent_started=1
fi

# ssh become a function, adding identity to agent when needed
ssh() {
  if ! ssh-add -l >/dev/null 2>-; then
    ssh-add ~/.ssh/id_dsa
  fi
  /usr/bin/ssh "$@"
}
export -f ssh

# another example: git
git() {
  if ! ssh-add -l >/dev/null 2>-; then
    ssh-add ~/.ssh/id_dsa
  fi
  /usr/bin/git "$@"
}
export -f git

Итак, как вы можете видеть, функция git запускается при каждой операции git.

Я думал, что git будет использовать ssh для установления соединения, но, похоже, он не запускает функцию ssh() в приведенном выше сценарии. Как git выполняет свои операции ssh? Обращается ли он к /usr/bin/ssh напрямую, а не по пути bash?

У вас есть лучший способ сделать это или хороший обходной путь для текущего скрипта?


person Treffynnon    schedule 26.04.2011    source источник
comment
Исполняемый файл git /usr/bin/git не написан на bash (AFAIK), поэтому у него нет причин выполнять вашу функцию ssh.   -  person nhed    schedule 26.04.2011
comment
@nhed это была моя гипотеза. Интересно, могу ли я заменить /usr/bin/ssh скриптом-оболочкой bash ssh, чтобы он запускался?   -  person Treffynnon    schedule 26.04.2011
comment
звучит опасно, справочная страница git упоминает переменную env GIT_SSH - укажите это на оболочку - это может работать чище. Дайте этому шанс   -  person nhed    schedule 26.04.2011


Ответы (2)


Вы можете использовать переадресацию агента, даже если вы рекурсивно подключаетесь к нескольким хостам по ssh. Когда ssh запрашивает ключ в первый раз, ваш локальный агент запускает $SSH_ASKPASS и пересылает разблокированный ключ на хост. Обратите внимание, что вам необходимо включить переадресацию агента (см. man 5 ssh_config). ).

В ~/.ssh/config включите переадресацию для каждого требуемого хоста:

Host example.org
    ForwardAgent yes

На стороне сервера переадресация агента включена по умолчанию.

Если вы по какой-то причине не хотите использовать переадресацию агента, то я думаю, что переопределение команды ssh — ваш единственный вариант.

person drizzd    schedule 26.04.2011
comment
Я забыл о AgentForwarding. Хороший звонок, и он идеально подходит для моего рабочего процесса. - person Treffynnon; 27.04.2011

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

My $0.02

person Adam Dymitruk    schedule 26.04.2011
comment
Гитолитом не пользуюсь, так что не вижу в этом проблемы. Я недостаточно доверяю тому, чтобы иметь незащищенный ключ на моем диске, и у меня никогда не было бы его, если бы не действительно заблокированная учетная запись для автоматизированных процессов. Я не понимаю, как парольная фраза повлияет на git, поскольку все это обрабатывается на уровне ssh, а не в самом git. - person Treffynnon; 26.04.2011