理解SSH密钥认证:公钥与私钥详解
通过本全面指南,解锁SSH密钥认证的秘密。了解公钥和私钥的基本作用、它们如何协同保护远程连接,以及为何此方法远胜于密码登录。本文提供生成和部署密钥的逐步说明,以及关键的安全优势和最佳实践。使用SSH密钥增强服务器安全性并简化访问。
理解SSH密钥认证:公钥与私钥详解
SSH密钥认证是许多管理员、开发者、CI系统和部署工具登录服务器的标准方式。您的笔记本电脑保存私钥,服务器存储匹配的公钥,SSH在不通过网络发送私钥的情况下证明您拥有私钥。
最后一点是整个关键。密码是您在许多地方输入的秘密。私钥是应保留在您机器上的秘密。如果您用密码短语保护它,并仅在服务器上存储公钥,您将获得一种比共享密码更安全且更易于自动化的登录方法。
密码的问题
传统的基于密码的认证依赖于共享秘密:密码。虽然强密码可以提供一定程度的安全性,但它们容易受到多种弱点的影响:
- 暴力攻击:攻击者可以尝试无数密码组合,直到猜对为止。
- 字典攻击:使用常见单词或短语,攻击者可以快速破解账户。
- 键盘记录器:恶意软件可以捕获按键,泄露密码。
- 钓鱼攻击:社会工程策略可以诱骗用户泄露其凭证。
- 人为错误:用户经常选择弱、可猜测或重复使用的密码,并可能意外暴露它们。
SSH密钥认证降低了这些风险,因为私密信息不会输入到远程服务器。但这并不意味着密钥是神奇的。被盗的未加密私钥仍然可以被滥用,而管理不善的authorized_keys文件可能成为一个隐蔽的后门。
SSH密钥认证:概述
SSH密钥认证利用非对称加密,这是一种使用一对数学上关联的密钥的系统:公钥和私钥。与对称加密(使用同一密钥进行加密和解密)不同,非对称加密使用一个密钥进行加密,另一个不同但相关的密钥进行解密。
当您使用密钥连接时,服务器检查您的账户是否信任所提供的公钥。然后,您的客户端使用匹配的私钥对认证数据进行签名。服务器使用公钥验证该签名。私钥不会上传到服务器。
加密双雄:公钥与私钥
SSH密钥认证的核心是这两个不同但相互关联的组件。
私钥
私钥是您的秘密身份。它是一个长而复杂的字符串,必须绝对保密,绝不能与任何人共享。将其视为您数字保险箱的独特钥匙。
- 安全关键:如果您的私钥被泄露,攻击者可以冒充您,并获得对任何部署了相应公钥的服务器的未授权访问。
- 位置:通常存储在您的本地机器上(例如,
~/.ssh/id_rsa,~/.ssh/id_ed25519)。 - 保护:它可以用密码短语保护。如果有人复制了密钥文件,密码短语是“文件被盗”和“服务器访问被盗”之间的额外屏障。
公钥
公钥是您私钥的对应部分。它从您的私钥派生而来,但不能用于重新创建私钥。顾名思义,公钥旨在共享,并放置在您希望访问的任何服务器上。
- 可共享:您可以安全地将公钥分发给任何人或任何服务器,而不会危及您的安全。
- 位置:在服务器上,公钥通常存储在每个用户账户的
~/.ssh/authorized_keys文件中。该文件中的每一行代表一个受信任的公钥。 - 作用:公钥允许服务器验证由匹配私钥生成的签名。
SSH密钥认证的工作原理:握手过程
让我们分解SSH密钥认证建立安全连接的逐步过程:
- 生成密钥对:首先,您在本地机器上生成一对公钥和私钥。私钥保持秘密,公钥是您将分发的。
- 部署公钥:您将公钥复制到要访问的远程服务器。此密钥通常添加到服务器上用户主目录的
~/.ssh/authorized_keys文件中。 - 尝试连接:当您从本地机器发起SSH连接到远程服务器时,您的SSH客户端指示它想要使用密钥进行认证。
- 服务器检查:服务器检查所提供的公钥是否被允许用于该用户。
- 客户端证明:您的客户端使用私钥对认证数据进行签名。如果私钥有密码短语,系统可能会提示您在本地解锁它。
- 验证:服务器使用
authorized_keys中的公钥验证签名。如果签名有效且账户允许登录,则认证成功。 - 认证授予:如果验证成功,服务器授予您访问权限,并建立安全的SSH会话。
关键的是,您的私钥在整个过程中从未离开您的本地机器。 只有从它派生的加密证明被交换。
生成SSH密钥对
使用本地机器(Linux、macOS或Windows上的WSL/Git Bash)上的ssh-keygen命令生成SSH密钥对是一个简单的过程。
ssh-keygen -t ed25519 -C "[email protected]"
-t ed25519:指定要创建的密钥类型。Ed25519是大多数新OpenSSH密钥的现代默认选择。RSA仍然常见,尤其是在较旧的系统上。-C "[email protected]":向公钥添加注释,帮助您识别其用途或所有者。
系统会提示您输入保存密钥的文件(默认为~/.ssh/id_ed25519)和密码短语。始终使用强密码短语来保护您的私钥。
Generating public/private ed25519 key pair.
Enter file in which to save the key (~/.ssh/id_ed25519):
Created directory '/home/youruser/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/youruser/.ssh/id_ed25519.
Your public key has been saved in /home/youruser/.ssh/id_ed25519.pub.
The key fingerprint is: SHA256:...
The key's randomart image is:
+--[ED25519 256]----+
| .=+ |
| . o. . |
| . + o. |
| o = B o. |
| . S @ + + |
| = + B . |
| o * * E |
| . o o |
| . . |
+----[SHA256]-------+
生成后,您将在~/.ssh目录中有两个文件:
id_ed25519(您的私钥)id_ed25519.pub(您的公钥)
确保您的私钥文件具有严格的权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
部署您的公钥
要使用密钥认证,您的公钥必须放置在您要访问的远程服务器上。
使用ssh-copy-id(推荐)
ssh-copy-id实用程序是部署公钥最简单、最安全的方法。如果它们不存在,它会处理创建~/.ssh目录和authorized_keys文件并设置正确的权限。
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote_host
将user替换为远程服务器上的用户名,将remote_host替换为服务器的IP地址或主机名。系统会提示您最后一次输入user@remote_host的密码以上传密钥。
手动部署
如果ssh-copy-id不可用,您可以手动复制公钥:
复制公钥内容:使用
cat显示您的公钥。cat ~/.ssh/id_ed25519.pub复制整个输出,它以
ssh-ed25519 ...开头,以您的注释结尾。使用密码认证SSH到远程服务器:
ssh user@remote_host提示时输入您的密码。
如果不存在,创建
~/.ssh目录和authorized_keys文件:mkdir -p ~/.ssh chmod 700 ~/.ssh touch ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys将您的公钥追加到
authorized_keys:将之前复制的公钥内容粘贴到authorized_keys文件中。echo "ssh-ed25519 AAAA..." >> ~/.ssh/authorized_keys(将
ssh-ed25519 AAAA...替换为您的实际公钥内容)
使用SSH密钥连接
一旦您的公钥在服务器上,您只需指定用户和主机即可连接:
ssh user@remote_host
如果您有多个密钥对,或者您的私钥不在默认位置(~/.ssh/id_rsa或~/.ssh/id_ed25519),您可能需要使用-i选项指定它:
ssh -i ~/.ssh/my_custom_key user@remote_host
如果您的私钥受密码短语保护,系统会提示您输入它。为了避免在会话期间重复输入密码短语,您可以使用ssh-agent。
SSH密钥认证的安全优势
- 降低密码猜测风险:如果禁用了密码登录,攻击者无法通过SSH密码对该账户进行暴力破解。
- 更强的凭证:正确生成的SSH密钥不是人类可以猜测的。
- 不上传私钥:在认证过程中,您的私钥保持本地。
- 自动化友好:密钥允许可脚本化的无密码登录,这对于自动化工具和CI/CD管道至关重要。
- 密码短语保护:为您的私钥添加密码短语提供了额外的安全层。即使您的私钥文件被盗,没有密码短语它仍然无法使用。
管理您的SSH密钥
ssh-agent
ssh-agent是一个在后台运行的程序,它在内存中保存您解密的私钥。当您尝试连接到SSH服务器时,您的SSH客户端可以查询ssh-agent以获取必要的私钥,从而无需重复输入密码短语。
要启动ssh-agent并添加您的密钥:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
在将密钥添加到代理时,您只需输入一次密码短语。
密钥命名和组织
为了管理多个密钥(例如,用于不同的组织、项目或个人使用),请考虑使用有意义的名称:
ssh-keygen -t ed25519 -f ~/.ssh/id_work_project -C "work_project_key"
ssh-keygen -t ed25519 -f ~/.ssh/id_personal_github -C "personal_github_key"
然后,您可以使用-i选项指定要使用的密钥,或配置您的~/.ssh/config文件以根据主机自动选择正确的密钥。
示例~/.ssh/config:
Host github.com
IdentityFile ~/.ssh/id_personal_github
User git
Host work-server
Hostname 192.168.1.100
IdentityFile ~/.ssh/id_work_project
User devuser
最佳实践和技巧
- 永远不要共享您的私钥:这是黄金法则。您的私钥是您的数字身份。
- 使用强密码短语:用强大的密码短语保护您的私钥,类似于强密码。即使私钥落入坏人之手,这也使其无用。
- 在有理由时轮换:当设备丢失、承包商离职、密钥被错误共享或旧算法不再符合您的策略时,生成新密钥。
- 限制文件权限:确保您的私钥文件具有
600权限(rw-------),并且您的~/.ssh目录具有700(rwx------)。 - 谨慎禁用密码认证:一旦从第二个终端确认密钥登录正常工作,许多服务器应在
/etc/ssh/sshd_config中设置PasswordAuthentication no。在远程系统上更改此设置之前,请保持控制台访问可用。 - 使用
ssh-agent:为了方便和安全,使用ssh-agent管理您的密钥,尤其是那些带有密码短语的密钥。
一个简单的思维模型
公钥是您安装在服务器账户上的锁。私钥是您保存在自己机器上的凭证。密码短语在文件被复制时保护该凭证。authorized_keys文件是访问列表。
大多数SSH密钥问题源于混淆这些概念:将私钥复制到服务器,将公钥粘贴到错误的用户下,使用错误的身份文件,或者权限设置过于开放以至于OpenSSH不信任它们。按用途命名密钥,用密码短语保护私钥,使用ssh-agent方便操作,在访问应结束时移除旧公钥,并在禁用密码登录之前从第二个终端测试更改。