Obie odpowiedzi sugerują uruchomienie socat, aby odsłonić gniazdo unix agenta GPG na porcie TCP. Jednak w przeciwieństwie do gniazd unix, porty TCP nie mają tego samego poziomu kontroli dostępu. W szczególności każdy użytkownik na tym samym hoście może teraz połączyć się z agentem GPG. Jest to prawdopodobnie w porządku, jeśli masz laptopa dla jednego użytkownika, ale jeśli inni użytkownicy mogą również zalogować się do tego samego systemu (systemu, w którym działa agent GPG), mogą również uzyskać dostęp do Twojego agenta GPG, co stanowi poważny problem z bezpieczeństwem. Umożliwienie socat bezpośredniego uruchomienia SSH przy użyciu typu adresu EXEC jest prawdopodobnie najlepszym sposobem na rozwiązanie tego problemu.
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 socatprzekaź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-agentgniazda.
Teraz, mam nadzieję, wszystko czego potrzebujesz to sposób, aby uruchomić to wszystko automatycznie!
Cóż, klucze agenta ssh są przekazywane automatycznie, gdy przekazywanie jest ustawione w pliku konfiguracyjnym. Spróbuję tego.
txwikinger
Masz rację, ssh-agent używa również gniazda unix, ale ma specjalne wsparcie dla niego (tutaj trochę zmęczone :) Niemniej jednak rozwiązanie powinno nadal działać.
b0fh
1
W przypadku tego rozwiązania mój gpg-agent byłby publicznie dostępny przez port 12345, gdybym nie był za firewallem / NAT. Należy o tym wspomnieć w odpowiedzi.
Jonas Schäfer
Chyba ostatnia edycja rozwiązała ten problem, Jonas? jest to wiążące tylko localhostteraz.
jmtd
To nie dla mnie z następującym argumentem ze zdalnego hosta gpg-connect-agent: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC. Pilot socatnastępnie umiera. Miejscowi socatginą 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?
jmtd
17
Nowe Unixowe przekazywanie gniazd domenowych OpenSSH może to zrobić bezpośrednio, począwszy od wersji 6.7.
Bardziej szczegółowy samouczek, w tym niektóre rozwiązywanie problemów, można znaleźć tutaj: mlohr.com/gpg-agent-forwarding
MaLo
1
W przypadku, gdy zdalny host uruchamia bieżącą wersję Debiana, wydaje się, że systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socketjest on wymagany, aby systemd nie uruchomił zdalnego kradnącego gniazda agenta gpg. Według bugs.debian.org/850982 jest to zamierzone zachowanie.
sampi,
3
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:
Breloki, których zamierzasz używać do podpisywania / en / deszyfrowania rzeczy.
W zależności od wersji gpg na pilocie, fałszywa GPG_AGENT_INFOzmienna. 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.
Czy w ostatnim poleceniu nie brakuje jakiegoś argumentu „użytkownik @ host” przed socat? W każdym razie nawet po naprawieniu tego, dla mnie to się nie powiodło z pojawieniem się „socat [6788] E connect (3, AF = 2 127.0.0.1:0, 16): Połączenie odrzucone” lokalnie, gdy próbuję zdalnie gpg-connect-agent.
David Faure,
1
Zgodnie z GnuPG Wiki , musisz przekazać zdalne gniazdo S.gpg-agent.extrado gniazda lokalnego S.gpg-agent. Ponadto musisz włączyć StreamLocalBindUnlinkna serwerze.
Pamiętaj, że potrzebujesz także publicznej części klucza dostępnej na zdalnym GnuPG .
Użyj gpgconf --list-dir agent-socketodpowiednio gpgconf --list-dir agent-extra-socketna pilocie, aby uzyskać rzeczywiste ścieżki.
@brian minton: Nie działa dla mnie, jeśli nie przekierowuję do dodatkowego gniazda.
doak
0
Zamiast modyfikowania za /etc/ssh/sshd_configpomocą StreamLocalBindUnlink yesmożna zamiast tego zapobiec tworzeniu plików gniazd, które wymagają wymiany:
W moim przypadku dostęp do ścieżki jest idealnie dopasowany ${remote_sock}, ale to gniazdo nie zostało utworzone, sshdkiedy się zalogowałem, pomimo dodania StreamLocalBindUnlink yesdo 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 sshdNajwyraźniej nie było wystarczające ...)
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):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!
źródło
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
. Pilotsocat
następnie umiera. Miejscowisocat
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:
źródło
W nowych wersjach dystrybucji GnuPG lub Linux ścieżki gniazd mogą się zmieniać. Można je znaleźć za pośrednictwem
i
Następnie dodaj te ścieżki do konfiguracji SSH:
Szybkie rozwiązanie do kopiowania kluczy publicznych:
Na zdalnym komputerze aktywuj agenta GPG:
Na komputerze zdalnym zmodyfikuj również konfigurację serwera SSH i dodaj ten parametr (/ etc / ssh / sshd_config):
Zrestartuj serwer SSH, połącz się ponownie ze zdalnym komputerem - to powinno działać.
źródło
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.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.źródło
Zgodnie z GnuPG Wiki , musisz przekazać zdalne gniazdo
S.gpg-agent.extra
do gniazda lokalnegoS.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
odpowiedniogpgconf --list-dir agent-extra-socket
na pilocie, aby uzyskać rzeczywiste ścieżki.Podsumowanie
Dodano konfigurację na pilocie
/etc/sshd_config
:Zaimportuj swój klucz publiczny na pilocie:
Polecenie połączenia przez SSH z włączonym przekazywaniem agenta gpg: (ścieżki dla mojego Debiana)
źródło
Zamiast modyfikowania za
/etc/ssh/sshd_config
pomocąStreamLocalBindUnlink yes
można zamiast tego zapobiec tworzeniu plików gniazd, które wymagają wymiany: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:
Przykładowe dane wyjściowe:
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 dodaniaStreamLocalBindUnlink 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
źródło