让我们使用Ubuntu20.04LTS从头开始构建和配置一个最小的SSH堡垒主机(跳箱)。
就像家庭WiFi路由器位于巨大而危险的互联网和本地网络上通常不安全的设备之间一样,堡垒主机位于公共互联网和内部网络(例如vPC)之间,充当到达内部主机的网关,同时保护它们不会直接暴露在公共互联网的荒野中。堡垒主机通常运行OpenSSH或远程桌面服务器。
堡垒主机是网络中的重要瓶颈。鉴于其地位,它可以承担很多职责:审核和会话日志记录、内部主机的用户身份验证以及高级威胁检测。但它并不需要做所有这些事情。我们将在这里让事情变得简单,并从头开始构建一个支持SSH连接代理的堡垒。然后我们再谈一些我们可以做的更花哨的事情。
如果您有内部网络,并且需要从公共互联网访问这些主机,则堡垒主机是一个简单的选择。
你甚至需要一个堡垒吗?与几乎任何技术决策一样,这要视情况而定。以下是您可能会考虑的一些替代方案。
如果您需要比使用SSH或RDP更深入地访问内部网络,您可能需要VPN。但是,与包括堡垒主机在内的其他选项相比,IPsec VPN增加了很多复杂性和维护负担。
覆盖网络是一种更轻、更简单的VPN,它支持漫游端点。这仍然需要一些设置。最常见的开源选择是Wireguard和Nebula。您可以在内部网络的边缘(如VPN)或在您希望能够访问的所有主机上运行其中一个,并通过隧道传输SSH流量。您的所有客户还需要运行Wireguard或Nebula。
Google IAP和AWS Session Manager是将SSH流量传输到内部云网络的托管解决方案。这里的好处是,您可以使用云IAM角色进行身份验证,并且可以实施更复杂的安全策略(安全密钥策略,或设备级策略,而不是基于IP的策略),如果您运行自己的堡垒主机,这些策略是不可行的。这些服务可以免费使用,但缺点是IAP和AWS Session Manager比纯SSH更复杂,而且它们给GCP或AWS增加了一些限制。
我们只想让这个堡垒将SSH连接转发到我们的内部主机。因为我们这里使用的是SSH,所以用户必须先向堡垒进行身份验证,然后再向内部主机进行身份验证。要完成连接,用户需要两台主机的有效凭据,但堡垒和内部主机可以使用不同的凭据,我们将利用这一功能。
用户将使用ssh-J[bastion][内部主机]或其.ssh/config的Match Host块中的ProxyJump指令连接到内部主机。
在您最喜欢的云提供商上安装一个Linux实例。我们将使用Ubuntu20.04LTS,因为它简单,支持良好,并且包含最近发布的OpenSSH 8.2。
设置防火墙或安全组策略,将到堡垒的连接限制为端口22(SSH),如果可以,只允许来自您信任的IP的连接。
我们建议执行Mozilla的OpenSSH安全指南。不幸的是,他们的指南只涵盖OpenSSH6.7之前的版本。以下是仍然与OpenSSH 8.2相关的指导原则:
停用短模。模数用于SSH连接开始时的密钥交换。Mozilla建议仅使用3071位或更大的模数以获得更高的安全性。要强制执行此操作,请运行以下命令:
按优先顺序#支持的HostKey算法。HostKey/etc/ssh/ssh_host_ed25519_keyHostKey/etc/ssh/ssh_host_ecdsa_keyHostKey/etc/ssh/ssh_host_rsa_key#基于密码的登录被禁用-仅允许基于公钥的登录。AuthenticationMethods public key#LogLevel Verbose在登录时记录用户的密钥指纹。需要有关于使用哪个密钥进行登录的清晰审核跟踪。LogLevel详细PermitRootLogin no#Log sftp级别文件访问(读/写/等)。否则不容易记录。子系统sftp/usr/lib/ssh/sftp-server-f AUTHPRIV-l info。
您还应该考虑您希望支持哪些算法和密钥类型。Mozilla建议使用以下密钥类型(比OpenSSH默认值更严格):
除了Mozilla的推荐(只涵盖OpenSSH6.7之前的版本)之外,您还可以做一些事情来增强您的SSHD安全性:
您可以将sshd设置为仅接受使用FIDO U2F安全令牌的密钥。
注意:这将防止以后使用启动时获得的原始PEM密钥连接到主机。因此,您需要为ubuntu帐户生成一个新的-sk类型密钥。我们在这里写了说明。
如果您不想在安全组规则中按IP地址限制访问,请考虑一些额外的强化措施:
端口敲门将使连接到堡垒的任务变得复杂,但如果您需要堡垒对任何IP地址可用,则这可能是一个很好的选择。
因为我们不允许shell访问,所以我们还想禁止除TCP转发之外的所有转发,ssh-J使用TCP转发来支持堡垒。
如果您只需要一个SSH网关,您可以在堡垒本身上禁用shell访问。
默认情况下,SSHD的TCP端口转发将允许用户将其连接转发到您专用网络中的任何远程TCP端口。如果您不希望将其他类型的通信转发到内部主机,则可以将转发限制到端口22(SSH):
您可以使用sshd-t测试您的配置,然后重新启动sshd服务器。在继续之前,请确保您仍然可以ssh进入计算机!😱。
如果您只有几个用户,您可以在堡垒上创建一个每个人都将使用的帐户,并确保将他们的所有公钥都添加到该帐户中。
您可以设置AWS CloudWatch代理或Google Cloud Logging Agent,这样您的SSH日志就会特别上传到云中。准备就绪后,您可以为可疑的SSH活动设置警报。
有关允许紧急访问主机的安全方法,请参阅我们的SSH紧急访问指南。
一旦设置了紧急访问密钥,您就可以禁用任何其他root访问选项-因为没有人有理由定期使用此计算机上的root帐户。
这是一项重要的零信任策略:您连接到的任何内部主机都应该只允许来自堡垒的SSH连接。实现这一点的最简单方法是使用入站1G。
您的客户端应该接受已知主机提供的新主机密钥,从而使主机密钥轮换变得容易得多。(这将是未来OpenSSH的默认设置。)。
此外,您还可以添加配置指令,以便通过堡垒更轻松地访问内部主机。让我们假设您的所有内部主机都具有.internet域中的名称,就像AWS上的情况一样。您可以使用此指令联系他们:
然后,只需通过堡垒连接到内部主机的ssh host.Internal即可。这里有一个微妙的注意事项:内部主机名将通过堡垒上的DNS查找进行解析,而不是由您的本地计算机解析。因此,只要堡垒知道如何根据内部主机的内部名称和IP来查找它们,这就是您所需要的全部。