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

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

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

              Да, это я видел, но почему бы не рассказать, что это, и зачем оно нужно.
              • НЛО прилетело и опубликовало эту надпись здесь
            • 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
                    Кто что думает об этом?

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