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

Joe*_*nte 185 ssh openssh

如果重要:

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

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

小智 226

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

Include

    包括指定的配置文件。可以指定多个路径名,每个路径名可以包含 glob(3) 通配符,对于用户配置,类似 shell 的“~”引用用户主目录。~/.ssh如果包含在用户配置文件中或/etc/ssh如果包含在系统配置文件中,则假定没有绝对路径的文件在其中。  Include指令可能出现在 aMatchHost块内以执行条件包含。
来源:ssh_config(5)

您应该将Include子句放在文件的顶部。

例如,您可以在~/.ssh/config

Include config.d/home

Host github.com
    HostName github.com
    User git
Run Code Online (Sandbox Code Playgroud)

并在~/.ssh/config.d/home

Host laptop
    HostName laptop.lan
Run Code Online (Sandbox Code Playgroud)

从注释中,使用以下内容包含目录中的所有文件config.d

Include config.d/* 
Run Code Online (Sandbox Code Playgroud)

  • Ftr:这必须放在文件的顶部,不能只是附加到 `Host` 条目列表中。 (37认同)
  • 使用 $ ssh -V 检查版本 (19认同)
  • 使用 `Include config.d/*` 来包含 `config.d` 中的所有条目。 (12认同)
  • 他并没有撒谎,要确保把它放在首位。 (3认同)
  • 在 Ubuntu 16.04 上试过。虽然,它可以工作,但**自动完成已损坏**,这使得它不太有用。如果您想在 ubuntu 上升级 ssh,请查看此链接 https://gist.github.com/stefansundin/0fd6e9de172041817d0b8a75f1ede677 (2认同)
  • @dtk 另一种解决方法是将 `Include` 放在 `Host *` 条目中并避免重新排序配置 (2认同)

rem*_*ems 29

不,据我所知,这是不可能的。

以下是相应的开放功能请求/错误票证的链接:

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

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

  • 我的天啊。它正在发生。来自 2016-04-15 13:01:08 EST:`稍微修改补丁应用,这将在 openssh-7.3` (11认同)
  • 这个答案当时是正确的,但现在已经过时了。 (4认同)
  • 还有 Debian 上的这个错误:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=631189 (2认同)

est*_*ani 25

如果要启动 ssh 客户端,可以在 bash 中执行此操作:

#files are .ssh/config and ~/.ssh/foo.config
alias ssh='ssh -F <(cat .ssh/config ~/.ssh/foo.config)'
Run Code Online (Sandbox Code Playgroud)

然后您通常使用 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
Run Code Online (Sandbox Code Playgroud)

因此,如果您愿意,可以从中创建一个函数(或脚本):

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"
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*don 17

从 ssh 7.3(2016 年 8 月 1 日发布)开始,提供了一个Include指令。

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

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


小智 14

与另一个“丑陋”类似,这是我的单线:

alias ssh="cat ~/.ssh/config.d/* > ~/.ssh/config; ssh"
Run Code Online (Sandbox Code Playgroud)

  • (我仍然喜欢答案,因为它使用“config.d/”并且非常简单。) (2认同)
  • 简单,优雅,但很hacky (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
Run Code Online (Sandbox Code Playgroud)

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

现在我知道了,有人会抱怨,如果您经常登录,这可能会导致速度过慢,但实际上我从未真正注意到这一点。而且我相信你可以把它放在一个脚本中并通过 cron 启动它。