使用 SSH 连接远程 Linux 服务器

LinuxBeginner
立即练习

简介

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

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

安装并配置 OpenSSH 服务器

在此步骤中,你将安装 OpenSSH 服务器软件包,它允许你的系统接受传入的 SSH 连接。SSH 是一种加密网络协议,用于在不安全的网络上安全地操作网络服务。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 标志会自动对所有提示回答“yes”,从而使安装过程无需人工干预。

sudo apt-get install -y openssh-server

在某些 LabEx 环境中,Ubuntu 可能会在安装过程中显示服务重启对话框。如果发生这种情况,请不要重启 vncserver,因为重启它可能会导致浏览器桌面断开连接并使页面变灰。请改用以下安全选项之一:

  • Tab 键选择 <Cancel>,然后按回车键。
  • 或者按 Space 键取消勾选 vncserver,然后选择 <Ok>

如果浏览器桌面仍然变灰,请刷新 LabEx 页面以重新连接到会话并继续实验。

命令完成后,你应该会看到确认安装并设置 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 的两种主要方式:建立完整的交互式命令行会话以直接在远程服务器上工作,以及远程执行单个非交互式命令,这对于脚本编写和自动化任务非常高效。