Moduł Net::SSH::Perl

Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowa

Co to jest?

Jest to moduł perlowy implementujący klienta SSH (secure shell).Jest kompatybilny zarówno z protokołami SSH-1 oraz SSH-2.

Net::SSH::Perl umożliwia proste oraz bezpieczne wykonywanie komend na zdalnej maszynie, oraz otrzymywanie komunikatów z standarowego wejścia, oraz wyjścia. Mamy dostęp również do statusu z jakim zakończyła sie komenda na zdalnej maszynie. Zawiera wbudowaną obsługę dla wielu metod poświadczających z serwera (poświadczenie hasłem, protokół RSA wyzwanie-odpowiedź, itd.) Kompletnie implementuje bufforowanie wyjścia/wejścia, transportu pakietów, warstwe poświadczająca użytkownika protokołu SSH, używa również zewnętrznych bibliotek (z rodziny modułów Crypt::) aby radzić sobie z szyfrowaniem wszystkich danych wysyłanych przez niezabezpieczone sieci. Czyta również istniejące pliki konfiguracyjne SSH (/etc/ssh_config, itp.), pliki identyfikujące RSA i DSA, pliki znanych hostów, itp..

Jedna zaleta używania Net::SSH::Perl nad implementacjami tylko opakowujących istniejących juz klientów ssh jest oszczędność w kosztach procesów: już więcej nie potrzebujemy tworzyć prosesu potomnego i wykonywać osobnych procesów aby połączyć sie do sshd. W zależności od czasu i pamięci potrzebnej do utworzenia procesu potomnego, może to być pokaźny zysk. W szczególności jeśli uruchamiamy bezustanne środowisko perlowe (mod_perl, na przykład), gdzie tworzenie procesu potomnego (fork) może wyczerpać zasoby pamięci oraz ilości procesów.

Upraszcza również proces używania poświadczeń bazujących na haśle, kiedy pisana jest nakładka na ssh prawdopodobnie musi zostać użyte Expect do kontorli klienta ssh i przekazanie mu swojego hasła. Net::SSH::Perl ma wbudowana obsługę protokołu potwierdzającego, wiec nie ma dłużej potrzeby komunikowania sie z zewnętrznymi procesami.

Obsługa protokołu SSH2 (obecna w Net::SSH::Perl od wersji 1.00) jest kompatybilna z implementacja SSH2 w OpenSHH, i powinna być w pełni kompatybilna z "oficjalna" implementacja SSH. Jeśli znajdziecie implementacje SSH2 która nie jest kompatybilna z Net::SSH::Perl, proszę dać znać (autorowi email w części informacje o autorze); okazuje sie że niektóre implementacje SSH2 maja subtelne różnice od innych. Szyfry 3DES (3des-cbc), Blowfish (blowfish-cbc), oraz RC4 (arcfour) są obecnie obsługiwane w szyfrowaniu SSH2, i sprawdzaniu poprawności w algorytmach zarówno hmac-sha1 oraz hmac-md5. Kompresja jeśli potrzebna, jest ograniczona do Zlib. Obsługiwane główne algorytmy serwer host to ssh-dss (domyślny) oraz ssh-rsa (na żądanie Crypt::RSA); obsługiwane SSH2 algorytmy kluczy publicznych są takie same.

Jeśli szukasz obsługi SFTP, spójrz do Net::SFTP, która zapewnia pełną Perlową implementacje SFTP.

Metody

Net::SSH::Perl->new($host, %params)
Aby nawiązać nowe połączenie, wywołuje metode new, która łączy sie z $host i zwraca obiekt Net::SSH::Perl
new akceptuje nastepujące parametry %params:
  • protocol
  • Protokół jakiego chcesz użyć do połączenia: powinno być albo 2, 1, 1,2 albo 2,1. Dwa pierwsze dwa mówią po prostu "używaj tylko tej wersji protokołu" (odpowiednio SSH-2,SSH-1). Dwie późniejsze mówią ze obie wersje protokołu mogą zostać użyte, jednak jeden protokół (pierwszy w liscie gdzie elementy są oddzielone przecinkami) jest preferowanym.

    Bezpieczniej używać jest drugiej wersji, ponieważ zapewnia ona polaczenie jeśli nie jednym protokołem to drugim; jeśli twój serwer nie obsługuje pierwszego protokołu z listy, zostanie użyty drugi.

    Domyślna wartość to 1,2, aby zapewnić kompatybilność z OpenSSH;

  • cipher
  • Określa nazwę szyfrowania jaką chcemy użyć w połączeniu. To musi być jeden z obsługiwanych rodzajów; podanie nie obsługiwanego szyfrowania wyświetli błąd kiedy zaczniesz prowadzić negocjacje co do algorytmu (zarówno SSH-1 jak i SSH-2).

    W SSH-1, obsługiwanymi nazwami szyfrów są IDEA, DES, DES3 oraz Blowfish; w SSH-2 arcfour, blowfish-cbc i 3des-cbc.

    Domyślnym szyfrem dla SSH-1 jest IDEA; dla SSH-2 3des-cbc.

  • ciphers
  • Podobnie jak wyżej, ta metoda określa nazwę szyfrowania jaką chcemy użyć w połączeniu; jednak ta metoda odpowiada opcjom szyfru.

    Powinna to być lista z elementami oddzielonymi przecinkami lista szyfrów; szyfry wypisane wyżej.

    Domyślnie 3des-cbc,blowfish-cbc,arcfour.

  • port
  • Port na demona sshd na który chcemy się połączyć; jeśli nie sprecyzowany, zakładamy domyślny port ssh.

  • debug
  • Ustawiamy na prawdę jeśli chcemy widzieć wiadomości debugowania w trakcie jak połączenie zostaje otwarte. Może to być pomocne do ustalenia problemów z połączeniem, itp. Wiadomości są podobne (w niektórych przypadkach identyczne) do tych wypisywanych przez klienta ssh kiedy użyjemy opcji -v.

    Domyślnie ustawione na fałsz.

  • interactive
  • Ustawione na prawda jeśli używamy Net::SSH::Perl w trybie interaktywnym. Jest używane czy należy wyświetlić np. prośbę o hasło.

    Domyślnie fałsz.

  • privileged
  • Ustawione na prawdę jeśli chcemy "podłączyć" sie do uprzywilejowanego portu lokalnego. Będziemy tego potrzebować jeśli planujemy używać uwierzytelnienia Rhosts lub Rhosts-RSA, ponieważ zdalny serwer potrzebuje aby klient połączył sie na uprzywilejowanych portach. Oczywiście aby "podłączyć" sie do uprzywilejowanych portów musimy być root'em.

    Jeśli nie dostarczymy tego parametru, oraz Net::SSH::Perl wykryje ze działamy jako root, automatycznie wartość zostanie ustawiona na prawdę. W przeciwnym przypadku ustawione jest na fałsz.

  • identity_files
  • Lista RSA/DSA plików identyfikujących które maja być wykorzystane do poświadczenia w RSA/DSA. Wartość tego argumentu powinna być referencją do tablicy napisów, każdy napis wskazuje lokacje pliku. Każdy plik identyfikujący będzie testowany przez serwer dopóki klient nie znajdzie takiego dla którego poświadczenie się powiedzie.

    Jeśli nie dostarczymy tego parametru, poświadczenie RSA używa domyślnie $ENV{HOME}/.ssh/identity, a DSA domyślnie $ENV{HOME}/.ssh/id_dsa.

  • compression_level
  • Określa poziom kompresji który ma zostać użyty jeśli została ona włączona. (zwróć uwagę ze musisz dostarczyć oba argumenty compression ora compression_level aby ustawic poziom kompresji; dostarczenie wyłącznie tego argumentu nie włączy kompresji).

    Te ustawienia są wyłącznie odpowiednie dla SSH-1; stopień kompresji dla SSH-2 kompresji Zlib jest zawsze ustawiony na 6.

    Domyślnie wartość ustawiona na 6.

  • use_pty
  • Ustawiamy na 1 jeśli chcemy poprosić o pseudo terminal (tty) na zdalnej maszynie. Opcja ta jest pomocna wyłącznie jeśli ustanowimy polaczenie shell'owe (spójrz na metode poniżej).

    Domyślnie jeśli włączamy shell ustawione jest na 1, w przeciwnym przypadku 0.

  • options
  • Używane aby wskazać dodatkowe opcje do ustawień konfiguracyjnych. Przydatne aby wskazać opcje dla których nie ma oddzielnych konstruktorów. Jest to analogiczne do opcji -o podanej z linii poleceń dla programu ssh.

    Jeśli zostanie użyte, wartość powinna być referencja do listy wytycznych opcji w formacie użytym w pliku konfiguracyjnym.

    Na przykład:

    my $ssh = Net::SSH::Perl->new("host", options => [ "BatchMode yes", "RhostsAuthentication no" ]);
$ssh->login([ $user [, $password [, $suppress_shell ] ] ])

Ustawia nazwę użytkownika oraz hasło jakie mają zostać używane podczas potwierdzania dla demona sshd. Nazwa użytkownika $user jest potrzebna wszystkich protokołów poświadczających. Jeśli nazwa użytkownika nie jest sprecyzowana, użyta zostanie bieżąca nazwa użytkownika wykonywującego program.

Hasło $password jest potrzebna tylko do poświadczeń z hasłem. Jeśli uruchomiłeś sesje w trybie interaktywnym a hasło nie zostało sprecyzowane zostaniesz o nie zapytany.

Domyślnie, Net::SSH::Perl otwiera nowy kanał z uruchomionym na nim shell'em. Zazwyczaj tego właśnie chcemy. Jeśli tulnelujemy inny protokół przez SSH, zapewne chcielibyśmy zapobiec temu zachowaniu. Dostarczenie wartości prawda dla $suppress_shell zapobiegnie takiemu zachowaniu.

($out, $err, $exit) = $ssh->cmd($cmd, [ $stdin ])

Uruchamia komendę $cmd na zdalnym serwerze i zwraca standardowe wejście, wyjście oraz status zakończenia komendy.

Jeśli $stdin jest dostarczone, dostarczane jest do zdalnej komendy $cmd na standardowe wejście.

Protokół SSH-1 nie obsługuje uruchamiania wielu komend w trakcie jednego połączenia, chyba że komendy te są "połączone" w taki sposób ze zdalny shell może je obsłużyć. Z tego powodu, nowe gniazdo połączenia jest tworzone za każdym razem wywołamy cmd, oraz usuwane po wykonaniu.

$ssh->shell

Otwiera interaktywny shell na zdalnej maszynie i łączy go z twoim standardowym wejściem. Jest to najefektywniejsze gdy używane wraz z pseudo terminalem; w przeciwnym wypadku nie dostaniemy znaku zachęty linii poleceń, i nie będzie wyglądało to jak shell. Z tego powodu jeśli nie sprecyzujemy inaczej terminal będzie zażądany od zdalnej maszyny, nawet jeśli nie ustawiłeś argumentu use_pty.

Jest to naprawdę użyteczne w trybie interaktywnym.

$ssh->register_handler($packet_type, $subref [, @args ])

Rejestruje wskaźnik do anonimowej funkcji $subref aby obsługiwał pakiety typu $packet_type podczas pętli klienta. Funkcja będzie wywołana kiedy pakiet typu $packet_type został otrzymany.

Do pętli w kliencie wchodzimy gdy klient wyśle komendę do zdalnego serwera, i po wysłaniu jakich kolwiek danych standardowym wejściem; składa sie z czytania pakietów z serwera (pakiety ze standardowego wyjścia,błędu itp.) dopóki serwer serwer nie wyśle statusu zakończenia komendy. W tym momencie klient wychodzi z pętli oraz rozłącza sie z serwerem.

Kiedy wywołujemy metodę cmd, pętla klienta domyślnie po prostu wrzuca pakiety ze standardowego wyjścia do skalara i zwraca te wartości do metody wywołującej. Robi to samo z pakietami z wyjsia błędu, i dla statusu zakończenia programu.

Metody bardziej zaawansowane

$ssh->config

Zwraca obiekt Net::SSH::Perl::Config obsługujący dane konfiguracyjne dla obiektu SSH. Jest on tworzony z danych podanych do konstruktora new (zobacz wyżej), połączonych z danymi przeczytanymi z plików konfiguracyjnych użytkownika. Zobacz Net::SSH::Perl::Config dokumenty aby poznać detale.

$ssh->sock

Zwraca gniazdo podłączone do sshd. Jeśli twój klient nie jest podłączony, ginie.

$ssh->debug($msg)

Jeśli debugowanie jest włączone dla tej sesji, pisze $msg na wyjście błędu. W przeciwnym przypadku nic nie jest robione.

$ssh->incoming_data

Bufor przychodzących danych, obiekt typu Net::SSH::Perl::Buffer. Zwraca obiekt bufora

Pomysł na to jest taki ze nasze gniazdo nie jest blokowane, dlatego buforujemy wejście i okresowo sprawdzamy spowrotem czy nie przeczytaliśmy całego pakietu. Jeśli mamy cały pakiet, wyciagamy go z bufora przychodzących danych i przetwarzamy go, zwracając do wywołania który prawdobodobnie oczekuje go.

Te dane "należą" do niższej warstwy pakietów w Net::SSH::Perl::Packet. Chyba ze naprawdę wiesz co robisz prawdopodobnie nie chcesz przeszkadzać im

$ssh->session_id

Zwraca ID sesji, który jest generowany przez hosta serwera oraz przez klucze na serwerze, oraz poprzez kontrolne bajty które są wysyłane razem z kluczami. Serwer może wymagać aby ID sesji było wysyłane razem z innymi pakietami.

$packet = $ssh->packet_start($packet_type)

Zaczyna budować nowy pakiet typu $packet_type. To jest tylko zręczna metoda dla leniwych ludzi. W końcu i tak wywoływana jest Net::SSH::Perl::Packet::new, wiec tam należy spojrzeć aby poznać więcej szczegółów.

Dodatkowe informacje.

Dlaczego wybrałem ten moduł?

Poszukiwałem modułu, który pomoże mi pisać programy czytające pliki zarówno z mojego lokalnego systemu plików jak i konta na uniwersytecie. Znalazłem inny moduł Net::SSH jednak po pewnym czasie użytkowania, zwróciłem uwagę na jego mocne uzależnienie od programu ssh (moduł Net::SSH jest "nakładką" na ten program) oraz na tworzenie dużej liczby procesów. Na moim komputerze to nie stanowi problemu jednak na uczelni to juz pewien problem. Przenośność tych programów na inne platformy też pozostawiało wiele do życzenia. Problemy te rozwiązał ten właśnie moduł Net::SSH::Perl. Godny uwagi jest tryb shell'owy który pozwala działać interaktywnie.

Mój przykładowy program
use Net::SSH::Perl; if($#ARGV < 2){exit 0;} my $ssh = Net::SSH::Perl->new($ARGV[2]); $ssh->login($ARGV[0], $ARGV[1]); my($stdout, $stderr, $exit) = $ssh->cmd("ls -l --time-style=long-iso ./var/mail/ARGV[0]"); my @napis=split /\s/,$stdout; my($stdout, $stderr, $exit) = $ssh->cmd("ls -lu --time-style=long-iso ./var/mail/ARGV[0]"); my @napis2=split /\s/,$stdout; if(@napis[6] ge @napis2[6] && @napis[7] gt @napis2[7]){ print "masz nowa poczte\n"; }else{ print "nie masz nowej poczty\n"; }

Program ten po uruchomieniu z argumentami nazwa_użytkownika, hasło, nazwa_serwera sprawdza daty os taniej modyfikacji pliku użytkownika /var/mail/[nazwa_użytkownika] oraz czasu dostępu i na tej podstawie wyświetla czy mamy nową pocztę na danym serwerze czy nie.

Przydatne linki

Dokumentacja tego modułu w cpan'ie
To samo trochę dokładniej
Jeszcze więcej dokumentacji

Kontakt i informacje o autorze opracowania

Autorzy modułu:

projektem obecnie zajmuje sie David Robins, dbrobins@cpan.org.

Wcześniej projekt podtrzymywał Dave Rolsky, autarch@urth.org.

Pierwotnie napisane przez Benjamina Trotta.

Autor przekładu: MD

Numer GG: Słoneczko 2194164

Uniwersytet Gdański - Instytut Informatyki - Strona domowa - Perl - Wyklady
[c] Piotr Arłukowicz, materiały z tej strony udostępnione są na licencji GNU.