C

SSH基础知识:使用SSH服务器,客户端和密钥

SSH Essentials: Working with SSH Servers, Clients, and Keys

Posted by xuepro on March 3, 2021

介紹

SSH是一种安全协议,是远程连接Linux服务器的主要手段。它通过生成一个远程shell来提供一个基于文本的界面。连接后,你在本地终端中输入的所有命令都会被发送到远程服务器并在那里执行。

SSH概述

最常见的连接到远程Linux服务器的方式是通过SSH。SSH是Secure Shell的缩写,它提供了一种安全可靠的方式来远程执行命令、进行更改和配置服务。当你通过SSH连接时,你使用一个存在于远程服务器上的账户登录。

SSH的工作原理

当你通过SSH连接时,你将会进入一个shell会话,这是一个基于文本的界面,你可以在这里与你的服务器进行交互。在SSH会话期间,你在本地终端上输入的任何命令都会通过加密的SSH隧道发送,并在服务器上执行。

SSH连接使用客户端-服务器模型实现。这意味着要建立一个SSH连接,远程机器必须运行一个叫做SSH守护进程的软件。该软件监听特定网络端口上的连接,验证连接请求,如果用户提供正确的凭证,则生成相应的环境。

用户的计算机必须有一个SSH客户端。这是一个知道如何使用SSH协议进行通信的软件,可以得到有关要连接到的远程主机的信息、要使用的用户名以及应该传递给验证的凭证。客户端还可以指定他们想要建立的连接类型的某些细节。

SSH如何验证用户

客户端一般使用密码(安全性较低,不建议使用)或SSH密钥(SSH keys,非对称密钥)进行认证,SSH密钥非常安全。

密码登录是加密的,对新用户来说很容易理解。然而,自动机器人和恶意用户经常会反复尝试对允许基于密码登录的账户进行验证,这可能会导致安全漏洞。出于这个原因,我们建议总是为大多数配置设置基于SSH密钥的身份验证。

SSH密钥(SSH keys)是一组匹配的加密密钥,可用于身份验证。每一组都包含一个公钥和一个私钥。公钥可以毫无顾忌地自由共享,而私钥则必须严加防范,决不能暴露给任何人。

要使用SSH密钥进行身份验证,用户必须在本地计算机上拥有一对SSH密钥。在远程服务器上,必须将公钥复制到用户主目录内的~/.ssh/authorized_keys 文件中。这个文件包含了授权登录这个账户的公钥列表,每行一个。

当客户端连接到主机,希望使用SSH密钥认证时,会将此意图告知服务器,并告诉服务器要使用哪个公钥。然后服务器会检查其authorized_keys文件中的公钥,生成一个随机字符串,并使用公钥对其进行加密。这个加密的消息只能用相关的私钥来解密。服务器将把这个加密的消息发送给客户端,以测试他们是否真的拥有相关的私钥。

收到这个消息后,客户端将使用私钥对其进行解密,并将揭示的随机字符串与之前协商的会话ID相结合。然后,它将生成这个值的MD5哈希值,并将其传回服务器。服务器已经有了原始消息和会话ID,所以它可以比较这些值生成的MD5哈希值,并确定客户端一定有私钥。

现在你已经知道了SSH的工作原理,我们可以开始讨论一些例子来演示不同的SSH工作方式了

生成和使用SSH密钥

本节将介绍如何在客户端机器上生成SSH密钥,并将公钥分发到应该使用它们的服务器上。如果你之前没有生成过密钥,那么本节是一个很好的开始,因为它可以提高未来连接的安全性。

生成SSH密钥对 在本地计算机上生成新的 SSH 公钥和私钥对是在没有密码的情况下与远程服务器进行身份验证的第一步。除非有很好的理由不这样做,否则你应该始终使用SSH密钥进行验证。

有很多加密算法可以用来生成SSH密钥,包括RSA、DSA和ECDSA。RSA 密钥通常是首选,也是默认的密钥类型。

要在你的本地计算机上生成RSA密钥对,键入:

ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa):

这个提示允许你选择存储RSA私钥的位置。按ENTER键可以将其设为默认值,这样就可以将它们存储在用户主目录下的.ssh隐藏目录中。选择默认位置会让你的SSH客户端自动找到密钥。

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

下一个提示允许你输入一个任意长度的口令来保护你的私钥。默认情况下,每次使用私钥时,你都必须输入你在这里设置的任何口令,作为额外的安全措施。如果你不想要密码,可以按ENTER键留空。但请记住,这将允许任何获得你的私钥控制权的人登录到你的服务器。

如果你选择输入密码,那么在你输入时将不会显示任何内容。这是一种安全防范措施。

Output
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
8c:e9:7c:fa:bf:c4:e5:9c:c9:b8:60:1f:fe:1c:d3:8a root@here
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|       +         |
|      o S   .    |
|     o   . * +   |
|      o + = O .  |
|       + = = +   |
|      ....Eo+    |
+-----------------+

这个过程已经生成了RSA SSH密钥对,位于用户主目录下的.ssh隐藏目录中。这些文件是

  • ~/.ssh/id_rsa: 私钥。不要共享这个文件!
  • ~/.ssh/id_rsa.pub: 相关的公钥。这个文件可以自由分享,不会有任何后果。

生成一个具有较大比特数的SSH密钥对。

SSH 密钥默认为 2048 位。这通常被认为是足够安全的,但你可以指定更多的位数来获得更坚固的密钥。

要做到这一点,请在-b参数中加入你想要的位数。大多数服务器支持长度至少为 4096 位的密钥。出于 DDOS 保护的目的,可能不接受更长的密钥。

ssh-keygen -b 4096
```bash
 
如果您之前已经创建了一个不同的密钥,您将被问及是否要覆盖您之前的密钥。

覆盖(y/n)?

如果您选择 "yes(是)",您之前的密钥将被覆盖,您将无法再使用该密钥登录服务器。正因为如此,请务必谨慎地覆盖密钥。

#### 删除或更改私钥上的密码口令。
如果你已经为你的私钥生成了一个密码口令,并希望更改或删除它,你可以很容易地做到这一点。

  - 注意:要更改或删除口令,你必须知道原始口令。如果你丢失了密钥的口令,就没有办法了,你必须生成一个新的密钥对。

要更改或删除密码,只需键入。
```bash
ssh-keygen -p
```bash 
出现如下提示

Enter file in which the key is (/root/.ssh/id_rsa): “输入密钥所在的文件(/root/.ssh/id_rsa)”:

你可以输入你想修改的密钥的位置,或者按回车键接受默认值。

提示你输入旧的密码口令。
```bash
Enter old passphrase:

输入你想修改的旧密码。然后系统会提示你输入新的口令。

Enter new passphrase (empty for no passphrase):
Enter same passphrase again:

在这里,输入新的口令或按 ENTER 键删除口令。

显示SSH密钥指纹

每个SSH密钥对共享一个单一的加密 “指纹”,它可以用来唯一地识别密钥。这在各种情况下都很有用。

要找出一个SSH密钥的指纹,键入:

ssh-keygen -l

提示“ 输入密钥所在的文件(/root/.ssh/id_rsa)。”

Enter file in which the key is (/root/.ssh/id_rsa):

如果密钥的位置正确,你可以按回车键,否则输入修改后的位置。你会得到一个字符串,其中包含密钥的位长、指纹、账户和主机,以及使用的算法。 输出:

4096 8e:c4:82:47:87:c2:26:4b:68:ff:96:1a:39:62:9e:4e  demo@test (RSA)

使用 SSH-Copy-ID 复制您的公共 SSH 密钥到服务器上。

要把你的公钥复制到服务器上,让你在没有密码的情况下进行身份验证,可以采取一些方法。

如果你目前已经在服务器上配置了基于密码的 SSH 访问,并且你已经安装了 ssh-copy-id 工具,这是个简单的过程。ssh-copy-id 工具包含在许多 Linux 发行版的 OpenSSH 包中,所以它很可能是默认安装的。

如果你有这个选项,你可以很容易地通过键入来传输你的公钥。

ssh-copy-id username@remote_host

这将提示你在远程系统上的用户账户密码。 ··· The authenticity of host ‘111.111.11.111 (111.111.11.111)’ can’t be established. ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe. Are you sure you want to continue connecting (yes/no)? yes /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 demo@111.111.11.111’s password: ··· 将提示你:”主机的真实性无法建立,是否需要用新的密钥登陆。

111.111.11.111(111.111.11.111) "主机的真实性无法建立。
ECDSA密钥指纹为fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe。
您确定要继续连接吗(是/否)?
/usr/bin/ssh-copy-id。INFO: 试图用新的密钥登录,以过滤掉任何已经安装的密钥。
/usr/bin/ssh-copy-id。INFO: 还有1个密钥未安装--如果现在提示你安装新的密钥。
demo@111.111.11.111's password:

输入密码后,你的 ~/.ssh/id_rsa.pub 密钥的内容将被追加到用户账户~/.ssh/authorized_keys 文件的末尾。

Output
Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'demo@111.111.11.111'"
and check to make sure that only the key(s) you wanted were added.

告诉你添加了一个密钥(即你的公钥),并尝试通过”ssh ‘demo@111.111.11.111’“登录、检查是否只添加了你想要的密钥。

现在你可以在没有密码的情况下登录该账户了。

ssh username@remote_host

在没有SSH-Copy-ID的情况下,将你的公共SSH密钥复制到服务器上。

如果你没有ssh-copy-id实用程序,但仍然有基于密码的SSH访问远程服务器,你可以用另一种方式复制公钥的内容。

你可以输出密钥的内容,并将其管道化到ssh命令中。在远程端,你可以确保 ~/.ssh 目录存在,然后将管道中的内容追加到 ~/.ssh/authorized_keys 文件中。

cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
  • 译者注: cat ~/.ssh/id_rsa.pub是输出你客户端机器目录的公钥内容~/.ssh/id_rsa.pub|是管道化命令,将前面的输出管道化后面的命令中,ssh username@remote_host是SSH登录原创服务器,"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"是在远程服务器上执行命令mkdir和»。>>表示将前面管道中的输出内容输出到后面的文件中,即服务器的文件~/.ssh/authorized_keys.
  • 如果已经服务器上创建了~/.ssh目录,只要执行:
      cat ~/.ssh/id_rsa.pub | ssh username@remote_host "cat >> ~/.ssh/authorized_keys"
    
  • 另外windows的cmd命令行窗口没有cat命令,可以用type命令代替cat命令,建议用PowerShell代替cmd窗口执行ssh等命令。

您将被要求提供远程账户的密码。

the authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
demo@111.111.11.111's password:

输入密码后,你的密钥将被复制,允许你在没有密码的情况下登录。

ssh username@remote_IP_host.

手动复制公共SSH密钥到服务器上

如果你没有基于密码的SSH访问权限,你将不得不手动添加你的公钥到远程服务器。

在你的本地机器上,你可以通过键入以下内容找到你的公钥文件。

cat ~/.ssh/id_rsa.pub

将输出:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@test

您可以复制这个值,并手动粘贴到远程服务器的适当位置。您将不得不通过其他方式登录到远程服务器(如DigitalOcean web console)。

在远程服务器上,创建 ~/.ssh 目录,如果它还不存在的话。

mkdir -p ~/.ssh

之后,你通过键入 ~/.ssh/authorized_keys 来创建或追加方式将这个公钥的内容添加到文件~/.ssh/authorized_keys中。

echo public_key_string » ~/.ssh/authorized_keys

现在您应该可以在没有密码的情况下登录到远程服务器。

译者注:在windows 10系统上需要将私钥的路径告诉ssh-agent,首先以管理员身份打开Powershell,然后执行下面的命令:

Set-Service ssh-agent -StartupType Manual
Start-Service ssh-agent
Get-Service  ssh-agent 
ssh-add ~\.ssh\id_rsa   # Now load your key files into ssh-agent

现在,你可以用ssh登录ssh服务器了:

ssh username@servername

参考:OpenSSH key management Starting ssh-agent on Windows 10 fails: “unable to start ssh-agent service, error :1058”

未完…

翻译自SSH Essentials: Working with SSH Servers, Clients, and Keys

译者注:Windows系统上自带了openssh,可以通过PowerShell或cmd窗口执行ssh。可以看这篇文件How to Enable and Use Windows 10’s New Built-in SSH Commands


支付宝打赏 微信打赏

您的打赏是对我最大的鼓励!