Serwer Bastion: użyj przekierowania TCP VS umieszczając klucz prywatny na serwerze


10

Mamy serwer bastionowy B. Musimy SSH od A do B do C, używając klucza prywatnego.

Jaka jest lepsza opcja:

  • Umieść prywatny klucz SSH na serwerze B. Czytamy, że złym pomysłem jest robienie tego w środowisku produkcyjnym.

    Od tutaj :

    Nigdy nie umieszczaj kluczy prywatnych SSH w instancji bastionu. Zamiast tego użyj przekazywania agenta SSH, aby połączyć się najpierw z bastionem, a stamtąd z innymi instancjami w prywatnych podsieciach. Pozwala to zachować prywatny klucz SSH tylko na komputerze.

  • Użyj przekazywania agenta SSH . Aby skonfigurować przekazywanie agentów, muszę zezwolić na przekazywanie TCP. Podczas konfigurowania przekazywania agenta na hoście przekazującym tworzony jest plik gniazda, który jest mechanizmem, za pomocą którego można przekazać klucz do miejsca docelowego. W ustawieniach Bastionu w AWS:

    Przekazywanie TCP: Ustawienie wartości true spowoduje włączenie przekazywania TCP (tunelowanie SSH). Może to być bardzo przydatne, ale stanowi również zagrożenie bezpieczeństwa, dlatego zalecamy zachowanie domyślnego (wyłączonego) ustawienia, chyba że jest to wymagane

    Również stąd :

    Przekazywanie agentów SSH uważane jest za szkodliwe

Co jest lepsze? Co z alternatywą z drugiego łącza: ProxyCommand , rozumiem, że to pomaga w przypadku problemu z plikiem gniazda, ale nadal uważam, że muszę włączyć przekazywanie TCP, więc czy jest wystarczająco bezpieczne?


2
Z ProxyCommand nie musisz włączać przekierowywania TCP. Przekazywanie odbywa się przez ssh na hoście pośrednim.
wurtel

Dzięki. Czy powinien to być plik konfiguracyjny? na moim komputerze czy w Bastionie?
user2503775

W systemie lokalnym, w którym będziesz wpisywać ssh hostbpolecenie, aby mógł wyszukać hostb w lokalnej konfiguracji i wiedzieć, że musi się połączyć przez hosta. Nie można tego zrobić, jeśli umieścisz konfigurację na hosta ...
wurtel

Gdzie będzie przechowywany klucz prywatny serwera C? także w mojej kompie? Używam keepass z keeAgent
user2503775

2
Obawiam się, że mylisz przekazywanie TCP z przekazywaniem agentów . To są różne rzeczy.
MLu

Odpowiedzi:


13

Użyj ProxyCommand lub ProxyJump

Polecam użyć ProxyCommand(lub nawet lepiej, ProxyJumpponieważ składnia jest łatwiejsza, ale wymaga openssh 7.3+, myślę, że po stronie klienta) i nie trzeba wdrażać klucza prywatnego na Bastionie, wszystko pozostaje lokalne.

Przykład z ProxyJump

Na komputerze klienckim piszesz plik ~/.ssh/configo podobnej treści do poniższej:

Host bastion
  HostName bastion.example.com
  User bastion-user
  Port 22
  IdentityFile ~/.ssh/id_bastion

Host srvC
  HostName srvC.local
  User server-user
  IdentityFile ~/.ssh/id_protected_lan
  ProxyJump bastion

W ten sposób ssh srvCpołączysz się z C za pośrednictwem B (bastion) bez przekazywania agenta ani wdrażania klucza prywatnego do bastionu.

W powyższym przykładzie „bastion” jest aliasem dla twojego hosta Bastion, a srvC jest aliasem dla twojego serwera C. W polu HostNamemusisz podać IP lub prawdziwą w pełni kwalifikowaną nazwę domeny dla swoich hostów. Dla użytkowników musisz zaktualizować Userprawidłową nazwę logowania na Bastionie i serwerze C. Wreszcie IdentityFileopcja jest opcjonalna, jeśli używasz lokalnego agenta (np. KeeAgent lub ssh-agent), ale jeśli nie jest uruchomiony, to również będzie pracuj i pytaj o każde kluczowe hasło.

Wdrażanie kluczy publicznych

Oczywiście musisz wdrożyć klucze publiczne zarówno do bastionu, jak i srvC. Możesz użyć (znak $ ma tylko zilustrować monit, nie wpisuj go):

$ ssh-copy-id -i ~/.ssh/id_bastion.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   bastion
$ ssh-copy-id -i ~/.ssh/id_protected_lan.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   srvC

Uwaga: powyższe będzie działać tylko wtedy, gdy uwierzytelnianie hasłem jest nadal dozwolone. Po powyższym wdrożeniu i sprawdzeniu, czy wszystko działa zgodnie z przeznaczeniem, należy zabronić uwierzytelniania hasła na 2 serwerach.

Przykład z ProxyCommand zamiast ProxyJump

Jeśli masz starszą wersję OpenSSH, która nie obsługuje ProxyJump(po stronie klienta), zamień:

ProxyJump bastion

przez

ProxyCommand ssh -q -W %h:%p bastion

O ile rozumiem, jest to podobne.


Dziękuję Ci! Pracuję z Linuksem, ale niektórzy członkowie zespołu pracują nad oknami. Powinno tam również działać, prawda?
user2503775

Z którego klienta SSH będą korzystać? OpenSSH (przez WSL, cygwin itp.) Lub PuTTY (lub inne narzędzie oparte na PuTTY), takie jak MobaXterm?
Huygens

Niektóre z nich używają PuTTy, a inne ssh przez Git Shell.
user2503775

@ user2503775 Nigdy nie próbowałem tego z PuTTY, ale wydaje się, że jest to możliwe przy użyciu podejścia ProxyCommand, patrz tutaj: stackoverflow.com/a/28937185
Huygens

1
Dziękuję bardzo za szczegółową odpowiedź!
user2503775

5

Widziałem odpowiedź na temat ProxyJump. Porozmawiajmy o ProxyCommand .

Ale czekaj, czekaj! Mogę napisać do ciebie, jak zhakować serwer, który korzysta z przekazywania agentów, znacznie łatwiej byłoby zrozumieć różnicę!

Hakujmy!

Podstawowe kroki: możesz przeczytać mój post tutaj

Podstawowe kroki są następujące:

  1. Utwórz użytkowników bastionu
  2. Wyłącz logowanie roota
  3. Blokuj próby włamania
  4. Zmień port
  5. Skonfiguruj zaporę ogniową
  6. Skonfiguruj SELinux

Jak korzystać z AgentForwarding

-Utwórz config w ~ / .ssh / config

  Host bast
        Hostname BASTION_IP
        ForwardAgent yes
        User bastion

-Dodaj swój klucz uwierzytelniający do ssh-agent

ssh-add ~/.ssh/name_rsa

-Połącz się z bastionem

ssh bast

-Podłącz serwer aplikacji od bastionu

 ssh app@IP -p PORT

Hakerstwo!

Możesz zadać mi pytanie:

  • Czy mój serwer jest bezpieczny? Odpowiedź jest dość prosta:

    • NIE!
  • Dlaczego?

    • Ponieważ używasz przekazywania SSH Agent!
  • A gdzie jest problem?

    • Ponieważ przekazywanie agentów jest niebezpieczne i uważa się je za szkodliwe.
  • Dlaczego?

    • Wytłumaczmy wszystko na lewą stronę: kiedy podłączysz hosta bastionu, twój wspaniały agent ssh zostanie przekazany. Oznacza to, że gniazdo zostanie skonfigurowane, aby ktoś mógł użyć tych danych gniazda do uzyskania dostępu do serwerów. Wyobraź sobie, że twój serwer bastionowy jest zagrożony. Jeśli ktoś ma wystarczające uprawnienia na serwerze Linux, użyje informacji o twoim gnieździe. W rezultacie można uzyskać dostęp do całego serwera. Wiem, że okno kompromisu jest bardzo małe, ponieważ zależy od tego, ile czasu jesteś podłączony do hosta bastionu. Ale czy naprawdę chcesz ryzykować, gdy masz inne opcje, takie jak ProxyCommand? Dlatego po prostu użyj ProxyCommand!

Jak zhakować serwery, jeśli zaatakowałeś hosta bastionu?

Śledź cel

W katalogu / tmp możesz zobaczyć coś takiego:

[root@localhost tmp]# ll
total 12
drwx------  2 bastion bastion 4096 Sep  7 17:35 ssh-mKX88v0Vlo

Otwórzmy plik tymczasowy

[root@localhost tmp]# cd ssh-mKX88v0Vlo/
[root@localhost ssh-mKX88v0Vlo]# ll
total 0
srwxr-xr-x 1 bastion bastion 0 Sep  7 17:35 agent.10507

Zobaczmy połączenia z tym identyfikatorem procesu.

netstat -nxp | grep  10507

wynik:

unix  [ ]   STREAM     CONNECTED     501384   10507/sshd: bastion

i kto jest połączony?

lsof -i -a -p 10507

wynik:

COMMAND  PID   USER  FD  TYPE DEVICE SIZE/OFF NODE NAME
sshd    10507 bastion  3u  IPv4 501301  0t0  TCP *IP*:ssh->*IP*:8279 (ESTABLISHED)

Możemy również zobaczyć pliki gniazd:

cd /proc/10507/fd/
ls

wynik:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

A co się stanie, gdy klient zostanie podłączony do zdalnego serwera? Zobaczmy:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:48 11 -> socket:[502267]
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

Możemy nawet sprawdzić, czy plik gniazda jest używany przy użyciu netstat:

unix  3 [ ]  STREAM  CONNECTED  502267  10561/sshd: 
                     bastion  /tmp/ssh-oVoMXC6vb8/agent.10561
unix  3  [ ] STREAM     CONNECTED     502072   10561/sshd:  bastion 

Kradzież informacji o gnieździe i adres IP

Teraz musimy ukraść informacje o gnieździe, gdy sesja hosta bastionu jest otwarta . Och, potrzebujemy również adresu IP serwera docelowego , więc po prostu użyj netstat:

netstat -tn

Końcowy etap użyć przekierowanego pliku gniazda

eval "$(ssh-agent -s)"
SSH_AUTH_SOCK=/tmp/ssh-EAKxOdL4fl/agent.10507

Sprawdź, czy klucz jest załadowany .

ssh-add -l

wynikiem powinno być coś takiego :

2048 SHA256:2Psdl..B5KQ /home/usr/.ssh/name_rsa (RSA)

Serwer został zhakowany, jak rozwiązać problem bezpieczeństwa?

Polecenie proxy

Host app
    Hostname *.*.*.*
    IdentityFile ~/.ssh/your_rsa
    User *******
    Port ****
    ProxyCommand ssh -W %h:%p bast

Host bast
     Hostname *.*.*.*
     ForwardAgent no
     User ******

Podstawowe operacje: jak przesyłać pliki przez serwery (z klienta na serwer, z serwera na klienta), możesz przeczytać w moim poście tutaj

Wniosek

  • Jeśli korzystasz z hosta bastionu, nie używaj AgentForwarding, ale użyj ProxyCommand
  • Zawsze używaj użytkownika innego niż root do uwierzytelniania
  • Użyj zapory i zablokuj wszystkie niepotrzebne połączenia.
  • Użyj SELinux (ogólnie)
  • Zablokuj adres IP, który próbuje zalogować się kilka razy przy użyciu nieprawidłowych danych logowania
  • Jeśli nie jest to konieczne, nie udzielaj sudo użytkownikowi
  • Monitoruj swój serwer
  • Zaktualizuj serwer, aby uzyskać poprawki bezpieczeństwa

Więcej informacji znajdziesz na moim blogu . Dodatkowo mam kilka zrzutów ekranu, więc może ci się przydać.


Dziękuję Ci bardzo! w rzeczywistości używamy również uwierzytelnienia Google po zalogowaniu.
user2503775,

Dostaję błąd podczas próby wywołania ssh aplikacji: channel 0: open failed: administratively prohibited: open failed. stdio forwarding failed. . Masz pojęcie dlaczego? W bezpiecznym dzienniku widzę:refused local port forward: originator 127.0.0.1 port 65535, target *app-ip* port 22
user2503775

Fajne informacje. Mała rada, aby poprawić czytelność odpowiedzi. Nie kopiuj / wklejaj zawartości swojego bloga tutaj. Podaj link i podsumowanie. Następnie zaznacz prawdziwą część odpowiedzi (która dla Ciebie używa ProxyCommand). Na początku widziałem, że próbowałeś tego, ale biorąc pod uwagę kopiowanie / wklejanie, było to trochę mylące. W każdym razie +1
Huygens

@ user2503775 Powinien to być inny problem, niezwiązany z poleceniem ssh-agent forwarding / proxy. Otwórzmy nowe pytanie z logami.
grep,


4

Wystarczy użyć przekazywania agenta SSH, jak większość innych.

  • Klucze będą w agencie ssh na twoim laptopie.
  • Zaloguj się do bastionu, uwierzytelnionego przez agenta.
  • Stamtąd zaloguj się do hosta docelowego, a żądanie uwierzytelnienia zostanie przesłane z powrotem do laptopa .

Zaleta: w bastionie nie ma kluczy, których można by użyć w niewłaściwy sposób.

Mam nadzieję, że to pomoże :)


Cześć, to jest po prostu to, co OP opisuje w swojej drugiej kuli. Radzę sprawdzić drugi link podany w pytaniu.
Huygens

@Huygens true Zauważyłem teraz. Przesłoniłem to, ponieważ łączy on przekazywanie TCP z przekazywaniem Agentów.
MLu

Rzeczywiście jest to pomieszane :-)
Huygens

Nie jest mieszany. Rozumiem różnicę. Zredagowałem pytanie, aby było jasne.
user2503775

Napisałem odpowiedź, jak zhakować przekazywanie agentów (nie ma klucza, ale gniazdo jest otwarte). Ogólnie rzecz biorąc, przekazywanie agentów jest w porządku, ponieważ możliwość kradzieży kluczy jest bardzo niska - przede wszystkim musisz zhakować hosta bastionu. W każdym razie możesz zobaczyć moją odpowiedź: serverfault.com/a/958466/476642
grep
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.