如何显示主机/配置/默认 ssh“配置”?

如何显示主机/配置/默认 ssh“配置”?

根据我的ssh_config档案...

配置数据解析如下:

  1. 命令行选项
  2. 用户特定文件
  3. 系统范围的文件

话虽如此,(是的,我知道,我可以仔细检查man ssh_configAND man ssh,并(希望)找到记录的默认值)。如何“打印出”所有当前设置的活动配置。例如,类似...

ssh -o Tunnel=ethernet servername -p 2210 --print-config

SSH-2.0-OpenSSH_7.0
 Command Line Options
   Port 2210
   Host servername
 Command Line Configurations
   Tunnel Ethernet
 Config File
   ...
 SSH Defaults
   ...
   AddressFamily any (???)
   BatchMode no
   ...

这将让你清楚地知道设置了什么以及为什么。我喊道AddressFamily特别指出了这一点,因为它是一个完美的配置选项示例,没有记录默认值。 从man ssh_config...

指定连接时要使用的地址系列。有效参数为any, inet(仅使用 IPv4)或inet6(仅使用 IPv6)。

呃!谢谢大家建设性的建议(不只是一堆建议RTFM)。

答案1

最近的 openssh 中有一个选项,其行为与服务器端-G类似。-T

-G 使 ssh 在评估主机和匹配块后打印其配置并退出。

通过调用ssh -G host您将获得用于连接特定主机的选项,这有助于调试条件匹配ssh_config

另外,设置更详细的日志级别(-vvv)可以帮助调试配置解析器。

答案2

ssh -G remotehost

但这会打印出所有配置,包括默认配置(约 100 行)。有时您只想检查与默认配置的差异(当您对主机有一些特殊规则时),在这种情况下:

comm -13 <(ssh -G non-existing-host | sort) <(ssh -G remotehost | sort)

non-existing-host此命令将和 的配置进行比较remotehost。如果non-existing-host确实是您的配置中没有的东西(很有可能),那么第一个ssh -G...命令将返回默认配置。

下面是bash相同的函数(采用一个参数 remote hostname):

ssh-config-diff() {
    local remotehost=$1
    if ! [ "$remotehost" ]; then
        echo "ERROR: hostname required" >&2
        return 1
    fi
    comm -13 <(ssh-config non-existing-host | sort) <(ssh-config $remotehost | sort)
}

答案3

唯一的潜在缺点-G是它会转储给定目标主机的整个变量集,这对于脚本编写很有用,但在视觉上进行排序可能会有点混乱。

我拼凑了一个快速而粗糙的 AWK 脚本来满足我的需求;给它一个在一行中找到的名称的片段Host,它将打印在.ssh/config文件中找到的配置块。请记住 (1) 一个 Host 行可以有多个条目,并且 (2) 这确实假设配置行将针对每个 Host 块缩进。此外,脚本确实不是打印出配置文件中指定的任何全局选项,因为我不需要这些。

#!/usr/bin/gawk -f
#
# Given a ~/.ssh/config file that looks like
#
#    SettingOne foo
#    SettingTwo bar
#
#    Host hostX hostY
#      SettingBlah yes
#      SettingBlurg no
#
#    Host hostZ
#      SettingBlurg no
#
# then "print_ssh_block hostY" will print out the corresponding Setting block,
# which is considerably easier for a human to read than the output of
# "ssh -G hostY".

BEGIN {
    if (ARGC != 2) {
        print "Usage:  print_ssh_block host_fragment"
        exit 1
    }

    # ARGV[0] is the script file itself
    # ARGV[1] is the string fragment to later match in Host lines; we don't
    # want to actually process it as a filename...
    hostfrag = ARGV[1]
    # ...so we replace it with the filename of SSH's config, which we DO want
    # to process with patterns.
    ARGV[1] = ENVIRON["HOME"] "/.ssh/config"
    ARGC = 2
    inHostBlock = 0
}

/#/ { next }

/^[Hh][Oo][Ss][Tt] / {
    # skip $1, since that's "Host"
    for (i = 2; i <= NF; i++) {
        # $i is the individual host; if it matches the script argument,
        # set or clear the flag appropriately
        inHostBlock = ($i ~ hostfrag) ? 1 : 0
        if (inHostBlock) break
    }
}

# When not in a matching host block, skip the indented lines.
inHostBlock == 0 && /^[[:space:]]/ { next  }

# When inside a matching host block, clear the flag as soon as we reach an
# empty line.
inHostBlock == 1 && /^$/  { inHostBlock = 0 }

# When inside a matching host block, print every line we encounter.
inHostBlock == 1          { print }

对此可以进行无限的改进。真正的 AWK 大师大概可以用大约五行代码来编写它。

相关内容