2009年11月20日星期五

How to enabling scp or sftp, but disabling ssh

A very tricky problem.

Giles 的一個 undergraduate student 要 upload citeseerx 的 metadata 給我,所以我想要開一個能夠 sftp 或 scp 的帳號給他,但同時我又不希望他能夠 ssh 到 server 去做些莫名其妙的事情,這種需求很合理吧,沒想到這竟然是一個這麼 tricky 的問題。

引用 O'reilly 出的 ssh 蝸牛書官網 FAQ 上的說法 (http://www.snailbook.com/faq/restricted-scp.auto.html )
How do I allow a user to use scp or sftp, but not allow regular ssh (i.e. forbid getting a shell or running other programs)?
This answer is that this is a rather tricky thing to do right. Both scp1 and scp2 run ssh as a subprocess to connect to the remote host and run the appropriate server to talk to — scp -[tf] and sftp-server, respectively. So, the best you can do is to restrict the user to only running the file-transfer server.

The simplest way to do this is to make the target account special-purpose, by giving it a shell which only allows runing the file-transfer server. SSH always uses the shell to run remote programs, so this is a reliable restriction. SSH invokes the shell program with the option -c program to run program; your replacement should accept either scp with appropriate arguments, or sftp-server, as appropriate. SSH2 comes with ssh-dummy-shell for exactly this purpose, though naturally it only handles sftp.

If you don't want to limit the account this way, then it gets harder to do this reliably. The next thing to try would be public-key authentication with a forced command. It's simple with SSH2:

# SSH2
[remote:~/.ssh2/authorization]
key users_key.pub
command /usr/local/bin/sftp-server

With SSH1, this is more complicated, because the client passes arguments to scp in the remote command. For example:

client command runs this on server
----------------------------------------------
scp foo server:bar scp -t bar
scp server:bar foo scp -f bar
scp *.txt server:dir scp -d -t dir

So, you need to use a wrapper program to restrict it. Here's an example:

# SSH1
[remote:~/.ssh/authorized_keys]
command="/path/to/scp-wrapper" 1024 37 1440913682374...

scp-wrapper Perl script

Now, as given so far, each of these solutions has a glaring hole: the authorization and authorized_keys files are writable by the target account. These measures are easily circumvented by simply using scp to overwrite those files. So, you need to protect them from change by the target account. You can make the account's SSH control directory and its contents unwritable where it is, or you can change its location e.g. with the sshd2 UserConfigDirectory statement.

Beyond that, though, there are still more holes. For example, SSH runs the user's shell to exec the remote command, with $SHELL -c "command". So you can simply scp any commands at all that you want to run into the remote shell startup file (e.g. ~/.bashrc), and they'll be executed the next time you scp something. So really you need to lock down the remote home directory so it's not writable by the user, and create a separate area for depositing files.

這麼合理的需求怎麼還會要我去閱讀這麼一大段英文呢。 :-(

另外辜狗到這個人的做法,英文短很多,實作後成功了。(http://www.mail-archive.com/ssh@clinet.fi/msg06759.html )
Let's suppose you want these users to copy files only to a certain
directory.
(You wouldn't allow them to upload files anywhere, would you?)

You need to create a custom login shell (call it scp_shell) for these users:
--------------------
#!/bin/sh
#
exec /usr/bin/scp -t UPLOAD_DIR
--------------------
You can put this script to /usr/local/bin and you have to register it in
/etc/shells.

With this solution your users can upload files but only relative to
UPLOAD_DIR directory.
You can replace UPLOAD_DIR with $HOME if you want them to
upload to their home directories instead of a common one. Or you can
create a symlink in the home directory of the user pointing to a user
specific location outside of $HOME.

On the client side you may omit the remote destination when you invoke scp
because UPLOAD_DIR will be used.
The command your users have to issue is:
'scp SOURCE user@your_server:'
You need the colon at the end !!

另外辜到一個更簡單的做法,use rssh package
官網:http://www.pizzashack.org/rssh/index.shtml

但 mobisna server 上沒裝 C compiler,我也不想要多裝些有的沒的到 mobisna 上,所以這個最簡單最快的做法就被我放棄了,不過還是紀下來供未來參考。

0 意見: