Чи існує спосіб, щоб один конфігураційний файл 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

    Додайте вказані файли конфігурації. Можна вказати кілька імен шляхів, і кожне ім'я контуру може містити глобальні (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
Pieter

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

17
Ftr: це має знаходитись у верхній частині файлу, і його не можна просто додати до списку Hostзаписів.
dtk

2
спробував на Ubuntu 16.04. Хоча це працює, але автозаповнення порушено, що робить його менш корисним. Якщо ви хочете оновити ssh на ubuntu, перегляньте це посилання gist.github.com/stefansundin/0fd6e9de172041817d0b8a75f1ede677
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
Lluís

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і запишіть це там, де ви безпосередньо запускаєте демон. вам не потрібен псевдонім.

Друга можливість відповідно до сторінки man - це ввести в систему конфігурацію системи /etc/ssh/ssh_configта користувача ~/.ssh/config.

Оновлення Мабуть, є проблема з деякими версіями bash та способами створення пристроїв. (див. http://bugs.alpinelinux.org/isissue/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
На жаль, це не працює на OSX 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
@jim ні, це не працює так. Перший знайдений використовується. Ви пробували? на вхідній сторінці "-F configfile: Вказує альтернативний файл конфігурації для кожного користувача. Якщо в командному рядку вказаний файл конфігурації, системний файл конфігурації (/ etc / ssh / ssh_config) буде ігноруватися."
estani

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
простий, елегантний, але хакі
code_monk

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

Це також дозволяє мені робити такі речі, як додати блоки конфігурації до файлу 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 до версії 7.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 для використання включає з каталогу ~ / .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 config лише за потреби :

# 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.