7 апреля в 11:36

rssh, или Как разрешить SCP, но запретить SSH

Вполне адекватная ситуация: у вас есть удалённая Linux-машина с доступом по SSH, и вам срочно нужно дать кому-то из знакомых возможность загрузить на эту машину файл. Разумеется, нам абсолютно лениво разворачивать ради этого FTP-сервер. Да и зачем, когда есть SCP?

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

Выход вроде как всплывает: надо заменить пользователю shell по умолчанию (/bin/sh) на что-нибудь другое. Вот только что? /bin/false, /bin/true не дадут ничего делать по ssh, но и scp не отработает. Есть магический git-shell, но он немного для другого.

Недолгий поиск по просторам Интернета показывает, что проблему уже давно решили — есть rssh (Restricted SSH). Его задача как раз сводится к тому, чтобы разрешить пользователю некоторые сервисы вроде scp, sftp, rsync и т.п., но запретить выполнять другие команды.

На Debian/Ubuntu устанавливается из репозитория:

$ sudo apt-get install rssh

После установки нужно залезть в /etc/rssh.conf и расскомментировать строчки с нужными нам сервисами (allowscp, allowrsync, например). После чего свежесозданному пользователю в /etc/passwd прописать в качестве shell файл /usr/bin/rssh. Теперь можно проверять доступ:


$ ssh rsshuser@remote
This account is restricted by rssh.
Allowed commands: scp rsync
If you believe this is in error, please contact your system administrator.

Connection to remote closed.
$ scp ./file.txt rsshuser@remote:file.txt
file.txt                                           100% 51KB   1.2MB/s   00:03
$

Для паранойиков в тяжёлой стадии особо чувствительных систем там же можно настроить индивидуальные списки разрешённых сервисов для разных пользователей, и даже выделить отдельный chroot для максимальной изоляции.

P.S. Знаю, что утилита далеко не новая, но всё-таки я не видел её описания на Хабре, хотя кому-то она может оказаться очень полезной.
Никита Маслов @WebConn
карма
18,0
рейтинг 0,0
Программист
Самое читаемое Администрирование

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

  • –1
    Не проще ли воспользоваться в таком случае утилитой nc? (ничего устанавливать не требуется.)
    • +1
      Вы имеете в виду, передать файл с помощью nc?

      1. SSH даёт защищённый канал.
      2. У SSH куча замечательных фич для пробрасывания туннелей через NAT.
      3. SSH уже работает как демон, так что я могу просто отправить данные для входа пользователя, и не лазить самому на удалённую машину для подтверждения приёма файла.
  • +8
    У sshd давно уже есть возможность разрешать только sftp и делать sftp chroot (шелл при этом /bin/false).
    Для загрузки файла вполне достаточно.
    • –1
      Полезно, спасибо! Хотя я не помню, когда я использовал sftp в последний раз, scp уже на кончиках пальцев.
      • 0
        Между sftp и scp есть различия. Если кратко, то sftp позволяет работать как по ftp: создавать директории, смотреть список файлов, возобновить закачку. В зависимости от целей, это может быть преимуществом или недостатком. Судя по вашей задаче — просто забросить файл — открытый sftp скорее недостаток, т.к. дает слишком много контроля.
        но всё-таки я не видел её упоминания на Хабре
        С помощью запроса «rssh site:habrahabr.ru» легко гуглится SSH FTP (SFTP) instead/вместо FTP, и в первом же комментарии упоминается rssh.
        • 0
          С помощью запроса «rssh site:habrahabr.ru» легко гуглится SSH FTP (SFTP) instead/вместо FTP, и в первом же комментарии упоминается rssh.

          Да, это я видел, но почему бы не рассказать, что это, и зачем оно нужно.
          • 0
            но всё-таки я не видел её упоминания на Хабре
            • 0
              Исправил.
        • 0
          Там еще большая разница в режимах передачи. SCP текстовый протокол, и при передаче текстовых файлов через SCP может происходить преобразование, в том числе окончаний строк и кодировок.
          Например при копировании данных на OS390 происходит преобразование ASCII -> EBCDIC.

          Я был немножко в смятении когда столкнулся с этим впервые.
    • 0
      Можно заменить /bin/false на Sleep Dummy Shell
      Что в общем еще лучше

      https://www.mariovaldez.net/software/sleepshell/
      • 0
        /*
        2  
        3  #include <unistd.h>
        4  #include <stdio.h>
        5  #include <stdlib.h>
        6  
        7  #define SS_SLEEPTIME 10
        8  
        9  main() {
        10   char *ssh_connection;
        11   char *ssh_client;
        12   char *ssh_tty;
        13   
        14   ssh_connection = getenv ("SSH_CONNECTION");
        15   ssh_client = getenv ("SSH_CLIENT");
        16   ssh_tty = getenv ("SSH_TTY");
        17   printf ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        18   if (ssh_connection && ssh_client) {
        19     printf ("Connection: %s\nClient: %s\nTerminal: %s\n\n", ssh_connection, ssh_client, ssh_tty);
        20   }
        21   while (1) {
        22     sleep (SS_SLEEPTIME);
        23     printf ("*");
        24     fflush (NULL);
        25   }
        26 }
        27 
        28 
        
  • 0
    Может быть я что-то не понимаю, но при чём здесь дефолтный шелл? ssh позволяет любую команду исполнить на своей стороне. Я, собственно, так туннели поднимал.
    • 0
      ЕМНИП, в ssh команды на удалённом хосте вызываются строкой:
      default_shell -c command
      

      где default_shell — то, что прописано у пользователя в passwd, а command — то, что вы передаёте вызовом ssh. Так как по умолчанию у пользователей в качестве shell стоит /bin/sh или /bin/bash, обычно всё работает.

      Соответственно, rssh запретит вызывать произвольные команды таким способом.
  • +1
    Есть еще mysecureshell
    • 0
      mysecureshell интересен иным. Мне тут понадобилось ограничить пользователя отдельным набором команд и запереть его в чруте при sftp, вот тут мне связка lshell(я в курсе про то, что в прошлом году в нем были уязвимости) и mysecureshell в качестве sftp-сервера и помогли. Беда же родного opensshного chroot'а для sftp в том, что при его включении отрубается возможность заходить пользователю по ssh, а мне ее надо было сохранить.
      Огорчает только, что mysecureshell давно не обновлялся и, судя по всему, заброшен авторами.
      • 0
        Огорчает только, что mysecureshell давно не обновлялся и, судя по всему, заброшен авторами.

        Судя по тому, что его добавили в стандартные репозитории Ubuntu 15.04 или 15.10 (не помню точно), всё под контролем.
        • 0
          Да, действительно в 16.04 вижу в репах
          apt-cache policy mysecureshell
          mysecureshell:
          Installed: (none)
          Candidate: 2.0-2build1

          Ставил в 14.04, там не было в родных репах.
          Хорошая новость, спасибо, буду иметь в виду.
  • 0
    Ребят, а я вот что-то не понимаю. Зачем городить какой-то левый шелл, если можно создать пользователя, и в качестве шелла указать /bin/false ???
    • 0
      /bin/false, /bin/true не дадут ничего делать по ssh, но и scp не отработает.

      Получится, что сразу после подключения пользователя (неважно, по ssh или scp) /bin/false завершится, и передача не состоится.

      На деле, при вызове scp открывается ssh-соединение, после чего в удалённой консоли выполняется команда
      scp -t [filename]
      
      (если не путаю аргумент, но суть понятна). Так что пустая консоль здесь не сработает.
      • 0
        Да, согласен, тупанул. Проверил у себя на машинке — не работает. Но есть другой нюанс.
        Если мы хотим всё сделать по уму, то нужно ставить jail на SCP, а это уже опять же лишние телодвижения. Так что очень быстро опять же не получится.
  • 0
    Как уже сказали выше ssh умеет ограничивать себя до sftp сам. А если вы уж запускаете/устанавливаете доп. демона, то не проще ли ftp-шник?
  • 0
    Всем привет!
    Если включить Selinux и разрешить пользователю user_u использовать SSH среду CHROOT, вы должны включить selinuxuser_use_ssh_chroot булева.
    По умолчанию отключено.
    setsebool -P selinuxuser_use_ssh_chroot 1
    Кто что думает об этом?

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