Mogę użyć pliku konfiguracyjnego ssh, aby umożliwić przekazywanie kluczy ssh dodanych do ssh-agent. Jak mogę zrobić to samo z kluczami gpg?
Mogę użyć pliku konfiguracyjnego ssh, aby umożliwić przekazywanie kluczy ssh dodanych do ssh-agent. Jak mogę zrobić to samo z kluczami gpg?
Odpowiedzi:
EDYCJA: Ta odpowiedź jest już nieaktualna, ponieważ odpowiednie wsparcie zostało zaimplementowane w OpenSSH, patrz odpowiedź Briana Mintona.
SSH jest w stanie przekazywać połączenia TCP w tunelu.
Możesz jednak użyć programu takiego jak socat
przekaźnik gniazda unixowego przez TCP, z czymś takim (będziesz potrzebował socat zarówno na kliencie, jak i na serwerach):
# 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) &
Sprawdź, czy to działa gpg-connect-agent
. Upewnij się, że GPG_AGENT_INFO jest niezdefiniowany na zdalnym hoście, aby spadł z powrotem do $HOME/.gnupg/S.gpg-agent
gniazda.
Teraz, mam nadzieję, wszystko czego potrzebujesz to sposób, aby uruchomić to wszystko automatycznie!
localhost
teraz.
gpg-connect-agent
: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC
. Pilot socat
następnie umiera. Miejscowi socat
giną i mówią socat[24692] E connect(3, AF=1 "", 2): Invalid argument
. Ta strona prowadzi mnie do przekonania, że to nigdy nie zadziała, ponieważ agent nie przechowuje klucza (tylko hasło). Czy ktoś potwierdził, że to działa?
Nowe Unixowe przekazywanie gniazd domenowych OpenSSH może to zrobić bezpośrednio, począwszy od wersji 6.7.
Powinieneś być w stanie zrobić coś takiego:
ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
W nowych wersjach dystrybucji GnuPG lub Linux ścieżki gniazd mogą się zmieniać. Można je znaleźć za pośrednictwem
$ gpgconf --list-dirs agent-extra-socket
i
$ gpgconf --list-dirs agent-socket
Następnie dodaj te ścieżki do konfiguracji SSH:
Host remote
RemoteForward <remote socket> <local socket>
Szybkie rozwiązanie do kopiowania kluczy publicznych:
scp .gnupg/pubring.kbx remote:~/.gnupg/
Na zdalnym komputerze aktywuj agenta GPG:
echo use-agent >> ~/.gnupg/gpg.conf
Na komputerze zdalnym zmodyfikuj również konfigurację serwera SSH i dodaj ten parametr (/ etc / ssh / sshd_config):
StreamLocalBindUnlink yes
Zrestartuj serwer SSH, połącz się ponownie ze zdalnym komputerem - to powinno działać.
systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socket
jest on wymagany, aby systemd nie uruchomił zdalnego kradnącego gniazda agenta gpg. Według bugs.debian.org/850982 jest to zamierzone zachowanie.
Musiałem zrobić to samo i oparłem swój skrypt na rozwiązaniu autorstwa b0fh, z kilkoma drobnymi modyfikacjami: przechwytuje wyjścia i zabija procesy w tle, i używa opcji „fork” i „reuseaddr” do socat, co oszczędza ci pętli (i sprawia, że tło w tle może zostać zabite).
Całość ustawia wszystkie naprzód za jednym razem, więc prawdopodobnie zbliża się do automatycznej konfiguracji.
Pamiętaj, że na zdalnym hoście potrzebujesz:
GPG_AGENT_INFO
zmienna. Wypełniam moją kopią ~/.gnupg/S.gpg-agent:1:1
- pierwsza 1 to PID dla agenta gpg (sfałszuję go jako „init”, który zawsze działa), druga to numer wersji protokołu agenta. To powinno pasować do tego uruchomionego na twoim komputerze lokalnym.
#!/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'
Uważam, że istnieje również rozwiązanie, które polega na użyciu tylko jednego wywołania komendy SSH (połączenie z hosta zdalnego do lokalnego) -o LocalCommand
, ale nie mogłem do końca wymyślić, jak wygodnie zabić to po wyjściu.
Zgodnie z GnuPG Wiki , musisz przekazać zdalne gniazdo S.gpg-agent.extra
do gniazda lokalnego S.gpg-agent
. Ponadto musisz włączyć StreamLocalBindUnlink
na serwerze.
Pamiętaj, że potrzebujesz także publicznej części klucza dostępnej na zdalnym GnuPG .
Użyj gpgconf --list-dir agent-socket
odpowiednio gpgconf --list-dir agent-extra-socket
na pilocie, aby uzyskać rzeczywiste ścieżki.
Dodano konfigurację na pilocie /etc/sshd_config
:
StreamLocalBindUnlink yes
Zaimportuj swój klucz publiczny na pilocie:
gpg --export <your-key> >/tmp/public
scp /tmp/public <remote-host>:/tmp/public
ssh <remote-host> gpg --import /tmp/public
Polecenie połączenia przez SSH z włączonym przekazywaniem agenta gpg: (ścieżki dla mojego Debiana)
ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
Zamiast modyfikowania za /etc/ssh/sshd_config
pomocą StreamLocalBindUnlink yes
można zamiast tego zapobiec tworzeniu plików gniazd, które wymagają wymiany:
systemctl --global mask --now \
gpg-agent.service \
gpg-agent.socket \
gpg-agent-ssh.socket \
gpg-agent-extra.socket \
gpg-agent-browser.socket
Pamiętaj, że wpływa to na wszystkich użytkowników na hoście.
Bonus: Jak przetestować przekazywanie agentów GPG:
ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
${remote_sock}
jest to pokazane w pełnym danych wyjściowych z sshls -l ${remote_sock}
gpg --list-secret-keys
debug1
wiadomości z ssh pokazujących przekierowany ruchJeśli to nie zadziała (tak jak dla mnie), możesz sprawdzić, do którego gniazda GPG ma dostęp:
strace -econnect gpg --list-secret-keys
Przykładowe dane wyjściowe:
connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0
W moim przypadku dostęp do ścieżki jest idealnie dopasowany ${remote_sock}
, ale to gniazdo nie zostało utworzone, sshd
kiedy się zalogowałem, pomimo dodania StreamLocalBindUnlink yes
do mojego /etc/ssh/sshd_config
. Zostałem stworzony przez systemd po zalogowaniu.
(Uwaga: byłem zbyt tchórzliwy, aby zrestartować sshd, ponieważ nie mam teraz fizycznego dostępu do hosta. service reload sshd
Najwyraźniej nie było wystarczające ...)
Testowane na Ubuntu 16.04