三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

云服务器安全加固:从SSH端口更换到OpenClaw部署的完整指南

云服务器安全加固:从SSH端口更换到OpenClaw部署的完整指南

1. 为什么“养龙虾”的第一步是换掉SSH的22端口?

最近在折腾OpenClaw这类AI工具链的云服务器部署,发现一个挺有意思的现象:很多新手朋友拿到云服务器后,第一件事就是兴奋地跑各种安装脚本,从Docker到Ollama,再到OpenClaw,忙得不亦乐乎。但往往忽略了最基础、也最致命的一步——服务器安全。这就像你准备养一池子名贵的龙虾(比如你的AI模型、数据和应用),却把养殖场的正门钥匙(SSH的22端口)直接挂在网上,还贴了张“内有龙虾,欢迎光临”的告示。结果可想而知,龙虾还没养大,可能就被“不速之客”捞走了。

这里的“龙虾”,指的就是你部署在云服务器上的宝贵资产:可能是你辛苦调教的OpenClaw智能体,可能是正在运行的Ollama大模型服务,也可能是你的个人项目数据。而“养龙虾”的第一步,绝不是急着投喂饲料(安装软件),而是先加固池塘的围栏。在云服务器安全里,更换默认的SSH端口,就是加固围栏最直接、最有效的一步。SSH(Secure Shell)是我们远程管理服务器的生命线,但全世界都知道这条生命线的默认入口是22端口。每天都有无数的自动化脚本在扫描互联网上所有开放22端口的IP,尝试用弱密码或已知漏洞进行爆破登录。不换端口,就等于把你的服务器暴露在枪林弹雨之下,安全纯粹靠运气。

所以,这篇内容我们就聚焦在Ubuntu 20.04及以上系统上,如何稳妥、彻底地更换SSH端口。这不仅是OpenClaw部署的“安全第一步”,也是任何云服务器初始化时都应该做的“标准动作”。我会把原理、操作、以及我踩过的坑都讲清楚,让你不仅能“换掉”,还能理解“为什么这么换”,以及换完之后如何验证和应对意外情况。

2. SSH服务核心:从sshd_configsystemd的掌控链路

要安全地更换端口,不能只知其然,必须知其所以然。你得清楚你改的每一个配置,背后对应的是哪个服务组件,以及它们是如何协同工作的。在Ubuntu 20.04+的系统里,这条链路的核心是OpenSSH服务端(sshd)systemd这个系统和服务管理器。

2.1 OpenSSH服务端配置文件:/etc/ssh/sshd_config

这是SSH服务的行为准则。所有关于SSH服务如何运行的参数都在这里定义,包括监听的端口、允许的认证方式、用户登录限制等等。当我们说“更换SSH端口”,本质上就是修改这个文件里的Port指令。

默认情况下,该文件里会有一行:

#Port 22

注意,它默认是被注释掉的(以#开头),但SSH服务默认行为就是监听22端口。我们要做的,就是取消注释,或者添加一个新的Port行。一个更安全的做法是多端口监听,比如:

Port 22 Port 23456

这样配置后,SSH服务会同时监听22和23456端口。在测试新端口完全可用之前,保留22端口是一个重要的“逃生通道”,防止配置错误导致自己也无法登录。待新端口确认无误后,再回来删除Port 22这一行,只保留新端口。

2.2 Systemd:服务的管家

在Ubuntu 20.04+上,SSH服务是由systemd来管理的。这意味着:

  • 启动/停止/重启服务:我们不再使用老旧的/etc/init.d/ssh restart命令,而是使用systemctl命令,例如sudo systemctl restart ssh
  • 服务状态查看sudo systemctl status ssh可以查看服务是否在运行、最近的日志、以及是否有错误。
  • 开机自启sudo systemctl enable ssh确保服务在系统启动时自动运行。

理解这两者的关系至关重要:我们修改/etc/ssh/sshd_config只是改变了“行为准则”,要让新准则生效,必须通过systemd“管家”去重新通知SSH服务(即重启服务)。同时,systemd也是我们排查服务故障的第一站。

2.3 防火墙:端口的守门人

仅仅修改SSH配置并重启服务,端口就开放了吗?不一定。这还取决于系统的防火墙。Ubuntu 20.04默认安装并启用了ufw(Uncomplicated Firewall)防火墙。如果防火墙是激活状态,它默认会阻止所有传入连接,除非你明确放行规则。

所以,完整的链路是:

  1. sshd_config声明要监听新端口。
  2. 通过systemctl重启SSH服务,让它开始尝试监听新端口。
  3. 在防火墙(如ufw)中放行新端口的传入流量。

这三步缺一不可。很多人在第二步和第三步之间栽跟头,修改了配置却连不上,就是因为防火墙把连接挡在了外面。

3. 实操演练:一步步更换SSH端口并验证

理论清楚了,我们开始动手。请务必在现有的SSH连接会话中操作,或者通过云服务商提供的VNC/控制台登录操作,以防操作失误导致当前连接中断而无法恢复。

3.1 备份原始配置文件(好习惯从备份开始)

任何重要文件修改前先备份,这是铁律。

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d)

这条命令会将原配置文件复制一份,并在文件名后加上当天日期,便于追溯。

3.2 编辑SSH服务配置文件

使用你熟悉的文本编辑器,比如nanovim

sudo nano /etc/ssh/sshd_config

找到关于Port的行。通常在第13行左右。你会看到:

#Port 22

我们的策略是先添加,再禁用。在这行下面,添加一个新的端口号。端口号范围是1-65535,但应避免使用众所周知的端口(如80、443)和小于1024的“特权端口”。建议在10000-65535之间选择一个,比如23456

#Port 22 Port 23456

现在,SSH服务会同时监听22端口和23456端口。保存并退出编辑器(在nano中是Ctrl+X,然后按Y确认,再按Enter)。

注意:选择端口时,可以稍微“冷门”一点,但不要用2222,22222这种过于明显的替代端口,因为扫描器也会扫这些常见替代端口。随机一个5位数是不错的选择。

3.3 重启SSH服务使配置生效

执行以下命令:

sudo systemctl restart ssh

然后立即检查服务状态,确保重启成功,没有报错:

sudo systemctl status ssh --no-pager -l

重点查看输出中是否有“Active: active (running)”字样,以及下面是否有红色的“error”或“failed”信息。如果状态是active,通常意味着配置语法正确,服务已重新加载。

3.4 配置防火墙放行新端口

现在需要告诉防火墙,允许外部连接到我们的新端口。首先查看UFW状态:

sudo ufw status

如果状态是inactive,说明防火墙没开,你可以跳过这一步,但强烈建议启用防火墙并精细配置。如果状态是active,则需要添加规则。

sudo ufw allow 23456/tcp

这条命令允许TCP协议访问23456端口。接着,重新加载UFW规则:

sudo ufw reload

再次检查状态,确认新规则已生效:

sudo ufw status numbered

你应该能在输出列表中看到类似这样的一行:

[ 1 ] 23456/tcp ALLOW IN Anywhere

3.5 关键测试:在新端口上创建新的SSH连接

这是最核心的验证步骤。千万不要关闭当前的SSH连接窗口!打开一个新的终端窗口或标签页,尝试用新端口连接服务器。

ssh -p 23456 your_username@your_server_ip

your_usernameyour_server_ip替换为你的实际用户名和服务器公网IP。

  • 如果连接成功:恭喜!你已成功在新端口上登录。现在,你有了两个有效的SSH连接(旧端口和新端口)。
  • 如果连接失败:不要慌,你还有当前的连接可以排查。常见的失败原因和排查步骤我们放在下一节详细讲。

3.6 禁用旧端口并最终确认

假设新端口(23456)测试连接完全正常。现在,我们回到最初的SSH连接窗口,进行最终配置。

再次编辑/etc/ssh/sshd_config文件:

sudo nano /etc/ssh/sshd_config

将之前添加的两行改为:

#Port 22 Port 23456

即确保Port 22被注释,只有Port 23456生效。保存退出。

再次重启SSH服务:

sudo systemctl restart ssh

现在,SSH服务只监听23456端口。我们可以用netstatss命令来验证:

sudo ss -tlnp | grep sshd

或者

sudo netstat -tlnp | grep sshd

输出应该只显示你的新端口(例如:23456),而不再有:22

最后,更新防火墙规则,拒绝旧端口的连接(虽然服务已经不听了,但防火墙规则清理一下更干净):

sudo ufw delete allow 22/tcp sudo ufw reload

至此,SSH端口更换的核心操作全部完成。

4. 避坑指南:连接失败的完整排查链路

在实际操作中,从第3.5步“测试新连接”开始,就可能遇到问题。下面是我总结的一套完整的排查链路,你可以像侦探一样一步步排除可能性。

4.1 现象:新端口连接超时或拒绝连接

首先,在新终端里执行连接命令时,如果长时间卡住后显示“Connection timed out”,或者立刻显示“Connection refused”,排查思路如下:

  1. 检查SSH服务状态与配置语法:回到原连接窗口,运行sudo systemctl status ssh。如果服务状态不是active (running),或者有明确的错误信息(如“Failed to listen on port”),说明配置有问题。重点检查/etc/ssh/sshd_config文件的语法,特别是Port指令后面是否跟了正确的数字,是否有拼写错误。可以用sudo sshd -t命令测试配置文件语法,它会报告任何语法错误而不重启服务。

  2. 确认服务是否监听在新端口:运行sudo ss -tlnp | grep 23456(将23456换成你的端口)。如果没有任何输出,说明SSH服务根本没有在这个端口上监听。原因可能是:

    • 配置文件修改后没有重启SSH服务。请执行sudo systemctl restart ssh
    • 配置文件中Port指令仍然被注释或写错位置。
    • 与SELinux(Ubuntu默认不安装)或AppArmor(Ubuntu使用)有关。Ubuntu上SSH的AppArmor配置文件通常不会阻止监听非特权端口,但极端情况下可以检查sudo aa-status看看是否有关于sshd的拒绝日志。
  3. 检查防火墙(UFW)规则:运行sudo ufw status numbered,确认你的新端口(如23456)的规则是否存在且是ALLOW。如果不存在,用sudo ufw allow 23456/tcp添加。如果防火墙根本没开 (inactive),那问题就不在防火墙。

  4. 检查云服务商的安全组/网络ACL这是最容易忽略、也最致命的一环!云服务器(如阿里云、腾讯云、AWS等)除了操作系统自身的防火墙,在虚拟网络层还有一层安全组(Security Group)或网络访问控制列表(ACL)。你必须在云服务商的控制台里,找到你这台云服务器所属的安全组,添加入站规则,允许你的IP地址(或0.0.0.0/0以允许所有IP,但不推荐)访问你设置的新TCP端口(如23456)。很多朋友改了系统配置和UFW,却忘了这里,导致连接始终无法到达服务器。

  5. 检查本地网络或ISP:极少数情况下,你本地网络或互联网服务提供商(ISP)可能会封锁某些端口。可以尝试换一个端口号(比如从23456换成34567),重复上述配置步骤,看是否能连通。

4.2 现象:连接被重置或立即失败

如果错误信息是“Connection reset by peer”或快速失败,可能的原因:

  • 端口冲突:你选择的新端口已经被系统上的其他服务占用。用sudo ss -tlnp | grep :你的端口号sudo lsof -i :你的端口号检查。如果被占用,换一个端口。
  • SSH服务崩溃:配置文件有严重错误导致sshd进程无法启动。查看详细日志:sudo journalctl -u ssh --since “5 minutes ago” -xe。日志会给出明确的错误行。

4.3 建立“逃生舱”预案

在整个操作过程中,最坏的情况是:你修改了配置,重启了服务,关闭了当前连接,然后发现新端口连不上。你被锁在服务器外面了。对于云服务器,你有最后一道保障:

  • 云服务商控制台/VNC:几乎所有主流云服务商都提供基于网页的VNC或“连接管理终端”功能。即使SSH完全瘫痪,你也可以通过这个“后门”登录到服务器的本地控制台,去修正错误的配置文件。在开始操作前,请务必确认你知道如何进入你所用云平台的这个控制台

一个更稳妥的“逃生舱”做法是,在修改配置前,先通过云平台控制台,在安全组里临时添加一条允许你本地IP从任意端口(或一个备用端口)访问的规则。这样,即使SSH配置出错,你还可以通过这个备用通道进行修复。

5. 进阶配置与安全加固建议

成功更换端口只是基础安全的第一步。结合OpenClaw等服务的部署,我们可以做得更多。

5.1 完全禁用密码登录,使用SSH密钥对

端口改了,但如果你还在用密码登录,风险依然存在。暴力破解工具在找到端口后,下一步就是猜密码。最根本的解决方法是禁用密码认证,只允许更安全的SSH密钥对登录。

  1. 生成密钥对(在本地电脑上操作):

    ssh-keygen -t ed25519 -C “your_email@example.com”

    按照提示,一般直接回车使用默认路径(~/.ssh/id_ed25519)和空密码(或设置一个强密码)。

  2. 将公钥上传到服务器(在本地电脑上操作):

    ssh-copy-id -p 23456 your_username@your_server_ip

    这条命令会自动将你的公钥(~/.ssh/id_ed25519.pub)内容追加到服务器对应用户的~/.ssh/authorized_keys文件中。

  3. 在服务器上禁用密码认证:编辑/etc/ssh/sshd_config,确保以下设置:

    PasswordAuthentication no PubkeyAuthentication yes

    然后重启SSH服务:sudo systemctl restart ssh

现在,只有拥有对应私钥的电脑才能登录,安全性大幅提升。请务必妥善保管好本地~/.ssh/目录下的私钥文件。

5.2 使用Fail2ban阻止暴力破解

即使换了端口、用了密钥,扫描和尝试登录的“噪音”依然会有。Fail2ban可以监控系统日志,当发现同一个IP在短时间内多次尝试登录失败时,自动将其IP加入防火墙黑名单一段时间。

安装Fail2ban:

sudo apt update sudo apt install fail2ban -y

Fail2ban默认配置通常就够用,它会自动读取/var/log/auth.log等日志文件。你可以通过sudo systemctl status fail2ban查看其运行状态。

5.3 为SSH服务配置系统资源限制(systemd调优)

在部署OpenClaw等资源密集型应用时,可能会遇到系统资源紧张的情况。我们可以通过systemd为SSH服务设置一些资源限制,防止它因资源问题异常退出,或者影响其他关键服务。

编辑SSH服务的systemd单元覆盖文件:

sudo systemctl edit ssh

这会打开一个编辑器,你可以添加如下内容(例如,限制内存和CPU):

[Service] MemoryLimit=512M CPUQuota=50%

保存退出后,执行sudo systemctl daemon-reloadsudo systemctl restart ssh使配置生效。这样,SSH服务最多使用512MB内存和50%的单个CPU核心。这对于一个通常很轻量的SSH服务来说已经足够,同时避免了它失控占用过多资源。

5.4 应对“云服务器养龙虾”场景的额外考量

当你把服务器用于运行OpenClaw、Ollama、Docker容器等“养龙虾”应用时:

  • 端口规划:除了SSH端口,你还需要为OpenClaw的Web界面(默认可能是3000端口)、Ollama的API端口(默认11434)、以及其他可能的后端服务(如数据库)规划端口。建议在云平台安全组和服务器UFW中,仅精确放行必要的端口,而不是大范围开放。
  • 服务依赖:确保SSH服务的稳定,是维护其他所有服务的基础。在/etc/ssh/sshd_config中,可以考虑将ClientAliveIntervalClientAliveCountMax参数调大一些,防止因网络波动导致的长连接断开,这在长时间模型推理或文件传输时很有用。
  • 备份与回滚:像对待sshd_config一样,对你所有的应用配置文件(如OpenClaw的配置、Docker的Compose文件)进行版本管理和备份。在做出任何重大变更前,先通过SSH做好快照或备份。
← 返回列表