Что делает ssh -R © erik, unix.stackexchange.com

Подключиться к сервису за NAT, имея человека рядом с сервисом, вооруженного ssh, и белый ip у себя.

Опция -R


В ssh есть режим, в котором он открывает порт на сервере и, через туннель от сервера до клиента, перенаправляет соединения в указанный адрес в сети клиента.

То есть нам нужно поднять sshd, попросить человека выполнить

$ ssh -N -R server_port:target:target_port sshd_server

И у нас на машине с sshd откроется порт server_port, который будет туннелироваться в target:target_port в сети этого человека.

Как в sshd_config ограничить права


ForceCommand echo "no shell access is given"

Если задать эту опцию, то указанная команда будет выполняться вместо любой передаваемой клиентом (обычно клиент запускает шелл).
Так как scp работает через [встроенную] команду sftp, то копирование файлов тоже будет закрыто.

Туннелирование (форвардинг) при этом все еще работает.

AllowTcpForwarding remote

Разрешает режимы туннелирования tcp:

  • local (опция -L в ssh) — открыть порт на клиенте и перенаправить подключения на заданный клиентом адрес в сети сервера
  • remote (опция -R) — открыть порт на сервере и туннелировать подключения на заданный клиентом адрес в его сети
  • all или yes — разрешает и local, и remote
  • no — запрещает tcp туннели

Match

Как обычно, вышеуказанные опции можно положить в секцию, например, Match User tunnel, и они будут действительны только для соединений, аутентифицирующихся под именем этого пользователя. (ssh… tunnel@sshd_server)

Положить в конец sshd_config и не забыть создать пользователя tunnel
Match User tunnel
    ForceCommand echo "no shell access is given"
    AllowTcpForwarding remote
    # на случай, если у нас глобально установлено иначе:
    X11Forwarding no
    PermitTunnel no

Еще было бы хорошо ограничить порты, которые клиент может занимать на сервере, но без патчей к sshd этого не сделать.

Удобнее и без root-а


Хочется решать задачу в духе netcat: не трогать системный sshd, не создавать новых пользователей и не запускать демонов.

sshd можно запустить без рута, если сделать отдельный конфиг и отключить несколько опций. (При этом он не сможет принимать пользователей отличных от того, с которым он был запущен). Также нужно указать отдельный HostKey и отдельный PidFile.

Останется проблема аутентификации. Так как делиться собственным системным паролем (а мы не собираемся создавать отдельного пользователя) с клиентами неправильно, нужно оставить только аутентификацию по ключам и указать отдельный файлик с ними.

Кроме этого, получившийся sshd удобно запускать без демонизации и с логом в консоль, чтобы следить, как создаются туннели.

Готовый скрипт: запускалка пользовательского sshd, ограниченного созданием туннелей.

Комментарии (10)


  1. lega
    27.01.2016 17:05

    Дополню:
    ssh -N -R # Проброс данных на сервер через текущий хост, на сервере открывается серверное соединение
    ssh -N -L # Проброс данных из вне через сервер на текущий хост, на текущем хосте открывается серверное соединение
    ssh -w 0:0 # Создается нормальный VPN, на клиенте и сервере появляется tun0 (для этого на сервере нужно включить доп. опции)


  1. ahmpro
    27.01.2016 17:25
    +12

    Зачем? Если есть Памятка пользователям ssh от amarao


  1. StrangerInRed
    27.01.2016 17:46
    +1

    1. nwalker
      28.01.2016 18:24
      +1

      Они для другого предназначены, в STUN вообще нет описываемой функциональности и он не спасает от symmetric NAT. И вообще, вы где-нибудь видели standalone клиент для TURN?


  1. andrew_tch
    27.01.2016 20:05
    +4

    Серьезно?


  1. nikitasius
    27.01.2016 20:44
    +1

    Так UDP ж траффик SSH не умеет разруливать, если мне моя память не изменяет. Это ограничение.


    1. TheRipper
      27.01.2016 20:58

      Да, не умеет. Но я сейчас загуглил «ssh udp tunnel», так как что-то подсказывало мне, что по такому простому запросу обязательно что-то должно найтись — и действительно.

      Обычно предлагается создавать tcp туннель между двумя netcat, которые, при помощи fifo будут передавать данные следующим двум netcat, которые уже будут работать по udp:

      udp client <= udp => netcat -u <= fifo => netcat <= tcp => ssh <= tcp => sshd <= tcp => netcat <= fifo => netcat -u <= udp => udp server

      %)


      1. TheRipper
        27.01.2016 21:02

        Но в целом то что описано в статье все еще актуально, в том числе скрипт, просто для соединения с sshd нужен будет этот конвертер tcp<=>udp на netcat и fifo.


  1. tegoo
    27.01.2016 20:57
    +2

    Раз уж дело дошло до того, что на NAT узле порты не пробросить, то было бы неплохо дополнить статью способами обхода фаерволов, когда открыты только, например, http[s] (поднимаем sshd на 443); или когда еще и доступ в сеть только через proxy (как играть с ProxyCommand, чтобы пробить прокси). И было бы здорово упомянуть corkscrew. Проброс портов он такой ;)


    1. TheRipper
      27.01.2016 21:19

      Мне не приходилось сталкиваться с обходом фаерволов в этом смысле, поэтому не смогу сказать больше, чем вы уже сказали. Пусть информация останется как комментарий.