SSH with chroot and only working “sftp”, “rsync” (both)?












3















I have two users and one shared folder in my Ubuntu server:




  1. User writer, which has write access to /var/shared. It's an application regularly making file changes in this folder from remote, with SSH key.


  2. User reader is used by multiple clients with SSH key, a key they can get without my permission, that's why I need to restrict commands available in this shell.



Question:



I need to restrict commands accessible for reader user, so it can use only sftp and rsync protocols (no standard commands like mkdir, ls, top, ..); Only directory /var/shared must be readable, and must be a root path, e.g. no need to cd into it, it's already / in sftp or rsync.



How to write a shell script so I can apply it with usermod -s for user reader that will give such behavior? I cannot find any samples. How to make writer also remain "jailed" to /var/share, so paths are same?



Notes




  1. I have tried sshd_config's Match, ForceCommand internal-sftp and ChrootDirectory directives already. This requires ChrootDirectory to be owned by root and non-writable (755 or less), also does not support rsync


  2. I have tried rssh, but it simply don't work for directories outside home directory for logged in user. So I couldn't chroot users to same directory with different permissions...


  3. I tried to use command=".." ssh-rsa.... in authorized_keys file, but didn't get how can I enable behavior which I need, I only check rrsync script from rsync's docs. This method has no chroot feature I need.



Can I have a sample at least for such shells? Is this achievable with scripts?



Bash and C++(if needed) are welcome. Output of ldd /bin/bash:



    linux-vdso.so.1 =>  (0x00007fff7e9d1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f79dfd8b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f79dfb87000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f79df7bd000)
/lib64/ld-linux-x86-64.so.2 (0x000055bd0767c000)









share|improve this question
















bumped to the homepage by Community 1 hour ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
















  • You are almost there. The 755 permissions are a must, if you want a secure chroot, regardless technology. Then if you skip force command, you should be able to copy required binaries with dependencies into the chroot (rsync, sftp). But much easier would be to allow only one (sftp preferably).

    – Jakuje
    Jun 22 '16 at 10:53


















3















I have two users and one shared folder in my Ubuntu server:




  1. User writer, which has write access to /var/shared. It's an application regularly making file changes in this folder from remote, with SSH key.


  2. User reader is used by multiple clients with SSH key, a key they can get without my permission, that's why I need to restrict commands available in this shell.



Question:



I need to restrict commands accessible for reader user, so it can use only sftp and rsync protocols (no standard commands like mkdir, ls, top, ..); Only directory /var/shared must be readable, and must be a root path, e.g. no need to cd into it, it's already / in sftp or rsync.



How to write a shell script so I can apply it with usermod -s for user reader that will give such behavior? I cannot find any samples. How to make writer also remain "jailed" to /var/share, so paths are same?



Notes




  1. I have tried sshd_config's Match, ForceCommand internal-sftp and ChrootDirectory directives already. This requires ChrootDirectory to be owned by root and non-writable (755 or less), also does not support rsync


  2. I have tried rssh, but it simply don't work for directories outside home directory for logged in user. So I couldn't chroot users to same directory with different permissions...


  3. I tried to use command=".." ssh-rsa.... in authorized_keys file, but didn't get how can I enable behavior which I need, I only check rrsync script from rsync's docs. This method has no chroot feature I need.



Can I have a sample at least for such shells? Is this achievable with scripts?



Bash and C++(if needed) are welcome. Output of ldd /bin/bash:



    linux-vdso.so.1 =>  (0x00007fff7e9d1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f79dfd8b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f79dfb87000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f79df7bd000)
/lib64/ld-linux-x86-64.so.2 (0x000055bd0767c000)









share|improve this question
















bumped to the homepage by Community 1 hour ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
















  • You are almost there. The 755 permissions are a must, if you want a secure chroot, regardless technology. Then if you skip force command, you should be able to copy required binaries with dependencies into the chroot (rsync, sftp). But much easier would be to allow only one (sftp preferably).

    – Jakuje
    Jun 22 '16 at 10:53
















3












3








3








I have two users and one shared folder in my Ubuntu server:




  1. User writer, which has write access to /var/shared. It's an application regularly making file changes in this folder from remote, with SSH key.


  2. User reader is used by multiple clients with SSH key, a key they can get without my permission, that's why I need to restrict commands available in this shell.



Question:



I need to restrict commands accessible for reader user, so it can use only sftp and rsync protocols (no standard commands like mkdir, ls, top, ..); Only directory /var/shared must be readable, and must be a root path, e.g. no need to cd into it, it's already / in sftp or rsync.



How to write a shell script so I can apply it with usermod -s for user reader that will give such behavior? I cannot find any samples. How to make writer also remain "jailed" to /var/share, so paths are same?



Notes




  1. I have tried sshd_config's Match, ForceCommand internal-sftp and ChrootDirectory directives already. This requires ChrootDirectory to be owned by root and non-writable (755 or less), also does not support rsync


  2. I have tried rssh, but it simply don't work for directories outside home directory for logged in user. So I couldn't chroot users to same directory with different permissions...


  3. I tried to use command=".." ssh-rsa.... in authorized_keys file, but didn't get how can I enable behavior which I need, I only check rrsync script from rsync's docs. This method has no chroot feature I need.



Can I have a sample at least for such shells? Is this achievable with scripts?



Bash and C++(if needed) are welcome. Output of ldd /bin/bash:



    linux-vdso.so.1 =>  (0x00007fff7e9d1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f79dfd8b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f79dfb87000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f79df7bd000)
/lib64/ld-linux-x86-64.so.2 (0x000055bd0767c000)









share|improve this question
















I have two users and one shared folder in my Ubuntu server:




  1. User writer, which has write access to /var/shared. It's an application regularly making file changes in this folder from remote, with SSH key.


  2. User reader is used by multiple clients with SSH key, a key they can get without my permission, that's why I need to restrict commands available in this shell.



Question:



I need to restrict commands accessible for reader user, so it can use only sftp and rsync protocols (no standard commands like mkdir, ls, top, ..); Only directory /var/shared must be readable, and must be a root path, e.g. no need to cd into it, it's already / in sftp or rsync.



How to write a shell script so I can apply it with usermod -s for user reader that will give such behavior? I cannot find any samples. How to make writer also remain "jailed" to /var/share, so paths are same?



Notes




  1. I have tried sshd_config's Match, ForceCommand internal-sftp and ChrootDirectory directives already. This requires ChrootDirectory to be owned by root and non-writable (755 or less), also does not support rsync


  2. I have tried rssh, but it simply don't work for directories outside home directory for logged in user. So I couldn't chroot users to same directory with different permissions...


  3. I tried to use command=".." ssh-rsa.... in authorized_keys file, but didn't get how can I enable behavior which I need, I only check rrsync script from rsync's docs. This method has no chroot feature I need.



Can I have a sample at least for such shells? Is this achievable with scripts?



Bash and C++(if needed) are welcome. Output of ldd /bin/bash:



    linux-vdso.so.1 =>  (0x00007fff7e9d1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f79dfd8b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f79dfb87000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f79df7bd000)
/lib64/ld-linux-x86-64.so.2 (0x000055bd0767c000)






ubuntu ssh chroot sftp






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 26 '16 at 13:11









Jeff Schaller

42.9k1159137




42.9k1159137










asked Jun 21 '16 at 22:55









GeorgeGeorge

162




162





bumped to the homepage by Community 1 hour ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community 1 hour ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • You are almost there. The 755 permissions are a must, if you want a secure chroot, regardless technology. Then if you skip force command, you should be able to copy required binaries with dependencies into the chroot (rsync, sftp). But much easier would be to allow only one (sftp preferably).

    – Jakuje
    Jun 22 '16 at 10:53





















  • You are almost there. The 755 permissions are a must, if you want a secure chroot, regardless technology. Then if you skip force command, you should be able to copy required binaries with dependencies into the chroot (rsync, sftp). But much easier would be to allow only one (sftp preferably).

    – Jakuje
    Jun 22 '16 at 10:53



















You are almost there. The 755 permissions are a must, if you want a secure chroot, regardless technology. Then if you skip force command, you should be able to copy required binaries with dependencies into the chroot (rsync, sftp). But much easier would be to allow only one (sftp preferably).

– Jakuje
Jun 22 '16 at 10:53







You are almost there. The 755 permissions are a must, if you want a secure chroot, regardless technology. Then if you skip force command, you should be able to copy required binaries with dependencies into the chroot (rsync, sftp). But much easier would be to allow only one (sftp preferably).

– Jakuje
Jun 22 '16 at 10:53












1 Answer
1






active

oldest

votes


















0














First of all ChrootDirectory must be owned by root and not writable by other users. Thus /var/shared in your case cannot be ChrootDirectory value.



I would recommend to create a directory which would be writable by root only and make /var/shared accessible inside this dir either via Linux bind-mounting or some kind of symlinks workarounds.



If you need restrict sftp or rsync, you need to check SSH_ORIGINAL_COMMAND environment variable on the server with help of a "wrapper" enforced either via ForceCommand or via command in ssh public key, this variable is populated after user is authenticated and contains info what kind of connection clients is going to establish. For sftp it would have sftp-server inside, for rsync it would have rsync, for just ssh session it would have, IIRC, the variable empty, for ssh date it would be date. SSH_ORIGINAL_COMMAND is run under authenticated user on the server!



This could be your start of the wrapper:



#!/usr/bin/env bash

set -eu
set -o pipefail

[[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1

case "${SSH_ORIGINAL_COMMAND}" in
"/usr/libexec/openssh/sftp-server")
exec /usr/libexec/openssh/sftp-server
;;
"rsync --server"*)
exec ${SSH_ORIGINAL_COMMAND}
;;
*)
exit 1
;;
esac


As you can see, ssh -v gives you info about what command would be executed by the server. Thus you can change /tmp to something else in your wrapper as well.



$ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/





share|improve this answer























    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "106"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f291251%2fssh-with-chroot-and-only-working-sftp-rsync-both%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    First of all ChrootDirectory must be owned by root and not writable by other users. Thus /var/shared in your case cannot be ChrootDirectory value.



    I would recommend to create a directory which would be writable by root only and make /var/shared accessible inside this dir either via Linux bind-mounting or some kind of symlinks workarounds.



    If you need restrict sftp or rsync, you need to check SSH_ORIGINAL_COMMAND environment variable on the server with help of a "wrapper" enforced either via ForceCommand or via command in ssh public key, this variable is populated after user is authenticated and contains info what kind of connection clients is going to establish. For sftp it would have sftp-server inside, for rsync it would have rsync, for just ssh session it would have, IIRC, the variable empty, for ssh date it would be date. SSH_ORIGINAL_COMMAND is run under authenticated user on the server!



    This could be your start of the wrapper:



    #!/usr/bin/env bash

    set -eu
    set -o pipefail

    [[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1

    case "${SSH_ORIGINAL_COMMAND}" in
    "/usr/libexec/openssh/sftp-server")
    exec /usr/libexec/openssh/sftp-server
    ;;
    "rsync --server"*)
    exec ${SSH_ORIGINAL_COMMAND}
    ;;
    *)
    exit 1
    ;;
    esac


    As you can see, ssh -v gives you info about what command would be executed by the server. Thus you can change /tmp to something else in your wrapper as well.



    $ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
    debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/





    share|improve this answer




























      0














      First of all ChrootDirectory must be owned by root and not writable by other users. Thus /var/shared in your case cannot be ChrootDirectory value.



      I would recommend to create a directory which would be writable by root only and make /var/shared accessible inside this dir either via Linux bind-mounting or some kind of symlinks workarounds.



      If you need restrict sftp or rsync, you need to check SSH_ORIGINAL_COMMAND environment variable on the server with help of a "wrapper" enforced either via ForceCommand or via command in ssh public key, this variable is populated after user is authenticated and contains info what kind of connection clients is going to establish. For sftp it would have sftp-server inside, for rsync it would have rsync, for just ssh session it would have, IIRC, the variable empty, for ssh date it would be date. SSH_ORIGINAL_COMMAND is run under authenticated user on the server!



      This could be your start of the wrapper:



      #!/usr/bin/env bash

      set -eu
      set -o pipefail

      [[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1

      case "${SSH_ORIGINAL_COMMAND}" in
      "/usr/libexec/openssh/sftp-server")
      exec /usr/libexec/openssh/sftp-server
      ;;
      "rsync --server"*)
      exec ${SSH_ORIGINAL_COMMAND}
      ;;
      *)
      exit 1
      ;;
      esac


      As you can see, ssh -v gives you info about what command would be executed by the server. Thus you can change /tmp to something else in your wrapper as well.



      $ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
      debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/





      share|improve this answer


























        0












        0








        0







        First of all ChrootDirectory must be owned by root and not writable by other users. Thus /var/shared in your case cannot be ChrootDirectory value.



        I would recommend to create a directory which would be writable by root only and make /var/shared accessible inside this dir either via Linux bind-mounting or some kind of symlinks workarounds.



        If you need restrict sftp or rsync, you need to check SSH_ORIGINAL_COMMAND environment variable on the server with help of a "wrapper" enforced either via ForceCommand or via command in ssh public key, this variable is populated after user is authenticated and contains info what kind of connection clients is going to establish. For sftp it would have sftp-server inside, for rsync it would have rsync, for just ssh session it would have, IIRC, the variable empty, for ssh date it would be date. SSH_ORIGINAL_COMMAND is run under authenticated user on the server!



        This could be your start of the wrapper:



        #!/usr/bin/env bash

        set -eu
        set -o pipefail

        [[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1

        case "${SSH_ORIGINAL_COMMAND}" in
        "/usr/libexec/openssh/sftp-server")
        exec /usr/libexec/openssh/sftp-server
        ;;
        "rsync --server"*)
        exec ${SSH_ORIGINAL_COMMAND}
        ;;
        *)
        exit 1
        ;;
        esac


        As you can see, ssh -v gives you info about what command would be executed by the server. Thus you can change /tmp to something else in your wrapper as well.



        $ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
        debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/





        share|improve this answer













        First of all ChrootDirectory must be owned by root and not writable by other users. Thus /var/shared in your case cannot be ChrootDirectory value.



        I would recommend to create a directory which would be writable by root only and make /var/shared accessible inside this dir either via Linux bind-mounting or some kind of symlinks workarounds.



        If you need restrict sftp or rsync, you need to check SSH_ORIGINAL_COMMAND environment variable on the server with help of a "wrapper" enforced either via ForceCommand or via command in ssh public key, this variable is populated after user is authenticated and contains info what kind of connection clients is going to establish. For sftp it would have sftp-server inside, for rsync it would have rsync, for just ssh session it would have, IIRC, the variable empty, for ssh date it would be date. SSH_ORIGINAL_COMMAND is run under authenticated user on the server!



        This could be your start of the wrapper:



        #!/usr/bin/env bash

        set -eu
        set -o pipefail

        [[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1

        case "${SSH_ORIGINAL_COMMAND}" in
        "/usr/libexec/openssh/sftp-server")
        exec /usr/libexec/openssh/sftp-server
        ;;
        "rsync --server"*)
        exec ${SSH_ORIGINAL_COMMAND}
        ;;
        *)
        exit 1
        ;;
        esac


        As you can see, ssh -v gives you info about what command would be executed by the server. Thus you can change /tmp to something else in your wrapper as well.



        $ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
        debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 14 at 12:59









        Jiri BJiri B

        135




        135






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f291251%2fssh-with-chroot-and-only-working-sftp-rsync-both%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Histoire des bourses de valeurs

            Why is there Russian traffic in my log files?

            Rename multiple files to decrement number in file name?