Comment limiter les ports de tuning SSH inversés?

9

Nous avons un serveur public qui accepte les connexions SSH de plusieurs clients derrière les pare-feu.

Chacun de ces clients crée un tunnel SSH inversé en utilisant la ssh -Rcommande de leurs serveurs Web sur le port 80 vers notre serveur public.

Le port de destination (côté client) du tunnel SSH inversé est 80 et le port source (côté serveur public) dépend de l'utilisateur. Nous prévoyons de maintenir une carte des adresses de port pour chaque utilisateur.

Par exemple, le client A tunnelerait son serveur Web au port 80 vers notre port 8000; client B de 80 à 8001; client C de 80 à 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

Fondamentalement, ce que nous essayons de faire, c'est de lier chaque utilisateur avec un port et de ne pas leur permettre de tunneler vers d'autres ports.

Si nous utilisions la fonction de tunneling direct de SSH avec ssh -L, nous pourrions autoriser le port à tunneler en utilisant la permitopen=host:portconfiguration. Cependant, il n'y a pas d'équivalent pour le tunnel SSH inversé.

Existe-t-il un moyen de restreindre les ports de tunneling inverse par utilisateur?

Utku Zihnioglu
la source
1
Uniquement par une politique à l'échelle du système comme SELinux ou IPTABLES.
Andrew Smith

Réponses:

6

Puisque vous avez placé pas autoriser en gras, je suppose que vous voulez une sorte de rejet d'exécution au niveau du client SSH qui empêche la liaison de port. Donc, j'ai eu une fouille du code source pour vous:

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);
}

Malheureusement, comme vous pouvez le voir, il n'y a pas beaucoup de conditions qui semblent empêcher la redirection de port en dehors des conditions standard.

J'étais sur le point de recommander la même suggestion d'utilisation à l' mod_ownerintérieur iptables, mais Jeff m'a battu.

Votre solution la plus propre consiste simplement à modifier ce fichier (par exemple, vous pouvez utiliser pw->pw_uidpour obtenir l'uid de l'utilisateur qui se connecte et le mapper sur le bon port) et recompiler votre serveur SSH, mais cela dépendra de votre confort d'utilisation .

Geai
la source
Ceci est vraiment bon. Je peux réellement copier la même syntaxe depuis l'option -L (tunneling) et la faire fonctionner. Je vous remercie.
Utku Zihnioglu
3

Ma suggestion utilise SELinux pour cela. Vous devrez configurer des profils utilisateur qui permettent d'ouvrir les ports. Le sshdprocessus bifurque et tombe sur les privilèges de l'utilisateur avant d'ouvrir un port à transférer, donc tout ce qui est appliqué aux processus de l'utilisateur sera appliqué sshd. Gardez à l'esprit que vous devrez vous limiter à tous les processus utilisateur, car une fois vous pourriez utiliser netcatpour transférer un autre port. J'essaierai de trier la syntaxe appropriée pour vous plus tard (ou tout autre utilisateur est le bienvenu pour l'éditer pour moi).

Vous pouvez également essayer d'utiliser 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

Cela ne les empêchera cependant pas d'ouvrir le port et de refuser un autre utilisateur.

Jeff Ferland
la source
Merci pour la bonne réponse. Je vais essayer la configuration des profils SELinux / User. Cela ressemble à la solution à ma question.
Utku Zihnioglu