SSH with chroot and only working “sftp”, “rsync” (both)?
I have two users and one shared folder in my Ubuntu server:
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.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
I have tried
sshd_config
'sMatch
,ForceCommand internal-sftp
and ChrootDirectory directives already. This requiresChrootDirectory
to be owned by root and non-writable (755 or less), also does not supportrsync
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...
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 checkrrsync
script from rsync's docs. This method has nochroot
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
add a comment |
I have two users and one shared folder in my Ubuntu server:
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.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
I have tried
sshd_config
'sMatch
,ForceCommand internal-sftp
and ChrootDirectory directives already. This requiresChrootDirectory
to be owned by root and non-writable (755 or less), also does not supportrsync
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...
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 checkrrsync
script from rsync's docs. This method has nochroot
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
You are almost there. The755
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
add a comment |
I have two users and one shared folder in my Ubuntu server:
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.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
I have tried
sshd_config
'sMatch
,ForceCommand internal-sftp
and ChrootDirectory directives already. This requiresChrootDirectory
to be owned by root and non-writable (755 or less), also does not supportrsync
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...
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 checkrrsync
script from rsync's docs. This method has nochroot
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
I have two users and one shared folder in my Ubuntu server:
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.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
I have tried
sshd_config
'sMatch
,ForceCommand internal-sftp
and ChrootDirectory directives already. This requiresChrootDirectory
to be owned by root and non-writable (755 or less), also does not supportrsync
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...
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 checkrrsync
script from rsync's docs. This method has nochroot
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
ubuntu ssh chroot sftp
edited Jun 26 '16 at 13:11
Jeff Schaller
39.6k1054126
39.6k1054126
asked Jun 21 '16 at 22:55
GeorgeGeorge
162
162
You are almost there. The755
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
add a comment |
You are almost there. The755
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
add a comment |
1 Answer
1
active
oldest
votes
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/
New contributor
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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/
New contributor
add a comment |
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/
New contributor
add a comment |
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/
New contributor
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/
New contributor
New contributor
answered Jan 14 at 12:59
Jiri BJiri B
62
62
New contributor
New contributor
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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