有没有办法让一个SSH配置文件包含另一个文件?


131

如果很重要:

  • 操作系统:Ubuntu 10.04
  • SSH:OpenSSH_5.3p1 Debian-3ubuntu5

我想要一个SSH配置文件包含另一个。用例是在默认.ssh/config文件中定义所需的内容,然后在一个单独的文件(例如~/.ssh/foo.config)中添加一些额外的内容。不过,我希望第二个文件包含第一个文件,因此我不必重复第一个文件中的所有内容。那可行吗?谢谢!


2
上serverfault同样的问题:serverfault.com/questions/375525/...
guettli

Answers:


140

从7.3p1开始,有Include关键字,它允许您包含配置文件。

Include

    包括指定的配置文件。可以指定多个路径名,每个路径名都可以包含glob(3)通配符,并且对于用户配置,还可以使用类似于外壳的“〜”引用用户主目录。~/.ssh如果包含在用户配置文件中或/etc/ssh包含在系统配置文件中,则认为没有绝对路径的文件将位于其中。  Include指令可能出现在MatchHost块内以执行条件包含。
资料来源: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上尝试过。虽然可以,但是自动完成功能被破坏了,因此使用起来不太有用。如果要在ubuntu上升级ssh,请检查此链接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
LLUIS

8
我的天啊。它正在半途而废。从2016-04-15 13:01:08 EST: Slightly modified patch applied, this will be in openssh-7.3
oschrenk

这个答案当时是正确的,但现在已经过时了。
Mark Stosberg '18

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
不幸的是,这在OSX的ssh上不起作用:无法打开用户配置文件/ dev / fd / 63:错误的文件描述符
Ash Berlin-Taylor

它在(Ubuntu 11.10)Linux上也对我不起作用,给出与上述@AshBerlin相同的错误。
SzymonJeż2012年

@AshBerlin您也可以尝试,它也应适用于OSX,直到错误被修复为止
estani 2012年

给定ssh检查三个位置:1.命令行,2. ~/.ssh/config,3. /etc/ssh/ssh_config,您也不需要传递~/.ssh/config命令行。正义alias ssh='ssh -F ~/.ssh/foo.config'并且~/.ssh/config应该在那之后被拾起。只要您不介意foo.config首先加载,它应该比上面的解决方法更干净。
2013年

1
@jim不,它不能那样工作。使用找到的第一个。你试过了吗?手册页上的“ -F configfile:指定每个用户的备用配置文件。如果在命令行上提供了配置文件,则将忽略系统范围的配置文件(/ etc / ssh / ssh_config)。”
estani

17

从ssh 7.3(2016年8月1日发布)开始,可以使用Include伪指令。

包括:包括指定的配置文件。可以指定多个路径名,每个路径名都可以包含全局通配符和对用户主目录的类似于shell的“〜”引用。假定没有绝对路径的文件位于中~/.ssh。一个 Include指令,可能会出现内部MatchHost阻止执行条件包含。

(以下是已解决的错误报告的链接,其中还包括补丁:https ://bugzilla.mindrot.org/show_bug.cgi ? id = 1585#c24 )



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

这也使我可以做一些事情,例如仅当我在主机A或B上但不在我的家庭系统上时,才将配置块添加到ssh配置文件中。

现在我知道,有人会担心,如果您多次登录,这可能会导致速度过慢,但是实际上我从未真正注意到它。而且我相信您也可以将其放入脚本中,并通过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上的文件变化结合这一点,自动化的编译
马队

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

通过从Yakkety安装软件包,可以轻松地将Ubuntu上的SSH版本升级到v7.3(在Ubuntu Xenial 16.04上进行了测试):

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目录中的include

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

0

我愚蠢的答案:

  • 试图在Xenial(16.04)上安装OpenSSH> 7.3
  • 不喜欢它造成的混乱

所以我为此解决了:

  • 将单独的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'

它像一种魅力。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.