跳转到内容跳转到页面导航:上一页 [访问键 p]/下一页 [访问键 n]
适用于 openSUSE Leap 15.6

22 使用 OpenSSH 保护网络操作 编辑源文件

摘要

OpenSSH 是随 openSUSE Leap 提供的 SSH(安全外壳)实现,用于保护网络操作,例如远程管理、文件传输和隧道传输不安全的协议。SSH 会加密两个主机之间的所有流量,包括身份验证,以防止窃听和连接劫持。本章涵盖基本操作,以及主机密钥轮换和证书身份验证,这些对于管理更大的 SSH 部署非常有用。

22.1 OpenSSH 概述 编辑源文件

SSH 是一种网络协议,为网络上的计算机之间或网络上的计算机与外部系统之间的通信提供端到端保护。如果您拥有登录名和远程计算机的正确身份验证方法,则可以打开到任何其他计算机的 SSH 会话。

SSH 是一种客户端-服务器协议。运行 sshd 守护程序的任何主机都可以接受来自任何其他主机的 SSH 连接。运行 sshd 的每个主机都可以拥有自己的自定义配置,例如限制谁可以访问以及允许哪些身份验证方法。

身份验证和加密由加密密钥对提供。每个密钥对都有一个公钥和一个私钥。公钥加密,私钥解密。公钥旨在自由共享,而私钥必须受到保护,不得共享。如果私钥被泄露,拥有它的任何人都可以冒充原始密钥所有者。

SSH 提供强大的保护,因为服务器和客户端必须相互进行身份验证。当客户端首次尝试打开 SSH 会话时,服务器会呈现其公共主机密钥。如果客户端已经拥有此密钥的副本(存储在客户端机器上的 ~/.ssh/known_hosts 中),则客户端知道信任服务器。如果客户端没有适当的主机密钥,则会询问它是否应该信任服务器

The authenticity of host '192.168.22.219 (192.168.22.219)'
   can't be established. ECDSA key fingerprint is
   SHA256:yXf6pjV26N0fegvEYIt3HgG95s3Q1X6WYRhtHLF99pUo.
   Are you sure you want to continue connecting (yes/no/[fingerprint])?

用户可以键入 yesno,或者粘贴其主机密钥指纹的副本进行比较。

Note
注意:匹配主机密钥指纹

将您的主机密钥指纹分发给您的用户,可以让他们验证他们是否收到正确的主机密钥。当他们粘贴其主机密钥指纹的副本时,ssh 会比较指纹,并在指纹匹配时接受提供的主机密钥。这确保了比视觉比较更准确的匹配。

您不能依赖用户使用正确的验证方法。如果指纹不匹配,用户仍然可以键入 yes,或者复制消息中的指纹,并完成连接。更强大的替代方案是使用证书身份验证,它提供了一种全局身份验证机制,并且不需要用户行为完美(请参阅 第 22.8 节,“OpenSSH 证书身份验证”)。

如果主机的公钥已更改,则连接将被拒绝,并显示一个令人警惕的警告

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:keNu/rJFWmpQu9B0SjIuo8NLjbeDY/x3Tktpl7oDJqo.
Please contact your system administrator.
Add correct host key in /home/geeko/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/geeko/.ssh/known_hosts:210
You can use following command to remove the offending key:
ssh-keygen -R 192.168.121.219 -f /home/geeko/.ssh/known_hosts
ECDSA host key for 192.168.121.219 has changed and you have requested strict
checking.
Host key verification failed.

解决方法是从 ~/.ssh/known_hosts 中删除违规密钥,方法是使用警告中给出的命令,然后重新连接并接受新的主机密钥。

软件包 openssh 安装服务器、客户端、文件传输命令和某些实用程序。

OpenSSH 支持几种不同的身份验证类型

密码身份验证

使用远程机器上的任何系统登录名和密码。这是最简单、最灵活的身份验证,因为您可以从任何地方的任何机器打开 SSH 会话。它也是最不安全的,因为它容易受到密码破解和击键记录的影响。

公钥身份验证

使用您的个人 SSH 密钥进行身份验证,而不是登录名和密码。这比密码身份验证的灵活性较小,因为您只能从持有您的私钥的机器打开 SSH 会话。它更强大,因为它不易受到密码破解或击键记录的影响;攻击者必须拥有您的私钥并知道其密码短语。

请参阅 第 22.9 节,“使用 gnome-keyring 进行自动公钥登录”,了解如何使用 gnome-keyring 在 GNOME 会话中进行自动公钥身份验证。

请参阅 第 22.10 节,“使用 ssh-agent 进行自动公钥登录”,了解如何使用 ssh-agent 在控制台会话中进行自动公钥身份验证。

无密码短语的公钥身份验证

公钥身份验证,与没有密码短语的私钥配对。这对于自动化服务(例如脚本和 cron 作业)很有用。您必须保护私钥,因为获得访问权限的任何人都可以轻松冒充密钥所有者。

证书身份验证

OpenSSH 支持证书身份验证,以便于密钥管理、更强的身份验证和大规模 SSH 部署。

openSUSE Leap 默认安装 OpenSSH 软件包,提供以下命令

ssh

用于启动到远程主机的 SSH 连接的客户端命令。

scp

从远程主机安全地复制文件或到远程主机复制文件。

sftp

客户端和 SFTP 服务器之间安全的文件传输。(SFTP 协议(SSH FTP)与 FTPS 或 FTPES(通过 SSL/TLS 的 FTP)无关,而是独立编写的。)

ssh-add

将私钥身份添加到身份验证代理 ssh-agent

ssh-agent

管理用户的私钥身份及其密码短语,用于公钥身份验证。ssh-agent 将密码短语保存在内存中并按需应用它们,因此用户不必重新键入密码短语进行身份验证。

ssh-copy-id

安全地将公钥传输到远程主机,以设置公钥身份验证。

22.2 服务器加固 编辑源文件

OpenSSH 附带一个可用的默认服务器配置,但您可以采取其他步骤来保护您的服务器。

Important
重要:维护对远程 SSH 服务器的访问权限

当您更改任何 SSH 服务器时,要么物理访问该机器,要么在测试您的更改并一切正常之前保持活动的 root SSH 会话处于打开状态。然后,如果出现问题,您可以还原或更正您的更改。

默认服务器配置文件 /etc/ssh/sshd_config 包含默认配置,并且所有默认值都已注释掉。通过输入您自己的配置项(未注释)来覆盖任何默认项,如下例所示,该示例设置了不同的侦听端口,并指定了多宿主主机上的侦听 IPv4 地址

#Port 22
Port 2022

#ListenAddress 0.0.0.0
ListenAddress 192.168.10.100
Important
重要:更新 /etc/services

当您使用非标准侦听端口时,首先检查 /etc/services 文件中是否有未使用的端口。选择任何高于 1024 的未使用的端口。然后在 /etc/services 中记录您正在使用的端口。

最好禁止 root 登录。相反,以非特权用户身份登录到远程机器,然后使用 sudo 以 root 身份运行命令。如果您真的想允许 root 登录,则以下服务器配置示例显示了如何配置服务器以仅接受 root 用户的公钥身份验证(第 22.6 节,“公钥身份验证”),并使用 PermitRootLogin prohibit-passwordPasswordAuthentication 选项。

以下设置用于 /etc/ssh/sshd_config 加强访问控制

示例 22.1: 示例 sshd_config
# Check if the file modes and ownership of the user’s files and
# home directory are correct before allowing them to login
StrictModes yes

# If your machine has more than one IP address, define which address or
# addresses it listens on
ListenAddress 192.168.10.100

# Allow only members of the listed groups to log in
AllowGroups ldapadmins backupadmins

# Or, deny certain groups. If you use both, DenyGroups is read first
DenyGroups users

# Allow or deny certain users. If you use both, DenyUsers is read first
AllowUsers user1 user2@example.com user3
DenyUsers user4 user5@192.168.10.10

# Allow root logins only with public key authentication
PermitRootLogin prohibit-password

# Disable password authentication and allow only public key authentication
# for all users
PasswordAuthentication no

# Length of time the server waits for a user to log in and complete the
# connection. The default is 120 seconds:
LoginGraceTime 60

# Limit the number of failed connection attempts. The default is 6
MaxAuthTries 4

更改 /etc/ssh/sshd_config 后,运行语法检查器

> sudo sshd -t

语法检查器仅检查正确的语法,并且不会找到配置错误。完成操作后,重新加载配置

> sudo systemctl reload sshd.service

检查服务器的密钥目录是否具有正确的权限。

/etc/ssh 应该为模式 0755/drwxr-xr-x,由 root:root 拥有。

私钥应该为 0600/-rw-------,由 root:root 拥有。

公钥应该为 0644/-rw-r--r--,由 root:root 拥有。

22.3 密码身份验证 编辑源文件

使用密码身份验证,您所需要的只是远程机器上用户的登录名和密码,以及设置并运行的 sshd。在以下示例中,用户 suzanne 打开到主机 sun 的 SSH 会话

> ssh suzanne@sun

suzanne 被提示输入远程密码。键入 exit 并按 Enter 关闭 SSH 会话。

如果用户名在两台机器上相同,您可以省略它,然后使用 ssh HOST_NAME 就足够了。成功身份验证后,您可以在命令行上工作或使用交互式应用程序,例如文本模式下的 YaST。

您还可以使用 ssh USER_NAME HOST COMMAND 语法在远程系统上运行非交互式命令(登录、运行命令,然后会话关闭)。COMMAND 必须正确引用。多个命令可以像在本地 shell 中一样连接起来

> ssh suzanne@sun "df -h && du -sh  /home"
> ssh suzanne@sun "sudo nano /etc/ssh/sshd_config"

当您在远程机器上运行 sudo 时,系统会提示您输入 sudo 密码。

22.4 管理用户和主机加密密钥 编辑源文件

有几种密钥类型可供选择:DSA、RSA、ECDSA、ECDSA-SK、Ed25519 和 Ed25519-SK。DSA 已经弃用多年,并在 OpenSSH 7.0 中禁用,不应使用。RSA 是最通用的,因为它较旧且使用更广泛。(从 OpenSSH 8.2 开始,RSA 已弃用于主机密钥。使用 ECDSA 或 Ed25519 作为主机密钥。)

Ed25519 和 ECDSA 更强大、更快。Ed25519 被认为是强度最高的。如果您必须支持不支持 Ed25519 或 ECDSA 的旧客户端,请以所有三种格式创建主机密钥。

Note
注意:旧客户端不安全

一些旧的 SSH 客户端不支持 ECDSA 和 ED25519。ECDSA 和 ED25519 于 2014 年随 OpenSSH 6.5 发布。保持安全服务更新非常重要,如果可能,不要允许不安全的旧客户端。

SSH 密钥有两个目的:验证服务器到客户端,以及验证客户端到服务器(请参阅 第 22.6 节,“公钥身份验证”)。服务器主机密钥存储在 /etc/ssh 中。用户的个人密钥存储在 /home/user/.ssh 中。

/home/user/.ssh 在用户创建新的 SSH 密钥时创建。

主机密钥不应具有密码短语。

在大多数情况下,私有用户密钥应具有强大的密码短语。

22.4.1 创建用户 SSH 密钥对 编辑源文件

以下过程显示了如何创建用户 OpenSSH 加密密钥。

过程 22.1: 创建默认和自定义密钥
  1. 要使用默认参数(RSA,3072 位)生成用户密钥对,请在不带任何选项的情况下使用 ssh-keygen 命令。使用强大的密码短语保护您的私钥

    > ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/tux/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in id_rsa
    Your public key has been saved in id_rsa.pub
    The key fingerprint is:
    SHA256:z0uJIuc7Doy07bFTe1ppZHLVrkD/bWWlBAF/PcHjblU user@host2
    The key's randomart image is:
    +---[RSA 3072]----+
    |          ..o... |
    |           o . +E|
    |        . . o +.=|
    |       . o . o o+|
    |  .   . S . . o +|
    | . =  .= * + . = |
    |  o *.o.= * . +  |
    |   ..Bo+.. . .   |
    |    oo==  .      |
    +----[SHA256]-----+
  2. 创建具有更长位长的 RSA 密钥对

    > ssh-keygen -b 4096

    OpenSSH RSA 密钥最大长度为 16,384 位。但是,更长的位长不一定更可取。有关更多信息,请参阅 GnuPG FAQ,https://www.gnupg.org/faq/gnupg-faq.html#no_default_of_rsa4096

  3. 你可以创建任意数量的用户密钥,用于访问不同的服务器。每个密钥对必须具有唯一的名称,并且可以选择性地添加注释。这些有助于你记住每个密钥对的用途。创建一个具有自定义名称和注释的 RSA 密钥对

    > ssh-keygen -f backup-server-key -C "infrastructure backup server"
  4. 创建一个具有自定义名称和注释的 Ed25519 密钥对

    > ssh-keygen -t ed25519 -f ldap-server-key -C "Internal LDAP server"

    Ed25519 密钥固定为 256 位,在密码强度上相当于 RSA 4096。

22.4.2 创建 SSH 服务器主机密钥 编辑源代码

主机密钥的管理方式略有不同。主机密钥不能设置密码短语,并且密钥对存储在 /etc/ssh 中。OpenSSH 在安装时会自动生成一组主机密钥,例如以下示例

> ls -l /etc/ssh
total 608
-rw------- 1 root root 577834 2021-05-06 04:48 moduli
-rw-r--r-- 1 root root   2403 2021-05-06 04:48 ssh_config
-rw-r----- 1 root root   3420 2021-05-06 04:48 sshd_config
-rw------- 1 root root   1381 2022-02-10 06:55 ssh_host_dsa_key
-rw-r--r-- 1 root root    604 2022-02-10 06:55 ssh_host_dsa_key.pub
-rw------- 1 root root    505 2022-02-10 06:55 ssh_host_ecdsa_key
-rw-r--r-- 1 root root    176 2022-02-10 06:55 ssh_host_ecdsa_key.pub
-rw------- 1 root root    411 2022-02-10 06:55 ssh_host_ed25519_key
-rw-r--r-- 1 root root     96 2022-02-10 06:55 ssh_host_ed25519_key.pub
-rw------- 1 root root   2602 2022-02-10 06:55 ssh_host_rsa_key
-rw-r--r-- 1 root root    568 2022-02-10 06:55 ssh_host_rsa_key.pub

ssh-keygen 有一个特殊选项,-A,用于创建新的主机密钥。这将为所有不存在主机密钥的密钥类型创建新的密钥,使用默认密钥文件路径、空密码短语、密钥类型的默认位数和空注释。以下示例通过首先删除现有密钥,然后创建一组新密钥来创建一组完整的新主机密钥

> sudo rm /etc/ssh/ssh_host*
> sudo ssh-keygen -A

你可以通过首先删除要替换的密钥来替换选定的密钥对,因为 ssh-keygen -A 不会替换现有密钥。

Important
重要提示:不要使用 DSA 密钥

ssh-keygen -A 会创建 DSA 密钥,即使它们已被弃用为不安全已有数年。在 OpenSSH 7.0 中,它们仍然被创建,但由于未在 sshd_config 中列出而被禁用。你可以安全地删除 DSA 密钥。

当你想要轮换主机密钥时(请参阅 第 22.5 节,“轮换主机密钥”),你必须单独创建新的密钥,因为它们必须与你的旧主机密钥同时存在。你的用户使用旧密钥进行身份验证,然后接收新的密钥列表。它们需要唯一的名称,以避免与旧密钥冲突。以下示例创建新的 RSA 和 Ed25519 主机密钥,并标有创建年份和月份。请记住,新的主机密钥不能有密码短语

> cd /etc/ssh
> sudo ssh-keygen -b 4096 -f "SSH_HOST_RSA_2022_02"
> sudo ssh-keygen -t ed25519 -f "SSH_HOST_ED25519_2022_02"

你可以随意命名你的新密钥。

22.5 轮换主机密钥 编辑源代码

从版本 6.8 开始,OpenSSH 包含支持主机密钥轮换的协议扩展。SSH 服务器管理员必须定期淘汰旧的主机密钥并创建新的密钥,例如,如果密钥已被泄露,或者需要升级到更强的密钥。在 OpenSSH 6.8 之前,如果 StrictHostKeyChecking 在用户机器上的 ssh_config 中设置为 yes,用户会看到警告,提示主机密钥已更改,并且不允许连接。然后用户必须手动从他们的 known_hosts 文件中删除服务器的公钥,重新连接并手动接受新的密钥。任何自动 SSH 连接,例如计划备份,都会失败。

新的主机密钥轮换方案提供了一种在不中断服务的情况下分发新密钥的方法。当客户端连接时,服务器会向他们发送一个新密钥列表。然后,下次登录时,会询问他们是否希望接受更改。给用户几天时间连接并接收新密钥,然后你可以删除旧密钥。用户的 known_hosts 文件会自动更新,添加新密钥并删除旧密钥。

设置主机密钥轮换需要在服务器上创建新密钥,对服务器上的 /etc/ssh/sshd_config 和客户端上的 /etc/ssh/ssh_config 进行某些更改。

首先,创建你的新密钥或密钥。以下示例创建一个新的 RSA 密钥和一个新的 Ed25519 密钥,并具有唯一的名称和注释。一种有用的约定是用创建日期命名它们。请记住,主机密钥不能有密码短语

# ssh-keygen -t rsa -f ssh_host_rsa_2022-01 -C "main server"
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ssh_host_rsa_2022-01
Your public key has been saved in ssh_host_rsa_2022-01.pub
The key fingerprint is:
SHA256:F1FIF2aqOz7D3mGdsjzHpH/kjUWZehBN3uG7FM4taAQ main server
The key's randomart image is:
+---[RSA 3072]----+
|         .Eo*.oo |
|          .B .o.o|
|          o . .++|
|         . o ooo=|
|        S . o +*.|
|         o o.oooo|
|       .o ++oo.= |
|       .+=o+o + .|
|       .oo++..   |
+----[SHA256]-----+

# ssh-keygen -t ed25519 -f ssh_host_ed25519_2022-01 -C "main server"
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ssh_host_ed25519_2022-01
Your public key has been saved in ssh_host_ed25519_2022-01.pub
The key fingerprint is:
SHA256:2p9K0giXv7WsRnLjwjs4hJ8EFcoX1FWR4nQz6fxnjxg main server
The key's randomart image is:
+--[ED25519 256]--+
|   .+o ...o+     |
| . .... o *      |
|  o..  o = o     |
|  ..   .. o      |
|   o. o S  .     |
|  . oo.*+   E o  |
|   + ++==..  = o |
|    = +oo= o. . .|
|     ..=+o=      |
+----[SHA256]-----+

记录指纹,供用户验证新密钥。

将新的密钥名称添加到 /etc/ssh/sshd_config,并取消注释任何正在使用的现有密钥

## Old keys
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_ecdsa_key

## New replacement keys
HostKey /etc/ssh/ssh_host_rsa_2022-01
HostKey /etc/ssh/ssh_host_ed25519_2022-01

保存你的更改,然后重新启动 sshd

# systemctl restart sshd.service

用户机器上的 /etc/ssh/ssh_config 文件必须包含以下设置

UpdateHostKeys ask
StrictHostKeyChecking yes

通过打开到服务器的 SSH 会话来接收新的密钥列表来测试从客户端连接。注销,然后重新登录。当你重新登录时,你应该看到类似以下消息

The server has updated its host keys.
These changes were verified by the server's existing trusted key.
Deprecating obsolete hostkey: ED25519
SHA256:V28d3VpHgjsCoV04RBCZpLo5c0kEslCZDVdIUnCvqPI
Deprecating obsolete hostkey:
RSA SHA256:+NR4DVdbsUNsqJPIhISzx+eqD4x/awCCwijZ4a9eP8I
Accept updated hostkeys? (yes/no):yes

你可以将 UpdateHostKeys ask 设置为 UpdateHostKeys yes 以自动应用更改,并避免要求用户批准更改。

更多信息

22.6 公钥身份验证 编辑源代码

公钥身份验证使用你自己的个人身份密钥进行身份验证,而不是用户帐户密码。

以下示例显示了如何创建一个新的个人 RSA 密钥对并添加注释,以便你知道它的用途。首先更改到你的 ~/.ssh 目录(如果不存在则创建它),然后创建新的密钥对。为其设置一个强大的密码短语,并将密码短语写在一个安全的地方

> cd ~/.ssh
> ssh-keygen -C "web server1" -f id-web1 -t rsa -b 4096

接下来,将你的新公钥复制到你想要访问的机器上。你必须在该机器上拥有一个用户帐户,并且具有 SSH 访问权限才能通过网络复制它

> ssh-copy-id -i id-web1 user@web1

然后尝试使用你的新密钥登录

> ssh -i id-web1 user@web1
Enter passphrase for key 'id-web1':
Last login: Sat Jul 11 11:09:53 2022 from 192.168.10.122
Have a lot of fun...

你应该会被要求输入你的私钥密码短语,而不是你的用户帐户的密码。

为了有效,应在远程机器上强制执行公钥身份验证,并且不允许密码身份验证(请参阅 示例 22.1,“示例 sshd_config”)。如果你尚未在远程机器上获得公钥身份验证访问权限,则无法使用 ssh-copy-id 复制你的新公钥,并且必须使用其他方式,例如手动将其从 USB 存储设备复制到远程用户帐户的 ~/.ssh/authorized_keys 文件。

22.7 无密码短语的公钥身份验证 编辑源代码

这是没有密码短语的公钥身份验证。创建你的新私钥,无需密码短语,然后以与受密码短语保护的密钥相同的方式使用它们。这对于自动化服务(例如脚本和 cron 作业)很有用。但是,如果有人成功窃取了私钥,他们可以很容易地冒充你,因此你需要保护无密码短语的私钥。

使用无密码密钥的替代方法是 gnome-keyring,它会记住并为你应用你的私钥和密码短语。gnome-keyring 适用于 GNOME 桌面会话(第 22.9 节,“使用 gnome-keyring 进行自动公钥登录”)。

对于控制台会话,请使用 ssh-agent第 22.10 节,“使用 ssh-agent 进行自动公钥登录”)。

22.8 OpenSSH 证书身份验证 编辑源代码

OpenSSH 在 OpenSSH 5.4 中引入了证书身份验证。证书身份验证类似于公钥身份验证,但主机和用户使用数字签名的加密证书相互身份验证,而不是加密密钥。证书身份验证提供对服务器和用户证书的集中管理,无需手动将用户公钥复制到多个主机。它通过赋予管理员更多控制权,减少用户控制权,从而提高安全性。

证书由公共加密密钥、用户定义的身份字符串、零个或多个用户名或主机名以及其他选项组成。用户和主机公钥由证书颁发机构 (CA) 私钥签名以创建加密证书。用户和主机信任公共 CA 密钥,而不是信任单个用户和主机公钥。

传统的 OpenSSH 公钥身份验证要求将用户公钥复制到他们需要访问的每个 SSH 服务器(到适当的 ~/.ssh/authorized_keys 文件),并依赖用户在接受新的 SSH 服务器主机密钥之前对其进行验证(存储在 ~/.ssh/known_hosts 中)。这容易出错且难以管理。另一个缺点是 OpenSSH 密钥永不过期。当你需要撤销特定的公钥时,你必须找到并删除网络上所有其副本。

自动化整个过程(例如,使用 Ansible)几乎是必要的。大型组织,例如 Meta(请参阅 https://engineering.fb.com/2016/09/12/security/scalable-and-secure-access-with-ssh/),完全自动化该过程,以便他们可以尽可能频繁地撤销和替换证书,甚至证书颁发机构,而不会中断操作。

一个先决条件是能够打开到网络上所有主机的 SSH 会话,并执行诸如编辑配置文件和重新启动 sshd 之类的任务。

设置 OpenSSH 证书颁发机构涉及以下步骤

  • 设置一个安全的受信任服务器来托管你的证书颁发机构,用于签名主机和用户密钥。创建用于签名密钥的新密钥对。私钥签名用户和主机密钥,并将公钥复制到允许访问服务器的所有用户。

  • 接收并签名主机公钥,然后将新的主机证书分发到它们各自的主机。主机证书位于 /etc/ssh 中,就像主机密钥一样。

  • 接收并签名用户公钥,然后将新的用户证书分发到其所有者。用户证书位于 ~/.ssh 中,就像用户密钥一样。

  • 编辑服务器和用户机器上的配置文件,并在主机上根据需要停止并启动 sshd

  • 根据需要撤销证书,例如,当你怀疑证书已被泄露、用户已离开你的组织或服务器已退役时。撤销证书比找到并删除所有相关的公钥副本要简单得多。

用户和服务器管理员创建和保护他们自己的 OpenSSH 密钥。安全地共享公钥是安全的。通过不安全的方法(例如电子邮件)传输新证书是安全的,因为它们需要其私钥才能验证。

SSH 证书遵循 OpenPGP 标准,而不是 SSL/TLS,并且证书格式为 OpenPGP,而不是 X.509。

22.8.1 设置新的证书颁发机构 编辑源代码

本节介绍如何设置新的证书颁发机构 (CA)。仔细考虑组织你的 CA,以使其易于管理和高效。

Important
重要提示:保护你的证书颁发机构

保护托管你的证书颁发机构的机器非常重要。你的 CA 实际上是整个网络的钥匙。任何获得访问 CA 的人都可以创建他们自己的证书并自由访问你的网络资源,甚至可以破坏你的服务器和 CA 本身。一种常见的做法是使用仅在你需要签名密钥时才启动的专用机器。

最佳实践是为服务器创建一个签名密钥,为客户端创建一个签名密钥。如果你有大量证书要管理,将 CA 用于主机和客户端放在不同的机器上可能会有所帮助。如果你更喜欢使用一台机器,请为每个 CA 创建自己的目录。本节中的示例使用 /ca-ssh-hosts/ca-ssh-users。示例机器是 ca.example.com

如果你的安全策略要求保留用户和主机公钥的副本,请将它们存储在自己的子目录中,以便更轻松地跟踪和避免密钥名称冲突。

Important
重要提示:RSA 签名密钥已弃用

OpenSSH 8.2,发布于 2020 年 2 月,已弃用 RSA 签名密钥。使用 Ed25519 或 ECDSA。

以下示例创建两个签名密钥,一个用于签名主机密钥,另一个用于用户密钥。请为它们设置强大的密码短语

> sudo ssh-keygen -t ed25519 -f /ca-ssh-hosts/ca-host-sign-key -C "signing key for host certificates"
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ca-host-sign-key
Your public key has been saved in ca-host-sign-key.pub
The key fingerprint is:
SHA256:STuQ7HgDrPcEa7ybNIW0n6kPbj28X5HN8GgwllBbAt0
 signing key for host certificates
The key's randomart image is:
+--[ED25519 256]--+
|      o+o..      |
|   . . o.=E      |
|    = + B .      |
|   + O + = B     |
|  . O * S = +    |
|   o B + o .     |
|    =o=   .      |
|   o.*+  .       |
|   .=.o+.        |
+----[SHA256]-----+
> sudo ssh-keygen -t ed25519 -f /ca-ssh-users/ca-user-sign-key -C "signing key for user certificates"
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ca-user-sign-key
Your public key has been saved in ca-user-sign-key.pub
The key fingerprint is:
SHA256:taYj8tTnjkzgfHRvQ6HTj8a37PY6rwv96V1x+GHRjIk signing key for user certificates
The key's randomart image is:
+--[ED25519 256]--+
|                 |
|             . +.|
|          . E o.o|
|         . + . ..|
|      . S * o .+.|
|     o + + = +..+|
|    . = * . O + o|
|     + = = o =oo+|
|      . o.o  oOX=|
+----[SHA256]-----+

将您的公共用户签名密钥(确保您复制的是公共密钥)复制到所有运行 SSH 服务器的主机的 /etc/ssh 中。然后在这些主机上将公共用户签名密钥的完整路径输入到 /etc/ssh/sshd_config

TrustedUserCAKeys /etc/ssh/ca-user-sign-key.pub

然后重启 sshd

22.8.2 创建主机证书 编辑源代码

以下示例对主机公钥进行签名,为数据库服务器创建主机证书

> sudo ssh-keygen -s /ca-ssh-hosts/ca-host-sign-key \
   -n venus,venus.example.com -I "db-server host cert" \
   -h -V +4w /etc/ssh/ssh_host_ed25519_key.pub
Enter passphrase:
Signed host key /etc/ssh/ssh_host_ed25519_key-cert.pub: id
"db-server host cert" serial 0 for venus,venus.example.com
valid from 2022-08-08T14:20:00 to 2022-09-05T15:21:19

如果服务器上有多个主机密钥,请全部签名。

  • -s 是您的私有签名密钥。

  • -n 是您的主体列表。对于主机证书,主体是机器的主机名和完全限定域名。

  • -I 是身份字符串。这是您想要的任何注释或描述。该字符串会被记录,以帮助您快速找到相关的日志条目。

  • -h 创建主机证书。

  • -V 设置证书的有效期。在示例中,证书在四周后过期。(有关允许的时间格式,请参阅 man 1 ssh-keygen 的“-V validity_interval”部分。)

验证您的新证书是否按照您想要的方式构建

> ssh-keygen -Lf /etc/ssh/ssh_host_ed25519_key-cert.pub
 /etc/ssh/ssh_host_ed25519_key-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com host certificate
        Public key: ED25519-CERT SHA256:/
         U7C+qABXYyuvueUuhFKzzVINq3d7IULRLwBstvVC+Q
        Signing CA: ED25519 SHA256:
         STuQ7HgDrPcEa7ybNIW0n6kPbj28X5HN8GgwllBbAt0 (using ssh-ed25519)
        Key ID: "db-server host cert"
        Serial: 0
        Valid: from 2022-08-08T14:20:00 to 2022-09-05T15:21:19
        Principals:
                venus
                venus.example.com
        Critical Options: (none)
        Extensions: (none)

将新主机证书的完整路径添加到 /etc/ssh/sshd_config,以便客户端可以使用它

HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

重启 sshd 以加载您的更改

> sudo systemctl restart sshd.service

请参阅 第 22.8.3 节,“CA 配置用于用户”,了解如何配置客户端以接受主机证书。

22.8.3 CA 配置用于用户 编辑源代码

以下示例显示如何配置客户端以信任您的 CA,而不是单个密钥。该示例授予对单个服务器的访问权限。此条目必须在用户的 ~/.ssh/known_hosts 文件中位于单行上。移动原始的 ~/.ssh/known_hosts 文件,并创建一个只包含 CA 配置的新文件。或者,在 /etc/ssh/ssh_known_hosts 中创建一个全局配置,这具有不让非特权用户编辑的优势

@cert-authority db,db.example.com ssh-ed25519
 AAAAC3NzaC1lZDI1NTE5AAAAIH1pF6DN4BdsfUKWuyiGt/leCvuZ/fPu
 YxY7+4V68Fz0 signing key for user certificates

以逗号分隔的列表列出用户允许访问的每个服务器,例如 venus,venus.example.com,saturn,saturn.example.com。您还可以授予对具有通配符的域中所有服务器的访问权限,例如 *.example.com,*.example2.com

尝试连接到服务器。您应该会被提示输入远程帐户的密码,而不会被提示验证主机证书。

22.8.4 创建用户证书 编辑源代码

对用户的公钥进行签名

> sudo ssh-keygen /ca-ssh-hosts/ca-user-sign-key -I "suzanne's cert" -n suzanne -V +52w user-key.pub
 Signed user key .ssh/ed25519key-cert.pub: id "suzanne's cert" serial 0
 for suzanne valid from 2022-09-14T12:57:00 to 2023-09-13T12:58:21

用户证书上的主体始终是用户名。将用户的证书存储在用户的机器上的 ~/.ssh 中。

用户证书取代了 ~/.ssh/authorized_keys 文件。从远程机器上的用户帐户中删除此文件,然后尝试打开到该帐户的 SSH 会话。您应该能够登录,而无需提示输入密码。(请记住,服务器应该在其 /etc/ssh/sshd_config 文件中有一行 TrustedUserCAKeys /etc/ssh/ca-user-sign-key.pub,以便服务器知道信任您的证书颁发机构。)

此外,查找您的日志文件中包含 Accepted publickey for suzanne 消息。

22.8.5 撤销主机密钥 编辑源代码

当您需要撤销证书,因为服务器已被攻破或退役时,请将证书的相应公钥添加到每个客户端上的文件中,例如 /etc/ssh/revoked_keys

ssh-ed25519-cert-v01@openssh.com
    AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIK6hyvFAhFI+0hkKehF/
    506fD1VdcW29ykfFJn1CPK9lAAAAIAawaXbbEFiQOAe5LGclrCHSLWbEeUauK5+CAuhTJyz0
    AAAAAAAAAAAAAAACAAAAE2RiLXNlcnZlciBob3N0IGNlcnQAAAAeAAAABXZlbnVzAAAAEXZl
    bnVzLmV4YW1wbGUuY29tAAAAAGMabhQAAAAAYz9YgQAAAAAAAAAAAAAAAAAAADMAAAALc3No
    LWVkMjU1MTkAAAAgfWkXoM3gF2x9Qpa7KIa3+V4K+5n98+5jFjv7hXrwXPQAAABTAAAAC3Nz
    aC1lZDI1NTE5AAAAQI+mbJsQjt/9bLiURse8DF3yTa6Yk3HpoE2uf9FW/
    KeLsw2wPeDv0d6jv49Wgr5T3xHYPf+VPJQW35ntFiHTlQg= root@db

此文件必须在 /etc/ssh/sshd_config 中命名

RevokedKeys /etc/ssh/revoked_keys

22.9 使用 gnome-keyring 实现自动公钥登录 编辑源代码

当安装 GNOME 桌面环境时,gnome-keyring 包默认安装并启用。gnome-keyring 与您的系统登录集成,在登录时自动解锁您的密钥存储。当您更改登录密码时,gnome-keyring 会自动使用您的新密码进行更新。

gnome-keyring 自动加载 ~/.ssh 中的所有密钥对,对于每个具有 *.pub 文件的密钥对。您可以使用 ssh-add 命令手动加载其他密钥,例如

> ssh-add ~/.otherkeys/my_key

列出所有已加载的密钥

> ssh-add -L

当您启动系统然后打开 SSH 会话时,系统会提示您输入私钥密码。

gnome-keyring 会记住密码,直到您的会话结束。在系统重启后,您才需要重新输入密码。

22.10 使用 ssh-agent 实现自动公钥登录 编辑源代码

openssh 包提供了 ssh-agent 实用程序,该实用程序保留您的私钥和密码短语,并在当前会话期间自动应用您的密码短语。

通过在您的 ~/.profile 文件中输入以下行来配置 ssh-agent 以自动启动并加载您的密钥

eval "$(ssh-agent)"
ssh-add

第一行启动 ssh-agent,第二行加载 ~/.ssh 文件夹中的所有密钥。当您打开需要公钥身份验证的 SSH 会话时,系统会提示您输入密码短语。在提供密码短语一次后,在您重新启动系统之前,您无需再次输入它。

您可以配置 ~/.profile 以仅加载特定的密钥,如下例所示,该例加载 id_rsaid_ed25519

> ssh-add id_rsa id_ed25519

22.10.1 在 X 会话中使用 ssh-agent 编辑源代码

openSUSE Leap 上,ssh-agent 由 GNOME 显示管理器自动启动。要同时调用 ssh-add 以在 X 会话开始时将您的密钥添加到代理,请执行以下操作

  1. 以所需的用户名登录,并检查文件 ~/.xinitrc 是否存在。

  2. 如果它不存在,请使用现有模板或从 /etc/skel 复制它

    if [ -f ~/.xinitrc.template ]; then mv ~/.xinitrc.template ~/.xinitrc; \
    else cp /etc/skel/.xinitrc.template ~/.xinitrc; fi
  3. 如果您已复制模板,请搜索以下行并取消注释它们。如果 ~/.xinitrc 已经存在,请添加以下行(不要带注释符号)。

    # if test -S "$SSH_AUTH_SOCK" -a -x "$SSH_ASKPASS"; then
    #       ssh-add < /dev/null
    # fi
  4. 当启动新的 X 会话时,系统会提示您输入 SSH 密码短语。

22.11 更改 SSH 私钥密码短语 编辑源代码

您可以使用 ssh-keygen 更改或删除私钥的密码短语

> ssh-keygen -pf ~/.ssh/server1
Enter old passphrase:
Key has comment 'shared videos server1'
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.

22.12 检索密钥指纹 编辑源代码

使用 ssh-keygen 显示公钥指纹。以下示例打印 ED25519 密钥的 SHA256 哈希值

> ssh-keygen -lf ldap-server
256 SHA256:W45lbmj24ZoASbrqW0q9+NhF04muvfKZ+FkRa2cCiqo comment (ED25519)

添加 -v 标志以显示密钥的 ASCII 艺术表示形式

> ssh-keygen -lvf ldap-server
256 SHA256:W45lbmj24ZoASbrqW0q9+NhF04muvfKZ+FkRa2cCiqo comment (ED25519)
+--[ED25519 256]--+
|                 |
|                 |
|    .. .         |
|  .o..+ +        |
| ...o+ BSo+      |
|. ..o.o =X       |
|...o o..* =      |
|o.*.* =+ = .     |
|E*o*+O. o.o      |
+----[SHA256]-----+

22.13 在远程主机上启动 X11 应用程序 编辑源代码

您可以在本地计算机上运行安装在远程机器上的图形应用程序。X11Forwarding Yes 必须在远程机器上的 /etc/ssh/sshd_config 文件中设置。然后,当您使用 -X 选项运行 ssh 时,DISPLAY 变量会自动在远程机器上设置,并且所有 X 输出都会通过 SSH 连接导出到本地机器。同时,远程启动的 X 应用程序不能被未经授权的用户拦截。

一个快速测试是在远程机器上运行一个简单的游戏,例如 GNOME Mines

> ssh wilber@sun
Password:
Last login: Tue May 10 11:29:06 2022 from 192.168.163.13
Have a lot of fun...

wilber@sun>  gnome-mines

远程应用程序应该出现在您的本地机器上,就像它本地安装一样。(网络延迟会影响性能。)以通常的方式关闭远程应用程序,例如单击关闭按钮。这将仅关闭应用程序,而您的 SSH 会话将保持打开状态。

Important
重要提示:X11 转发在 Wayland 上不起作用

X11 转发需要在远程主机上运行 X Window System。X Window System 具有内置的网络功能,而 Wayland 则没有。因此 Wayland 不支持 X11 转发。

使用以下命令来了解您的系统是否运行 X 或 Wayland

> echo $XDG_SESSION_TYPE
x11

如果使用 Wayland,则如下所示

> echo $XDG_SESSION_TYPE
wayland

systemd 的方法是使用 loginctl 查询

> loginctl show-session "$XDG_SESSION_ID" -p Type
Type=x11

> loginctl show-session "$XDG_SESSION_ID" -p Type
Type=wayland

22.14 代理转发 编辑源代码

通过添加 -A 选项,ssh-agent 身份验证机制会传递到下一台机器。这样,您就可以在不同的机器上工作,而无需输入密码,但前提是您已将您的公钥分发到目标主机并正确保存了它。(请参阅 第 22.6 节,“公钥身份验证”,了解如何将您的公钥复制到其他主机。)

AllowAgentForwarding yes/etc/ssh/sshd_config 中的默认设置。将其更改为 No 以禁用它。

22.15 scp—安全复制 编辑源代码

scp 将文件复制到或从远程机器。如果 jupiter 上的用户名与 sun 上的用户名不同,则使用 USER_NAME&host 格式指定后者。如果应将文件复制到远程用户主目录以外的目录中,则指定 sun:DIRECTORY。以下示例显示如何将文件从本地复制到远程机器,反之亦然。

> scp ~/MyLetter.tex tux@sun:/tmp 1
> scp tux@sun:/tmp/MyLetter.tex ~ 2

1

本地到远程

2

远程到本地

Tip
提示:-l 选项

使用 ssh 命令时,-l 选项可用于指定远程用户(作为 USER_NAME&host 格式的替代方案)。使用 scp-l 选项用于限制 scp 消耗的带宽。

在输入正确的密码后,scp 开始数据传输。它显示一个进度条和每个已复制文件的剩余时间。使用 -q 选项抑制所有输出。

scp 还提供了一个递归复制功能,用于复制整个目录。该命令

> scp -r src/ sun:backup/

将目录 src 的整个内容(包括所有子目录)复制到主机 sun 上的 ~/backup 目录。如果此子目录不存在,则会自动创建它。

-p 选项告诉 scp 保持文件的时间戳不变。-C 压缩数据传输。这最大限度地减少了要传输的数据量,但会给两台机器的处理器带来更大的负担。

22.16 sftp—安全文件传输 编辑源代码

22.16.1 使用 sftp 编辑源代码

要将多个文件从或到不同的位置复制,sftpscp 的便捷替代方案。它打开一个具有类似于常规 FTP shell 的一组命令的 shell。在 sftp 提示符处键入 help 以获取可用命令的列表。有关更多详细信息,请参阅 sftp man 页面。

> sftp sun
Enter passphrase for key '/home/tux/.ssh/id_rsa':
Connected to sun.
sftp> help
Available commands:
bye                                Quit sftp
cd path                            Change remote directory to 'path'
[...]

22.16.2 设置文件上传权限 编辑源代码

就像一个普通的 FTP 服务器一样,用户可以使用 put 命令将文件下载和上传到运行 SFTP 服务器的远程机器。默认情况下,文件会以与本地主机相同的权限上传到远程主机。有两种选项可以自动更改这些权限

设置 umask

umask 作为本地主机上原始文件权限的过滤器工作。它只能撤销权限

原始权限

umask

上传权限

0666

0002

0664

0600

0002

0600

0775

0025

0750

要在 SFTP 服务器上应用 umask,请编辑文件 /etc/ssh/sshd_configuration。搜索以 Subsystem sftp 开头的行,并添加带有所需设置的 -u 参数,例如

Subsystem sftp /usr/lib/ssh/sftp-server -u 0002
显式设置权限

显式设置权限为通过 SFTP 上传的所有文件设置相同的权限。使用 -u 指定三位数字模式,例如 600644755。如果同时指定了 -m-u,则忽略 -u

要在 SFTP 服务器上应用上传文件的显式权限,请编辑文件 /etc/ssh/sshd_config。搜索以 Subsystem sftp 开头的行,并添加带有所需设置的 -m 参数,例如

Subsystem sftp /usr/lib/ssh/sftp-server -m 600
Tip
提示:查看 SSH 守护进程日志文件

要查看 sshd 的日志条目,请使用以下命令

> sudo journalctl -u sshd

22.17 端口转发 (SSH 隧道) 编辑源文件

ssh 也可以用于重定向 TCP/IP 连接。此功能,也称为 SSH 隧道,通过加密通道将 TCP 连接重定向到另一个机器上的某个端口。

使用以下命令,任何定向到 jupiter 端口 25 (SMTP) 的连接都会被重定向到 sun 上的 SMTP 端口。这对于那些使用没有 SMTP-AUTH 或 POP-before-SMTP 功能的 SMTP 服务器的用户来说尤其有用。从连接到网络的任意位置,可以通过电子邮件将邮件传输到 邮件服务器进行发送。

# ssh -L 25:sun:25 jupiter

类似地,可以使用此命令将 jupiter 上的所有 POP3 请求 (端口 110) 转发到 sun 的 POP3 端口

# ssh -L 110:sun:110 jupiter

这两个命令必须以 root 的身份执行,因为连接是到特权本地端口建立的。电子邮件由正常用户在现有的 SSH 连接中发送和接收。要使此工作正常,SMTP 和 POP3 主机必须设置为 localhost。有关更多信息,请参阅上述每个程序的手册页以及 OpenSSH 包文档下的 /usr/share/doc/packages/openssh

22.18 更多信息 编辑源文件

https://www.openssh.com

OpenSSH 的主页

https://wikibooks.cn/wiki/OpenSSH

OpenSSH Wikibook

man sshd

OpenSSH 守护进程的手册页

man ssh_config

OpenSSH SSH 客户端配置文件手册页

man scp , man sftp , man ssh , man ssh-add , man ssh-copy-id , man ssh-keygen

安全复制文件 (scp, sftp)、登录 (slogin, ssh) 以及管理密钥的几个二进制文件的手册页。

/usr/share/doc/packages/openssh-common/README.SUSE

SUSE 包特定的文档;相对于上游的默认值更改等。

22.19 使用 Fail2Ban 阻止 SSH 暴力破解攻击 编辑源文件

SSH 暴力破解攻击涉及重复尝试用户名和密码组合,直到攻击者获得对远程服务器的访问权限。攻击者使用自动化工具测试各种用户名和密码组合来破坏服务器。

您可以使用 Fail2Ban 软件来限制入侵尝试。Fail2Ban 扫描系统日志以检测攻击并触发操作,例如通过防火墙阻止 IP。Fail2Ban 仅用于保护需要用户名和密码身份验证的服务。

22.19.1 什么是 Fail2Ban? 编辑源文件

Fail2Ban 扫描 /var/log/apache/error_log 中的日志文件,并禁止指示恶意迹象的 IP,例如过多的密码尝试等。然后,您可以使用 Fail2Ban 更新防火墙规则以拒绝指定时间段内的 IP 地址。

Fail2Ban 附带各种服务的过滤器,例如 Apache、SSH、Courier 等。您可以使用 Fail2Ban 来最大限度地减少不正确的身份验证尝试速率。

22.19.2 使用 Fail2Ban 阻止 SSH 暴力破解攻击 编辑源文件

您可以安装和配置 Fail2Ban 以保护服务器免受 SSH 暴力破解攻击。

Procedure 22.2: 使用 Fail2Ban 阻止 SSH 暴力破解攻击
  1. 要安装 Fail2Ban,请执行

    # sudo zypper -n in fail2ban firewalld
  2. 安装 Fail2Ban 时,还会安装默认配置文件 jail.conf。Fail2Ban 升级时会覆盖此文件。要保留您对文件所做的任何自定义设置,您可以将修改添加到名为 jail.local 的文件中。Fail2Ban 会自动读取这两个文件。

    # cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
  3. 在您的编辑器中打开该文件。

    vi /etc/fail2ban/jail.local
  4. 查看您需要了解的四个设置。

    Fail2Ban settings
    Figure 22.1: jail.local 文件设置
    ignoreip

    一个白名单 IP 列表,永远不会被禁止。默认情况下,本地主机 IP 地址 127.0.0.1 位于列表中,以及 IPv6 等效地址 ::1。您可以使用此设置添加您知道不应被禁止的 IP 地址列表。

    bantime

    IP 地址被禁止的分钟数。如果您输入的数值不以 mh 结尾,则将其视为秒数。如果您输入的值为 -1,则 IP 地址将被永久禁止。

    findtime

    在其中太多的失败连接尝试导致 IP 被禁止的时间段。

    maxretry

    失败尝试的限制数量。

    Note
    注意

    如果来自同一 IP 地址的连接在 findtime 期间进行 maxretry 次失败连接尝试,则它们将在 bantime 期间被禁止。唯一的例外是 ignoreip 列表中的 IP 地址。

    Fail2Ban 支持不同类型的 jail,每个 jail 都有针对连接类型的不同设置。

  5. 您可以使用以下命令使用 Fail2Ban 服务

    启用

    #  systemctl enable fail2ban

    启动

    #  systemctl start fail2ban

    检查服务状态

    #  systemctl status fail2ban.service
    Important
    重要提示

    每次进行配置更改时,都必须重新启动 Fail2Ban。

打印此页面