У нас есть общедоступный сервер, который принимает SSH-соединения от нескольких клиентов за брандмауэрами.
Каждый из этих клиентов создает обратный SSH-туннель с помощью ssh -R
со своих веб-серверов через порт 80 на наш общедоступный сервер.
Порт назначения (на стороне клиента) обратного туннеля SSH - 80, а порт источника (на стороне общедоступного сервера) зависит от пользователя. Мы планируем вести карту адресов портов для каждого пользователя.
Например, клиент A туннелирует свой веб-сервер через порт 80 на наш порт 8000; клиент Б от 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 нет эквивалента.
Есть ли способ ограничить количество портов обратного туннелирования для каждого пользователя?
Поскольку вы разместили не разрешено выделено жирным шрифтом, я предполагаю, что вам нужно какое-то отклонение во время выполнения на стороне клиента SSH, которое предотвращает привязку порта. Итак, я нашел для вас исходный код:
/* 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-сервер, но это будет зависеть от того, насколько вам это удобно.
Я предлагаю использовать для этого 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
Однако это не помешает им открыть порт и отказать другому пользователю.