How to disable ssh non-interactive commands from the server side?

Solution 1:

There is ForceCommand keyword in sshd_config:

ForceCommand
Forces the execution of the command specified by ForceCommand, ignoring any command supplied by the client and ~/.ssh/rc if present. The command is invoked by using the user's login shell with the -c option. This applies to shell, command, or subsystem execution. It is most useful inside a Match block. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. […]

(source)

If you use it like this:

ForceCommand    exec /bin/sh -i

then you will force interactive sh. There are at least two problems with this simple approach:

  1. I haven't found any simple way to force tty allocation by configuring the server. A client can choose, the server may allow or refuse (with PermitTTY). When forcing interactive sh, supposedly it would be good to force tty allocation. I may have missed something; it doesn't matter because on the other hand…
  2. A client trying to run a non-interactive command does not expect interactive shell instead. A better way to disable such command is to make it fail. Probably this is what you want.

Therefore:

ForceCommand    if [ "$SSH_ORIGINAL_COMMAND" ]; then echo "this server rejects non-interactive ssh usage" >&2; exit 1; else exec "$SHELL" -i; fi

Notes:

  • ForceCommand uses the user's login shell with the -c option. Our command uses portable syntax, it should work in many shells. If the user can choose something non-standard as his or her login shell then the command may misbehave. Consider putting the command in a script (with proper shebang) and executing the script instead (ForceCommand /path/to/the_script).

  • $SHELL will most likely work as expected, still I think the variable is not strictly required by POSIX. You may prefer ${SHELL:-/bin/sh} or something similar instead.