Есть ли способ для одного файла конфигурации SSH включить другой?


131

В случае, если это имеет значение:

  • ОС: Ubuntu 10.04
  • SSH: OpenSSH_5.3p1 Debian-3ubuntu5

Я хотел бы, чтобы один файл конфигурации SSH включал другой. Сценарий использования будет определять все, что я хочу в моем .ssh/configфайле по умолчанию, а затем предварительно ожидать несколько дополнительных вещей в отдельном файле (например ~/.ssh/foo.config). Я хочу, чтобы второй файл включал первый, поэтому мне не нужно дублировать все в первом. Это выполнимо? Спасибо!


2
Тот же вопрос на сервере: serverfault.com/questions/375525/…
guettli

Ответы:


140

Начиная с версии 7.3p1, есть Includeключевое слово, которое позволяет вам включать файлы конфигурации.

Include

    Включите указанные файлы конфигурации. Можно указать несколько имен путей, и каждое имя пути может содержать подстановочные знаки glob (3) и, для пользовательских конфигураций, «~» ссылки оболочки на домашние каталоги пользователей. Предполагается, что файлы без абсолютных путей находятся в том ~/.sshслучае, если они включены в файл конфигурации пользователя или /etc/sshвключены в файл конфигурации системы.  Includeдиректива может появляться внутри Matchили в Hostблоке для выполнения условного включения.
Источник: ssh_config (5) .

Например, вы можете иметь в ~/.ssh/config:

Include config.d/home

Host github.com
    HostName github.com
    User git

и в ~/.ssh/config.d/home:

Host laptop
    HostName laptop.lan

Из комментариев используйте ниже, чтобы включить все файлы в config.dкаталог:

Include config.d/* 

13
проверить версию с $ ssh -V
Питер

7
Используйте Include config.d/*для включения всех записей в config.d.
Саймон Вудсайд

17
Ftr: это должно идти в верхней части файла и не может быть просто добавлено в список Hostзаписей.
17

2
попробовал на Ubuntu 16.04. Хотя, это работает, но автозаполнение нарушено, что делает его менее полезным. Если вы хотите обновить ssh в Ubuntu, перейдите по
cwhsu

@dtk спасибо за это. Вот что меня озадачило
Адам Кинан

28

Нет, насколько мне известно, это невозможно.

Вот ссылки на соответствующие открытые запросы / сообщения об ошибках:

https://bugzilla.mindrot.org/show_bug.cgi?id=1585

https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/739495


2
Также эта ошибка в Debian: bugs.debian.org/cgi-bin/bugreport.cgi?bug=631189
Луис

8
О, МОЙ БОГ. Это происходит. С 2016-04-15 13:01:08 EST: Slightly modified patch applied, this will be in openssh-7.3
oschrenk

Этот ответ был верным в то время, но сейчас устарел.
Марк Стосберг

25

Если вы хотите запустить ssh-клиент, вы можете сделать это в bash:

#files are .ssh/config and ~/.ssh/foo.config
alias ssh='ssh -F <(cat .ssh/config ~/.ssh/foo.config)'

тогда вы используете ssh как обычно, и оба файла будут прочитаны в указанном порядке.

Для демона сервера sshdвы можете сделать то же самое, просто используйте -fвместо него -Fи запишите это, где вы запускаете демон напрямую. вам не нужен псевдоним.

Вторая возможность в соответствии со страницей руководства состоит в том, чтобы ввести общесистемную конфигурацию /etc/ssh/ssh_configи пользовательскую ~/.ssh/config.

Обновление Очевидно, что есть некоторые проблемы с некоторыми версиями bash и тем, как создаются устройства. (см. http://bugs.alpinelinux.org/issues/1465 )

Это обходной путь (хотя, на мой взгляд, некрасиво):

mkfifo /tmp/ssh_fifo
cat ~/.ssh/config ~/.ssh/foo.config >/tmp/ssh_fifo & 
ssh -F /tmp/ssh_fifo myserver
rm /tmp/ssh_fifo

так что если вы хотите, вы можете создать из него функцию (или скрипт):

ssh() {
    tmp_fifo=$(mktemp -u --suffix=_ssh_fifo)
    mkfifo "$tmp_fifo" 
    cat ~/.ssh/config ~/.ssh/foo.config >"$tmp_fifo" 2>/dev/null & 
    /usr/bin/ssh -F "$tmp_fifo" "$@"
    rm "$tmp_fifo"
}

1
К сожалению, это не работает для ssh OSX: Не удается открыть файл конфигурации пользователя / dev / fd / 63: Неверный дескриптор файла
Ash Berlin-Taylor

Это не работает для меня также на (Ubuntu 11.10) Linux, выдающем ту же ошибку, что и @AshBerlin, опубликованный выше.
Szymon Jeż

@AshBerlin Вы можете попробовать это тоже, это должно работать и для OSX, пока ошибка не будет исправлена
estani

Учитывая, что ssh проверяет три места: 1. командную строку, 2. ~/.ssh/config, 3. /etc/ssh/ssh_config, вам также не нужно передавать ~/.ssh/configкомандную строку. Просто так alias ssh='ssh -F ~/.ssh/foo.config'и ~/.ssh/configдолжно быть забрано после этого. Пока вы не возражаете против foo.configзагрузки в первую очередь, это должно быть чище, чем описанный выше обходной путь.
Джим

1
@ Джим, нет, это так не работает. Первый найденный используется. Ты это пробовал? со страницы руководства "-F configfile: указывает альтернативный файл конфигурации для каждого пользователя. Если файл конфигурации указан в командной строке, системный файл конфигурации (/ etc / ssh / ssh_config) будет проигнорирован."
Эстани

17

Начиная с ssh 7.3 (выпущен 1 августа 2016 г.), Includeдоступна директива.

Включить : Включить указанные файлы конфигурации. Можно указать несколько имен путей, и каждое имя пути может содержать подстановочные знаки глобуса и похожие на «~» ссылки на домашние каталоги пользователей. Предполагается, что файлы без абсолютных путей находятся в ~/.ssh. IncludeДиректива может появляться внутри Matchили Hostблок для выполнения условного включения.

(Вот ссылка на исправленный отчет об ошибке, который также включает патч: https://bugzilla.mindrot.org/show_bug.cgi?id=1585#c24 )


14

Так же, как и другие «уродливые», вот моя строка:

alias ssh="cat ~/.ssh/config.d/* > ~/.ssh/config; ssh"

Обратите внимание, что sftpкоманда не вызовет пересчет конфигурации.
ВасяНовиков

2
(Мне все еще нравится ответ, потому что он использует «config.d /» и очень прост.)
VasyaNovikov

2
простой, элегантный, но
хакерский

6

Ну, я вроде обманываю, чтобы сделать это. В моих файлах bash .profile-ish у меня есть блок, который заменяет различные части моего домашнего каталога при входе в систему, поэтому я просто генерирую новый каждый раз. Пример:

rm ~/.ssh/config
cat ~/conf/myservers.sshconfig >> ~/.ssh/config

[ -f ~/conf/workservers.sshconfig ] && cat ~/conf/workservers.sshconfig >> ~/.ssh/config
(or something like this:)
for i in `ls ~/conf/sshconfigs` ; do
    cat $i >> ~/.ssh/config
done

chmod 600 ~/.ssh/config

Это также позволяет мне делать такие вещи, как добавление блоков конфигурации в файл конфигурации ssh, только если я на хосте A или B, но не на моих домашних системах.

Теперь я знаю, что кто-то пожалеет, что если вы войдете в систему, это может вызвать чрезмерное замедление, но на практике я никогда этого не замечал. И я уверен, что вы можете поместить это в скрипт и запустить его через cron.


3

Я лично использую эти команды для компиляции конфигурации ssh:

alias compile-ssh-config='echo -n > ~/.ssh/config && cat ~/.ssh/*.config > ~/.ssh/config'
alias ssh='compile-ssh-config && ssh'
# (This will get used by other programs depending on the ~/.ssh/config)
# (If you need you can run the compile-ssh-config command via cron etc.)

или же:

alias compile-ssh-config='echo -n > ~/.ssh/config-compilation && cat ~/.ssh/*.config > ~/.ssh/config-compilation'
alias ssh='compile-ssh-config && ssh -F ~/.ssh/config-compilation'
# (This is saver and won't over write an existing ~/.ssh/config file)

потому что:

alias ssh='ssh -F <(cat .ssh/*.config)'

у меня не работает, возвращаю

ssh: Can't open user config file /dev/fd/63: Bad file descriptor

Надеюсь, это поможет.


Вы можете пойти еще дальше и объединить это с fswatch для автоматической компиляции при изменении файла
cavalcade

3

Другое решение на базе FUSE (сам не проверял):

https://github.com/markhellewell/sshconfigfs

«Вместо того, чтобы продолжать управлять одним большим файлом, вместо этого [...] создайте файл конфигурации« динамически из множества меньших логических блоков ».

Я также нашел статью, делающую это через FIFO: http://www.linuxsysadmintutorials.com/multiple-ssh-client-configuration-files/


1
Я нахожу содержание комментариев достаточно описательным - там написано «FUSE» (возможно, расширение аббревиатуры было бы лучше); Ссылка только на реализацию.
Авив

1
Не знал о проблеме коротких ответов, ответ расширился. Похоже, мне придется время от времени проверять сайт на предмет моих ответов, в отсутствие уведомлений по электронной почте. Спасибо за комментарии.
amontero

2

Ни одно из этих решений псевдонимов не работает для gitдругих программ, кроме ssh.

Я быстро и грязно собрал все вместе, но вы можете улучшить его.

Добавьте это к вашему ~/.bashrc

mkdir -p ~/.ssh/config.d/
[ -e ~/.ssh/config ] && mv ~/.ssh/config ~/.ssh/config.bak.$(date -Ins)
cat ~/.ssh/config.d/* > ~/.ssh/config

Каждый раз, когда вы начинаете сеанс, он объединяет все файлы ~/.ssh/config.d. (строка 3)

Недостатком этой версии является то, что если вы измените ~/.ssh/configследующую сессию, то ваши изменения будут потеряны, поэтому я не могу переместить существующий файл в файл .bak. (строка 2) Проблема в том, что через некоторое время у вас будет много .bak файлов.


Отлично с добавлением некоторых is_anything_changedусловий
vp_arth

1

Вы можете легко обновить версию SSH в Ubuntu до v7.3 (протестировано в Ubuntu Xenial 16.04), установив пакеты из Yakkety:

echo "deb http://archive.ubuntu.com/ubuntu yakkety main" > /etc/apt/sources.list.d/yakkety.list
apt-get update
apt-get install -y ssh
rm /etc/apt/sources.list.d/yakkety.list
apt-get update

Проверьте версию SSH

ssh -V
OpenSSH_7.3p1 Ubuntu-1, OpenSSL 1.0.2g 1 Mar 2016

Настройте SSH для использования include из каталога ~ / .ssh / config.d

mkdir ~/.ssh/config.d
sed -i '1iInclude config.d/*' ~/.ssh/config

0

Мой тупой ответ:

  • Попытался установить OpenSSH> 7.3 на Xenial (16.04)
  • Не понравился беспорядок, который это сделало

Поэтому я согласился на это:

  • Храните ваши отдельные файлы конфигурации OpenSSH в ~/.ssh/config.d/
  • Когда вы меняете один, делать cat ~/.ssh/config.d/* > ~/.ssh/config
  • В славный день вы обновляете до версии с дистрибутивом OpenSSH 7.3p1 или новее, вместо этого вы можете создать файл, содержащий

Include config.d/*


0

Я не могу обновить SSH на моей машине.

Я использовал GNU make для генерации конфигурационного файла ssh только при необходимости :

# Concatenates all the .config files.
aInput  = *.config
aOutput = ~/.ssh/config

aCurrentMakefile = $(lastword $(MAKEFILE_LIST))

$(aOutput): $(shell ls $(aInput)) $(aCurrentMakefile)
    @echo "Generating $(aOutput)"
    @echo "# File generated by $(aCurrentMakefile) on $(shell date +'%F %T.%6N')" > $(aOutput)
    @cat $(aInput) >> $(aOutput)

Затем SSH связывается с

alias ssh='make -s -f ~/Tools/config.d/makefile -C ~/Tools/config.d && ssh'

Отлично работает.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.