Как задать опцию scp -O (устаревший протокол) в конфигурационном файле?

Вопрос или проблема

У меня, в основном, такая же проблема, как описано (и решено) здесь на Stack Overflow.

Эта проблема заключается в том, что SCP к некоторым хостам, которые не поддерживают подсистему SFTP, работает только если я использую флаг -O.

Однако, есть ли способ настроить это поведение по умолчанию?

Например, с помощью опции в ~/.ssh/config?
Дело в том, что для ручного использования я могу просто использовать alias scp='scp -O', однако это не сработает в скриптах и не оболочечных действиях (таких как запуск плейбуков Ansible).

Я думаю, что вы не можете использовать ~/.ssh/config для решения вашей проблемы, потому что этот файл предназначен для ssh, а не для scp. Правда, scp использует ssh под капотом, но -O, который вы хотите принудить, является опцией строго для scp, а не для ssh.

Возможно, вы сможете достичь приемлемого результата с помощью оборачивающего скрипта. Вот этот скрипт:

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

Вам нужно использовать полный путь к реальному scp. Сохраните скрипт под именем scp в директории, которая находится раньше в вашем $PATH, чем все остальные директории в $PATH, содержащие другие (в практике: реальные) исполняемые файлы scp. Создайте новую директорию и при необходимости отредактируйте ваш $PATH. Убедитесь, что скрипт исполняемый (chmod +x scp).

С этого момента любой процесс, который наследует ваш измененный $PATH и пытается запустить scp, будет запускать обертку вместо реального scp. Обертка заменит себя на реальный scp, который получит -O вместе со всеми аргументами, переданными обертке. Таким образом, -O будет автоматически внедрен.

Есть случаи, когда этот метод не может сработать:

  • Если процесс, вызывающий scp, использует $PATH, который не является вашим измененным $PATH, тогда он не найдет обертку и запустит реальный scp напрямую; следовательно, -O не будет внедрен. По этой причине вы можете захотеть изменить $PATH как можно более “глобально”.

  • Если процесс явно вызывает /usual/path/to/scp, то очевидно, что он вызовет реальный scp напрямую, независимо от $PATH; следовательно, -O не будет внедрен.

  • Не изменяйте $PATH.
  • Переместите оригинальный scp в другое местоположение.
  • Используйте это местоположение в обертке, чтобы обертка всегда вызывала реальный scp.
  • Сохраните обертку как /usual/path/to/scp.
  • Недостаток в том, что ваша операционная система при обновлении может заменить обертку на новую версию реального scp. Эта ошибка не может произойти в методе с измененным $PATH и неизмененным /usual/path/to/scp.

    С момента выхода OpenSSH 9.8 единственный способ выбрать протокол SCP с помощью scp — это использовать -O флаг.

    Никакой файл конфигурации или что-то еще не участвует.

    Таким образом, все решения должны быть внешними для scp. Например, с использованием алиаса.

    Вот простой оберточный скрипт, который должен работать, независимо от того, требует ли целевой хост устаревший -O флаг или нет. Он пытается подключиться без него, и если это не удается, пробует с флагом -O (если он еще не пробовался).

    #!/bin/sh
    
    if ! /usr/bin/scp "$@"; then
        [ $# -gt 0 ] || exit
        for a; do [ "$a" = '-O' ] && exit 2; done
        echo >&2 "переход в режим совместимости (-O)"
        /usr/bin/scp -O "$@"
    fi
    

    Я предлагаю назвать его scp_safe и поместить в ваш $PATH где-нибудь.

    Ответ или решение

    Для решения проблемы с использованием параметра -O в scp, который необходим для работы с хостами, не поддерживающими SFTP, вы не сможете настроить это поведение по умолчанию напрямую через файл конфигурации ~/.ssh/config. Этот файл предназначен исключительно для параметров ssh, а scp, хотя и использует ssh под капотом, не позволяет задать параметр -O в конфигурации.

    Однако, вы можете создать обертку для scp, которая будет автоматически добавлять нужный параметр. Вот шаги, которые необходимо выполнить:

    1. Создайте скрипт обертки для scp:
    #!/bin/sh
    
    if ! /usr/bin/scp "$@"; then
        [ $# -gt 0 ] || exit
        for a; do [ "$a" = '-O' ] && exit 2; done
        echo >&2 "переход на совместимый режим (-O)"
        /usr/bin/scp -O "$@"
    fi
    1. Сохраните этот скрипт, например, под именем scp_safe. Убедитесь, что вы указываете полный путь к оригинальному scp (/usr/bin/scp в данном примере, измените его при необходимости).

    2. Сделайте скрипт исполняемым:

    chmod +x /путь/к/вашему/scp_safe
    1. Поместите этот скрипт в директорию, которая стоит выше по пути ($PATH), чем оригинальный scp, или измените PATH, чтобы он использовал ваш скрипт:
    export PATH="/путь/к/директории/с/scp_safe:$PATH"

    Теперь, когда любой процесс будет пытаться вызвать scp, он будет вызывать ваш скрипт обертки. Скрипт сначала попытается выполнить команду без параметра -O, и если она завершится неудачей, то попробует снова с этим параметром, если он еще не был использован.

    Таким образом, ваши сценарии и автоматизированные процессы, такие как Ansible, смогут использовать scp_safe, что позволит избежать необходимости вручную добавлять -O.

    Важно

    Имейте в виду, что если вас интересуют другие случаи использования scp, важно следить за тем, чтобы процесс, вызывающий scp, использовал модифицированный $PATH, чтобы гарантировать, что используется именно обертка, а не оригинал.

    Оцените материал
    Добавить комментарий

    Капча загружается...