Kopiujesz chronione pliki między serwerami w jednym wierszu?

13

Chciałbym skopiować squid.confz jednego serwera na drugi.

  • Serwery nie rozmawiają ze sobą. Chciałbym przejść przez moją stację roboczą.
  • Oba serwery mają plik, więc zostanie on nadpisany na obiekcie docelowym.
  • Pliki mają 600uprawnienia i są własnością root.
  • logowanie użytkownika root przez ssh jest wyłączone ( PermitRootLogin no).
  • Chciałbym to zrobić w jednym wierszu, jeśli to możliwe, ponieważ będzie to część przewodnika konfiguracji.

Wiem co zrobić

ssh source 'tar czpf - -C /etc/squid/ squid.conf' | \
    ssh target 'tar xzpf - -C /etc/squid/'

kopiować pliki między serwerami i zachować uprawnienia. Jednak w tym przypadku otrzymam komunikat „Odmowa zezwolenia”.

Wiem też, że mogę to zrobić:

ssh -t source 'sudo cat /etc/squid/squid.conf'

W ten sposób -tsudo może poprosić o hasło administratora przed wysłaniem zawartości pliku.

Problem polega na tym, że nie wiem, jak połączyć te techniki w coś, co poprosi o hasło sudo na każdym serwerze i prześle plik do miejsca docelowego. czy to możliwe?

AKTUALIZACJA : Oto najlepsze, co mogłem wymyślić:

ssh -t source 'sudo tar czf /tmp/squid.tgz -C /etc/squid squid.conf' && \
ssh source 'cat /tmp/squid.tgz' | \
    ssh target 'cat >/tmp/squid.tgz' && \
ssh -t source 'sudo rm /tmp/squid.tgz' && \
ssh -t target \
    'sudo tar xzf /tmp/squid.tgz -C /etc/squid && sudo rm /tmp/squid.tgz'

Nazywanie tego jednowarstwowym wydaje się odcinkiem. Myślę, że podzielę to na osobne kroki w przewodniku konfiguracji.

itsadok
źródło
Powiązane: Kopiowanie dużego drzewa z jednej maszyny na drugą, utrzymanie własności
Gilles „SO- przestań być zły”

Odpowiedzi:

11

Łatwiej jest połączyć łańcuch ssh z ssh niż łańcuch ssh z sudo. Tak więc zmiana konfiguracji serwera ssh jest w porządku, sugeruję otwarcie ssh dla katalogu głównego każdego serwera, ale tylko z lokalnego hosta. Możesz to zrobić z Matchklauzulą ​​w sshd_config:

PermitRootLogin no
Match Host localhost
    PermitRootLogin yes

Następnie możesz skonfigurować łańcuch uwierzytelniania oparty na kluczach od użytkownika zdalnego do użytkownika lokalnego i od użytkownika lokalnego do użytkownika root. Nadal masz ścieżkę uwierzytelniania, więc Twoje logi informują, kto zalogował się jako root, a kroki uwierzytelnienia są takie same, jakby w grę wchodziło sudo.

Aby połączyć się z serwerem jako root, zdefiniuj alias w ~/.ssh/confignastępujący sposób:

Host server-root
HostName server.example.com
User root
ProxyCommand "ssh server.example.com nc %h %p"

Jeśli nalegasz na użycie sudo, uważam, że będziesz potrzebować oddzielnych poleceń, ponieważ sudonalega na czytanie z terminala (nawet jeśli ma bilet na twoje konto) ¹ i żadnej ze zwykłych metod kopiowania plików (scp, sftp, rsync) obsługa interakcji ze zdalnym terminalem.

Trzymając się ssh i sudo, proponowane polecenia można uprościć. Z każdej strony, jeśli sudo zostało skonfigurowane tak, aby nie pytać o hasło ponownie, możesz je uruchomić raz, aby spełnić wymagania dotyczące hasła, a innym razem skopiować plik. (Nie można łatwo skopiować pliku bezpośrednio, ponieważ przeszkadza monit o podanie hasła).

ssh -t source 'sudo true'
ssh -t target 'sudo true'
ssh -t source 'sudo cat squid.conf' |
ssh -t target 'sudo tee /etc/squid/squid.conf'

¹, chyba że masz NOPASSWD, ale nie pytasz o to.

Gilles „SO- przestań być zły”
źródło
Pierwsze rozwiązanie działało dla mnie dobrze, ale powinna być druga linia Match host localhost.
cduck
4

Możesz ustawić, sudoaby nie pytać o hasło w następujący sposób:

U źródła:

user    ALL=NOPASSWD:/bin/cat

Na celu:

user    ALL=NOPASSWD:/usr/bin/tee

I wykonaj na komputerze:

ssh source 'sudo cat /test' | ssh target 'sudo tee /test'

Ale polecam użyć czegoś takiego jak marionetka . O wiele lepiej i łatwiej rozwiązuje problem z dystrybucją plików konfiguracyjnych.

PS. Nawiasem mówiąc, jeśli skonfigurujesz sudożądanie hasła od użytkownika, ciąg z [sudo] password for userpojawi się w pliku docelowym.

wysypka
źródło
+1 za sugerowanie marionetki, ale twoje rozwiązanie wydaje się niepewne. Równie dobrze mogę zezwolić na zalogowanie się jako root.
itsadok
2

Zamiast ssh możesz użyć scp do przesłania pliku między serwerami.

Zaloguj się do serwera docelowego:

Przejdź do katalogu docelowego, w którym chcesz skopiować plik.

#scp -r -p -P 22 root@source-ipaddress:/source-path-file-to-copy .

r - rekurencyjny p - Zachowuje czasy modyfikacji, czasy dostępu i tryby z oryginalnego pliku

Mughil
źródło
Zakłada się, że mogę zalogować się jako root, czego nie mogę. Aktualizacja pytania.
itsadok
2

Bez zmiany konfiguracji ssh możesz utworzyć dwa tunele ssh host-> serwer1 i serwer2-> host poprzez połączenie ssh z serwerem2. Połącz te dwa tunele na maszynie hosta (ten sam port). I uruchom sudo na serwerze 2, aby pobrać dane z podłączonych tuneli na serwerze 1 i zapisać je na serwerze 2.

ssh -L60000:${source}:22 -R60000:localhost:60000 -t ${target} 'sudo bash -c "ssh -p 60000 '$(whoami)'@localhost \"cd /path/to/dir; tar -czf - files\"|tar -C/path/to/target -xzf -"'

Pomysł jest następujący: 1 - utworzenie lokalnego tunelu z maszyny do maszyny źródłowej na porcie 60000

ssh -L60000:${source}:22

1b- Utwórz zdalny tunel, aby dotrzeć z powrotem do maszyny

-R60000:localhost:60000

2 - podłącz do maszyny docelowej

-t ${target}

3 - uruchom wszystko jako root na maszynie docelowej do pisania

'sudo bash -c "..."'

4- połącz się z maszyną źródłową przez tunel. whoami i na localhost oznacza localhost na maszynie $ {target}.

ssh -p 60000 '$(whoami)'@localhost

5- spakuj zdalne pliki i wyślij spakowane na standardowe wyjście

cd /path/to/dir; tar -czf - file

6 - otrzymaj pakiet przez stdout i odpowiednio wypakuj pliki z katalogu / path / to / target

|tar -C/path/to/target -xzf -

Uwaga: Możesz otrzymać do 3 potwierdzeń sshkey i 3 żądań hasła. Ale pliki zostaną skopiowane.

Marco Aurelio
źródło