Ssh, uruchom komendę podczas logowania, a następnie pozostań zalogowany?

29

Próbowałem tego z oczekiwaniem, ale to nie zadziałało: na końcu zamknęło połączenie.

Czy możemy uruchomić skrypt za pośrednictwem ssh, który zaloguje się do zdalnych komputerów, uruchomi polecenie i nie rozłączy się?

Więc ssh na komputerze, cd do takiego i takiego katalogu, a następnie uruchom polecenie i pozostań zalogowany.

-Jonathan

(oczekuję, że użyłem)

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
spawn ssh root@marlboro "cd /tmp; ls -altr | tail"
expect "?assword:*"
send -- "$password\r"
send -- "\r"
interact
jonathan
źródło
9
Czy to tylko ja, czy „automatyzujesz” uwierzytelnianie hasłem w ten sposób, zamiast korzystać z pubkeys lub innej zdrowej metody?
grawity

Odpowiedzi:

25

Dodać a ; /bin/bashna końcu linii poleceń po drugiej stronie? To jest:

spawn ssh -t root@marlboro "cd /tmp; ls -altr | tail; /bin/bash -i"

Co więcej, zmień .bashrc roota na coś takiego:

PROMPT_COMMAND="cd /tmp && ls -altr | tail ; unset PROMPT_COMMAND"

:)

Bill Weiss
źródło
2
Możesz dodać -ido tej bash.
Teddy
Tak, chyba :)
Bill Weiss
Kiedy to robię, uzupełnianie tabulatorów przerywa się w nowej powłoce (nawet z „-i”) - jakiś pomysł, dlaczego / jak to naprawić?
Coderer
1
Przetestowałem tutaj moją nową odpowiedź, działa świetnie. Trochę szorstki, ale działa.
Bill Weiss
7
Spróbuj ssh -tprzydzielić pty.
Wstrzymano do odwołania.
4

Jeśli nie masz nic przeciwko robieniu tego w Pythonie, pexpect ma przykład, który robi prawie dokładnie to, o co prosisz:

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('[email protected]')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Aby to zrobić za pomocą ssh zamiast ftp, potrzebujesz kodu podobnego do następującego (pliki przykładowe w pexpect zawierają znacznie więcej szczegółów i informacji, ale oto podstawy):

import pexpect
child = pexpect.spawn ('ssh root@marlboro')
child.expect ('Password:')
child.sendline ('password')
child.expect ('prompt# ')
child.sendline ('cd /tmp')
child.expect ('prompt# ')
child.sendline ('ls -altr | tail')
child.expect ('prompt# ')
print child.before, child.after   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Nie zrozum mnie źle, KOCHAM się spodziewać (szczególnie autoekspektu), ale python jest o wiele łatwiejszy do zrozumienia.

Jed Daniels
źródło
Ja też przechodzę z oczekiwania na oczekiwanie. python jest teraz znacznie bardziej wszechobecny.
JM Becker
4

Prawdopodobnie najłatwiejszym i najczystszym sposobem na ssh na serwer, odrodzenie interaktywnej powłoki i wykonywanie poleceń wewnątrz tej powłoki jest utworzenie niestandardowego pliku rc dla bash.

W niestandardowym pliku bashrc na serwerze najpierw źródłowy plik, a następnie dodaj własne polecenia, np

~ / .bashrc_custom:

. ~/.bashrc
cd dir/
workon virtualenvproject

Następnie możesz rozpocząć sesję SSH w następujący sposób:

$ ssh -t server "/bin/bash --rcfile ~/.bashrc_custom -i"

Ta -topcja wymusza alokację pseudo-tty, aby rzeczy takie jak uzupełnianie tabulacji działały.

Do --rcfileopcja określa, który plik rc załadować zamiast jednej domyślnej. Ważne: aby możliwe było rozpoznanie, należy w wierszu poleceń wstawić „argumenty podwójnego myślnika”.

-iArgument / bin / bash ma powołać interaktywną powłokę.

Danilo Bargen
źródło
właściwie to nie. Co zrobić, jeśli chcę uruchamiać różne polecenia dla każdego połączenia?
Eugen Konkov
1

Jeśli ktoś chce informacji o tym, co dzieje się w tle, zapoznaj się z instrukcją sshd:

Gdy użytkownik pomyślnie się zaloguje, sshd wykonuje następujące czynności:

  1. Jeśli login jest ustawiony na tty i nie podano żadnej komendy, drukuje czas ostatniego logowania i / etc / motd (chyba że jest to niemożliwe w pliku konfiguracyjnym lub ~ / .hushlogin; patrz sekcja PLIKI).
  2. Jeśli logowanie jest na urządzeniu tty, rejestruje czas logowania.
  3. Sprawdza / etc / nologin i / var / run / nologin; jeśli taki istnieje, drukuje zawartość i kończy pracę (chyba że root).
  4. Zmiany do uruchomienia z normalnymi uprawnieniami użytkownika.
  5. Konfiguruje podstawowe środowisko.
  6. Odczytuje plik ~ / .ssh / environment, jeśli istnieje, a użytkownicy mogą zmieniać swoje środowisko. Zobacz opcję PermitUserEnvironment w sshd_config (5).
  7. Przechodzi do katalogu domowego użytkownika.
  8. Jeśli ~ / .ssh / rc istnieje, uruchamia go; w przeciwnym razie, jeśli istnieje / etc / ssh / sshrc, uruchamia go; w przeciwnym razie uruchamia xauth (1). Pliki `` rc '' otrzymują protokół uwierzytelniania X11 i pliki cookie na standardowym wejściu. Zobacz SSHRC poniżej.
  9. Uruchamia powłokę lub polecenie użytkownika.

https://www.freebsd.org/cgi/man.cgi?sshd(8)#LOGIN_PROCESS

Gerry
źródło
0

Zasadniczo powinieneś unikać używania ssh w ten sposób, ponieważ nie pozwala to na osiągnięcie celu.
Zrób

ssh-add -l | grep "file_of_your_rsa_priv_key_here"

aby sprawdzić, czy klucz znajduje się na liście w aktywnej puli sesji ssh, czy też dodaj go samodzielnie (za pomocą ssh-add).

Kounavi
źródło