接手一台全新的Debian 12服务器,第一件事不是装面板,不是配防火墙,而是锁定SSH。默认的22端口和密码登录在公网上存活不超过半小时就会被扫描到。直接修改SSH配置文件,路径在/etc/ssh/sshd_config。把默认端口改成一个高位端口,比如49221,同时彻底禁用密码登录和root直接登录。修改前先确保你已经把本地公钥写入了目标服务器的authorized_keys文件,否则改完你自己就进不去了。

Port 49221
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes

改完重启sshd服务,systemctl restart sshd。保留当前会话不要断开,新开一个终端测试用密钥能否连上,确认无误再关旧会话。这一步做完,90%的自动化攻击就已经对你无效了。

系统自动更新与最小化安装原则

Debian的unattended-upgrades包是运维懒人利器,但它默认只装安全更新,配置需要微调。安装后编辑/etc/apt/apt.conf.d/50unattended-upgrades,把Debian-Security这一行的注释去掉,同时建议把-updates也加上,因为有些关键补丁会走updates通道。在同一个文件里找到Unattended-Upgrade::AutoFixInterruptedDpkg这一项,设为true,防止dpkg中断后系统卡住。再设置Unattended-Upgrade::Remove-Unused-Kernel-Packages和Remove-New-Unused-Dependencies为true,自动清理旧内核和孤立依赖,避免/boot分区被撑爆。

最小化安装的意思是,服务器初始安装时只选SSH server和standard system utilities,其他图形界面、打印服务、桌面环境一律不装。装完系统后执行dpkg --get-selections | grep -v deinstall查看已安装包列表,把不需要的libreoffice、cups、bluetooth相关包全部purge掉。每多一个包就多一个潜在漏洞入口,这个逻辑很简单。

防火墙策略:用nftables替代iptables

Debian 12已经默认使用nftables作为防火墙后端,不要再抱着iptables不放了。nftables配置语法更简洁,规则匹配效率更高。一个极简的入站策略是:放行你改过的SSH端口,放行80和443,放行本地回环,其余全部丢弃。出站默认放行,因为服务器通常需要主动访问外部资源更新软件。配置文件/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
        tcp dport { 49221, 80, 443 } accept
        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept
    }
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

启用nftables并设为开机自启:systemctl enable nftables && systemctl start nftables。注意规则顺序很重要,established,related状态放行必须放在具体端口放行之前,这样已建立的连接回包才能正常通过。ICMP放行是为了ping和路径MTU探测,完全禁掉ping在某些网络环境下会导致诡异问题。

内核参数加固:sysctl的五个关键项

编辑/etc/sysctl.d/99-security.conf,加入以下参数。这些不是网上随便抄的,每一个都有明确的安全意义。net.ipv4.tcp_syncookies=1防止SYN Flood攻击,开启后服务器在SYN队列满时发送带cookie的SYN+ACK,合法客户端会带回正确cookie完成握手。net.ipv4.conf.all.rp_filter=1开启反向路径过滤,防止IP欺骗攻击,数据包进入接口如果其源地址在路由表中不可达该接口则丢弃。net.ipv4.conf.all.accept_redirects=0和net.ipv6.conf.all.accept_redirects=0禁用ICMP重定向,防止中间人篡改路由表。net.ipv4.conf.all.send_redirects=0禁止本机发送重定向,避免被利用做跳板。kernel.kptr_restrict=2限制内核指针泄露给普通用户,增加本地提权难度。

net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
kernel.kptr_restrict = 2

执行sysctl --system使配置生效。这些参数对性能影响微乎其微,但防御效果实实在在。

Fail2ban:动态封锁恶意IP

改端口和禁密码登录已经挡住了大部分扫描器,但总有更顽固的对手会针对你的高位端口持续尝试。Fail2ban通过监控日志,在短时间内多次失败后自动添加nftables规则封禁IP。安装后创建/etc/fail2ban/jail.local,不要直接修改jail.conf,因为后者会被包更新覆盖。极简配置只监控SSH:

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
banaction = nftables-multiport
banaction_allports = nftables-allports

[sshd]
enabled = true
port = 49221
logpath = /var/log/auth.log

这里bantime设为一小时,findtime十分钟内maxretry三次即触发封禁。如果你的SSH端口改了,port字段必须同步修改,否则fail2ban会去监控默认22端口,等于没配。banaction用nftables-multiport是因为我们前面用的是nftables,保持一致。启动服务systemctl enable fail2ban --now,然后用fail2ban-client status sshd查看封禁状态。

日志与监控:用logwatch做每日简报

安全运维不是配完就完事了,你得知道服务器每天发生了什么。logwatch是一个日志分析工具,能生成可读性很强的每日摘要邮件。安装后主要配置文件在/usr/share/logwatch/default.conf/logwatch.conf,复制到/etc/logwatch/conf/覆盖默认值。关键参数:Output设为mail,MailTo填你的邮箱,Detail设为Low或Med,Range设为yesterday。然后在crontab里加一条每天凌晨执行的任务:

0 3 * * * /usr/sbin/logwatch --output mail --mailto your@email.com --detail low

每天花两分钟扫一眼邮件,SSH登录记录、失败尝试、软件更新情况、磁盘使用率一目了然。这个习惯比装任何监控面板都管用,因为面板本身也是攻击面。

服务审计与进程最小化

用ss -tlnp查看所有监听端口,每一个端口你都必须清楚是哪个服务在用。如果看到127.0.0.1:631这种,那是cups打印服务,服务器上完全没用,apt purge cups干掉。看到0.0.0.0:5353可能是avahi-daemon,同样purge。systemd-resolved的127.0.0.53:53如果不需要本地DNS缓存也可以禁用,但注意有些应用依赖它解析,禁用前先确认。最终目标是你执行ss -tlnp时,只看到SSH端口和Web服务端口,其他什么都没有。

systemd服务也要审计,systemctl list-unit-files --state=enabled列出所有开机自启服务,逐个审视。snapd、ModemManager、wpa_supplicant这些在服务器上毫无意义,systemctl disable --now彻底关掉。每关掉一个不必要的服务,就减少一个潜在的攻击入口。

用户权限与sudo配置

永远不要用root直接操作日常任务。创建一个普通用户,加入sudo组,然后配置sudoers让它只允许执行特定命令就更安全,但至少做到必须通过sudo提权。visudo编辑sudoers文件,确保有这样一行:%sudo ALL=(ALL:ALL) ALL,然后你的用户属于sudo组即可。更进一步,可以限制sudo命令列表,比如只允许执行systemctl、apt、journalctl等运维常用命令,但这对新手可能过于严格,至少做到必须输入密码才能sudo,不要加NOPASSWD。

检查/etc/passwd里有哪些用户可以登录,grep -v nologin /etc/passwd,除了root和你的管理用户,其他系统账户的shell都应该是/usr/sbin/nologin或/bin/false。如果有异常账户,立即排查。

Web服务隔离与权限控制

如果这台服务器要跑Web服务,无论是Nginx还是Apache,务必以非root用户运行。Nginx默认会以www-data用户运行worker进程,这个不要改。关键是你放网站文件的目录权限设置。网站根目录比如/var/www/html,所有者设为root:root,权限755,这样Web进程只能读不能写。需要上传的目录比如upload,单独设为www-data可写,权限770,并且在该目录下放置一个.htaccess或nginx配置禁用PHP执行。很多入侵都是通过上传目录写入webshell,禁掉PHP执行直接断了这条路。

Nginx配置里加几条安全头:add_header X-Frame-Options "SAMEORIGIN"; 防止点击劫持,add_header X-Content-Type-Options "nosniff"; 防止MIME类型嗅探,add_header X-XSS-Protection "1; mode=block"; 开启浏览器XSS过滤器。这些头不消耗服务器资源,但能有效防御客户端攻击。

备份策略:3-2-1原则的极简实现

安全运维的最后一道防线是备份。3-2-1原则指3份副本、2种介质、1份异地。极简实现方案是用rsync加cron定时任务。每天凌晨把关键目录同步到外挂存储或另一台服务器。脚本核心就一行:rsync -avz --delete /var/www /etc /home /备份目标路径。--delete参数让目标与源严格一致,避免残留已删除的漏洞文件。备份目标如果是远程服务器,用ssh密钥认证,限制备份用户的shell为rssh或直接使用rsync专用命令限制。cron设置凌晨4点执行,比logwatch晚一小时,确保日志已经生成完毕再备份。

数据库备份同理,mysqldump或pg_dump导出后一并rsync。如果数据量小,可以直接tar打包压缩,文件名带日期,保留最近30天的滚动备份。这套方案没有花哨的增量备份和快照,但胜在简单可靠,出问题五分钟就能恢复。

定期审计与更新检查

安全不是一次配置终身无忧。每月至少做一次全面检查:执行apt update && apt upgrade看有没有未安装的更新,执行debsecan查看已知漏洞,执行lynis audit system跑一遍安全审计。Lynis是开源的安全审计工具,会检查内核参数、文件权限、服务配置等上百项指标,给出具体修复建议。装完直接跑lynis audit system,看输出的Warning和Suggestion,逐条处理。不需要全部修到满分,但高危项必须清零。

另外关注Debian的安全公告邮件列表,或者定期查看Debian Security页面。出现高危漏洞时,unattended-upgrades通常会在24小时内自动安装补丁,但你得确认它确实在工作。检查/var/log/unattended-upgrades/目录下的日志,看最近有没有成功安装的安全更新。

这套方案从SSH加固开始,到防火墙、内核参数、入侵防御、日志监控、服务精简、权限控制、Web安全、备份恢复,最后到持续审计,覆盖了一台Debian服务器从上线到长期运维的全生命周期。每一步都给出了具体命令和配置,没有抽象的理论,没有复杂的架构图,拿过去直接就能用。安全运维的本质不是堆砌工具,而是持续缩减攻击面并保持可见性,你始终知道服务器上在发生什么,这才是极简方案的核心逻辑。