一些工程师可能会对通过配置文件可以配置多少 ssh 客户端行为感到惊讶。如果没有配置文件,指定命令行参数ssh很快就会变得很麻烦:
ssh -i /users/virag/keys/us-west/ed25519 -p 1024 -l virag \ myserver.aws-west.example.com
打字一次太长了,更不用说一天多次了。如果您要管理多个服务器和 VM,创建自定义~/.ssh/ssh_config是修剪常用ssh命令的好方法。
我们可以ssh myserver通过编辑将上面的示例缩短ssh_config为:
Host myserver
Hostname myserver.aws-west.example.com
User virag
Port 1024
IdentityFile /users/virag/keys/us-west/ed25519
优雅而简单。现在我们有了基础知识,让我们看看这里实际发生了什么。
ssh 客户端按以下顺序从三个地方读取配置:
1.系统范围内/etc/ssh/ssh_config
2.用户特定的~/.ssh/ssh_config
3.ssh直接提供给的命令行标志
这意味着命令行标志 (#1) 可以覆盖用户特定的配置 (#2),它可以覆盖全局配置 (#3)
当重复使用连接参数时,通常更容易在 中定义它们ssh_config,这些参数会在连接时自动应用。虽然它们通常是在用户ssh第一次运行时创建的,但可以通过以下方式手动创建目录和文件:
ouch ~/.ssh/ssh_config
回到上面的例子,你可能会注意到它ssh_config被组织成以主机头开头的节:
Host [alias]
Option1 [Value]
Option2 [Value]
Option3 [Value]
虽然在技术上不是必需的,但这种缩进格式很容易被人类阅读。然而,ssh 客户端并不关心这种格式。相反,它将通过将ssh命令行中输入的参数与任何和所有主机头匹配来获取配置参数。通配符也可以用作主机头的一部分。考虑:V
Host myserver2
Hostname myserver2.aws-west.example.com
Host myserver*
Hostname myserver1.aws-west.example.com
User virag
Port 1024
使用myserver1别名,我们可以从第二节中得到我们所期望的。
Hostname myserver1.aws-west.example.com
User virag
Port 1024
但myserver2也有类似的选项列表。
Hostname myserver2.aws-west.example.com
User virag
Port 1024
ssh 客户端在顺序读取文件时通过模式匹配和锁定值来获取此信息。因为myserver2同时匹配myserver2和myserver*,所以它将首先从 中获取Hostname值myserver2。然后,当涉及到第二个模式匹配时,使用了UserandPort值,但该Hostname字段已被填充。让我重复一遍,ssh接受每个选项的第一个值。
.ssh_config 中有近 100 个选项man 5 ssh_config。我编制了一个我个人发现自己使用的列表,其中许多将在本文后面使用。
Port- 运行远程ssh守护程序的端口。如果守护程序在默认端口 22 上运行,则不需要定义此选项。在不同的端口上运行ssh守护程序被认为是一种很好的做法,因为它可以减少哑机器人探测的数量。
Hostname- 用于建立连接的真实主机名,例如 DNS 或 IP 地址。这对于缩短主机名很有用。例如,您可以方便ssh mongo地带您到mongo-12.staging.example.com.
ProxyJump- 此选项简化了通过连接的服务器到单个标志的隧道,该标志-J使用别名命名中间主机(本地客户端和最终目的地之间的主机)。这仅适用于较新的客户端(OpenSSH 7.3+)。我将在下面更详细地介绍这一点。
ForwardAgent& AddKeysToAgent- 在主机之间跳转(当您ssh在另一个ssh会话中再次键入时)需要重复身份验证。为此,ssh必须将凭据存储在中间服务器上,但这不是一种安全的做法。这两个选项允许另一个通常调用ssh-agent的进程将本地凭据自动加载ssh到内存中,并通过安全转发的 UNIX 套接字将它们提供给中间机器的 ssh 客户端。ForwardAgent启用此转发行为,同时AddKeysToAgent自动将密钥加载到内存的过程。我将在下面提供更多详细信息。
IdentityFile- 此选项指定 ssh 客户端应尝试进行身份验证的密钥的路径。这并不排除 ssh 客户端尝试输入密钥~/.ssh或 ssh-agent。通常在密钥出于某种原因未存储在默认位置时使用。
IdentitiesOnly- 通常与 一起使用IdentityFile,此选项告诉 ssh 客户端确切地显示哪个密钥并放弃任何密钥~/.ssh或 ssh-agent。因为ssh如果尝试过多的无效密钥会引发身份验证错误,此选项可帮助客户端准确识别要呈现的密钥。即使在IdentitiesOnly中启用ssh_config,在命令行中输入的任何身份也会被尝试。
CertificateFile- 鉴于密钥在很大程度上已经过时,此选项可以与IdentityFile指定要提供的证书结合使用。这并不总是必要的。当证书颁发机构签署密钥以创建证书时,-cert.pub将自动附加到密钥的文件名中。在加载密钥之前,ssh 客户端将首先尝试使用预期的命名约定从提供的文件名加载证书。但是,如果密钥和证书文件名不遵循此模式,则CertificateFile必须使用,否则将无法找到证书。阅读更多关于为什么你应该使用 certs的信息。
SetEnv& SendEnv- 这些选项允许 ssh 客户端将本地环境变量发送到指定的主机。主机服务器必须配置为接受这些环境变量,方法是在 中设置AcceptEnv为 Yes /etc/ssh/sshd_config。
ServerAliveInterval&ServerAliveCountMax-如果 ssh 客户端在指定的时间间隔内没有收到任何数据,它将向主机服务器请求响应。这可以防止负载平衡器和服务器由于不活动而断开连接。
HostKeyAlias- 指示 ssh 客户端使用来自的密钥别名,~/.ssh/known_hosts而不是HostName. 这对于具有动态更改 IP 地址的主机或在一台主机上运行的多个服务器很有用。
PreferredAuthentication- 此选项规定应尝试验证方法的顺序。默认值为gssapi-with-mic, hostbased, publickey, keyboard-interactive, 和password
扩展我们在前两个部分中学到的知识,让我们看看ssh_config当我们拥有一个适度的机队时如何组织。采取以下场景:
Virag 适用于六种环境:东海岸和西海岸 AWS 区域的开发、测试和生产环境
Virag 具有对 Dev 和 Prod 环境的常规用户访问权限,但在 Test 上是 root
生产环境具有更严格的安全控制
Host east-prod
HostName east-prod.prod.example.com
Host *-prod
HostName west-prod.prod.example.com
User virag
PasswordAuthentication no
PubKeyAuthentication yes
IdentityFile /users/virag/keys/production/ed25519
Host east-test
HostName east-test.test.example.com
Host *-test
HostName west-test.test.example.com
User root
Host east-dev
HostName east-dev.east.example.com
Host *-dev
HostName west-dev.west.example.com
User virag
Host * !prod
PreferredAuthentications publickey
Host *
HostName bastion.example.com
User Default
ServerAliveInternal 120
ServerAliveCountMax 5
如果我们要运行ssh east-test,我们的完整选项列表将显示为:
HostName east-test.test.example.com
User root
PreferredAuthentications publickey
ServerAliveInternal 30
ServerAliveCountMax 5
east-test客户端通过匹配、*-test、* !prod和来获取预期的选项值*。您可能会注意到该Host *节将适用于任何ssh论点。换句话说,Host *定义所有用户的全局设置。这对于应用客户端可用的安全控制特别有用。上面,我们只使用了两个,但有几个关键字会加强安全性,例如CheckHostIP, HashKnownHosts,StrictHostKeyChecking和更多隐藏的宝石。
提醒一句:因为 ssh 客户端按顺序解释选项,所以通用配置应该放在文件的底部。如果放置在顶部,选项值将在客户端可以进一步读取下面的主机特定选项之前固定。在上述情况下,放在Host *文件的开头会导致用户是Default.
如果出现一次性情况,请始终记住在命令行中输入的选项将覆盖ssh_config:中的选项ssh -o "User=root" dev。
一个ssh 跳转服务器是一个代理,位于客户端和队列的其余部分之间ssh。ssh跳转主机通过强制所有流量通过单个强化位置并最小化单个节点ssh到外部世界的端点来最大程度地减少威胁。
配置多跳设置的一种方法是在我们的跳转服务器上存储目标服务器的私钥。不要这样做。跳转服务器通常是多用户环境,这意味着任何具有提升权限的一方都可以破坏任何私钥。AddKeysToAgent解决这种安全威胁的方法是启用代理转发,我们用和简要介绍了这一点ForwardAgent。考虑到这种方法的普遍性,当我建议不要这样做时,你可能会感到惊讶。为了理解为什么,让我们更深入地挖掘一下。
代理转发如何工作?
ssh-agent是作为与 SSH 不同的程序存在的密钥管理器。它在内存中保存用于身份验证的私钥和证书。它不会写入磁盘或导出密钥。相反,代理的转发功能允许我们的本地代理通过现有ssh连接进行访问,并通过环境变量在远程服务器上进行身份验证。基本上,当客户ssh端接收到密钥质询时,代理会将这些质询上游转发到我们的本地机器,其中质询响应将通过本地存储的私钥构造并转发回下游到目标服务器进行身份验证。我个人发现这种视觉解释在研究时很有帮助。
在幕后,ssh-agent绑定到一个 unix 域套接字以与其他程序($SSH_AUTH_SOCK环境变量)进行通信。问题是在链中任何地方拥有 root 权限的任何人都可以使用创建的套接字来劫持我们的本地ssh-agent. 即使套接字文件受到操作系统的良好保护,root 用户也可以冒充另一个用户并将 ssh 客户端指向他们自己的恶意代理。本质上,使用代理进行转发与在整个链中与在机器上具有根的任何人共享私钥相同。(深入了解使用 ssh-agent 的陷阱)
事实上,关于手册页的内容ForwardAgent如下:
“应谨慎启用代理转发。能够绕过远程主机上的文件权限(对于代理的 Unix 域套接字)的用户可以通过转发连接访问本地代理。攻击者无法从代理获取密钥材料,但他们可以对密钥执行操作,使他们能够使用加载到代理中的身份进行身份验证。”
要浏览跳转服务器,我们实际上不需要代理转发。一种现代方法是使用ProxyJump或其命令行等效-J的 .
Host myserver
HostName myserver.example.com
User virag
IdentityFile /users/virag/keys/ed25519
ProxyJump jump
Host jump
HostName jump.example.com
User default
不是通过代理转发密钥挑战响应,而是ProxyJump将我们本地客户端的标准输入和标准输出转发到目标主机。这样,我们就不会ssh在jump.example.com. sshd直接myserver.example.com连接到我们的本地客户端并控制该连接。作为一个额外的好处,跳转服务器看不到任何通过它的流量,因为它在ssh隧道内被加密。无需直接访问即可设置跳转服务器的能力是安全和正确设置ssh的重要组成部分。如果您想了解更多相关知识,不妨来关注一下极悦的Java视频,里面的课程内容细致全面,从入门到精通,很适合没有基础的小伙伴学习,希望对大家能够有所帮助。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习