Jak ograniczyć porty tunelowania zwrotnego SSH?

9

Mamy publiczny serwer, który akceptuje połączenia SSH od wielu klientów za firewallami.

Każdy z tych klientów tworzy tunel zwrotny SSH za pomocą ssh -Rpolecenia z ich serwerów sieciowych na porcie 80 na naszym serwerze publicznym.

Port docelowy (po stronie klienta) tunelu Reverse SSH to 80, a port źródłowy (po stronie serwera publicznego) zależy od użytkownika. Planujemy utrzymywać mapę adresów portów dla każdego użytkownika.

Na przykład klient A tunelowałby swój serwer sieciowy na porcie 80 do naszego portu 8000; klient B od 80 do 8001; klient C od 80 do 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

Zasadniczo próbujemy powiązać każdego użytkownika z portem i nie pozwolić mu na tunelowanie do innych portów.

Gdybyśmy korzystali z funkcji tunelowania w przód SSH ssh -L, moglibyśmy zezwolić na tunelowanie portu przy użyciu permitopen=host:portkonfiguracji. Jednak nie ma odpowiednika dla odwrotnego tunelu SSH.

Czy istnieje sposób ograniczenia portów tunelowania wstecznego na użytkownika?

Utku Zihnioglu
źródło
1
Tylko przez zasady systemowe, takie jak SELinux lub IPTABLES.
Andrew Smith,

Odpowiedzi:

6

Ponieważ nie zezwoliłeś pogrubioną czcionką, zakładam, że chcesz pewnego rodzaju odrzucenie w czasie wykonywania po stronie klienta SSH, które zapobiega wiązaniu portów. Mam dla ciebie kopię kodu źródłowego:

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

Niestety, jak widać, nie ma wielu warunków, które uniemożliwiają przekierowanie portów oprócz standardowych.

Już miałam zalecić tę samą sugestię do użycia mod_ownerw iptablesśrodku, ale Jeff mnie do tego pobił.

Najczystszym rozwiązaniem byłoby po prostu zmodyfikowanie tego pliku (na przykład możesz użyć, pw->pw_uidaby uzyskać identyfikator użytkownika łączącego się i zmapować go do właściwego portu) i ponownie skompilować serwer SSH, ale to zależy od tego, jak dobrze się z tym czujesz .

Sójka
źródło
To jest naprawdę dobre. Mogę skopiować tę samą składnię z opcji -L (tunelowanie) i sprawić, by działała. Dziękuję Ci.
Utku Zihnioglu
3

Moja sugestia używa do tego SELinux. Musisz skonfigurować profile użytkowników, które pozwolą na otwarcie portów. Te sshdwidelce procesowe i krople do przywilejów użytkownika przed otwarciem portu do przodu, więc cokolwiek stosowane do procesów użytkownika będą egzekwowane na sshd. Pamiętaj, że musisz ograniczyć się do wszystkich procesów użytkownika, ponieważ kiedyś można było użyć netcatdo przekierowania innego portu. Później postaram się znaleźć dla ciebie odpowiednią składnię (lub każdy inny użytkownik może ją dla mnie edytować).

Możesz też spróbować użyć 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

To jednak nie uniemożliwi im otwarcia portu i odmówienia innemu użytkownikowi.

Jeff Ferland
źródło
Dzięki za świetną odpowiedź. Spróbuję skonfigurować profile SELinux / użytkownika. Brzmi jak rozwiązanie mojego pytania.
Utku Zihnioglu