Как ограничить обратные порты настройки SSH?

9

У нас есть публичный сервер, который принимает 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.

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

Утку Зихниоглу
источник
1
Только общесистемной политикой, такой как SELinux или IPTABLES.
Эндрю Смит

Ответы:

6

Поскольку вы поместили жирный шрифт not allow , я предполагаю, что вы хотите какой-то отказ во время выполнения на стороне клиента 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-сервер, но это будет зависеть от того, насколько вам комфортно с этим ,

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

Мое предложение использует 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

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

Джефф Ферланд
источник
Спасибо за отличный ответ. Я попробую конфигурацию профилей SELinux / User. Это звучит как решение моего вопроса.
Утку Зихниоглу