使用 SSH 连接远程 Linux 服务器

LinuxBeginner
立即练习

介绍

在本实验中,你将学习使用安全外壳(SSH)协议连接和管理远程 Linux 服务器的核心技能。你将从搭建远程环境开始,包括安装和配置 OpenSSH 服务器软件包。在确保服务器准备好接收连接后,你将学习如何获取其 IP 地址,这是从客户端机器建立连接的关键步骤。

服务器配置完成后,你将练习通过 SSH 进行远程交互的两种主要方法。首先,你将建立一个完全交互式的 Shell 会话,从而获得对远程机器的完整命令行访问权限。其次,你将学习如何在不启动完整交互式会话的情况下,在远程服务器上执行特定的单个命令,这种技术在脚本编写和自动化任务中非常高效。

这是一个引导实验,提供分步指导以帮助你学习和练习。请仔细遵循说明完成每个步骤并获得实践经验。历史数据表明,这是一个初学者级别的实验,完成率为 99%。它获得了学习者 99% 的好评率。

安装并配置 OpenSSH 服务器

在这一步中,你将安装 OpenSSH 服务器软件包,它允许你的系统接收传入的 SSH 连接。SSH(Secure Shell)是一种加密网络协议,用于在不安全的网络上安全地运行网络服务。openssh-server 软件包包含了托管 SSH 服务器的核心组件。

首先,更新系统的软件包列表是一个好习惯,以确保你获取到最新版本的软件。labex 用户拥有 sudo 权限,这是进行系统级软件包管理所必需的。

运行以下命令来更新软件包索引:

sudo apt-get update

你将看到类似以下的输出,表明正在从仓库中获取软件包列表:

Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
...
Fetched 1,845 kB in 2s (1,040 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up-to-date.

现在,你可以使用 apt-get 安装 openssh-server 软件包。-y 标志会自动对所有提示回答「是」,从而实现非交互式安装。

sudo apt-get install -y openssh-server

命令完成后,你应该会看到确认安装和设置 openssh-server 及其依赖项的输出:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  ncurses-term openssh-sftp-server ssh-import-id
...
Setting up openssh-server (1:8.9p1-3ubuntu0.1) ...
...
Creating SSH2 ECDSA key; this may take some time ...
Creating SSH2 ED25519 key; this may take some time ...
...

名为 sshd 的 OpenSSH 服务器服务在安装后应自动启动。你可以使用 systemctl 命令验证其状态,该命令是用于控制 systemd 系统和服务管理器的工具。

检查 SSH 服务状态:

sudo systemctl status ssh

输出应显示该服务为 active (running)。这确认了 SSH 服务器已准备好接收连接。

● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-10-30 10:30:00 UTC; 5s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1234 (sshd)
      Tasks: 1 (limit: 4617)
     Memory: 1.2M
        CPU: 8ms
     CGroup: /system.slice/ssh.service
             └─1234 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

...

按下键盘上的 q 键退出状态视图并返回命令行提示符。

太棒了!OpenSSH 服务器现在已在你的系统上安装并运行。在下一步中,你将创建一个用于 SSH 演示的新用户,然后学习如何查找服务器的 IP 地址并连接到它。

创建用于 SSH 演示的新用户

在这一步中,你将创建一个新的用户账户,用于 SSH 连接。由于默认的 labex 用户虽然拥有 sudo 权限,但我们不知道其用于 SSH 身份验证的密码,因此我们需要为此演示创建一个已知密码的专用用户。

首先,使用 adduser 命令创建一个名为 sshuser 的新用户。此命令将创建用户账户并提示你设置密码和其他详细信息。

sudo adduser sshuser

系统会提示你为新用户输入并确认密码。在本实验中,请使用 password123 作为密码。系统还会询问全名、房间号等额外信息,你可以直接按回车键跳过这些字段。

Adding user `sshuser' ...
Adding new group `sshuser' (1001) ...
Adding new user `sshuser' (1001) with group `sshuser' ...
Creating home directory `/home/sshuser' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for sshuser
Enter the new value, or press ENTER for the default
 Full Name []:
 Room Number []:
 Work Phone []:
 Home Phone []:
 Other []:
Is the information correct? [Y/n] Y

现在通过检查 /etc/passwd 文件来验证用户是否创建成功:

grep sshuser /etc/passwd

你应该看到类似以下的输出:

sshuser:x:1000:1000:,,,:/home/sshuser:/bin/bash

这确认了 sshuser 账户已创建,其家目录位于 /home/sshuser,并使用 bash shell。具体的 UID(用户 ID)和 GID(组 ID)数字可能会根据系统上已有的用户而有所不同。

你还可以验证用户的家目录是否已创建。请注意,你需要 sudo 权限才能访问另一个用户的家目录:

sudo ls -la /home/sshuser

输出应显示该用户家目录的内容:

total 20
drwxr-x--- 2 sshuser sshuser 4096 Jun 30 09:26 .
drwxr-xr-x 5 root    root    4096 Jun 30 09:26 ..
-rw-r--r-- 1 sshuser sshuser  220 Jun 30 09:26 .bash_logout
-rw-r--r-- 1 sshuser sshuser 3771 Jun 30 09:26 .bashrc
-rw-r--r-- 1 sshuser sshuser  807 Jun 30 09:26 .profile

请注意,家目录具有受限权限(drwxr-x---),这意味着只有所有者(sshuser)和同组用户可以访问它。这就是为什么需要 sudo 才能列出其内容的原因。

完美!你现在拥有一个用户账户 sshuser,密码为 password123,可以在接下来的步骤中用于 SSH 连接。

获取 SSH 服务器的 IP 地址

在这一步中,你将学习如何查找 SSH 服务器的 IP 地址。IP 地址是分配给连接到使用互联网协议进行通信的计算机网络中每个设备的唯一数字标签。要建立 SSH 连接,客户端机器需要知道它想要连接的服务器的 IP 地址。

在典型的双机场景中,你会使用此 IP 地址从客户端进行连接。但是,在本实验中,你在单个虚拟机上操作,该机器将同时充当 SSH 服务器和 SSH 客户端。要连接到运行在你自己机器上的 SSH 服务器,你可以使用一个特殊的 IP 地址 127.0.0.1,也称为 localhost(本地主机)。此地址始终指向本地机器本身。

即便如此,了解如何查找机器面向网络的 IP 地址也是一项基本技能。在 Linux 中,用于此操作的现代命令是 ip

要显示系统中所有网络接口的信息,请使用 ip addr 命令:

ip addr

输出将列出所有网络接口,例如 lo(回环接口)、eth0(主要以太网接口),可能还有 docker0(Docker 桥接接口)。你需要查找主网络接口(通常是 eth0)下的 inet 条目。

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:01:82:ae brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 172.16.50.114/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
       valid_lft 1892159625sec preferred_lft 1892159625sec
    inet6 fe80::216:3eff:fe01:82ae/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:86:fe:f0:88 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

在上面的示例中,eth0 接口的主要 IP 地址是 172.16.50.114。如果系统上安装了 Docker,你可能还会看到 docker0 接口。

一个仅显示机器 IP 地址的更简单的命令是 hostname -I

hostname -I

此命令将打印机器 IP 地址的空格分隔列表。

172.16.50.114 172.17.0.1

输出显示了多个 IP 地址:主网络接口 IP(172.16.50.114)和 Docker 桥接 IP(172.17.0.1)。

现在你已经知道如何查找机器的 IP 地址了。在下一步中,你将使用 localhost 地址(127.0.0.1)连接到运行在同一台机器上的 SSH 服务器。

建立到远程服务器的交互式 SSH 会话

在这一步中,你将使用 ssh 客户端与你配置的 OpenSSH 服务器建立交互式会话。交互式会话会在远程服务器上为你提供一个命令行提示符,允许你像物理登录到该服务器一样执行命令。

要进行连接,你需要使用 ssh 命令,后跟用户名和服务器地址,格式为 ssh <user>@<hostname_or_ip>。由于你是以 sshuser 用户身份连接到运行在你自己机器(localhost)上的服务器,因此你将使用 IP 地址 127.0.0.1

打开终端并运行以下命令:

ssh sshuser@127.0.0.1

当你第一次连接到任何新的 SSH 服务器时,你的 SSH 客户端会显示该服务器的公钥指纹,并要求你确认其真实性。这是一种防止「中间人」攻击的安全措施。你应该输入 yes 并按回车键继续。

The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '127.0.0.1' (ED25519) to the list of known hosts.

确认主机密钥后,系统会提示你输入远程服务器上 sshuser 用户的密码。输入你在创建用户时设置的密码 password123

sshuser@127.0.0.1's password:

输入正确的密码后,你将登录并看到服务器的欢迎消息和新的命令行提示符。请注意提示符可能会发生变化,以指示你当前处于远程主机上。

Welcome to Ubuntu 22.04.x LTS (GNU/Linux x.x.x-xx-generic x86_64)

* Documentation:  https://help.ubuntu.com
* Management:     https://landscape.canonical.com
* Support:        https://ubuntu.com/advantage

sshuser@ubuntu:~$

要确认你处于远程会话中,可以运行 pwd 等命令来打印当前工作目录。

pwd

输出将显示你在远程机器上的家目录。

/home/sshuser

要关闭交互式 SSH 会话并返回本地机器的 Shell,只需输入 exit 并按回车键。

exit

你将看到一条确认连接已关闭的消息,并且你原来的命令行提示符将恢复。

logout
Connection to 127.0.0.1 closed.

你现在已成功建立并关闭了一个交互式 SSH 会话。

通过 SSH 远程执行单个命令

在这一步中,你将学习如何在不启动完整交互式会话的情况下,在远程服务器上执行单个命令。这是 SSH 的一个强大功能,广泛用于脚本和自动化,因为它允许你快速获取信息或在远程机器上执行任务,然后立即断开连接。

其语法是简单地将你希望运行的命令附加到通常的 ssh 连接字符串末尾。将远程命令括在引号中是一个好习惯,可以防止本地 Shell 对其进行解析。

让我们尝试在远程服务器上运行 hostname 命令。此命令会打印系统的网络主机名。

ssh sshuser@127.0.0.1 "hostname"

系统会像之前一样提示你输入密码(password123)。输入后,hostname 命令将在远程服务器上执行,其输出将打印到你的终端,并且 SSH 连接将自动关闭。

sshuser@127.0.0.1's password:
iZrj91w6gb8osv0mra83hdZ

请注意,你立即返回到了本地命令行提示符,而无需输入 exit

你也可以执行更复杂的命令。例如,让我们使用 ls -l / 列出远程服务器上根目录(/)的内容。

ssh sshuser@127.0.0.1 "ls -l /"

同样,在提示时输入密码 password123。输出将是远程服务器根文件系统中文件和目录的详细列表。

sshuser@127.0.0.1's password:
total 72
lrwxrwxrwx   1 root root     7 Apr 21  2022 bin -> usr/bin
drwxr-xr-x   4 root root  4096 May 30  2023 boot
drwxr-xr-x  19 root root  4080 Jun 30 09:23 dev
drwxr-xr-x 137 root root 12288 Jun 30 09:26 etc
drwxr-xr-x   5 root root  4096 Jun 30 09:26 home
lrwxrwxrwx   1 root root     7 Apr 21  2022 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Apr 21  2022 lib32 -> usr/lib32
lrwxrwxrwx   1 root root     9 Apr 21  2022 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    10 Apr 21  2022 libx32 -> usr/libx32
drwx------   2 root root 16384 Dec 28  2022 lost+found
drwxr-xr-x   2 root root  4096 Apr 21  2022 media
drwxr-xr-x   2 root root  4096 Apr 21  2022 mnt
drwxr-xr-x   5 root root  4096 Feb 27  2023 opt
dr-xr-xr-x 231 root root     0 Jun 30 09:22 proc
drwx------   8 root root  4096 Jun 30 09:26 root
drwxr-xr-x  35 root root  1060 Jun 30 09:30 run
lrwxrwxrwx   1 root root     8 Apr 21  2022 sbin -> usr/sbin
drwxr-xr-x  10 root root  4096 Feb 18  2023 snap
drwxr-xr-x   2 root root  4096 Apr 21  2022 srv
dr-xr-xr-x  13 root root     0 Jun 30 09:22 sys
drwxrwxrwt  18 root root  4096 Jun 30 09:30 tmp
drwxr-xr-x  14 root root  4096 Apr 21  2022 usr
drwxr-xr-x  13 root root  4096 Apr 21  2022 var

这种方法对于管理多台服务器或将远程操作集成到本地 Shell 脚本中非常高效。你现在已经学习了使用 SSH 的两种主要方式:交互式会话和单命令执行。

总结

在本实验中,你学习了启用和使用安全外壳(SSH)进行远程服务器管理的基本步骤。你首先准备了远程 Linux 服务器,包括使用 sudo apt-get update 更新软件包仓库索引,然后安装 openssh-server 软件包。此过程配置了系统以安全地接收传入的 SSH 连接,并自动启动了 sshd 服务。

接着,你创建了一个具有已知密码(password123)的专用用户账户(sshuser)用于 SSH 身份验证,因为默认的 labex 用户虽然有 sudo 权限,但没有用于 SSH 连接的密码。你验证了用户的创建并确认家目录已正确建立。

在服务器和用户账户准备就绪后,你学习了如何获取服务器的 IP 地址,这是任何客户端发起连接的关键信息。随后,你练习了使用 SSH 的两种主要方式:建立完整的交互式命令行会话以直接在远程服务器上工作,以及远程执行单个非交互式命令,这在脚本编写和自动化任务中非常高效。