![chroot を使用した SSH で、「sftp」、「rsync」(両方) のみが動作しますか?](https://rvso.com/image/89137/chroot%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%20SSH%20%E3%81%A7%E3%80%81%E3%80%8Csftp%E3%80%8D%E3%80%81%E3%80%8Crsync%E3%80%8D(%E4%B8%A1%E6%96%B9)%20%E3%81%AE%E3%81%BF%E3%81%8C%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%3F.png)
私の Ubuntu サーバーには 2 人のユーザーと共有フォルダーが 1 つあります。
ユーザー は
writer
、 への書き込みアクセス権を持っています/var/shared
。これは、SSH キーを使用してリモートからこのフォルダー内のファイルを定期的に変更するアプリケーションです。ユーザー
reader
は SSH キーを持つ複数のクライアントによって使用されますが、クライアントは私の許可なくキーを取得できるため、このシェルで使用できるコマンドを制限する必要があります。
質問:
reader
ユーザーがアクセスできるコマンドを制限して、sftp および rsync プロトコルのみを使用できるようにする必要があります( mkdir
、、、などls
の標準コマンドは使用できませんtop
)。 ディレクトリのみ/var/shared
が読み取り可能で、ルート パスである必要があります。たとえば、ディレクトリ内に入る必要はありません。すでにsftp または rsync 内にcd
あります。/
usermod -s
このような動作をユーザーに実行させるためには、シェル スクリプトをどのように記述すればよいでしょうかreader
?writer
サンプルが見つかりません。パスが同じになるように、にも「監禁」されたままにするにはどうすればよいでしょうか/var/share
?
ノート:
sshd_config
のMatch
、ForceCommand internal-sftp
およびディレクティブをすでに試しましたChrootDirectory
。これには、がChrootDirectory
ルートによって所有され、書き込み不可 (755 以下) である必要があり、をサポートしていませんrsync
。試してみました
rssh
が、ログインしているユーザーのホーム ディレクトリ以外のディレクトリでは機能しません。そのため、異なる権限を持つ同じディレクトリにユーザーを chroot することができませんでした。command=".." ssh-rsa....
ファイルで使用しようとしましたauthorized_keys
が、必要な動作を有効にする方法がわかりませんでした。rsyncrrsync
のドキュメントからスクリプトを確認するだけです。この方法にはchroot
必要な機能がありません。
少なくともそのようなシェルのサンプルを入手できますか? これはスクリプトで実現できますか?
Bash と C++ (必要な場合) も歓迎します。出力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)
答え1
まず第一に、ChrootDirectory
ルートが所有し、他のユーザーが書き込みできないようにする必要があります。したがって、/var/shared
あなたの場合はChrootDirectory
値にはなりません。
ルートのみが書き込み可能なディレクトリを作成し、/var/shared
Linux のバインドマウントまたは何らかのシンボリックリンクの回避策を使用してこのディレクトリ内にアクセスできるようにすることをお勧めします。
sftp
またはを制限する必要がある場合はrsync
、または を介してSSH 公開キーでSSH_ORIGINAL_COMMAND
強制される「ラッパー」の助けを借りて、サーバー上の環境変数を確認する必要があります。この変数は、ユーザーが認証された後に入力され、クライアントが確立する接続の種類に関する情報が含まれます。 の場合は内部に が含まれ、の場合は含まれ、セッションのみの場合は が含まれます。IIRC によると、変数は空で、 の場合は含まれます。は、サーバー上の認証されたユーザーの下で実行されます。ForceCommand
command
sftp
sftp-server
rsync
rsync
ssh
ssh date
date
SSH_ORIGINAL_COMMAND
これはラッパーの始まりになります:
#!/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
ご覧のとおり、ssh -v
サーバーによって実行されるコマンドに関する情報が提供されます。したがって、/tmp
ラッパー内で他のものに変更することもできます。
$ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/