Вопрос: Как ограничить обратные SSH-туннельные порты?


У нас есть общедоступный сервер, который принимает SSH-соединения от нескольких клиентов за брандмауэрами.

Каждый из этих клиентов создает обратный туннель SSH, используя ssh -R команды со своих веб-серверов в порту 80 на наш общедоступный сервер.

Порт назначения (на стороне клиента) реверсивного SSH-туннеля - 80, а исходный порт (на стороне общего сервера) зависит от пользователя. Мы планируем поддерживать карту адресов портов для каждого пользователя.

Например, клиент A будет туннелировать свой веб-сервер на порту 80 до нашего порта 8000; клиент B от 80 до 8001; клиент C от 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

В основном, мы пытаемся связать каждого пользователя с портом и не разрешать их туннелировать в любые другие порты.

Если бы мы использовали функцию прямого туннелирования SSH с ssh -L, мы могли бы разрешить туннелирование этого порта с помощью permitopen=host:port конфигурации. Однако нет эквивалента для обратного туннеля SSH.

Существует ли способ ограничения портов обратного туннелирования для каждого пользователя?


9
2018-06-29 19:24


Источник


Только общесистемной политикой, такой как SELinux или IPTABLES. - Andrew Smith


Ответы:


Поскольку вы разместили не разрешать выделен жирным шрифтом, я предполагаю, что вы хотите, чтобы на стороне клиента SSH было какое-то отклонение во время выполнения, которое предотвращает привязку порта. Итак, у меня есть исходный код для вас:

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

К сожалению, как вы можете видеть, не так много условий, которые препятствуют перенаправлению портов, кроме стандартных.

Я собирался рекомендовать такое же предложение для использования mod_owner в iptables, но Джефф меня избил.

Ваше самое чистое решение просто для изменения этого файла (например, вы можете использовать pw->pw_uid чтобы получить uid пользователя, подключаемого, и сопоставить его с правильным портом) и перекомпилировать ваш SSH-сервер, но это будет зависеть от того, насколько вам комфортно с этим.


6
2018-06-29 21:59



Это действительно хорошо. Я могу фактически скопировать тот же синтаксис из опции -L (туннелирование) и заставить его работать. Спасибо. - Utku Zihnioglu


Мое предложение использует SELinux для этого. Вам нужно будет настроить профили пользователей, позволяющие открывать порты. sshd обрабатывает вилки и падает до привилегий пользователя, прежде чем открывать порт для пересылки, поэтому все, что применяется к процессам пользователя, будет sshd, Помните, что вам нужно будет ограничить все пользовательские процессы, поскольку однажды можно было использовать netcat для пересылки другого порта. Я попытаюсь разобраться в правильном синтаксисе для вас позже (или любой другой пользователь может отредактировать его для меня).

Кроме того, вы можете попробовать использовать 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

Однако это не помешает им открыть порт и отказать другому пользователю.


3
2018-06-29 21:56



Спасибо за отличный ответ. Я попробую настроить SELinux / User profiles. Это похоже на решение моего вопроса. - Utku Zihnioglu