Jak uruchomić polecenie sftp z hasłem ze skryptu Bash?

173

Muszę przesłać plik dziennika do zdalnego hosta przy użyciu protokołu SFTP z hosta Linux. Otrzymałem dane uwierzytelniające do tego samego z mojej grupy operacyjnej. Jednak ponieważ nie mam kontroli nad innym hostem, nie mogę generować i udostępniać kluczy RSA innemu hostowi.

Czy jest więc sposób na uruchomienie sftppolecenia (z podaną nazwą użytkownika / hasłem) z poziomu skryptu Bash za pomocą zadania cron ?

Znalazłem podobne pytanie dotyczące przepełnienia stosu, podaj hasło do sftp w skrypcie Bash , ale nie było zadowalającej odpowiedzi na mój problem.

anubhava
źródło

Odpowiedzi:

178

Masz kilka opcji innych niż uwierzytelnianie za pomocą klucza publicznego:

  1. Użyj pęku kluczy
  2. Użyj sshpass (mniej zabezpieczony, ale prawdopodobnie spełnia Twoje wymagania)
  3. Oczekiwanie użycia (najmniej zabezpieczone i potrzebne więcej kodowania)

Jeśli zdecydujesz się dać sshpass szansę, oto działający fragment skryptu, który to zrobi:

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!
anubhava
źródło
3
Do używania na Macu: stackoverflow.com/questions/9102557/ ...
anubhava
18
Myślę, że nie ma potrzeby eksportu. SSHPASS=password sshpass -e ...powinieneś zrobić.
Jens,
9
Udało mi się wykonać jedną linijkę, aby pobrać plik dziennika:sshpass -p "my_password" sftp -oPort=9999 user@host:dir/file.log
Cloud Artisans
6
@gorus: Jedna linijka jest bardzo fajna, ale nie chciałem używać hasła w wierszu poleceń ze względu na zwiększone ryzyko podsłuchiwania.
anubhava
8
-oBatchMode=nobył dla mnie kluczowym brakującym elementem.
richardkmiller
99

Innym sposobem byłoby użycie lftp:

lftp sftp://user:password@host  -e "put local-file.name; bye"

Wadą tej metody jest to, że inni użytkownicy komputera mogą odczytać hasło z narzędzi takich jak psi to, że hasło może stać się częścią historii powłoki.

Bardziej bezpieczną alternatywą, która jest dostępna od LFTP 4.5.0, jest ustawienie LFTP_PASSWORDzmiennej środowiskowej i wykonanie lftp z --env-password. Oto pełny przykład:

LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user@host  -e "put local-file.name; bye"

LFTP zawiera również funkcję fajnego tworzenia kopii lustrzanych (może obejmować usuwanie po potwierdzonym transferze --Remove-source-files):

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
Karassik
źródło
9
+1 za zasugerowanie alternatywy, ale czy możemy uniknąć podawania hasła w wierszu poleceń?
anubhava
1
Głos odrzucony za pokazanie hasła każdemu na tym samym komputerze
Aaron Digulla
10
Możesz stworzyć plik skryptu dla lftp, dzięki czemu nie będziesz musiał podawać hasła w linii poleceń. Utwórz plik put-script: open sftp://user:password@host; put local-file.name; exit Następnie uruchom W lftp -f put-script ten sposób nie musisz mieć nazwy użytkownika i hasła w wierszu poleceń i możesz ustawić restrykcyjne uprawnienia do pliku skryptu.
obaranovsky
@obaranovsky To dobry pomysł. Zastanawiam się, czy dodam to do mojej zmiennej środowiskowej jako alias lub funkcję, czy byłoby bezpieczne i możliwe byłoby ukrycie tego przed innymi użytkownikami?
sdkks,
1
O wiele łatwiejsze do zrobienia lftpniż bałagan z sftpi sshpass. Dobra odpowiedź.
MeanEYE
53

Expect to świetny program w użyciu.

W systemie Ubuntu zainstaluj go za pomocą:

sudo apt-get install expect

Na maszynie CentOS zainstaluj ją z:

yum install expect

Powiedzmy, że chcesz nawiązać połączenie z serwerem SFTP, a następnie przesłać plik lokalny z komputera lokalnego na zdalny serwer SFTP

#!/usr/bin/expect

spawn sftp username@hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact

Otwiera to połączenie sftp z hasłem do serwera.

Następnie przechodzi do katalogu, do którego chcesz przesłać swój plik, w tym przypadku „logdirectory”

Spowoduje to przesłanie pliku dziennika z katalogu lokalnego znajdującego się w / var / log / z nazwą pliku file.log do "logdirectory" na zdalnym serwerze

rezizter
źródło
Dziękuję za odpowiedź, spodziewałem się jednej z moich opcji realizacji tego zadania.
anubhava
Dziękuję Ci. Znalazłem twoją odpowiedź poprzez wyszukiwanie, użyłem jej i zbudowałem skrypt pomyślnie z oczekiwaniem. Właśnie opublikowałem scenariusz poterity
rezizter
Dziękuję bardzo za odpowiedź, już ją zagłosowałem :)
anubhava
Używam tego do wprowadzenia hasła do klucza prywatnego SSH. Wygodniej jest umieścić ten sam klucz publiczny na wszystkich serwerach i po prostu okresowo zmieniać hasło klucza prywatnego.
sdkks
24

Możesz użyć lftp interaktywnie w skrypcie powłoki, aby hasło nie zostało zapisane w .bash_history lub podobnym, wykonując następujące czynności:

vi test_script.sh

Dodaj do swojego pliku:

#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>

cd <base directory for your put file>

lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT

I napisz / zamknij edytor vi po edycji hosta, użytkownika, hasła i katalogu do wpisywania pliku put. :wqNastępnie spraw, aby skrypt był wykonywalny chmod +x test_script.shi wykonaj go ./test_script.sh.

Mike S.
źródło
2
Aby nadpisać istniejący plik, dodaj „set xfer: clobber on” po lftp << END_SCRIPT
Balaji Natarajan
17

Niedawno poproszono mnie o przejście z ftp na sftp, aby zabezpieczyć transmisję plików między serwerami. Używamy pakietu Tectia SSH, który ma opcję --passwordpodania hasła w linii poleceń.

przykład: sftp --password="password" "userid"@"servername"

Przykład partii:

(
  echo "
  ascii
  cd pub
  lcd dir_name
  put filename
  close
  quit
    "
) | sftp --password="password" "userid"@"servername"

Pomyślałem, że powinienem udostępnić te informacje, ponieważ przeglądałem różne witryny internetowe przed uruchomieniem polecenia pomocy ( sftp -h) i byłem zaskoczony, widząc opcję hasła.

Mahony
źródło
9
+1 dla Ciebie dobra sugestia. Będzie to jednak wymagało podania hasła w wierszu poleceń, a każdy w systemie wykonujący pspolecenie będzie mógł zobaczyć Twoje hasło.
anubhava,
4
Próbowałem tego, dostałemunknown option -- - usage: sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host
cyber8200
1
@ihue prawdopodobnie dlatego, że potrzebujesz Techia SSH , a nie OpenSSH
qris
17

Możesz to zmienić, włączając uwierzytelnianie bez hasła. Ale powinieneś zainstalować klucze (pub, priv) przed tym.

Wykonaj następujące polecenia na serwerze lokalnym.

Local $> ssh-keygen -t rsa 

Naciśnij klawisz ENTER dla wszystkich wyświetlonych opcji. Nie trzeba wpisywać żadnych wartości.

Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user@targetmachine:
Prompts for pwd$>  ENTERPASSWORD

Połącz się ze zdalnym serwerem za pomocą następującego polecenia

Local $> ssh user@targetmachine
Prompts for pwd$> ENTERPASSWORD

Wykonaj następujące polecenia na serwerze zdalnym

Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit

Wykonaj następujące polecenie na serwerze lokalnym, aby przetestować uwierzytelnianie bez hasła. Powinien być podłączony bez hasła.

$> ssh user@targetmachine
SriniV
źródło
1
+1 dla Twojej odpowiedzi, ale pytanie dotyczyło zrobienia tego bez kluczy publicznych / prywatnych.
anubhava,
Ups ... Właśnie zobaczyłem ograniczenia dotyczące udostępniania kluczy :)
SriniV,
Z ciekawości czy to polecenie lftp -p ${port} -u ${login_id},${password} ${ip_number}wywołane ze skryptu powłoki wydrukuje je gdzieś? Jak rozwiązałeś problem poza sshpass?
SriniV,
Nie mam lftpi polegam na sshpassobu systemach Mac i Linux.
anubhava,
Czyste złoto. Dzięki! :)
Nikolay Tsenkov
7

Połącz sshpass z zablokowanym plikiem poświadczeń i, w praktyce, jest tak bezpieczny jak wszystko inne - jeśli masz roota na skrzynce, aby odczytać plik z danymi uwierzytelniającymi, wszystkie zakłady i tak są wyłączone.

Rich Harding
źródło
5

Program Bash czeka, aż sftp zapyta o hasło, a następnie wyśle ​​je razem:

#!/bin/bash
expect -c "
spawn sftp username@your_host
expect \"Password\"
send \"your_password_here\r\"
interact "

Być może będziesz musiał oczekiwać instalacji, zmień sformułowanie „Hasło” na małe litery „p”, aby dopasować je do tego, co otrzymujesz. Problem polega na tym, że ujawnia twoje hasło w postaci zwykłego tekstu w pliku, a także w historii poleceń. Co prawie przeczy celowi posiadania hasła.

Eric Leschinski
źródło
+1, ale myślę, że jasno określasz, jakie są problemy związane z tym podejściem.
anubhava
5

Możesz do tego użyć sshpass. Poniżej znajdują się kroki

  1. Zainstaluj sshpass dla Ubuntu - sudo apt-get install sshpass
  2. Dodaj zdalny adres IP do pliku znanego hosta, jeśli jest to pierwszy raz W przypadku Ubuntu -> ssh user @ IP -> wpisz „tak”
  3. podaj dla niego połączone polecenie scp i sshpass. Poniżej znajduje się przykładowy kod radzenia sobie w wojnie z odległym kotem sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps
ravi ranjan
źródło