przekazywanie ssh-agent i sudo do innego użytkownika

153

Jeśli mam serwer A, do którego mogę się zalogować przy użyciu mojego klucza ssh i mam możliwość „sudo su - otheruser”, tracę przekazywanie kluczy, ponieważ zmienne env są usuwane, a gniazdo jest czytelne tylko dla mojego pierwotnego użytkownika. Czy istnieje sposób na zmostkowanie przekazywania kluczy za pomocą „sudo su - otheruser”, dzięki czemu mogę robić rzeczy na serwerze B za pomocą przesłanego klucza (w moim przypadku git clone i rsync)?

Jedyny sposób, jaki mogę wymyślić, to dodanie mojego klucza do uprawnionych kluczy innego użytkownika i „ssh otheruser @ localhost”, ale jest to uciążliwe dla każdej kombinacji użytkowników i serwerów, jaką mogę mieć.

W skrócie:

$ sudo -HE ssh user@host
(success)
$ sudo -HE -u otheruser ssh user@host
Permission denied (publickey). 
kolypto
źródło

Odpowiedzi:

182

Jak wspomniałeś, zmienne środowiskowe są usuwane ze sudowzględów bezpieczeństwa.

Ale na szczęście sudojest dość konfigurowalny: możesz dokładnie powiedzieć, które zmienne środowiskowe chcesz zachować, dzięki env_keepopcji konfiguracyjnej w /etc/sudoers.

W przypadku przekazywania agentów należy zachować SSH_AUTH_SOCKzmienną środowiskową. Aby to zrobić, po prostu edytuj /etc/sudoersplik konfiguracyjny (zawsze za pomocą visudo) i ustaw odpowiednią env_keepopcję dla odpowiednich użytkowników. Jeśli chcesz ustawić tę opcję dla wszystkich użytkowników, użyj następującego Defaultswiersza:

Defaults    env_keep+=SSH_AUTH_SOCK

man sudoers po więcej szczegółów.

Teraz powinno być w stanie zrobić coś takiego (o ile user1jest klucz publiczny jest obecny w ~/.ssh/authorized_keysw user1@serverAi user2@serverB, i serverA's /etc/sudoersplik jest ustawiony jak wskazano powyżej):

user1@mymachine> eval `ssh-agent`  # starts ssh-agent
user1@mymachine> ssh-add           # add user1's key to agent (requires pwd)
user1@mymachine> ssh -A serverA    # no pwd required + agent forwarding activated
user1@serverA> sudo su - user2     # sudo keeps agent forwarding active :-)
user2@serverA> ssh serverB         # goto user2@serverB w/o typing pwd again...
user2@serverB>                     # ...because forwarding still works
MiniQuark
źródło
1
To poprawna odpowiedź, należy ją zaznaczyć.
Xealot
41
Działa to tylko , jeśli user2powyżej jest root! W przeciwnym razie user2SSH_AUTH_SOCK będzie poprawnie skonfigurowany, ale user2nie będzie mógł uzyskać dostępu np. / Tmp / ssh-GjglIJ9337 /. rootma ten dostęp. Może to rozwiązać część problemu, ale nie OP: „ a gniazdo jest czytelne tylko dla mojego oryginalnego użytkownika”
Peter V. Mørch
6
Defaults>root env_keep+=SSH_AUTH_SOCKPowinieneś upewnić się, że przesuwa się tylko podczas sudo do rootowania . I tak nie chcesz tego robić innym użytkownikom ze względów bezpieczeństwa. Lepiej uruchom osobny agent ssh dla innych i dodaj odpowiednie klucze.
Paul Schyska
1
sudo su -nie działa dla mnie, prawdopodobnie nie może chronić środowiska, ponieważ nie jest to sudoczas uruchamiania powłoki. sudo suwydaje się działać.
Alex Fortuna,
3
I tak nigdy nie zrozumiałem, dlaczego ludzie używają sudo su. Jeśli potrzebujesz powłoki roota, po to jest sudo -slub sudo -ijest.
eaj
68
sudo -E -s
  • -E będzie chronić środowisko
  • -s uruchamia polecenie, domyślnie jest to powłoka

To da ci powłokę root z wciąż załadowanymi oryginalnymi kluczami.

Joao Costa
źródło
2
Podobnie jak w powyższym komentarzu, to rozwiązuje tylko pytanie, czy stajesz się rootem, ponieważ w takim przypadku root może obejść zwykłe uprawnienia dostępu do $ SSH_AUTH_SOCK.
doshea
35

Pozwól innemu użytkownikowi uzyskać dostęp do $SSH_AUTH_SOCKpliku i jego katalogu, na przykład przez poprawną listę ACL, przed przełączeniem się na nie. Przykład zakłada Defaults:user env_keep += SSH_AUTH_SOCKsię /etc/sudoersna urządzeniu hosta:

$ ssh -A user@host
user@host$ setfacl -m otheruser:x   $(dirname "$SSH_AUTH_SOCK")
user@host$ setfacl -m otheruser:rwx "$SSH_AUTH_SOCK"
user@host$ sudo su - otheruser
otheruser@host$ ssh server
otheruser@server$

Bardziej bezpieczny i działa również dla użytkowników innych niż root ;-)

Viliam Pucik
źródło
6
Pamiętaj, że korzystając z tej metody, inne osoby zalogowały się, ponieważ otherusermogą również korzystać z uwierzytelnienia ssh.
gitaarik
Działa to dla mnie, tyle że musiałem zmienić „sudo su - otheruser” na „sudo su otheruser” (usunięcie -).
Charles Finkel
1
Dlaczego rwxi nie rw(lub rwcale)?
anatoly techtonik
3
@ anatolytechtonik Od man 7 unix- w Linuksie połączenie z gniazdem wymaga uprawnień do odczytu i zapisu w tym gnieździe. Potrzebne są także uprawnienia do wyszukiwania (wykonywania) i zapisu w katalogu, w którym utworzono gniazdo, lub uprawnienia tylko do wyszukiwania (wykonywania) po podłączeniu do tego gniazda. Tak więc w powyższej odpowiedzi wykonanie uprawnienia na gnieździe jest zbędne.
mixel
zamiast edytować / etc / sudoers, których możesz użyćsudo -u otheruser --preserve-env=HOME -s
Sec
14

Przekonałem się, że to również działa.

sudo su -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

Jak zauważyli inni, nie zadziała to, jeśli użytkownik, do którego się przełączasz, nie ma uprawnień do odczytu na $ SSH_AUTH_SOCK (który jest praktycznie dowolnym użytkownikiem oprócz root). Możesz obejść ten problem, ustawiając $ SSH_AUTH_SOCK i katalog, w którym się znajduje, aby mieć uprawnienia 777.

chmod 777 -R `dirname $SSH_AUTH_SOCK`
sudo su otheruser -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

Jest to jednak dość ryzykowne. Zasadniczo dajesz każdemu użytkownikowi w systemie pozwolenie na używanie agenta SSH (do czasu wylogowania). Możesz także ustawić grupę i zmienić uprawnienia na 770, co może być bezpieczniejsze. Jednak gdy próbowałem zmienić grupę, otrzymałem komunikat „Operacja niedozwolona”.

phylae
źródło
6
To jest bardzo ryzykowne. Zezwolenie każdemu użytkownikowi na korzystanie z agenta SSH jest równoznaczne z przekazaniem mu wszystkich poświadczeń (a jeśli kiedykolwiek korzystasz z sudo lub su, dajesz im uprawnienia roota nad wszystkimi innymi użytkownikami systemu, a także ze wszystkimi innymi systemami, do których ssh!) . NIGDY nie można tego robić!
Matija Nalis
4
Nie zgadzam się ze stwierdzeniem, że „NIGDY nie należy tego robić!” Istnieje wiele przypadków, w których ryzyko to jest dopuszczalne. Na przykład mały zespół, w którym wszyscy mają takie same uprawnienia, a ty ufasz wszystkim innym użytkownikom. Nigdy nie należy tego robić bez zrozumienia związanego z tym ryzyka. Ale kiedy te ryzyka zostaną zrozumiane, są chwile, że ryzyko jest akceptowalne.
phylae
6

Jeśli jesteś do tego upoważniony sudo su - $USER, prawdopodobnie będziesz miał dobry argument za tym, że możesz zrobić ssh -AY $USER@localhostzamiast tego, z ważnym kluczem publicznym w katalogu domowym $ USER. Wówczas Twoje przekazywanie uwierzytelnienia zostanie przeprowadzone razem z Tobą.

David Mackintosh
źródło
Wspomniał o tym na końcu swojego pytania i powiedział, że będzie to trudne.
Fahad Sadah
Jest to prawdopodobnie najlepsze rozwiązanie, ale robi się owłosione, jeśli $ USER jest prawdziwą osobą (tm) - mogą usunąć klucz SA z kluczy autoryzowanych lub zmienić hasło ...
voretaq7
Możesz usunąć ich dostęp do zapisu do uprawnionych
kluczy
4

Zawsze możesz po prostu ssh do localhost z przekazaniem agenta zamiast używać sudo:

ssh -A otheruser@localhost

Wadą jest to, że musisz się ponownie zalogować, ale jeśli używasz go na karcie screen / tmux, to tylko jednorazowy wysiłek, jednak jeśli rozłączysz się z serwerem, gniazdo (oczywiście) zostanie ponownie zepsute . Nie jest to więc idealne, jeśli nie możesz utrzymywać otwartej sesji screen / tmux przez cały czas (możesz jednak ręcznie zaktualizować SSH_AUTH_SOCKenv var, jeśli jesteś fajny).

Pamiętaj również, że podczas korzystania z przekazywania ssh root może zawsze uzyskać dostęp do gniazda i korzystać z uwierzytelniania ssh (o ile jesteś zalogowany przy użyciu przekazywania ssh). Upewnij się więc, że możesz zaufać rootowi.

gitaarik
źródło
To nie działa, jeśli masz dostęp tylko otheruserprzez via sudozamiast przez SSH (np. Chcesz SCP jako as www-data)
Gert van den Berg
3

Nie używaj sudo su - USER, ale raczej sudo -i -u USER. Pracuje dla mnie!

Fahad Sadah
źródło
Jaką masz wersję sudo? Mój (1.6.7p5, CentOS 4.8) nie ma -i na swojej stronie man.
David Mackintosh
Sudo version 1.6.9p17działa na Debianie Lennym. Spróbować sudo -s?
Fahad Sadah
6
Nie działa dla mnie
Na Ubuntu, używając Sudo 1.8.9p5, ani sudo -snie sudo -ipracuj dla mnie ...
Jon L.
2

Łącząc informacje z innych odpowiedzi, wpadłem na to:

user=app
setfacl -m $user:x $(dirname "$SSH_AUTH_SOCK")
setfacl -m $user:rwx "$SSH_AUTH_SOCK"
sudo SSH_AUTH_SOCK="$SSH_AUTH_SOCK" -u $user -i

Podoba mi się to, ponieważ nie muszę edytować sudoerspliku.

Testowany na Ubuntu 14.04 (musiał zainstalować aclpakiet).

warvariuc
źródło
1

Myślę, że w twoim poleceniu jest problem z -opcją (myślnik) su:

sudo su - otheruser

Jeśli przeczytasz stronę man su , może się okazać, że opcja -, -l, --loginuruchamia środowisko powłoki jako powłokę logowania. Będzie to środowisko otheruserniezależnie od zmiennych env, w których działasz su.

Mówiąc najprościej, myślnik podważy wszystko, co przeszedłeś sudo.

Zamiast tego powinieneś wypróbować to polecenie:

sudo -E su otheruser

Jak wskazał @ joao-costa, -Ezachowa wszystkie zmienne w środowisku, w którym działałeś sudo. Wtedy bez myślnika suużyje bezpośrednio tego środowiska.

Koala Yeung
źródło
0

Niestety, gdy poznasz innego użytkownika (lub nawet użyjesz sudo), utracisz możliwość korzystania z przekazanych kluczy. Jest to funkcja bezpieczeństwa: nie chcesz, aby przypadkowi użytkownicy łączyli się z twoim agentem ssh i korzystali z twoich kluczy :)

Metoda „ssh -Ay $ {USER} @localhost” jest nieco uciążliwa (i jak zauważono w moim komentarzu do odpowiedzi Davida podatnej na pękanie), ale prawdopodobnie jest to najlepsza metoda, jaką możesz zrobić.

voretaq7
źródło
1
Hmm, ale jeśli zrobię to z ssh, to mój agent będzie dostępny dla tego użytkownika, czy też się mylę?
Jeśli wpiszesz SSH do użytkownika docelowego z przekazywaniem agenta, Twoje żądania odskoczą do łańcucha, gdziekolwiek jest „prawdziwy” agent. Kiedy su lub sudo znajdujesz się poza pierwotnym użytkownikiem, gniazdo agenta SSH nie będzie (lub nie powinno) być dostępne - katalog, w którym on mieszka, jest w trybie 700 i jest własnością oryginalnego użytkownika. (Oczywiste zastrzeżenie: jeśli
przejdziesz do rootowania
1
Na moim serwerze (Ubuntu 12.04, ssh wersja OpenSSH_5.9p1 Debian-5ubuntu1.1, OpenSSL 1.0.1 14 marca 2012), ssh ma -ai -Aargumenty. -arobi dokładnie odwrotność tego, co jest zamierzone, wyłącza przekazywanie agentów! Tak więc w najnowszej (i prawdopodobnie całej) wersji Ubuntu użyj, -Aaby włączyć przekazywanie agentów.
knite
@knite Masz rację - w mojej odpowiedzi to literówka (3-letnia!). Naprawiono teraz :-)
voretaq7