部署在云端的Debian服务器,默认的SSH密码登录在公网暴露不到半小时,就会被自动化扫描工具盯上。登录失败日志里塞满了来自全球各地的暴力破解记录,这不是危言耸听,而是每天都在发生的现实。安全加固不是锦上添花,是系统上线前的必选项。下面直接切入具体的加固手段,每一条都可以立即在Debian 12环境中执行。
SSH密钥认证,彻底关闭密码登录密码无论多复杂,都存在被猜测、泄露或暴力破解的风险。密钥对的安全性是指数级的。首先在你本地的工作站生成一对密钥,推荐使用ed25519算法,它在安全性和性能上都优于传统的RSA。
ssh-keygen -t ed25519 -C "your_email@example.com"
这条命令会在~/.ssh目录下生成id_ed25519私钥和id_ed25519.pub公钥。私钥必须妥善保管在本地,绝不外传。接下来把公钥部署到你的Debian服务器上,使用ssh-copy-id命令是最便捷的方式。
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your_server_ip
输入一次当前用户的密码后,公钥就被追加到服务器上对应用户的~/.ssh/authorized_keys文件里。现在测试用密钥登录,确认成功后,立即着手修改SSH守护进程的配置文件/etc/ssh/sshd_config。这是整个加固过程中最关键的一步,需要修改或确认以下指令。
PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no UsePAM yes
PasswordAuthentication no直接斩断了所有通过密码登录的可能性。ChallengeResponseAuthentication no关闭了基于质询响应的认证方式,这也常被用于密码验证。UsePAM保留为yes是因为它仍然为密钥认证提供会话管理功能,但密码模块已被禁用。修改保存后,必须重启SSH服务使配置生效。
sudo systemctl restart sshd
强烈建议在重启服务后,不要关闭当前的SSH连接,另开一个终端窗口尝试登录。如果新连接成功,说明配置无误;如果失败,你还有原来的会话可以回滚配置。一旦被锁在服务器外面,就只能通过云服务商的控制台救援了。
更改SSH默认端口,降低噪音和自动化攻击将SSH端口从22改为一个高位端口,比如在10000到65535之间选一个不常用的数字。这不是通过隐藏来实现安全,而是有效过滤掉99%的自动化扫描流量,让你的日志变得干净,也减轻了fail2ban这类工具的负担。在同一个sshd_config文件中,找到Port这一行,去掉注释并修改。
Port 26622
重启SSH服务后,所有后续连接都需要指定新端口。别忘了在云服务商的安全组或防火墙规则中,放行这个新的TCP端口,同时删除或拒绝22端口的入站规则。
配置Fail2ban,动态封禁恶意IP即使只允许密钥登录,也仍有大量扫描器会尝试连接,消耗服务器资源。Fail2ban通过监控日志文件,在短时间内发现多次认证失败后,自动调用iptables或nftables将攻击源IP临时封禁。在Debian上安装非常简单。
sudo apt update && sudo apt install fail2ban -y
默认配置是通用的,我们需要为SSH创建一个专门的监狱配置。复制默认的jail.conf文件作为本地配置的基础。
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
然后编辑jail.local,找到[sshd]部分,进行针对性调整。
[sshd] enabled = true port = 26622 filter = sshd logpath = /var/log/auth.log maxretry = 3 findtime = 10m bantime = 1h ignoreip = 127.0.0.1/8 ::1 你的可信IP地址
这里的逻辑是:在10分钟内,任何IP(除了你设定的白名单)只要有3次认证失败,就会被封禁1小时。port字段必须与你更改后的SSH端口一致。ignoreip是保命设置,把你固定的办公或家庭IP放进去,防止自己输错密钥被误封。启用并检查Fail2ban状态。
sudo systemctl enable fail2ban --now sudo fail2ban-client status sshd
你会看到当前被监控的监狱和封禁的IP列表。这个工具是动态防御的核心,能极大提升暴力破解的成本。
部署防火墙,构建最小权限访问控制Debian默认的防火墙前端是nftables,但iptables的语法对很多人来说更熟悉,或者你可以直接使用nftables。这里以更现代的nftables为例,建立一个白名单模式的入站策略。首先启用并启动nftables服务。
sudo systemctl enable nftables --now
然后编辑/etc/nftables.conf,清空默认内容,写入一套严谨的规则集。
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# 允许回环接口的所有流量
iif lo accept
# 允许已建立和相关联的连接
ct state established,related accept
# 允许ICMPv4和ICMPv6的特定类型,用于网络诊断
ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept
ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, time-exceeded, nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert } accept
# 放行你的SSH新端口
tcp dport 26622 accept
# 如果你的服务器提供Web服务,放行80和443
tcp dport { 80, 443 } accept
# 记录并丢弃所有其他入站流量
log prefix "nftables-drop: " flags all counter drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
这套规则的核心是默认丢弃所有入站连接,只显式放行你需要的服务。ct state established,related accept这条规则至关重要,它允许服务器主动发起的外部请求的响应流量回来,保证你apt update这类操作能正常工作。配置完成后,用命令检查语法并加载。
sudo nft -f /etc/nftables.conf sudo systemctl restart nftables
现在,你的服务器只对指定的端口开放,任何未授权的连接尝试都会被内核直接拒绝并记录。
限制可登录用户和禁用Root直接登录Root用户是每个Linux系统都有的超级账户,禁止它通过SSH直接登录,可以消除一个巨大的攻击面。所有需要提权的操作,都应该由普通用户通过sudo来完成。在sshd_config文件中,找到并确认PermitRootLogin指令。
PermitRootLogin no
更进一步,你可以明确指定哪些用户组或用户可以通过SSH登录。创建一个系统管理组,比如sshlogin,把需要远程管理的用户加入这个组。
sudo groupadd sshlogin sudo usermod -a -G sshlogin your_username
然后在sshd_config末尾添加一行,只允许这个组的成员登录。
AllowGroups sshlogin
这样,即使某个非授权用户的密码或密钥意外泄露,他也无法通过SSH进入系统。这是纵深防御原则的体现。
实施双因素认证,增加额外安全层对于极其敏感的生产环境,仅有密钥还不够。可以叠加基于时间的一次性密码,也就是TOTP,实现双因素认证。在Debian上安装google-authenticator的PAM模块。
sudo apt install libpam-google-authenticator -y
然后,以你需要远程登录的普通用户身份运行初始化命令。
google-authenticator
按提示回答yes或no。建议对基于时间的令牌回答yes,对更新验证文件回答yes,对限制多次使用同一令牌回答yes,对时间窗口扩大回答no。程序会生成一个二维码和一系列应急恢复码,用你手机上的认证器应用扫描二维码,并把恢复码保存在安全的地方。
接下来,配置SSH调用这个PAM模块。编辑/etc/pam.d/sshd文件,在@include common-auth这一行上面添加一行。
auth required pam_google_authenticator.so
同时,注释掉@include common-auth这一行,因为我们之前已经禁用了密码登录,这里要确保PAM不再尝试密码认证。然后再次修改sshd_config,确保ChallengeResponseAuthentication被设置为yes,以启用交互式认证流程。
ChallengeResponseAuthentication yes
最后,还需要在sshd_config中增加一条认证方法,让SSH先要求密钥,再要求TOTP验证码。
AuthenticationMethods publickey,keyboard-interactive
重启SSH服务。现在登录时,你会先完成密钥交换,然后被提示输入Verification code。输入手机认证器上显示的6位数字,才能成功进入系统。这完美实现了“你知道什么”和“你拥有什么”的双重验证。
系统层面的基础加固安全是一个体系,SSH只是入口。系统本身的基础防护同样重要。首先,保持系统更新是抵御已知漏洞的最有效方式。配置无人值守的安全更新,避免因疏忽导致系统滞后。
sudo apt install unattended-upgrades apt-listchanges -y sudo dpkg-reconfigure -plow unattended-upgrades
在出现的界面中选择“是”,系统就会自动安装来自安全源的重要更新。其次,用非常规手段隐藏一些系统信息。编辑/etc/host.conf,增加一行。
OBSCUREHOSTNAMES yes
这会让系统在对外连接时,尽量不泄露主机名。最后,限制coredump文件,防止敏感信息泄露。在/etc/security/limits.conf中添加。
* hard core 0
并在/etc/sysctl.d/99-security.conf中设置内核参数。
fs.suid_dumpable = 0 kernel.core_pattern = |/bin/false
应用这些设置。
sudo sysctl -p /etc/sysctl.d/99-security.conf
这些操作从系统底层减少了信息泄露和权限提升的风险。
日志监控与入侵检测再坚固的盾也需要哨兵。配置并理解日志是发现潜在入侵的唯一途径。除了fail2ban的实时反应,还应定期审查/var/log/auth.log,关注任何异常时间、异常IP的成功登录记录。安装并配置auditd,可以对关键文件,如/etc/shadow、/etc/sshd_config的访问进行审计。
sudo apt install auditd -y sudo auditctl -w /etc/ssh/sshd_config -p war -k sshd_config_changes sudo auditctl -w /etc/shadow -p r -k shadow_access
这些规则会记录下任何对SSH配置文件的写入和属性修改,以及对影子密码文件的读取尝试。使用ausearch命令可以查询这些审计日志。对于更高级的需求,部署基于主机的入侵检测系统,如AIDE,来监控整个文件系统的完整性。
sudo apt install aide -y sudo aideinit sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db sudo aide.wrapper --check
初始化数据库后,定期运行检查命令,AIDE会报告所有被修改、添加或删除的文件。结合cron定时任务,可以将报告发送到你的邮箱。至此,你的Debian服务器已经拥有了一套从认证、网络、系统到审计的立体防护体系,能够从容应对绝大多数自动化攻击和定向入侵尝试。
