介绍
SSH (Secure Shell) 是用于管理服务器并与服务器通信的加密协议。在使用 Linux 服务器时,大部分时间都花在通过 SSH 连接到服务器的终端会话中。尽管有几种不同的登录 SSH 服务器的方法,但在这里将重点介绍设置 SSH 密钥。SSH 密钥提供了一种简单但极为安全的登录服务器的方法。因此,这是建议所有用户使用的方法。
SSH 密钥如何工作
SSH 服务器可以使用多种不同的方法对客户端进行身份验证。其中最基本的是密码身份验证,它易于使用,但不是最安全的。尽管密码以安全的方式发送到服务器,但密码通常不够复杂或不够长,无法抵御重复的持久性攻击者。现代化的算力与自动脚本相结合,使得暴力破解受密码保护的账户成为可能。尽管还有其他增加安全性的方法(如 Fail2ban 等),但是 SSH 密钥被证明是可靠且安全的替代方法。
SSH 密钥对是两个加密的安全密钥,用于向 SSH 服务器认证客户端。密钥对包含一个公钥和一个私钥。私钥由客户端保留,应绝对保密。私钥的任何泄露都将使攻击者无需其他身份验证即可登录配置了关联公钥的服务器。作为额外的预防措施,可以使用口令在磁盘上对私钥进行加密。关联的公钥可以自由共享,而不会产生任何负面影响。公钥可用于加密仅私钥可以解密的消息,使用密钥对进行身份验证的方式就是基于这样的原理。
将公钥添加到远程账户的家目录内 authorized_keys 文件中,当客户端尝试使用 SSH 密钥进行身份验证时,服务器可以测试客户端是否拥有私钥。如果客户端可以证明其拥有私钥,则将产生一个 Shell 会话或执行所请求的指令。
如何创建 SSH 密钥
为服务器配置 SSH 密钥身份验证的第一步是在本地生成 SSH 密钥对。可以使用名为 ssh-keygen 的实用工具,该实用工具包含在标准的 OpenSSH 套件中。默认情况下,运行它将创建一个 2048 位的 RSA 密钥对。
在本地使用指令 ssh-keygen
来生成 SSH 密钥对。运行该工具时,将提示选择要保存密钥的位置。默认情况下,密钥对将存储在当前用户家目录里的 .ssh 目录中。
Generating public/private rsa key pair.
Enter file in which to save the key (/benhon/.ssh/id_rsa): //输入保存密钥的位置
Created directory '/benhon/.ssh'.
Enter passphrase (empty for no passphrase): //输入私钥的保护口令
Enter same passphrase again: //重复输入口令以确认
Your identification has been saved in /benhon/.ssh/id_rsa
Your public key has been saved in /benhon/.ssh/id_rsa.pub
建议使用默认路径存储位置,这样做将方便 SSH 客户端在尝试进行身份验证时自动找到 SSH 密钥。如果要选择非标准路径,请立即输入,否则直接按回车键以接受默认路径。生成的私钥对:
- 私钥:
~/.ssh/id_rsa
- 公钥:
~/.ssh/id_rsa.pub
加密私钥(可选)
Enter passphrase (empty for no passphrase): //输入私钥的保护口令
Enter same passphrase again: //重复输入口令以确认
关于添加私钥的保护口令,这是个可选项,用于加密私钥文件。你可能想知道加密 SSH 私钥有哪些好处:
- SSH 密钥对的私钥(可以受口令保护的部分)永远不会在网络上公开,保护口令仅用于解密本地磁盘上的私钥。这意味着无法针对保护口令进行基于网络的暴力破解。
- 私钥保存在受限制的目录中。SSH 客户端将无法识别未保存在受限目录中的私钥。私钥本身还必须具有受限的权限(仅所有者拥有读写权限),这意味着系统上的其他用户无法窥探。
- 希望破解私钥保护口令的任何攻击者都必须已经可以访问系统。这意味着攻击者已经可以访问你的账户或 root 账户。如果发生这样情况,保护口令则可以阻止本地攻击者立即登录到远程服务器。这将使被攻击者有时间创建和实施新的 SSH 密钥对,并删除旧密钥对的访问权限。
由于私钥永远不会暴露给网络并且受到文件权限的保护,因此除你与 root 用户以外的任何人都不能访问该文件。如果这些条件被破坏,保护口令将作为附加的保护措施。私钥保护口令是可选的,如果选择使用保护口令,则每次使用私钥时都必须提供口令(除非使用可以存储解密后私钥的 SSH 代理软件)。建议使用保护口令,但是如果不想设置,则按回车键即可跳过这一步。
拷贝公钥到服务器
方法 1
最简单方法是使用 ssh-copy-id 实用工具,建议使用此方法(如果可用)。ssh-copy-id 工具包含在许多发行版的 OpenSSH 软件包中,因此你可以在本地系统上直接使用它,前提是你必须已经具有对服务器基于密码的 SSH 访问权限。使用指令:
ssh-copy-id <用户名>@<服务器地址> -p <端口>
示例 1
ssh-copy-id root@benhon.net -p 22
示例 2(通过 Socks5 代理来连接)
ssh-copy-id root@benhon.net -p 22 -o "ProxyCommand=nc -X 5 -x 127.0.0.1:1080 %h %p"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@benhon.net's password: //输入登录密码
ssh-copy-id 实用工具将在本地账户家目录中扫描到之前创建的公钥文件 id_rsa.pub ,然后将提示输入远程主机用户的登陆密码。输入完密码后按回车键,该实用工具将使用提供的登陆密码连接到远程主机上的账户,然后将 id_rsa.pub 公钥内容复制到远程账户家目录下 .ssh 目录中名为 authorized_keys 的文件中,这样公钥就上传到远程账户家目录里了。
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@benhon.net'" and check to make sure that only the key(s) you wanted were added.
另外,本地如果有多个密钥,可以手动指定上传,操作如下:
ssh-copy-id -i ~/.ssh/id_rsa.pub root@benhon.net -p 22
or
ssh-copy-id -i ~/.ssh/id_rsa.pub root@benhon.net -p 22 -o "ProxyCommand=nc -X 5 -x 127.0.0.1:1080 %h %p"
方法 2
在本地计算机上输出 SSH 公钥内容,然后通过 SSH 连接到远程服务器将其传递给管道。另一方面,我们可以确保该 .ssh 目录存在于正在使用的账户家目录下,然后将通过管道传输的内容输出到 authorized_keys 文件中。使用“>>”重定向符号来追加内容,而不是覆盖内容,这样就能够添加密钥而不会破坏先前添加的密钥。
示例:
cat ~/.ssh/id_rsa.pub | ssh root@benhon.net -p 22 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
root@benhon.net's password: //输入登录密码
输入密码后按回车键,本地 id_rsa.pub 公钥内容将复制到远程账户家目录里的文件 authorized_keys 尾部。
其他方法
- 手动拷贝
查看本地 id_rsa.pub 公钥文件内容cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAr4kGg1r+/pa3f1q4yg8/v3bF1scvApvacRwzHMKIFeRRSL+uRFXWGOM5XWE/WnicwBwyCFlGYd7TucD+G1WN/PepeLbfRxIx3ajdWJoOyodNLpwvpUwR1UvZbZiXSGwieuuqOTyI4WYyyV0IyY+r7bvvnZd89eVdhUuWdgboHwubdZ8bbp/1+gKuqu9C7Sxn3YvhqjFvM8uzF3V20FBDi0UbAF8L2IUx98pCnzD1JAUNehGVz1joJUnep6ihf+XLQhxnMQg7nRq2hj3Q9JgiUwNwWD7frMosH9XdIvPI0pKGyxQX1/3/YTK6dcxB+cL588L8w2exfTW08KCTHdKDUQ== user@demo
然后使用指令 echo "<公钥内容>" >> ~/.ssh/authorized_keys
,将本地 id_rsa.pub 公钥内容追加到 authorized_keys 文件尾部。
示例:
mkdir ~/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsoDXW/kx98Q6q/9Kv977vdDKGExkRvG4VuvPk8itmyL5M1m4O4TXFaFpPh2VMeIEdr59UxF9BVeO/Snrozqqikc3oO3gX31p9DQu6WXlOshpePwRqXrmLGT1Py2M8jwR+sDKCyewE8RQTIrnjmcuREN2lQAfJG5cDZTPSp6Fw+xWJimqS2O5W3q+4368xa5dVBHgaaZ8tsGyTkz+QAb2HPP7sBvoWTI4ZcRtM3Sbx9FLQv9gGSrOW2Yw+DQG1wgM/M5uIdbkukhljHbK9jwtj6I6qybqCr64S4hFcPJFKoD3aRT/R0KDfP836+DvZRD1dcHsCemZI610m5kdJXOcsxzbLZoOXmnrH+7PPmbHhTuGGYmCpSa5ZmmQnrEVmGonMJD26Ck9KxMVj8LBDKvVSbWwZEcs0aElACo+DCMHbEm1PBo1S0AdmYZUcikxAbBoASfnw0ocpBc46Vag8uXMSo3lC7N4FxmfusLH/FLvV/5tz//Jz+rSjV/QrvvDBbPc= benhon@Bens-MBP.local" >> ~/.ssh/authorized_keys
- 手动上传
使用第三方 SFTP 工具(如 FileZilla、WinSCP 等)将本地公钥文件 id_rsa.pub 上传到服务器账户家目录中 .ssh 目录下,并重命名文件为 authorized_keys ( ~/.ssh/authorized_keys) 。
使用密钥登陆服务器
修改配置
编辑服务器 ssh 配置文件 vi /etc/ssh/sshd_config
以启用基于密钥的身份验证方式登陆服务器。找到如下几行参数,删除各行首的“#”注释符(如果有的话),并确认各参数的值对应如下,然后保存。
RSAAuthentication yes //二代 SSH 协议无此行(忽略)
PubkeyAuthentication yes //是否验证公钥
AuthorizedKeysFile .ssh/authorized_keys //指定公钥文件
重启服务 service sshd restart
完成上述的步骤后就可以无需使用远程账户的密码即可登录到远程服务器了。
ssh root@benhon.net -p 22
如果未设置私钥的保护口令,则将立即登录;如果在创建密钥时为私钥设置了保护口令,则需要输入口令。如果遇到错误提示 server refused our key 表示远程服务器公钥文件的权限设置不当,需要修改文件权限。不建议修改配置文件 sshd_config 中的 StrictModes 值为 no 来规避此问题!
指定私钥
使用 ssh 指令与参数“-i”,示例:
ssh -i ~/.ssh/privatekeyfile user@benhon.net -p 22
禁用密码登陆服务器
如果能够使用 SSH 无需密码登录到远程账户,则说明已成功为账户配置了基于 SSH 密钥的身份验证。但是,基于密码的身份验证机制仍然处于启用状态,意味着服务器仍然容易受到暴力攻击。
在服务器上禁用基于密码的身份验证机制之前,请确保已为服务器上的 root 账户配置了基于 SSH 密钥的身份验证,或者最好为服务器上具有 sudo 访问权限的账户配置了基于 SSH 密钥的身份验证。因为接下来的操作将会禁用基于密码的登录方式,所以确保仍然能够获得服务器的管理访问权限很重要。
如果满足上述条件,先以 SSH 密钥(具有 root 用户身份或具有 sudo 特权的账户)登录到远程服务器。编辑配置文件 vi /etc/ssh/sshd_config
,找到 PasswordAuthentication 行,删除行首的“#”注释符(如果有的话),同时将 PasswordAuthentication 值修改为 no,然后保存。
PasswordAuthentication no //是否使用基于密码的身份验证方式
然后重启服务 service sshd restart
,这样服务器就只响应基于 SSH 密钥的身份验证方式的登陆请求了。
进阶
在服务器上成功配置了基于 SSH 密钥的身份验证方式后,使用 SSH 密钥与密码双验证的登录方式。
vi /etc/ssh/sshd_config
修改配置如下
PasswordAuthentication yes //是否使用基于密码的身份验证方式
AuthenticationMethods publickey,password //添加此行;身份验证方式为密钥与密码
重启服务 service sshd restart
其他
在服务器上创建密钥
生成 SSH 密钥对的操作也可以在远程服务器上进行,创建完毕后新建公钥文件:
cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
or
touch ~/.ssh/authorized_keys && cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
然后记得将远程服务器上的私钥文件 ~/.ssh/id_rsa
下载到本地存放!
在 Windows 下创建密钥
https://www.ssh.com/ssh/putty/windows/puttygen#creating-a-new-key-pair-for-authentication
版权声明:本文为原创文章,版权归 BenhoN 所有。
本文链接:https://blog.benhon.net/archives/config_ssh_key_based_auth_on_server.html
所有原创文章采用知识共享 署名-非商业性使用 4.0 国际 许可协议进行许可,你可以自由地转载和修改,但请务必注明文章来源并且不可用于商业目的。