Вполне адекватная ситуация: у вас есть удалённая 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. Знаю, что утилита далеко не новая, но всё-таки я не видел её описания на Хабре, хотя кому-то она может оказаться очень полезной.
Поделиться с друзьями
-->

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


  1. yusman
    07.04.2017 11:47
    -1

    Не проще ли воспользоваться в таком случае утилитой nc? (ничего устанавливать не требуется.)


    1. WebConn
      07.04.2017 11:51
      +1

      Вы имеете в виду, передать файл с помощью nc?

      1. SSH даёт защищённый канал.
      2. У SSH куча замечательных фич для пробрасывания туннелей через NAT.
      3. SSH уже работает как демон, так что я могу просто отправить данные для входа пользователя, и не лазить самому на удалённую машину для подтверждения приёма файла.


  1. redfs
    07.04.2017 12:00
    +8

    У sshd давно уже есть возможность разрешать только sftp и делать sftp chroot (шелл при этом /bin/false).
    Для загрузки файла вполне достаточно.


    1. WebConn
      07.04.2017 12:18
      -1

      Полезно, спасибо! Хотя я не помню, когда я использовал sftp в последний раз, scp уже на кончиках пальцев.


      1. alexkunin
        07.04.2017 12:33

        Между sftp и scp есть различия. Если кратко, то sftp позволяет работать как по ftp: создавать директории, смотреть список файлов, возобновить закачку. В зависимости от целей, это может быть преимуществом или недостатком. Судя по вашей задаче — просто забросить файл — открытый sftp скорее недостаток, т.к. дает слишком много контроля.

        но всё-таки я не видел её упоминания на Хабре
        С помощью запроса «rssh site:habrahabr.ru» легко гуглится SSH FTP (SFTP) instead/вместо FTP, и в первом же комментарии упоминается rssh.


        1. WebConn
          07.04.2017 13:51

          С помощью запроса «rssh site:habrahabr.ru» легко гуглится SSH FTP (SFTP) instead/вместо FTP, и в первом же комментарии упоминается rssh.

          Да, это я видел, но почему бы не рассказать, что это, и зачем оно нужно.


          1. alexkunin
            07.04.2017 14:09

            но всё-таки я не видел её упоминания на Хабре


            1. WebConn
              07.04.2017 14:31

              Исправил.


        1. balexa
          08.04.2017 12:00

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

          Я был немножко в смятении когда столкнулся с этим впервые.


    1. icCE
      07.04.2017 17:57

      Можно заменить /bin/false на Sleep Dummy Shell
      Что в общем еще лучше

      https://www.mariovaldez.net/software/sleepshell/


      1. icCE
        07.04.2017 18:03

        /*
        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 
        


  1. NaHCO3
    07.04.2017 13:45

    Может быть я что-то не понимаю, но при чём здесь дефолтный шелл? ssh позволяет любую команду исполнить на своей стороне. Я, собственно, так туннели поднимал.


    1. WebConn
      07.04.2017 13:55

      ЕМНИП, в ssh команды на удалённом хосте вызываются строкой:

      default_shell -c command
      

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

      Соответственно, rssh запретит вызывать произвольные команды таким способом.


  1. SchmeL
    07.04.2017 14:23
    +1

    Есть еще mysecureshell


    1. Erelecano
      07.04.2017 18:40

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


      1. VitalKoshalew
        09.04.2017 06:55

        Огорчает только, что mysecureshell давно не обновлялся и, судя по всему, заброшен авторами.

        Судя по тому, что его добавили в стандартные репозитории Ubuntu 15.04 или 15.10 (не помню точно), всё под контролем.


        1. Erelecano
          09.04.2017 13:49

          Да, действительно в 16.04 вижу в репах
          apt-cache policy mysecureshell
          mysecureshell:
          Installed: (none)
          Candidate: 2.0-2build1

          Ставил в 14.04, там не было в родных репах.
          Хорошая новость, спасибо, буду иметь в виду.


  1. IvansSusanins
    08.04.2017 11:56

    Ребят, а я вот что-то не понимаю. Зачем городить какой-то левый шелл, если можно создать пользователя, и в качестве шелла указать /bin/false ???


    1. WebConn
      08.04.2017 11:59

      /bin/false, /bin/true не дадут ничего делать по ssh, но и scp не отработает.

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

      На деле, при вызове scp открывается ssh-соединение, после чего в удалённой консоли выполняется команда
      scp -t [filename]
      
      (если не путаю аргумент, но суть понятна). Так что пустая консоль здесь не сработает.


  1. DmitriyPanteleev
    09.04.2017 20:55

    Как уже сказали выше ssh умеет ограничивать себя до sftp сам. А если вы уж запускаете/устанавливаете доп. демона, то не проще ли ftp-шник?


  1. unixweb
    09.04.2017 20:56

    Всем привет!
    Если включить Selinux и разрешить пользователю user_u использовать SSH среду CHROOT, вы должны включить selinuxuser_use_ssh_chroot булева.
    По умолчанию отключено.
    setsebool -P selinuxuser_use_ssh_chroot 1
    Кто что думает об этом?