Ubuntu 安装 SSH 详细教程:远程管理的强大基石(超详细版)
前言
在现代计算机网络环境中,远程管理服务器、执行命令、传输文件是日常工作中不可或缺的部分。对于广泛应用于服务器和开发环境的 Ubuntu 操作系统而言,安全壳协议(Secure Shell,简称 SSH)无疑是实现这些功能的最佳工具。SSH 提供了加密的通信通道,确保数据传输的机密性和完整性,极大地提高了远程操作的安全性。
本篇文章将提供一个极其详细的 Ubuntu 系统安装和配置 OpenSSH 服务器的教程。我们将从零开始,涵盖 SSH 的基本概念、安装过程、服务管理、防火墙配置、基础安全设置,以及更高级但至关重要的密钥认证方式。无论您是刚接触 Linux 的新手,还是希望系统性巩固 SSH 知识的进阶用户,本文都将为您提供清晰、可操作的指导。
预计阅读时间较长,请耐心跟随步骤操作。掌握 SSH 的安装与配置,将为您打开安全高效的远程管理之门。
文章结构概述:
- 什么是 SSH?为什么使用 SSH?
- 准备工作:系统环境与权限
- 检查 SSH 客户端和服务器状态
- 安装 OpenSSH 服务器
- 验证 SSH 服务状态
- 配置防火墙(UFW)允许 SSH 连接
- SSH 服务器基础配置 (
sshd_config
)- 文件位置与编辑
- 修改默认端口
- 禁用 Root 用户登录(强烈建议)
- 禁用密码认证(强烈建议,结合密钥认证)
- 其他重要配置项(监听地址、登录超时、最大认证尝试次数等)
- 应用配置更改
- 增强安全性:使用 SSH 密钥进行认证
- 为什么使用密钥认证?
- 在客户端生成 SSH 密钥对
- 将公钥上传到服务器
- 配置服务器只允许密钥认证
- 使用密钥连接 SSH
- SSH 连接基础:客户端使用
- 常见问题与故障排除
- 连接被拒绝(Connection refused)
- 权限被拒绝(Permission denied)
- 防火墙问题
- SSH 服务未运行
- 配置错误
- 进阶安全建议
- 定期更新 SSH
- 使用 Fail2Ban 防御暴力破解
- 使用非标准端口(有限建议)
- 限制用户或组的访问
- 总结
1. 什么是 SSH?为什么使用 SSH?
SSH (Secure Shell) 是一种加密的网络协议,用于在不安全的网络中安全地执行网络服务。最常见的用途是远程登录到计算机并执行命令行操作,但它也可以用于安全地传输文件(如 SCP 和 SFTP)、隧道化其他协议或端口转发。
为什么使用 SSH?
- 安全性: 这是 SSH 最核心的优势。与 Telnet、Rlogin 等未加密的远程登录协议不同,SSH 对所有传输的数据进行加密,包括登录密码、执行的命令、命令的输出等。这有效地防止了中间人攻击、嗅探和数据泄露。
- 远程管理: 允许您从任何地方安全地连接到服务器,进行系统维护、软件安装、故障排除等操作,无需物理接触服务器。
- 文件传输: SCP (Secure Copy Protocol) 和 SFTP (SSH File Transfer Protocol) 允许您在本地和远程系统之间安全地复制和移动文件,它们都基于 SSH 协议。
- 端口转发/隧道: SSH 可以创建安全隧道,将其他网络服务的流量通过 SSH 连接转发,即使这些服务本身不安全(如访问内部网络的数据库)。
- 自动化: SSH 可以通过密钥认证实现无密码登录,这对于脚本自动化、配置管理工具(如 Ansible, Chef, Puppet)以及持续集成/持续部署 (CI/CD) 流程至关重要。
在 Ubuntu 系统中,SSH 的实现通常由 OpenSSH 项目提供,它包含 openssh-client
(客户端)和 openssh-server
(服务器端)。本文主要关注 openssh-server
的安装和配置。
2. 准备工作:系统环境与权限
在开始安装之前,请确保您具备以下条件:
- 一台运行 Ubuntu 的计算机或虚拟机: 可以是桌面版或服务器版。本文以 Ubuntu Server 为例,但大部分步骤同样适用于桌面版。
- 互联网连接: 用于下载安装包。
- Sudo 权限: 您需要一个具有执行
sudo
命令权限的用户账户来安装软件包和修改系统配置。
重要提示: 如果您是通过其他远程方式(如物理控制台、其他远程桌面工具)连接到这台 Ubuntu 机器进行 SSH 服务器安装,请务必在配置防火墙或进行其他可能中断网络连接的操作时小心,以免将自己锁定在系统之外。如果您是通过现有的 SSH 连接执行这些步骤,请格外注意,强烈建议在修改防火墙规则前先添加允许当前 SSH 连接的规则,或者保持一个额外的物理/虚拟机控制台会话作为备用。
3. 检查 SSH 客户端和服务器状态
在安装服务器之前,我们先检查一下系统是否已经安装了 SSH 客户端或服务器。Ubuntu 在安装时,尤其是服务器版,可能会默认安装 SSH 客户端,甚至有时会安装服务器端。
打开终端,输入以下命令:
bash
dpkg -l openssh-client
dpkg -l openssh-server
dpkg -l
命令用于列出已安装的软件包。openssh-client
是 SSH 客户端软件包。openssh-server
是 SSH 服务器软件包。
命令输出解释:
- 如果软件包已安装,输出会类似这样,其中状态码通常为
ii
(installed):
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-============================================
ii openssh-client 1:8.2p1-4 amd64 secure shell (SSH) client, for secure access to remote machines - 如果软件包未安装,输出会显示找不到匹配项,类似这样:
dpkg-query: no packages found matching openssh-server
根据您的需求,如果您只需要连接到其他 SSH 服务器,只需要 openssh-client
。如果您希望其他机器连接到这台 Ubuntu,您需要安装 openssh-server
。
检查 SSH 服务是否正在运行(如果 openssh-server
已安装):
bash
sudo systemctl status ssh
或者(对于较旧的 Ubuntu 版本):
bash
sudo service ssh status
- 如果服务正在运行,您会看到 “active (running)” 的字样。
- 如果服务没有运行,可能会显示 “inactive (dead)” 或其他非活动状态。
- 如果软件包未安装,会提示找不到服务。
4. 安装 OpenSSH 服务器
如果 openssh-server
尚未安装,或者您想确保安装的是最新版本,可以使用以下命令进行安装。首先,建议更新软件包列表以获取最新的可用版本信息:
bash
sudo apt update
接下来,安装 openssh-server
软件包:
bash
sudo apt install openssh-server
apt
是 Ubuntu 中用于管理软件包的命令行工具。install
命令会下载并安装指定的软件包及其依赖项。
在安装过程中,系统可能会提示您确认安装并询问是否使用额外的磁盘空间。输入 Y
并按 Enter 键继续。
安装完成后,OpenSSH 服务器服务 (sshd
) 通常会随之启动。
5. 验证 SSH 服务状态
安装完成后,再次使用 systemctl
命令检查 SSH 服务的状态,确认它是否正在运行。
bash
sudo systemctl status ssh
理想情况下,您应该看到类似以下的输出,其中 active (running)
表示服务正在正常运行:
“`
● ssh.service – OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2023-10-26 10:00:00 UTC; 1 day ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1234 (sshd)
Tasks: 1 (limit: 4915)
Memory: 3.5M
CPU: 0.123s
CGroup: /system.slice/ssh.service
└─1234 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
Oct 26 10:00:00 ubuntu systemd[1]: Starting OpenBSD Secure Shell server…
Oct 26 10:00:00 ubuntu sshd[1234]: Server listening on 0.0.0.0 port 22.
Oct 26 10:00:00 ubuntu sshd[1234]: Server listening on :: port 22.
Oct 26 10:00:00 ubuntu systemd[1]: Started OpenBSD Secure Shell server.
…
“`
服务管理命令:
除了查看状态,您还需要知道如何启动、停止和重启 SSH 服务:
- 启动服务:
sudo systemctl start ssh
- 停止服务:
sudo systemctl stop ssh
- 重启服务:
sudo systemctl restart ssh
(在修改配置文件后常用) - 重载配置:
sudo systemctl reload ssh
(部分配置修改后可以使用,更平滑,不中断现有连接,但不是所有修改都支持) - 设置开机自启:
sudo systemctl enable ssh
(通常安装时已默认设置) - 禁止开机自启:
sudo systemctl disable ssh
默认情况下,安装 openssh-server
后,服务会自动启动并设置为开机自启。
6. 配置防火墙(UFW)允许 SSH 连接
在 Ubuntu 中,默认的防火墙管理工具是 UFW (Uncomplicated Firewall)。为了允许外部机器连接到您的 SSH 服务器,您需要在防火墙中打开 SSH 端口(默认是 TCP 端口 22)。
重要提示: 如果您是通过 SSH 连接到机器来执行这些步骤,请在启用防火墙或修改规则前确保您已经允许了当前的 SSH 连接,否则可能会立即中断您的连接!
-
检查 UFW 状态:
bash
sudo ufw status verbose如果 UFW 是非活动的 (
Status: inactive
),您可以跳过添加规则的步骤,直接启用防火墙。如果 UFW 已经是活动的 (Status: active
),您需要确保 SSH 端口已经被允许。 -
允许 SSH 连接:
UFW 提供了一个方便的预设规则,叫做
ssh
,它对应于默认的 SSH 端口 22。bash
sudo ufw allow ssh或者,您也可以直接指定端口号:
bash
sudo ufw allow 22/tcp这两个命令的效果是相同的,都会在防火墙中添加一条规则,允许所有外部 IP 通过 TCP 协议访问本机的 22 号端口。
如果您计划将 SSH 端口修改为非默认值(例如 2222),您需要允许新的端口:
bash
sudo ufw allow 2222/tcp -
检查新规则是否已添加:
再次运行
sudo ufw status verbose
查看当前的防火墙规则列表。您应该看到类似ALLOW IN Anywhere on eth0
或ALLOW IN Anywhere
针对端口 22 或您指定的新端口的规则。 -
启用 UFW (如果它当前是非活动的):
如果您之前运行
sudo ufw status verbose
看到状态是inactive
,现在可以启用防火墙了。请务必在启用前确认您已经允许了 SSH 端口!bash
sudo ufw enable系统会提示您,启用防火墙可能会中断现有的 SSH 连接。输入
Y
并按 Enter 确认。启用后,再次检查状态,应该显示
Status: active
,并且您之前添加的 SSH 规则应该出现在列表中。禁用 UFW (如果需要):
bash
sudo ufw disable删除规则:
如果您想删除之前添加的 SSH 规则,可以使用
ufw delete
命令,后面跟着allow
和规则内容:“`bash
sudo ufw delete allow ssh或者
sudo ufw delete allow 22/tcp
“`
防火墙配置是确保服务器安全的重要一步。请始终只开放必要的端口。
7. SSH 服务器基础配置 (sshd_config
)
SSH 服务器的核心配置文件是 /etc/ssh/sshd_config
。通过修改这个文件,您可以调整 SSH 服务的行为,包括监听端口、允许哪些用户登录、是否允许密码认证等。
重要: 在修改任何系统配置文件之前,强烈建议先备份原始文件,以防修改出错导致服务无法启动或连接中断。
bash
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak_$(date +%Y%m%d_%H%M%S)
这样会将当前配置文件复制一份,并加上日期和时间戳作为备份。
使用文本编辑器(如 nano
或 vim
)打开配置文件:
bash
sudo nano /etc/ssh/sshd_config
配置文件中的大多数行以 #
开头,表示注释。要启用某个配置项,您需要移除行首的 #
。
下面是一些重要的配置项及其建议设置:
a. 修改默认端口 (Port)
默认的 SSH 端口是 22。将其更改为非标准端口(如 2222, 22022 等)可以帮助减少针对默认端口的自动化扫描和攻击尝试。这是一种“安全通过模糊”(Security Through Obscurity)的手段,不能替代其他安全措施,但可以减少日志中的噪音。
找到或添加 Port
这一行。
“`ini
Port 22 # 找到这一行,它可能被注释掉了
Port 2222 # 修改为你想要的新端口号,并确保没有注释
“`
如果您修改了端口,请务必同时更新您的防火墙规则以允许新的端口,并删除允许旧端口的规则(如果不需要的话)。在远程连接时,客户端也需要指定新端口(例如 ssh user@server_ip -p 2222
)。
b. 禁用 Root 用户登录 (PermitRootLogin)
Root 用户拥有系统的最高权限。直接允许 Root 用户通过 SSH 登录存在巨大的安全风险,一旦 Root 密码被破解或密钥泄露,攻击者将完全控制您的系统。最佳实践是禁用 Root 直接登录,而是通过普通用户登录后再使用 sudo
提升权限。
找到 PermitRootLogin
这一行,将其值修改为 no
。
“`ini
PermitRootLogin prohibit-password # 或者其他值,找到它
PermitRootLogin no # 修改为 no
“`
yes
: 允许 Root 直接登录(不安全)。no
: 完全禁止 Root 直接登录。prohibit-password
或without-password
: 允许 Root 通过密钥登录,但禁止密码登录。如果您 必须 允许 Root 登录(不推荐),至少应该使用这个选项结合密钥认证。
强烈建议设置为 no
。
c. 禁用密码认证 (PasswordAuthentication)
虽然密码认证方便,但容易受到暴力破解攻击。使用 SSH 密钥对进行认证是更安全、更推荐的方式。密钥认证将在下一节详细介绍。一旦您成功配置并测试了密钥认证,就可以禁用密码认证。
找到 PasswordAuthentication
这一行,将其值修改为 no
。
“`ini
PasswordAuthentication yes # 找到这一行
PasswordAuthentication no # 修改为 no (仅在配置好密钥认证并验证可用后执行)
“`
重要: 切勿在未成功配置并测试 SSH 密钥认证前将 PasswordAuthentication
设置为 no
! 否则您可能会因为无法通过密码登录而被锁定在服务器之外。
d. 其他重要配置项
ListenAddress
: 默认情况下,SSH 会监听所有网络接口的 IP 地址(0.0.0.0 for IPv4, :: for IPv6)。如果您有多块网卡,或者只想让 SSH 服务在特定的 IP 地址上监听,可以在这里指定。
ini
#ListenAddress 0.0.0.0
#ListenAddress ::
ListenAddress 192.168.1.100 # 例如,只监听这个局域网IPPermitEmptyPasswords
: 禁止空密码登录。默认通常是no
,保持这个设置。
ini
PermitEmptyPasswords no-
ClientAliveInterval
和ClientAliveCountMax
: 防止长时间不活动连接断开。ClientAliveInterval
指定服务器每隔多少秒发送一个心跳消息到客户端。ClientAliveCountMax
指定服务器在发送心跳后未收到响应的次数上限,达到上限后会断开连接。
ini
#ClientAliveInterval 0 # 默认不发送心跳
ClientAliveInterval 60 # 每60秒发送一次
#ClientAliveCountMax 3 # 默认3次
ClientAliveCountMax 5 # 连续5次心跳无响应后断开
这有助于在网络连接不稳定或客户端意外断开时清理僵尸连接。 -
LoginGraceTime
: 允许用户在断开连接前输入密码的超时时间。可以适当缩短以减少攻击者试错的时间。
ini
#LoginGraceTime 2m # 默认2分钟
LoginGraceTime 30 # 30秒内必须完成认证 -
MaxAuthTries
: 每个连接允许的最大密码尝试次数。
ini
#MaxAuthTries 6 # 默认6次
MaxAuthTries 3 # 尝试3次失败后断开连接
结合LoginGraceTime
可以提高安全性。 -
AllowUsers
,DenyUsers
,AllowGroups
,DenyGroups
: 限制哪些用户或用户组可以通过 SSH 登录。这些指令非常有用,可以精确控制访问权限。AllowUsers user1 user2
: 只允许 user1 和 user2 登录。DenyUsers user3
: 禁止 user3 登录。AllowGroups admin users
: 只允许 admin 和 users 组的用户登录。DenyGroups visitors
: 禁止 visitors 组的用户登录。
注意:
Allow
指令优先级高于Deny
。如果同时配置了AllowUsers
或AllowGroups
,则默认会拒绝所有未明确允许的用户。通常只使用Allow
指令族或Deny
指令族中的一个就足够了,避免混用增加复杂性。建议使用AllowUsers
或AllowGroups
来明确指定哪些用户或组可以登录。“`ini
AllowUsers your_username another_user或者
AllowGroups admin sshusers
“`
请根据您的用户和组结构进行设置。确保您自己使用的用户在允许列表中!
e. 应用配置更改
在修改并保存 /etc/ssh/sshd_config
文件后,您需要重启 SSH 服务以使更改生效:
bash
sudo systemctl restart ssh
如果配置文件有语法错误,SSH 服务可能无法正常重启。您可以使用以下命令检查配置文件语法是否有误:
bash
sudo sshd -t
如果命令没有任何输出,表示语法正确。如果有输出,通常会指示错误的行号和原因。
修改配置后的测试流程:
- 在修改并保存
/etc/ssh/sshd_config
后,不要立即关闭当前的 SSH 连接(如果您是通过 SSH 连接到服务器的)。 - 打开一个新的终端窗口或使用另一个设备,尝试使用新的配置(特别是如果修改了端口)连接到服务器。
- 如果新的连接成功建立,说明您的配置更改是正确的,并且您没有被锁定在服务器之外。这时您可以关闭旧的连接。
- 如果新的连接失败,请检查
sshd_config
文件中的改动、防火墙规则以及服务器的日志文件(通常是/var/log/auth.log
或/var/log/syslog
,使用sudo tail /var/log/auth.log
查看)。然后回滚更改(使用备份文件sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
),重启 SSH 服务,直到找到问题原因。
8. 增强安全性:使用 SSH 密钥进行认证
SSH 密钥认证是比密码认证更安全、更便捷的方式。它使用非对称加密算法(通常是 RSA 或 Ed25519),由一对密钥组成:一个私钥(只有您自己拥有,必须妥善保管)和一个公钥(可以分享给您想要登录的服务器)。
当您尝试使用密钥登录时,SSH 客户端使用您的私钥对一个挑战信息进行签名,并将签名和您的公钥发送给服务器。服务器使用您提供的公钥验证签名的有效性。如果签名有效,且公钥与服务器上存储的(在用户的 ~/.ssh/authorized_keys
文件中)相匹配,服务器就认为您是合法的用户,允许您登录,而无需输入密码。
为什么使用密钥认证?
- 安全性更高: 私钥极难通过暴力破解或字典攻击猜到。
- 自动化更方便: 可以实现无密码自动登录,便于脚本和自动化工具使用。
- 防范弱密码: 即使您为用户设置了弱密码,启用密钥认证并禁用密码认证后,弱密码也不会成为安全漏洞。
a. 在客户端生成 SSH 密钥对
在您用于连接服务器的本地计算机(客户端)上执行此步骤。
打开终端,运行 ssh-keygen
命令:
bash
ssh-keygen -t rsa -b 4096
-t rsa
: 指定密钥类型为 RSA。RSA 是一种常用的非对称加密算法。您也可以选择其他算法,如ed25519
(通常更短、更快,且安全性与 RSA 相当,或被认为更高)。如果您选择 Ed25519,命令是ssh-keygen -t ed25519
。对于新生成的密钥,推荐使用 Ed25519 或 4096位的 RSA。-b 4096
: 指定 RSA 密钥的长度为 4096 位。长度越长越安全,但生成和认证速度会稍慢。2048 位通常被认为是最低限度。Ed25519 密钥长度是固定的,所以不需要-b
参数。
命令会提示您保存密钥的文件路径:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/your_username/.ssh/id_rsa):
按 Enter 接受默认路径 (~/.ssh/id_rsa
),或者输入您自定义的路径。默认路径通常是最方便的。如果您之前已经生成过密钥,系统会询问是否覆盖,请谨慎选择。
接着,会提示您输入一个 passphrase(密码短语):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
强烈建议为您的私钥设置一个强 passphrase。 这为您的私钥提供了一层额外的保护。即使私钥文件被盗,没有 passphrase 也无法使用。设置 passphrase 后,每次使用私钥(例如登录 SSH)时都需要输入它。如果您希望实现完全无密码的自动化登录,可以将 passphrase 留空(不安全,请仅在清楚风险且环境受控时使用)。
完成这些步骤后,ssh-keygen
会在您指定的目录下生成两个文件:
id_rsa
(或id_ed25519
):这是您的私钥。绝对不要与任何人分享,务必妥善保管!id_rsa.pub
(或id_ed25519.pub
):这是您的公钥。您可以安全地将其复制到您想要登录的服务器上。
b. 将公钥上传到服务器
将公钥复制到服务器上您想要使用密钥登录的用户的家目录下的 .ssh/authorized_keys
文件中。
最方便的方式是使用 ssh-copy-id
命令(在客户端执行):
bash
ssh-copy-id your_username@server_ip_address
your_username
: 您在服务器上的用户名。server_ip_address
: 服务器的 IP 地址或域名。
如果您的 SSH 服务器监听非默认端口(例如 2222),使用 -p
参数指定:
bash
ssh-copy-id -p 2222 your_username@server_ip_address
首次连接时,会提示您确认服务器的指纹。确认无误后输入 yes
。
然后,系统会要求您输入服务器上 your_username
的密码(这是最后一次使用密码认证了,如果成功的话)。
成功后,ssh-copy-id
会将您的公钥(id_rsa.pub
或 id_ed25519.pub
文件内容)添加到服务器上对应用户的 ~/.ssh/authorized_keys
文件中,并确保 .ssh
目录和 authorized_keys
文件具有正确的权限。
手动复制公钥:
如果 ssh-copy-id
不可用或您更喜欢手动操作,可以这样做:
-
在客户端,显示您的公钥内容:
bash
cat ~/.ssh/id_rsa.pub
# 或 cat ~/.ssh/id_ed25519.pub
复制完整的输出内容(从ssh-rsa ...
或ssh-ed25519 ...
开始直到电子邮件地址或注释结束)。 -
通过 SSH 连接到服务器(此时仍使用密码认证):
bash
ssh your_username@server_ip_address
或指定端口:
bash
ssh -p 2222 your_username@server_ip_address -
在服务器上,创建
.ssh
目录(如果不存在),确保其权限正确,并将公钥添加到authorized_keys
文件中。
bash
mkdir -p ~/.ssh # 创建 .ssh 目录 (如果不存在)
chmod 700 ~/.ssh # 设置 .ssh 目录权限为只有所有者可读写执行
touch ~/.ssh/authorized_keys # 创建 authorized_keys 文件 (如果不存在)
chmod 600 ~/.ssh/authorized_keys # 设置 authorized_keys 文件权限为只有所有者可读写
# 将之前复制的公钥粘贴到文件末尾。可以使用 nano 编辑器:
nano ~/.ssh/authorized_keys
# 粘贴内容,保存并退出 (Ctrl+X, Y, Enter)。
# 或者使用 echo 和重定向(注意使用 >> 追加,而不是 > 覆盖):
# echo "粘贴您的公钥内容在这里" >> ~/.ssh/authorized_keys
重要:.ssh
目录权限必须是700
,authorized_keys
文件权限必须是600
。任何不正确的权限都可能导致密钥认证失败。authorized_keys
文件中每行包含一个公钥。
c. 测试密钥认证
在客户端,尝试使用 SSH 登录服务器,这次应该会提示您输入私钥的 passphrase(如果您设置了),而不是服务器用户的密码:
“`bash
ssh your_username@server_ip_address
或指定端口
ssh -p 2222 your_username@server_ip_address
“`
如果登录成功,恭喜您,密钥认证已经可以工作了!
如果您设置了私钥 passphrase,并且不想每次登录都输入,可以使用 ssh-agent
和 ssh-add
命令将其加载到内存中。具体操作方法请查阅相关文档,本文篇幅所限不详细展开。
d. 配置服务器只允许密钥认证
一旦您确认密钥认证工作正常且稳定,并且您已经通过密钥成功登录过服务器,就可以回到服务器上修改 /etc/ssh/sshd_config
文件,禁用密码认证,进一步提高安全性。
使用 sudo 编辑器打开配置文件:
bash
sudo nano /etc/ssh/sshd_config
找到 PasswordAuthentication
这一行,确保它被设置为 no
:
ini
PasswordAuthentication no
找到 PermitRootLogin
这一行,确保它被设置为 no
(除非您有特殊需求并通过密钥允许 Root 登录):
ini
PermitRootLogin no
确保 PubkeyAuthentication
设置为 yes
(这通常是默认值):
ini
PubkeyAuthentication yes
保存文件并重启 SSH 服务:
bash
sudo systemctl restart ssh
现在,服务器将只接受通过配置在 authorized_keys
文件中的有效公钥进行认证的连接尝试。任何通过密码进行登录的尝试都将被拒绝。
9. SSH 连接基础:客户端使用
在您的本地计算机(或其他客户端设备)上,使用 SSH 客户端连接到服务器非常简单:
bash
ssh [options] username@hostname_or_ip_address [command]
username
: 您在远程服务器上的用户名。hostname_or_ip_address
: 远程服务器的 IP 地址或域名。[options]
: 可选参数,如-p
指定端口,-i
指定私钥文件。[command]
: 可选参数,指定登录后立即执行的命令,执行完毕后连接会自动关闭。
常用选项:
-p port
: 指定连接的端口号(如果服务器的 SSH 端口不是默认的 22)。
bash
ssh -p 2222 your_username@server_ip_address-i identity_file
: 指定用于认证的私钥文件路径(如果您的私钥不是默认的~/.ssh/id_rsa
或~/.ssh/id_ed25519
,或者您有多个私钥)。
bash
ssh -i ~/.ssh/my_other_key your_username@server_ip_address-v
: 启用详细模式,输出连接过程中的调试信息,有助于故障排除。
bash
ssh -v your_username@server_ip_address
连接成功后,您将进入远程服务器的命令行环境,可以像在本地一样执行命令。
其他基于 SSH 的工具:
- SCP (Secure Copy Protocol): 安全地复制文件和目录。
bash
# 从本地复制文件到远程
scp /path/to/local/file your_username@server_ip_address:/path/to/remote/destination
# 从远程复制文件到本地
scp your_username@server_ip_address:/path/to/remote/file /path/to/local/destination
# 指定端口
scp -P 2222 /path/to/local/file your_username@server_ip_address:/path/to/remote/destination
注意 SCP 使用-P
参数指定端口,而不是 SSH 的-p
。 - SFTP (SSH File Transfer Protocol): 提供交互式的安全文件传输界面,类似于 FTP 但更安全。
bash
sftp your_username@server_ip_address
# 指定端口
sftp -P 2222 your_username@server_ip_address
连接后,您可以使用put
,get
,ls
,cd
等命令进行文件操作。
10. 常见问题与故障排除
在安装和配置 SSH 过程中,可能会遇到各种问题。以下是一些常见问题及其排查方向:
-
连接被拒绝 (Connection refused):
- 原因: SSH 服务未运行、防火墙阻止连接、或者您尝试连接的端口不正确。
- 排查:
- 在服务器上检查 SSH 服务状态:
sudo systemctl status ssh
。如果未运行,尝试启动:sudo systemctl start ssh
。 - 检查服务器防火墙 (UFW) 状态和规则:
sudo ufw status verbose
。确保您尝试连接的端口(默认 22 或您自定义的端口)被允许。 - 确认您在客户端连接时使用了正确的 IP 地址和端口号。
- 检查
sshd_config
文件中的Port
和ListenAddress
配置。
- 在服务器上检查 SSH 服务状态:
-
权限被拒绝 (Permission denied):
- 原因: 错误的用户名、错误的密码、密钥认证失败、或者 SSH 配置限制了用户登录。
- 排查:
- 确认您使用的用户名和密码是正确的。
- 对于密钥认证:
- 确保您的公钥已正确添加到服务器上对应用户的
~/.ssh/authorized_keys
文件中,并且内容完整无误。 - 检查服务器上用户家目录、
.ssh
目录和authorized_keys
文件的权限是否正确 (~
: 755 或 700,~/.ssh
: 700,~/.ssh/authorized_keys
: 600)。错误的权限会导致服务器拒绝使用该公钥。 - 确保您在客户端使用正确的私钥文件(使用
-i
参数指定)。 - 如果您设置了私钥 passphrase,确保输入正确。
- 确保您的公钥已正确添加到服务器上对应用户的
- 检查服务器的
/etc/ssh/sshd_config
文件:PermitRootLogin no
会阻止 Root 用户登录。PasswordAuthentication no
会阻止密码登录。AllowUsers
,DenyUsers
,AllowGroups
,DenyGroups
配置是否限制了您的用户或组。
- 查看服务器的认证日志:
sudo tail /var/log/auth.log
。这里会记录所有登录尝试、成功、失败以及原因,是排查权限问题的关键。
-
防火墙问题:
- 原因: 服务器防火墙阻止了来自客户端 IP 或端口的连接。
- 排查:
- 在服务器上运行
sudo ufw status verbose
检查规则。确保您使用的 SSH 端口(默认 22 或自定义)有ALLOW IN
规则。 - 如果您使用了更严格的规则(如只允许特定 IP),确保客户端的 IP 在允许列表中。
- 如果您在云服务商(如 AWS, GCP, Azure)上部署服务器,请检查云平台自身的安全组/防火墙规则,它们通常在操作系统防火墙之前生效。确保云平台的防火墙允许来自您的 IP 地址对 SSH 端口的连接。
- 在服务器上运行
-
SSH 服务未运行:
- 原因: 服务被停止、启动失败、或者安装有问题。
- 排查:
- 运行
sudo systemctl status ssh
查看服务状态。 - 尝试启动服务:
sudo systemctl start ssh
。 - 如果启动失败,查看日志获取更多信息:
sudo journalctl -u ssh.service
或sudo tail /var/log/syslog
。 - 尝试重启服务器看服务是否能随开机启动。
- 如果怀疑安装问题,尝试重新安装:
sudo apt --reinstall install openssh-server
。
- 运行
-
配置错误:
- 原因: 修改
/etc/ssh/sshd_config
文件时出现语法错误或逻辑错误。 - 排查:
- 检查配置文件语法:
sudo sshd -t
。根据提示修正错误。 - 如果SSH服务无法启动或连接中断,尝试使用备份文件恢复配置:
sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
,然后重启服务。 - 仔细检查您最近修改的配置项,特别是权限相关的设置(
PermitRootLogin
,PasswordAuthentication
,AllowUsers
,DenyUsers
等)。
- 检查配置文件语法:
- 原因: 修改
排错思路:
- 隔离问题: 是客户端问题还是服务器问题?尝试从其他客户端连接,或者在服务器本地尝试 SSH 连接自身 (
ssh localhost
或ssh 127.0.0.1
)。 - 检查服务状态: 确认
sshd
服务正在运行。 - 检查网络连接: 使用
ping
命令检查客户端和服务器之间网络是否可达。使用telnet server_ip port
或nc -zv server_ip port
检查目标端口是否开放并监听。 - 检查防火墙: 确认服务器的防火墙和云平台的安全组允许来自您 IP 的 SSH 连接。
- 检查日志: 查看服务器的认证日志 (
/var/log/auth.log
) 获取详细的错误信息。 - 检查配置: 仔细检查
/etc/ssh/sshd_config
文件,特别是您最近修改的部分。使用sshd -t
检查语法。 - 检查权限: 如果使用密钥认证,检查服务器上用户家目录、
.ssh
目录和authorized_keys
文件的权限。
11. 进阶安全建议
SSH 的安全性不仅仅在于安装和基础配置,持续的维护和一些进阶措施也非常重要。
- 定期更新 SSH: 使用
sudo apt update && sudo apt upgrade
命令定期更新系统软件包,包括 OpenSSH。这可以确保您获得最新的安全修复和功能改进。 - 使用 Fail2Ban 防御暴力破解: Fail2Ban 是一款入侵防御框架,它可以监控日志文件(如 SSH 认证日志),自动识别恶意 IP 地址(例如在短时间内多次尝试密码登录失败的 IP),并使用防火墙规则暂时或永久封锁这些 IP。强烈建议在暴露于互联网的 SSH 服务器上安装和配置 Fail2Ban。
- 使用非标准端口(有限建议): 如前所述,更改默认端口可以减少自动化扫描的噪音,但不能阻止有针对性的攻击。不应将其视为唯一的安全措施。
- 限制用户或组的访问: 使用
sshd_config
中的AllowUsers
,DenyUsers
,AllowGroups
,DenyGroups
指令,只允许特定的用户或组通过 SSH 登录。这最小化了攻击面。 - 禁用不安全的协议或算法: 在
sshd_config
中,可以配置允许使用的 SSH 协议版本 (Protocol 2
,Protocol 1 已弃用且不安全),以及允许使用的加密算法、MAC 算法、密钥交换算法等。默认配置通常是安全的,但在某些合规性要求下可能需要更精细的调整。 - 会话限制: 配置
MaxSessions
限制每个网络连接允许的最大同时会话数。 - 监控登录活动: 定期检查
/var/log/auth.log
文件,注意异常的登录尝试或成功记录。 - 使用强制命令 (ForceCommand): 对于某些只需要执行特定任务的用户,可以在
authorized_keys
文件中为特定的公钥配置command="/path/to/script"
选项。当使用该密钥登录时,SSH 会忽略用户指定的命令,只执行指定的脚本,然后断开连接。这可以限制用户的操作范围。
12. 总结
通过本篇详细教程,您应该已经掌握了在 Ubuntu 系统上安装、配置和安全加固 OpenSSH 服务器的各个环节。我们从 SSH 的基本概念和用途开始,逐步经历了安装过程、服务管理、防火墙配置,深入探讨了 /etc/ssh/sshd_config
文件的修改以调整服务行为和增强安全性,重点讲解了使用 SSH 密钥进行更安全、更便捷的认证方式,并提供了客户端连接方法和常见的故障排除指南。
SSH 是远程管理 Linux 服务器的基石,其安全性的重要性不言而喻。强烈建议您始终采用最佳实践,特别是禁用 Root 登录和使用密钥认证并禁用密码认证。持续关注安全动态,定期更新系统和 SSH 软件包,并考虑部署额外的安全工具(如 Fail2Ban),将有助于您的服务器免受潜在威胁。
希望这篇详细的教程对您有所帮助!通过安全地远程管理您的 Ubuntu 系统,您可以更高效、更安心地进行工作。
祝您使用愉快!