Force a specific shell for sshd
I use fish-shell
as my default shell on my own computer, because it’s a pretty nice shell.
Occasionally, though, this causes issues. Software tests in particular have a habit of sloppily running shell command. Typically, this can be fixed by just being more explicit, using execvp(['bash', '-c', '<command>'])
(or just use execv*
directly instead of going through a shell).
But one case I couldn’t figure out is SSH. When you’re testing an SSH client, the most reliable way to do that is to run some shell scripts over a local SSH session, and check that it does what you expect. SSH has no way of passing a nice array of arguments, all you get is a string which will be interpreted by the user’s SHELL.
If you want to use bash
for an SSH command, many online resources will tell to you run “ssh
What you can do however, is funnel the whole shell string through to your desired shell using this slightly underhand sshd
configuration:
ForceCommand sh -c 'eval "$SSH_ORIGINAL_COMMAND"'
This still requires a default shell that’s normal enough to not do any interpolation within single quotes, but that’s a much simpler requirement (and true of fish-shell
).
For the Conductance test suite, we run an unprivileged SSHD daemon with its own checked-in config during testing. So applying this globally is fine. But if you are doing this on actual SSH server, you might want to use a Match
directive to make sure this rule only applies to trusted user (e.g I haven’t tested how this works on a locked-down account with its shell set to /bin/nologin
, it could conceivably create a security hole).