Как я могу переслать ключ gpg через ssh-agent?

29

Я могу использовать файл конфигурации ssh, чтобы включить пересылку ключей ssh, добавленных в ssh-agent. Как я могу сделать то же самое с ключами gpg?

txwikinger
источник
3
В обоих ответах предлагается запустить socat для предоставления unix-сокета агента GPG через tcp-порт. Однако, в отличие от сокетов Unix, порты TCP не имеют одинакового уровня в управлении доступом. В частности, каждый пользователь на одном хосте теперь может подключаться к вашему агенту GPG. Это, вероятно, нормально, если у вас есть однопользовательский ноутбук, но если другие пользователи также могут войти в ту же систему (систему, в которой работает агент GPG), они также могут получить доступ к вашему агенту GPG, что создает серьезную проблему безопасности. Разрешение socat напрямую запустить SSH с использованием типа адреса EXEC, вероятно, является лучшим способом исправить это.
Маттис Коойман
Для другого представления решения OpenSSH 6.7+ см 2015.rmll.info/IMG/pdf/an-advanced-introduction-to-gnupg.pdf
PHS
Это было полезно для меня.
тел

Ответы:

16

РЕДАКТИРОВАТЬ: Этот ответ устарел теперь, когда надлежащая поддержка была реализована в OpenSSH, см. Ответ Брайана Минтона.

SSH способен только пересылать TCP-соединения внутри туннеля.

Однако вы можете использовать такую ​​программу, как socatретрансляцию сокета unix через TCP, с чем-то вроде этого (вам понадобится socat как на клиенте, так и на хостах сервера):

# Get the path of gpg-agent socket:
GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)

# Forward some local tcp socket to the agent
(while true; do
    socat TCP-LISTEN:12345,bind=127.0.0.1 UNIX-CONNECT:$GPG_SOCK;
done) &

# Connect to the remote host via ssh, forwarding the TCP port
ssh -R12345:localhost:12345 host.example.com

# (On the remote host)
(while true; do
    socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early TCP4:localhost:12345;
done) &

Проверьте, работает ли это с gpg-connect-agent. Убедитесь, что GPG_AGENT_INFO не определен на удаленном хосте, чтобы он вернулся к $HOME/.gnupg/S.gpg-agentсокету.

Теперь, надеюсь, все, что вам нужно, это способ запустить все это автоматически!

b0fh
источник
Что ж, ключи агента ssh пересылаются автоматически, когда в файле конфигурации задана переадресация. Я попробую это.
txwikinger
Вы правы, ssh-agent также использует сокет unix, но имеет специальную поддержку для него (немного усталый здесь :) Тем не менее, решение должно работать.
b0fh
1
Для этого решения мой gpg-агент был бы общедоступным через порт 12345, если бы я не был за брандмауэром / NAT. Это должно быть упомянуто в ответе, пожалуйста.
Йонас Шефер
Полагаю, твое последнее изменение исправило эту проблему, Джонас? это только localhostсейчас
JMTD
Это не может для меня следующего рассуждения от удаленного хоста gpg-connect-agent: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC. Затем пульт socatумирает. Местный socatумирает и произносит socat[24692] E connect(3, AF=1 "", 2): Invalid argument. Эта страница заставляет меня поверить, что это никогда не сработает, потому что агент не хранит ключ (только пароль). Кто-нибудь подтвердил, что это работает?
JMTD
17

Новая Unix Domain Socket Forwarding от OpenSSH может делать это напрямую, начиная с версии 6.7.

Вы должны быть в состоянии что-то вроде:

ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
Брайан Минтон
источник
@DrewR. Рад слышать.
Брайан Минтон
2
Я обнаружил необходимую критическую деталь: на удаленной машине (без личного ключа) должен присутствовать открытый ключ удостоверяющей личности. Локальная версия gpg 2.1.15 OS X, удаленная версия 2.1.11 Linux.
тел.
4

В новых версиях дистрибутивов GnuPG или Linux пути сокетов могут меняться. Это можно узнать через

$ gpgconf --list-dirs agent-extra-socket

а также

$ gpgconf --list-dirs agent-socket

Затем добавьте эти пути к вашей конфигурации SSH:

Host remote
  RemoteForward <remote socket> <local socket>

Быстрое решение для копирования открытых ключей:

scp .gnupg/pubring.kbx remote:~/.gnupg/

На удаленном компьютере активируйте агент GPG:

echo use-agent >> ~/.gnupg/gpg.conf

На удаленном компьютере также измените конфигурацию сервера SSH и добавьте этот параметр (/ etc / ssh / sshd_config):

StreamLocalBindUnlink yes

Перезапустите сервер SSH, переподключитесь к удаленному компьютеру - тогда он должен работать.

Malo
источник
Более подробное руководство, включая некоторые способы
MaLo
1
В случае, если на удаленном хосте запущена текущая версия Debian, кажется, что запуск systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socketнеобходим для предотвращения запуска systemd сокета, крадущего удаленный gpg-agent. Согласно bugs.debian.org/850982, это предполагаемое поведение.
Сампи
3

Мне пришлось сделать то же самое, и мой сценарий основывался на решении b0fh с несколькими крошечными модификациями: он перехватывает выходы и убивает фоновые процессы, а также использует параметры «fork» и «reuseaddr» для socat, что спасает вас от цикл (и делает фоновый сокат чисто убиваемым).

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

Обратите внимание, что на удаленном хосте вам потребуется:

  1. Брелки, которые вы намереваетесь использовать для подписи / en / decrypt.
  2. В зависимости от версии gpg на пульте, поддельная GPG_AGENT_INFOпеременная. Я ~/.gnupg/S.gpg-agent:1:1предварительно заполняю свой - первая 1 - это PID для агента gpg (я имитирую его как «init», который всегда работает), вторая - номер версии протокола агента. Это должно соответствовать тому, что работает на вашем локальном компьютере.

#!/bin/bash -e

FORWARD_PORT=${1:-12345}

trap '[ -z "$LOCAL_SOCAT" ] || kill -TERM $LOCAL_SOCAT' EXIT

GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
if [ -z "$GPG_SOCK" ] ; then
    echo "No GPG agent configured - this won't work out." >&2
    exit 1
fi

socat TCP-LISTEN:$FORWARD_PORT,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:$GPG_SOCK &
LOCAL_SOCAT=$!

ssh -R $FORWARD_PORT:127.0.0.1:$FORWARD_PORT socat 'UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early,fork,reuseaddr TCP4:localhost:$FORWARD_PORT'

Я считаю, что есть также решение, которое включает в себя только один вызов команды SSH (подключение обратно с удаленного хоста к локальному) с использованием -o LocalCommand, но я не мог понять, как удобно убить это при выходе.

antifuchs
источник
Вы не пропустили какой-то аргумент 'user @ host' перед socat, в последней команде? Во всяком случае, даже после исправления этого у меня ничего не получилось, если «socat [6788] E connect (3, AF = 2 127.0.0.1:0, 16): соединение отказано» выскочил локально при удаленной попытке gpg-connect-agent).
Дэвид Фор
1

Согласно GnuPG Wiki , вы должны перенаправить удаленный сокет S.gpg-agent.extraв локальный сокет S.gpg-agent. Кроме того, вам нужно включить StreamLocalBindUnlinkна сервере.
Имейте в виду, что вам также нужна открытая часть вашего ключа, доступная на удаленной GnuPG .

Используйте gpgconf --list-dir agent-socketсоответственно gpgconf --list-dir agent-extra-socketна пульте, чтобы получить фактические пути.


Резюме

  1. Добавленная конфигурация на пульте /etc/sshd_config:

    StreamLocalBindUnlink yes
    
  2. Импортируйте ваш открытый ключ на удаленный компьютер:

    gpg --export <your-key> >/tmp/public
    scp /tmp/public <remote-host>:/tmp/public
    ssh <remote-host> gpg --import /tmp/public
    
  3. Команда для подключения через SSH с включенной переадресацией gpg-agent: (пути к моему Debian)

    ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
    
Doak
источник
@ Брайан Минтон: Это не работает для меня, если не переадресация на дополнительный сокет.
Доак
0

В качестве альтернативы изменению /etc/ssh/sshd_configс помощью StreamLocalBindUnlink yesвы можете предотвратить создание файлов сокетов, которые необходимо заменить:

systemctl --global mask --now \
  gpg-agent.service \
  gpg-agent.socket \
  gpg-agent-ssh.socket \
  gpg-agent-extra.socket \
  gpg-agent-browser.socket

Обратите внимание, что это влияет на всех пользователей на хосте.

Бонус: Как проверить работоспособность агента GPG:

  • Местный: ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
  • Проверьте, что ${remote_sock}показано в подробном выводе из ssh
  • Удаленный: ls -l ${remote_sock}
  • Удаленный: gpg --list-secret-keys
    • Вы должны увидеть много debug1сообщений от ssh, показывающих перенаправленный трафик

Если это не сработает (как это было не для меня), вы можете отследить, к какому сокету GPG обращается:

strace -econnect gpg --list-secret-keys

Образец вывода:

connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0

В моем случае доступ к пути, который идеально подходит ${remote_sock}, но этот сокет не был создан, sshdкогда я вошел в систему, несмотря на добавление StreamLocalBindUnlink yesв мой /etc/ssh/sshd_config. Я был создан systemd при входе в систему.

(Обратите внимание, что я был слишком труслив, чтобы перезапустить sshd, так как у меня сейчас нет физического доступа к хосту. service reload sshdЯвно было недостаточно ...)

Проверено на Ubuntu 16.04

RobM
источник