跳到主要内容
注册无需实名认证
安云主机 AnYun VPS

教程 · 安全加固

加固 SSH:修改端口、关闭密码登录、限制 root

难度

进阶

预计时长

20 分钟

步骤

7

最近修订

基准系统

Debian 12

要点

加固 SSH:修改端口、关闭密码登录、限制 root

SSH 加固的三件事是改掉默认 22 端口、把 PasswordAuthentication 设为 no、把 PermitRootLogin 设为 prohibit-password。改完必须先用 sshd -t 校验语法,再在保留原有会话的前提下重载服务;Ubuntu 22.10 及以后的版本由 ssh.socket 接管监听端口,只改 sshd_config 里的 Port 不会生效。

前置条件

开始之前,先确认这些都具备

  • 已配置 SSH 密钥登录,并且用密钥成功登录过至少一次
  • 已创建可用的 sudo 用户
  • 知道怎么打开控制台 VNC —— 万一锁死了,这是唯一的救援通道

操作步骤

7

  1. 步骤 01 / 07

    先在防火墙上放行新端口 #

    顺序错了就会把自己关在外面:新端口必须先放行,SSH 才能改过去。端口号在 1024–65535 之间任选,避开常见服务端口。

    Shell
    # 用 ufw 的情况
    sudo ufw allow 22022/tcp comment 'ssh-new'
    sudo ufw status
    
    # 用 firewalld 的情况(Rocky / Alma)
    sudo firewall-cmd --permanent --add-port=22022/tcp
    sudo firewall-cmd --reload
  2. 步骤 02 / 07

    写一份 drop-in 配置,而不是改主文件 #

    Debian 12 与 Ubuntu 22.04 及以后的 sshd_config 里都有 Include /etc/ssh/sshd_config.d/*.conf。把自己的改动放进独立文件,系统升级时主配置被替换也不会丢,回滚时删掉一个文件就行。注意 AllowUsers 一旦写上,未列出的账号(包括 root)都无法登录。

    Shell
    # 先确认主文件里确实有 Include 行,没有就只能直接改主文件
    grep -n "^Include" /etc/ssh/sshd_config
    
    sudo tee /etc/ssh/sshd_config.d/99-hardening.conf > /dev/null <<'EOF'
    Port 22022
    PermitRootLogin prohibit-password
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    PubkeyAuthentication yes
    AuthenticationMethods publickey
    MaxAuthTries 3
    LoginGraceTime 30
    X11Forwarding no
    AllowUsers deploy
    EOF
  3. 步骤 03 / 07

    校验语法 #

    这是整个教程里最重要的一条命令。sshd -t 会在不重启服务的前提下检查配置,语法有问题会直接指出行号。没跑这一步就重启 sshd,等于闭着眼睛跳。

    Shell
    sudo sshd -t && echo "配置语法正确"
  4. 步骤 04 / 07

    Ubuntu 22.10 及以后:还要改 ssh.socket #

    从 Ubuntu 22.10 起,sshd 由 systemd socket 激活,监听端口写在 ssh.socket 里,sshd_config 中的 Port 会被忽略。这是「改了端口却没生效」最常见的原因。Debian 12 默认不是 socket 激活,可以跳过,但花十秒确认一下总没坏处。

    Shell
    # 确认是不是 socket 激活
    systemctl is-active ssh.socket
    
    # 如果是 active,用 drop-in 覆盖监听端口
    sudo systemctl edit ssh.socket
    # 在编辑器中填入:
    #   [Socket]
    #   ListenStream=
    #   ListenStream=22022
    # 第一行空的 ListenStream= 用于清空默认值,不能省
    
    sudo systemctl daemon-reload
    sudo systemctl restart ssh.socket
  5. 步骤 05 / 07

    重载服务,并且保持原窗口不关 #

    用 reload 而不是 restart,已建立的连接不会被切断。然后另开一个终端用新端口登录 —— 只有新窗口成功进来了,才可以关掉旧窗口。这个纪律能避免九成的 SSH 事故。

    Shell
    # Debian / Ubuntu 服务名是 ssh,Rocky / Alma 是 sshd
    sudo systemctl reload ssh
    
    # 另开一个终端:
    ssh -p 22022 [email protected]
    
    # 确认密码登录确实关闭了(应当被立即拒绝)
    ssh -p 22022 -o PreferredAuthentications=password -o PubkeyAuthentication=no [email protected]
  6. 步骤 06 / 07

    Rocky / AlmaLinux 还要处理 SELinux #

    SELinux 默认只允许 sshd 监听 22 端口,换端口后服务起不来,日志里往往只有一句语焉不详的权限错误。用 semanage 把新端口登记为 ssh_port_t 即可。

    Shell
    sudo dnf install -y policycoreutils-python-utils
    sudo semanage port -a -t ssh_port_t -p tcp 22022
    sudo semanage port -l | grep ssh_port_t
  7. 步骤 07 / 07

    收尾:撤掉旧端口的放行规则 #

    新端口稳定工作一两天之后,再把 22 端口的规则删掉。留着旧规则不放,前面做的一切就白做了。

    Shell
    sudo ufw status numbered
    sudo ufw delete allow 22/tcp
    sudo ufw status verbose

常见错误

这一步最容易踩的坑

下面每一条都对应一个真实会发生的故障。先读完再动手,比出问题之后再回来查要省时间。

  • 改端口只能减少日志噪音,不能提升安全性。真正起作用的是密钥登录与关闭密码认证 —— 端口扫描器发现 22022 上的 SSH 只需要几分钟。
  • Ubuntu 22.10 及以后忘了改 ssh.socket,是「端口没生效」的第一大原因。先用 systemctl is-active ssh.socket 判断。
  • AllowUsers 写错用户名,reload 之后所有人都进不来。写完先 sshd -t,再用 id 确认拼写。
  • 关掉密码登录时手上没有可用的密钥。控制台 VNC 是唯一的后路,动手之前先确认自己会用它。
  • 为了省事把 PermitRootLogin 设成 yes 再配合密码登录,这个组合是被爆破入侵的标准入口。
  • 同时装了 ufw 和 firewalld,或者手工 iptables 规则与 ufw 并存。两套规则会互相覆盖,排查起来极其费时。

这篇教程的边界

  • 命令以 Debian 12 为准。Ubuntu 与 Rocky Linux 的差异只在正文明确标注之处,未标注的部分请以你所用发行版的官方文档为准。
  • 示例中的 IP 来自文档保留段 203.0.113.0/24,域名为 example.com,端口为示意值。复制后必须替换成自己的值, 原样执行不会有任何效果。
  • 教程不能替代备份。任何会改动数据或线上流量的步骤,执行前先确认有一份验证过能恢复的备份。
  • 本站不提供任何用于绕过网络审查的配置或说明,这篇也不例外。

发现命令过时或有误,请发邮件到 [email protected]。 指出错误的邮件比沉默的旧文档有价值得多。

联系 工单
扫码
手机访问

扫码在手机上打开