4

I basically have the same problem as described (and solved) here on Stack Overflow.

This issue is: SCP to some hosts which do not support SFTP subsystem is only working if I provide the -O flag.

However is there a way to instead configure this behavior by default ?

E.g. by an option in ~/.ssh/config ?
The point is: For manual use I can just use an alias scp='scp -O', however this won't work in scripts and non-shell actions (such as running ansible playbooks).

Giacomo1968
  • 58,727

3 Answers3

4

I think you cannot use ~/.ssh/config to solve your problem because this file is for ssh, not for scp. It's true scp uses ssh under the hood, but -O you want to force is an option strictly for scp, not for ssh.

You may be able to achieve an acceptable result with a wrapper script. This is the script:

#!/bin/sh
exec /usual/path/to/scp -O "$@"

You need to use the full path to the real scp. Save the script as scp in a directory that is earlier in your $PATH than all other directories in $PATH that hold other (in practice: the real) scp executable(s). Create a new directory and adjust your $PATH if needed. Make the script executable (chmod +x scp).

From now on any process that inherits your modified $PATH and tries to run scp will run the wrapper instead of the real scp. The wrapper will replace itself with the real scp that will get -O along with all arguments passed to the wrapper. This way -O will be injected automatically.

There are cases when the method cannot work:

  • If a process calling scp uses $PATH which is not your modified $PATH then it won't find the wrapper and it will run the real scp directly; so -O won't be injected. For this reason you may want to modify $PATH as "globally" as possible.

  • If a process calls /usual/path/to/scp explicitly then it will obviously call the real scp directly regardless of $PATH; so -O won't be injected.

A way to overcome these is:

  1. Do not modify $PATH.
  2. Move the original scp to a different pathname.
  3. Use this pathname in the wrapper, so the wrapper execs to the real scp as it always should.
  4. Save the wrapper as /usual/path/to/scp.

The downside is your OS, when being upgraded, may replace the wrapper with a new version of the real scp. This mishap cannot happen in the method with modified $PATH and unaltered /usual/path/to/scp.

1

As of the OpenSSH 9.8, the only way to select the SCP protocol with scp is by -O switch.

No configuration file or anything else is involved.

So all solutions must be external to scp. Such as the alias.

0

Here's a simple wrapper script that should work whether the target host requires the legacy -O switch or not. It attempts to connect without it, and iff that fails, it tries with the -O flag (unless it was already tried).

#!/bin/sh

if ! /usr/bin/scp "$@"; then [ $# -gt 0 ] || exit for a; do [ "$a" = '-O' ] && exit 2; done echo >&2 "falling back to compatibility mode (-O)" /usr/bin/scp -O "$@" fi

I suggest naming it scp_safe and placing in your $PATH somewhere.

luckman212
  • 309
  • 2
  • 7