Win32-OpenSSH icon indicating copy to clipboard operation
Win32-OpenSSH copied to clipboard

Disable shell access while allowing SCP

Open Enf0 opened this issue 5 years ago • 7 comments

I have an OpenSSH Server on Windows that I want to use only for SCP. Is there a way to disable normal SSH (shell) access while still allowing SCP?

Enf0 avatar Dec 11 '20 15:12 Enf0

If your user authenticates via public-key, you can control the command that gets executed instead of the shell with the command attribute in front of the key in authorized_keys. This is commonly used e.g. as in

no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="scp -v -r -d -t ~/CONTENT" ssh-rsa AAAAMYRSAKEY...

See this answer for details.

I'm not sure how to achieve the same for other authentication mechanisms, e.g. GSSAPI or password, where there are no corresponding entries in an (equivalent of) the authorized_keys file. May be this can be done via the ForceCommand option in sshd_config, perhaps after a Match on the user name?

mgkuhn avatar Dec 15 '20 14:12 mgkuhn

Unfortunately, we are using password authentication in this case!

Enf0 avatar Dec 18 '20 11:12 Enf0

According to the OpenSSH Server Configuration for Windows 10 1809 and Server 2019 documentation, you can achieve this using ForceCommand internal-sftp in sshd_config.

See also sshd_config wiki page and #1148.

mgkuhn avatar Dec 18 '20 12:12 mgkuhn

From my testing, that command would force SFTP while disallowing SSH and SCP.

I need a way to disallow SSH (i.e. shell access) while allowing SCP (and optionally, SFTP).

Enf0 avatar Mar 31 '21 07:03 Enf0

The way scp host:file . works is that it just runs ssh host 'scp -f file' to start an scp -f file process on the other side for a download, or an ssh -t file process for an upload, and then uses stdin/stdout to communicate with that peer process to transfer the file. So unlike SFTP, SCP does not use any file-transfer protocol built into sshd, but instead calls another process at the other end to handle the transfer, just like rsync, svn, git, and many other programs that tunnel a protocol over ssh interactive sessions do. So if you want to allow SCP to work, you'd really need a replacement shell that doesn't allow the user to execute anything other than scp -f or scp -t at the other end. I don't know of a ready-to-use solution that doesn't involve writing such a tiny dummy shell to filter these permitted command lines.

mgkuhn avatar Mar 31 '21 11:03 mgkuhn

GNU Rush appears to be a sophisticated restricted shell to allow only a limited set of commands, such as scp to be executed by an ssh user. sshdo appears to be another one. I don't know if there is any Windows port available yet of either.

I would probably simply write a little Perl or Python script to achieve the same thing, i.e. check the command received from sshd and execute it if it matches an allowed pattern.

mgkuhn avatar Mar 31 '21 11:03 mgkuhn

As suggested above, I've handled this with a compiled python script using the ForceCommand in sshd_config. My code is available here:

https://github.com/flakshack/internal-scp

Basically, I just take the SSH_ORIGINAL_COMMAND, replace the "SCP" part with the full path to the Windows SCP.EXE file and pass the rest as an argument, hopefully avoiding shell injection issues. It works fine for my use case (simple config export from a network device that only supports SCP not SFTP). As usual, YMMV and my suggestion is that you don't risk your company on my dumb code.

flakshack avatar Oct 02 '25 21:10 flakshack