Bastion server: usa TCP forwarding VS posizionando la chiave privata sul server


10

Abbiamo un server bastione B. Dobbiamo SSH da A a B a C, usando la chiave privata.

Qual è l'opzione migliore:

  • Inserire la chiave SSH privata sul server B. Leggiamo che è una cattiva idea farlo in un ambiente di produzione.

    Da qui :

    Non posizionare mai le chiavi private SSH sull'istanza del bastione. Utilizzare invece l'inoltro dell'agente SSH per connettersi prima al bastione e da lì ad altre istanze nelle sottoreti private. Ciò ti consente di conservare la chiave privata SSH solo sul tuo computer.

  • Utilizzare l' inoltro dell'agente SSH . Per impostare l'inoltro dell'agente, devo consentire l'inoltro TCP. Quando si imposta l'inoltro dell'agente, viene creato un file socket sull'host di inoltro, che è il meccanismo tramite il quale la chiave può essere inoltrata alla destinazione. Nelle impostazioni del bastione su AWS:

    TCP forward: Impostando questo valore su true si abilita il forwarding TCP (tunneling SSH). Questo può essere molto utile ma rappresenta anche un rischio per la sicurezza, quindi ti consigliamo di mantenere l'impostazione predefinita (disabilitata) a meno che non sia necessario

    Anche da qui :

    Inoltro agente SSH considerato dannoso

Cos'è meglio? Che dire dell'alternativa dal secondo collegamento: ProxyCommand , capisco che aiuta con il problema del file socket, ma penso ancora di dover abilitare l'inoltro TCP, quindi è abbastanza sicuro?


2
Con ProxyCommand non è necessario abilitare l'inoltro TCP. L'inoltro viene effettuato da ssh sull'host intermedio.
wurtel

Grazie. Il file di configurazione dovrebbe essere? nel mio computer o nel bastione?
user2503775

Sul tuo sistema locale, dove ssh hostbinserirai il comando, in modo che possa cercare hostb nella configurazione locale e sapere che deve connettersi tramite hosta. Non potrebbe farlo se metti la configurazione su hosta ...
wurtel

Dove verrà archiviata la chiave privata del server C? anche nella mia comp? Sto usando keepass con keeAgent
user2503775

2
Temo che confondi l' inoltro TCP con l' inoltro dell'agente . Sono cose diverse.
MLu

Risposte:


13

Utilizzare ProxyCommand o ProxyJump

Consiglierei di usare ProxyCommand(o anche meglio ProxyJumpperché la sintassi è più semplice ma richiede openssh 7.3+ penso sul lato client) e non è necessario distribuire la chiave privata sul bastione, tutto rimane locale.

Esempio con ProxyJump

Sul tuo computer client scrivi un file ~/.ssh/configcon un contenuto simile al seguente:

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

Quindi facendo ssh srvCti collegherai a C tramite B (bastione) senza inoltro agente né distribuendo la chiave privata sul bastione.

Nell'esempio sopra, "bastion" è un alias per il tuo host Bastion e srvC è un alias per il tuo server C. Nel HostNamedevi inserire IP o nome di dominio reale completo per i tuoi host. Per gli utenti, è necessario aggiornare il Userper il nome di accesso corretto sul bastione e sul server C. Infine, IdentityFileè facoltativo se si utilizza un agente locale (ad esempio KeeAgent o ssh-agent), ma se non è in esecuzione, lo farà anche lavorare e chiederti ogni passphrase chiave.

Distribuire le chiavi pubbliche

Ovviamente devi distribuire le chiavi pubbliche sia su bastion che su srvC. È possibile utilizzare (il simbolo $ è solo per illustrare il prompt, non digitarlo):

$ 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

Nota: quanto sopra funzionerà solo se l'autenticazione con password è ancora consentita. Dopo la distribuzione sopra e verificando che tutto funzioni come previsto, è necessario impedire l'autenticazione della password sui 2 server.

Esempio con ProxyCommand invece di ProxyJump

Se hai una versione precedente di OpenSSH che non supporta ProxyJump(sul lato client), sostituisci:

ProxyJump bastion

di

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

Per quanto ho capito, questo è simile.


Grazie! Lavoro con Linux, ma alcuni membri del team lavorano su Windows. Dovrebbe funzionare anche lì, no?
user2503775

Quale client SSH useranno? OpenSSH (via WSL, o cygwin o ecc.) O PuTTY (o un altro strumento basato su PuTTY) come MobaXterm?
Huygens,

Alcuni usano PuTTy e altri usano ssh tramite Git Shell.
user2503775

@ user2503775 Non l'ho mai provato con PuTTY, ma sembra essere possibile usando l'approccio ProxyCommand, vedi qui: stackoverflow.com/a/28937185
Huygens

1
Grazie mille per la risposta dettagliata!
user2503775

5

Ho visto la risposta su ProxyJump. Parliamo di ProxyCommand .

Ma aspetta, aspetta! Posso scriverti come hackerare il server che utilizza l'inoltro agente, sarebbe molto più facile capire la differenza!

Facciamo hack!

Per i passaggi di base: puoi leggere il mio post qui

I passaggi di base sono i seguenti:

  1. Crea utenti del bastione
  2. Disabilita il login root
  3. Blocca i tentativi di hacking
  4. Cambia porta
  5. Configura firewall
  6. Configura SELinux

Come usare AgentForwarding

-Creare la configurazione in ~ / .ssh / config

  Host bast
        Hostname BASTION_IP
        ForwardAgent yes
        User bastion

-Aggiungere la chiave di autenticazione a ssh-agent

ssh-add ~/.ssh/name_rsa

-Collega ai bastioni

ssh bast

-Collegare il server delle applicazioni dal bastione

 ssh app@IP -p PORT

Hacking!

Potresti, bene, farmi la domanda:

  • Il mio server è sicuro? E la risposta è abbastanza semplice:

    • NO!
  • Perché?

    • Perché stai utilizzando l'inoltro dell'agente SSH!
  • E dov'è il problema?

    • Perché l'inoltro dell'agente è pericoloso ed è considerato dannoso.
  • Perché?

    • Spieghiamo tutto al rovescio: quando colleghi l'host del bastione, il tuo glorioso agente ssh viene inoltrato. Significa che il socket verrà impostato in modo tale che qualcuno possa utilizzare questi dati del socket per accedere ai server. Immagina che il tuo server bastione sia compromesso, se qualcuno ha autorizzazioni sufficienti sul tuo server Linux utilizzerà semplicemente le tue informazioni sui socket. Di conseguenza, è possibile accedere a tutto il server. So che la finestra del compromesso è molto piccola perché dipende da quanto tempo sei connesso all'host del bastione. Ma vuoi davvero correre il rischio quando hai altre opzioni come ProxyCommand? Quindi, basta usare ProxyCommand!

Come hackerare i server se hai compromesso l'host bastion?

Traccia target

Nella directory / tmp potresti vedere qualcosa del genere:

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

Apriamo il file temporaneo

[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

Vediamo le connessioni a questo ID processo.

netstat -nxp | grep  10507

risultato:

unix  [ ]   STREAM     CONNECTED     501384   10507/sshd: bastion

e chi è collegato?

lsof -i -a -p 10507

risultato:

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

Possiamo anche vedere i file socket:

cd /proc/10507/fd/
ls

risultato:

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]

E cosa succede quando il client sarà connesso al server remoto? vediamo:

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]

Possiamo anche vedere se il file socket è usato usando netstat:

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

Ruba informazioni su socket e indirizzo IP

Ora dobbiamo rubare le informazioni sul socket mentre la sessione dell'host bastione è aperta . Oh, abbiamo anche bisogno dell'IP del server di destinazione , quindi usa solo netstat:

netstat -tn

Il passaggio finale per utilizzare il file socket inoltrato

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

Controlla se la chiave è caricata .

ssh-add -l

il risultato dovrebbe essere qualcosa del genere :

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

Il server è stato violato, come risolvere il problema di sicurezza?

Comando proxy

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

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

Per le operazioni di base: come trasferire file tramite i server (da client a server, server a client), puoi leggere sul mio post qui

Conclusione

  • Se usi l'host bastion, non usare AgentForwarding ma usa ProxyCommand
  • Utilizzare sempre l'utente non root per l'autenticazione
  • Utilizzare un firewall e bloccare tutte le connessioni non necessarie.
  • Usa SELinux (in generale)
  • Blocca l'indirizzo IP che tenta di accedere più volte con credenziali errate
  • Se non è necessario, non concedere l'autorizzazione sudo all'utente
  • Monitora il tuo server
  • Aggiorna il tuo server per le patch di sicurezza

Maggiori informazioni, vedi il mio blog . Inoltre ho alcuni screeenshots, quindi potrebbe esserti utile.


Grazie mille! in realtà, utilizziamo anche Google Authenticator al momento dell'accesso.
user2503775

Ricevo un errore quando si cerca di chiamare App ssh: channel 0: open failed: administratively prohibited: open failed. stdio forwarding failed. . Hai un'idea del perché ?. Al registro sicuro vedo:refused local port forward: originator 127.0.0.1 port 65535, target *app-ip* port 22
user2503775

Informazioni interessanti. Un piccolo consiglio per migliorare la leggibilità della tua risposta. Non copiare / incollare il contenuto del tuo blog qui. Fornisci il link e solo un riepilogo. Quindi evidenzia la parte di risposta reale (che per te utilizza ProxyCommand). Ti ho visto in un certo senso all'inizio, ma data la parte copia / incolla è stato un po 'confuso. Comunque +1
Huygens

@ user2503775 Dovrebbe essere un problema diverso, non relativo al comando di inoltro / proxy ssh-agent. Apriamo una nuova domanda con i log.
grep,


4

Usa semplicemente l' inoltro dell'agente SSH come fanno molti altri.

  • Le chiavi saranno in ssh agent sul tuo laptop.
  • Accedi al bastione, autenticato tramite l'agente.
  • Da lì accedi al tuo host di destinazione, con la richiesta di autenticazione inoltrata al tuo laptop .

Vantaggio: non ci sono chiavi memorizzate sul bastione che possono essere utilizzate in modo improprio.

Spero che aiuti :)


Ciao, questo è fondamentalmente ciò che l'OP descrive nel suo secondo proiettile. Ti consiglio di controllare il secondo link fornito nella domanda.
Huygens,

@Huygens vero che ho notato ora. L'ho superato mentre mescolava l'inoltro TCP con l'inoltro agente.
MLu

In effetti questo è confuso :-)
Huygens

Non è misto. Capisco la differenza Ho modificato la domanda per chiarire.
user2503775

Ho scritto una risposta, come hackerare l'inoltro dell'agente (Non c'è chiave ma c'è socket aperto). Generalmente, l'inoltro dell'agente va bene perché la possibilità di rubare le chiavi è molto bassa - prima di tutto, devi hackerare l'host bastion. Puoi comunque vedere la mia risposta: serverfault.com/a/958466/476642
grep
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.