Come limitare le porte di sintonizzazione SSH inverse?


9

Abbiamo un server pubblico che accetta connessioni SSH da più client dietro i firewall.

Ognuno di questi client crea un tunnel SSH inverso usando il ssh -Rcomando dai propri server Web sulla porta 80 al nostro server pubblico.

La porta di destinazione (sul lato client) del tunnel SSH inverso è 80 e la porta di origine (sul lato del server pubblico) dipende dall'utente. Stiamo programmando di mantenere una mappa degli indirizzi delle porte per ciascun utente.

Ad esempio, il client A eseguirà il tunneling del proprio server Web dalla porta 80 alla nostra porta 8000; client B da 80 a 8001; client C da 80 a 8002.

Client A: ssh -R 8000:internal.webserver:80 clienta@publicserver

Client B: ssh -R 8001:internal.webserver:80 clientb@publicserver

Client C: ssh -R 8002:internal.webserver:80 clientc@publicserver

Fondamentalmente, ciò che stiamo cercando di fare è associare ogni utente con una porta e non consentire loro di passare ad altre porte.

Se stessimo utilizzando la funzione di tunneling in avanti di SSH ssh -L, potremmo consentire a quale porta eseguire il tunneling utilizzando la permitopen=host:portconfigurazione. Tuttavia, non esiste un equivalente per il tunnel SSH inverso.

Esiste un modo per limitare le porte di tunneling inverso per utente?


1
Solo con criteri di sistema come SELinux o IPTABLES.
Andrew Smith,

Risposte:


6

Dal momento che hai inserito il non consentire in grassetto, suppongo che desideri un tipo di rifiuto di runtime sul lato client SSH che impedisce il bind della porta. Quindi, ho avuto uno scavo del codice sorgente per te:

serverloop.c:

/* check permissions */
if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
    || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)
#endif
    ) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");
} else {
        /* Start listening on the port */
        success = channel_setup_remote_fwd_listener(
            listen_address, listen_port,
            &allocated_listen_port, options.gateway_ports);
}

Sfortunatamente, come puoi vedere, non ci sono molte condizioni che sembrano impedire il port forwarding a parte quelle standard.

Stavo per raccomandare lo stesso suggerimento per l'uso mod_ownerall'interno iptables, ma Jeff mi ha battuto.

La soluzione più pulita sarebbe solo modificare questo file (ad esempio, è possibile utilizzare pw->pw_uidper ottenere l'UID dell'utente che si connette e mapparlo alla porta corretta) e ricompilare il server SSH, ma ciò dipenderebbe da quanto ci si sente a proprio agio con questo .


Questo è veramente buono. Posso effettivamente copiare la stessa sintassi dall'opzione -L (tunneling) e farlo funzionare. Grazie.
Utku Zihnioglu,

3

Il mio suggerimento è usare SELinux per questo. Dovrai configurare i profili utente che consentono di aprire le porte. Il sshdprocesso richiede e scende ai privilegi dell'utente prima di aprire una porta per l'inoltro, quindi verrà applicato tutto ciò che viene applicato ai processi dell'utente sshd. Tieni presente che dovrai limitarti a tutti i processi utente poiché una volta potresti utilizzare netcatper inoltrare un'altra porta. Proverò a sistemare la sintassi corretta per te in seguito (o qualsiasi altro utente è invitato a modificarla per me).

In alternativa, puoi provare a usare iptables.

iptables -m owner --add-owner $user -p tcp --sport 8000 -j ACCEPT
iptables -m owner --add-owner $user -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT

Ciò non impedirà loro di aprire la porta e negare a un altro utente.


Grazie per la magnifica risposta. Proverò la configurazione dei profili SELinux / User. Sembra la soluzione alla mia domanda.
Utku Zihnioglu,
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.