Debian 服务器上线前安全加固:附一键部署脚本
Debian 安全加固方案|一键部署
在生产环境中,Debian 服务器常被用于部署 Web 服务、数据库、缓存、文件服务、CI/CD、容器平台等关键业务。由于其稳定、轻量、软件仓库成熟,Debian 一直是服务器系统中的热门选择。但稳定并不意味着天然安全,任何暴露在公网或企业内网中的服务器,都可能面临口令爆破、漏洞利用、权限滥用、恶意进程驻留、日志篡改、弱配置等风险。
本文将围绕 Debian 安全加固 展开,提供一套适合大多数服务器的通用安全加固思路,并附带一个可直接使用的 一键部署脚本。该方案主要面向 Debian 11 / Debian 12 系统,适用于云服务器、物理机、虚拟机以及基础业务服务器。
说明:本文方案以“通用安全基线”为目标,不代表所有场景都可无脑套用。若服务器承载数据库、容器集群、堡垒机、VPN、Kubernetes、邮件服务等特殊业务,请在执行前做好评估与备份。
一、为什么 Debian 服务器需要安全加固?
Debian 默认安装完成后,系统通常处于“可用但未充分加固”的状态。例如:
- SSH 可能允许 root 远程登录;
- 默认 SSH 端口暴露在公网;
- 系统未配置自动安全更新;
- 防火墙策略不完善;
- 用户密码复杂度要求不足;
- 日志审计能力有限;
- 无登录失败封禁策略;
- 内核参数未针对网络攻击做优化;
- 不必要的软件包、服务可能处于开启状态;
- 文件权限和账号权限可能缺乏检查。
攻击者最常见的入侵方式并不总是复杂的 0day,而是利用以下问题:
- 弱口令或复用密码;
- SSH 暴力破解;
- 未修复的系统漏洞;
- 服务错误配置;
- Web 应用漏洞导致权限扩大;
- 过度授权的普通用户;
- 日志缺失导致问题无法追踪。
因此,服务器上线前进行安全加固,是基础运维工作中非常重要的一环。
二、Debian 安全加固总体目标
一套合理的 Debian 安全加固方案,应当至少覆盖以下方向:
| 加固方向 | 目标 |
|---|---|
| 系统更新 | 保持系统安全补丁及时安装 |
| SSH 安全 | 减少远程登录暴露面,防止爆破 |
| 防火墙 | 仅开放必要端口 |
| 账户权限 | 限制 root 使用,强化 sudo 管理 |
| 密码策略 | 提升账号密码复杂度 |
| 登录保护 | 对异常登录进行封禁 |
| 内核参数 | 降低常见网络攻击影响 |
| 日志审计 | 保留关键行为记录 |
| 服务管理 | 禁用无关服务 |
| 文件权限 | 保护关键配置和敏感文件 |
| 时间同步 | 保证日志时间准确 |
| 自动更新 | 自动安装安全补丁 |
三、加固前准备工作
在执行任何安全加固之前,务必完成以下准备:
1. 备份重要数据
建议至少备份以下内容:
/etc
/home
/var/www
/var/lib/mysql
/var/lib/postgresql
/opt
如果是云服务器,建议先创建快照。
2. 确认有备用登录方式
如果你准备修改 SSH 端口、禁用 root 登录或启用防火墙,请确保:
- 当前 SSH 会话不要立即关闭;
- 云厂商控制台可以进入系统;
- 已创建普通 sudo 用户;
- 新 SSH 端口已在云安全组中放行;
- 防火墙规则不会误封自己。
3. 明确业务所需端口
常见端口如下:
| 服务 | 端口 |
|---|---|
| SSH | 22 或自定义端口 |
| HTTP | 80 |
| HTTPS | 443 |
| MySQL | 3306 |
| PostgreSQL | 5432 |
| Redis | 6379 |
| Docker API | 2375/2376 |
| Kubernetes API | 6443 |
原则上,不需要对公网开放的端口,一律不要开放。
四、核心加固项说明
1. 系统更新与安全补丁
保持系统更新是最基础的安全措施。Debian 官方会持续发布安全补丁,如果长期不更新,攻击者可能利用公开漏洞直接入侵系统。
执行命令:
apt update
apt upgrade -y
apt autoremove -y
建议安装自动安全更新组件:
apt install -y unattended-upgrades apt-listchanges
dpkg-reconfigure unattended-upgrades
自动更新的主要作用是及时安装安全补丁,降低人工遗漏风险。对于生产环境,可以只启用安全更新,不建议自动升级所有软件包,以免业务依赖发生变化。
2. SSH 安全加固
SSH 是服务器最常见的远程入口,也是攻击者重点扫描和爆破的目标。
建议采取以下措施:
- 禁止 root 用户远程登录;
- 禁止空密码登录;
- 建议使用密钥认证;
- 限制最大认证次数;
- 设置登录超时时间;
- 可选:修改默认端口;
- 可选:限制允许登录的用户;
- 安装 fail2ban 防止暴力破解。
典型 SSH 配置如下:
PermitRootLogin no
PasswordAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 60
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
UseDNS no
如果已经配置了密钥登录,可以进一步关闭密码登录:
PasswordAuthentication no
PubkeyAuthentication yes
注意:关闭密码登录前,请务必确认密钥登录可用,否则可能导致无法远程登录。
3. 创建普通 sudo 用户
生产服务器不建议长期使用 root 直接操作。应创建普通用户,并授予 sudo 权限。
示例:
adduser ops
usermod -aG sudo ops
之后使用该用户登录,再通过 sudo 执行管理命令。
这样做的好处包括:
- 降低 root 被直接爆破的风险;
- 操作日志更容易追踪;
- 可以按用户分配权限;
- 减少误操作造成的破坏。
4. 防火墙配置
Debian 上常用防火墙工具包括 iptables、nftables 和 ufw。对于普通服务器,ufw 简单易用,适合作为通用方案。
安装并启用:
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
如果 SSH 使用自定义端口,例如 22222:
ufw allow 22222/tcp
启用防火墙前一定要确认 SSH 端口已放行,否则可能导致远程连接中断。
5. fail2ban 登录防护
fail2ban 可以监控日志,当发现同一 IP 多次登录失败时,自动将其封禁一段时间。它对 SSH 暴力破解非常有效。
安装:
apt install -y fail2ban
创建配置文件:
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
典型 SSH 防护配置:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 3600
表示 10 分钟内失败 5 次,将封禁 1 小时。
查看状态:
fail2ban-client status
fail2ban-client status sshd
6. 密码策略加固
如果服务器仍允许密码登录,应设置较强的密码策略。可以安装 libpam-pwquality:
apt install -y libpam-pwquality
修改配置文件:
nano /etc/security/pwquality.conf
建议设置:
minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
retry = 3
含义:
- 密码长度至少 12 位;
- 至少包含数字;
- 至少包含大写字母;
- 至少包含小写字母;
- 至少包含特殊字符;
- 最多重试 3 次。
同时可以设置密码有效期:
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 1/' /etc/login.defs
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE 7/' /etc/login.defs
7. 内核参数安全优化
通过调整 sysctl 参数,可以增强系统对部分网络攻击的抵抗能力,例如 SYN Flood、IP Spoofing、ICMP 重定向等。
建议写入 /etc/sysctl.d/99-security-hardening.conf:
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
kernel.randomize_va_space = 2
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
应用配置:
sysctl --system
如果服务器作为路由器、NAT 网关、VPN 节点、Kubernetes 节点,部分网络参数需要根据实际情况调整,不能简单禁用 IP 转发。
8. 日志审计与时间同步
日志是安全事件排查的重要依据。应确保日志服务和时间同步正常。
安装常用组件:
apt install -y rsyslog logrotate chrony auditd
启用服务:
systemctl enable --now rsyslog
systemctl enable --now chrony
systemctl enable --now auditd
常见日志路径:
| 日志 | 路径 |
|---|---|
| SSH 登录日志 | /var/log/auth.log |
| 系统日志 | /var/log/syslog |
| 内核日志 | /var/log/kern.log |
| sudo 操作 | /var/log/auth.log |
| fail2ban 日志 | /var/log/fail2ban.log |
建议对关键服务器配置集中日志采集,例如使用 ELK、Graylog、Loki、Wazuh 等方案。
9. 禁用不必要服务
服务器暴露的服务越多,攻击面越大。可以使用以下命令查看当前服务:
systemctl list-unit-files --type=service
systemctl --type=service --state=running
查看监听端口:
ss -tulnp
如果发现不需要的服务,应停止并禁用:
systemctl disable --now 服务名
对于不需要的软件包,也可以直接卸载:
apt purge -y 软件包名
apt autoremove -y
10. 文件权限与敏感文件保护
关键文件权限应保持严格:
chmod 600 /etc/shadow
chmod 644 /etc/passwd
chmod 644 /etc/group
chmod 600 /etc/gshadow
chmod 700 /root
SSH 配置权限:
chmod 600 /etc/ssh/sshd_config
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
检查 SUID 文件:
find / -perm -4000 -type f 2>/dev/null
SUID 文件并不一定都是危险的,但异常新增的 SUID 文件可能意味着系统已被植入后门,需要重点关注。
五、Debian 安全加固一键部署脚本
下面提供一个通用的一键加固脚本,适用于 Debian 11 / Debian 12。脚本会执行以下操作:
- 更新系统软件包;
- 安装常用安全组件;
- 配置 SSH 安全选项;
- 安装并配置 UFW;
- 安装并配置 fail2ban;
- 配置基础密码策略;
- 配置内核安全参数;
- 启用 chrony、rsyslog、auditd;
- 设置关键文件权限;
- 生成加固报告。
强烈建议先在测试环境运行,确认无误后再应用到生产环境。
六、一键加固脚本内容
将以下内容保存为:
debian_hardening.sh
脚本如下:
#!/bin/bash
set -e
SSH_PORT="${SSH_PORT:-22}"
ALLOW_HTTP="${ALLOW_HTTP:-yes}"
ALLOW_HTTPS="${ALLOW_HTTPS:-yes}"
CREATE_USER="${CREATE_USER:-}"
REPORT_FILE="/root/debian_hardening_report_$(date +%F_%H%M%S).log"
log() {
echo -e "[+] $1" | tee -a "$REPORT_FILE"
}
warn() {
echo -e "[!] $1" | tee -a "$REPORT_FILE"
}
check_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "请使用 root 用户执行该脚本。"
exit 1
fi
}
backup_configs() {
log "备份关键配置文件..."
BACKUP_DIR="/root/security_backup_$(date +%F_%H%M%S)"
mkdir -p "$BACKUP_DIR"
cp -a /etc/ssh/sshd_config "$BACKUP_DIR/" 2>/dev/null || true
cp -a /etc/sysctl.conf "$BACKUP_DIR/" 2>/dev/null || true
cp -a /etc/login.defs "$BACKUP_DIR/" 2>/dev/null || true
cp -a /etc/security/pwquality.conf "$BACKUP_DIR/" 2>/dev/null || true
log "配置备份目录:$BACKUP_DIR"
}
update_system() {
log "更新系统软件包..."
apt update
DEBIAN_FRONTEND=noninteractive apt upgrade -y
apt autoremove -y
}
install_packages() {
log "安装安全加固组件..."
apt install -y \
sudo \
ufw \
fail2ban \
unattended-upgrades \
apt-listchanges \
libpam-pwquality \
rsyslog \
logrotate \
chrony \
auditd \
ca-certificates \
curl \
vim \
net-tools \
lsof
}
create_sudo_user() {
if [ -n "$CREATE_USER" ]; then
if id "$CREATE_USER" >/dev/null 2>&1; then
warn "用户 $CREATE_USER 已存在,跳过创建。"
else
log "创建 sudo 用户:$CREATE_USER"
adduser "$CREATE_USER"
usermod -aG sudo "$CREATE_USER"
fi
else
warn "未设置 CREATE_USER,跳过创建普通用户。"
fi
}
configure_ssh() {
log "配置 SSH 安全策略..."
SSHD_CONFIG="/etc/ssh/sshd_config"
cp -a "$SSHD_CONFIG" "${SSHD_CONFIG}.bak.$(date +%F_%H%M%S)"
set_sshd_option() {
local key="$1"
local value="$2"
if grep -qE "^\s*#?\s*${key}\s+" "$SSHD_CONFIG"; then
sed -i -E "s|^\s*#?\s*${key}\s+.*|${key} ${value}|g" "$SSHD_CONFIG"
else
echo "${key} ${value}" >> "$SSHD_CONFIG"
fi
}
set_sshd_option "Port" "$SSH_PORT"
set_sshd_option "PermitRootLogin" "no"
set_sshd_option "PermitEmptyPasswords" "no"
set_sshd_option "MaxAuthTries" "3"
set_sshd_option "LoginGraceTime" "60"
set_sshd_option "ClientAliveInterval" "300"
set_sshd_option "ClientAliveCountMax" "2"
set_sshd_option "X11Forwarding" "no"
set_sshd_option "UseDNS" "no"
set_sshd_option "PubkeyAuthentication" "yes"
if sshd -t; then
systemctl restart ssh || systemctl restart sshd
log "SSH 配置已应用,端口:$SSH_PORT"
else
warn "SSH 配置检测失败,已保留备份,请手动检查。"
exit 1
fi
}
configure_firewall() {
log "配置 UFW 防火墙..."
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow "${SSH_PORT}/tcp"
if [ "$ALLOW_HTTP" = "yes" ]; then
ufw allow 80/tcp
fi
if [ "$ALLOW_HTTPS" = "yes" ]; then
ufw allow 443/tcp
fi
ufw --force enable
log "UFW 防火墙已启用。"
ufw status verbose | tee -a "$REPORT_FILE"
}
configure_fail2ban() {
log "配置 fail2ban..."
mkdir -p /etc/fail2ban/jail.d
cat > /etc/fail2ban/jail.d/sshd.local <> "$PWQUALITY"
fi
}
set_pwquality_option "minlen" "12"
set_pwquality_option "dcredit" "-1"
set_pwquality_option "ucredit" "-1"
set_pwquality_option "lcredit" "-1"
set_pwquality_option "ocredit" "-1"
set_pwquality_option "retry" "3"
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 1/' /etc/login.defs
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE 7/' /etc/login.defs
log "密码策略配置完成。"
}
configure_sysctl() {
log "配置内核安全参数..."
cat > /etc/sysctl.d/99-security-hardening.conf < /etc/apt/apt.conf.d/20auto-upgrades < /etc/apt/apt.conf.d/50unattended-upgrades </dev/null || true
echo ""
echo "SSH Port: $SSH_PORT"
echo ""
echo "Listening Ports:"
ss -tulnp || true
echo ""
echo "UFW Status:"
ufw status verbose || true
echo ""
echo "fail2ban Status:"
fail2ban-client status || true
echo ""
echo "Users with sudo group:"
getent group sudo || true
echo ""
echo "============================================="
} >> "$REPORT_FILE"
log "加固完成,报告文件:$REPORT_FILE"
}
main() {
check_root
log "开始 Debian 安全加固..."
backup_configs
update_system
install_packages
create_sudo_user
configure_ssh
configure_firewall
configure_fail2ban
configure_password_policy
configure_sysctl
configure_auto_updates
configure_services
fix_permissions
generate_report
log "全部加固任务已完成。"
warn "请不要立即关闭当前 SSH 会话,建议新开终端验证 SSH 登录是否正常。"
}
main
七、脚本使用方法
1. 下载或创建脚本
nano debian_hardening.sh
将上面的脚本内容粘贴进去,保存退出。
2. 授权执行
chmod +x debian_hardening.sh
3. 默认执行
bash debian_hardening.sh
默认情况下:
- SSH 端口保持 22;
- 放行 80 和 443;
- 不自动创建普通用户;
- 禁止 root 远程 SSH 登录;
- 启用 UFW 和 fail2ban。
八、自定义执行示例
1. 修改 SSH 端口为 22222
SSH_PORT=22222 bash debian_hardening.sh
执行前请确保云安全组已放行 22222 端口。
2. 创建普通 sudo 用户
CREATE_USER=ops bash debian_hardening.sh
脚本会创建 ops 用户,并加入 sudo 组。
3. 修改 SSH 端口并创建用户
SSH_PORT=22222 CREATE_USER=ops bash debian_hardening.sh
4. 不开放 HTTP 和 HTTPS
ALLOW_HTTP=no ALLOW_HTTPS=no bash debian_hardening.sh
适合不运行 Web 服务的服务器。
九、执行后的验证步骤
加固完成后,不建议立即关闭当前终端,应重新打开一个终端进行验证。
1. 验证 SSH 登录
如果端口为 22:
ssh ops@服务器IP
如果端口为 22222:
ssh -p 22222 ops@服务器IP
确认普通用户可以登录,并且可以执行:
sudo whoami
输出应为:
root
2. 检查防火墙状态
ufw status verbose
确认只开放了必要端口。
3. 检查 fail2ban 状态
fail2ban-client status
fail2ban-client status sshd
4. 检查 SSH 配置
sshd -t
systemctl status ssh
5. 查看监听端口
ss -tulnp
如果发现不明端口,需要进一步确认对应进程。
十、生产环境加固建议
上述脚本属于基础安全加固,若用于生产环境,还可以进一步强化。
1. 使用 SSH 密钥登录
建议生成密钥:
ssh-keygen -t ed25519
将公钥复制到服务器:
ssh-copy-id -p 端口 用户名@服务器IP
确认密钥登录成功后,再关闭密码登录:
PasswordAuthentication no
然后重启 SSH:
systemctl restart ssh
2. 使用堡垒机或 VPN
对于重要服务器,不建议直接暴露 SSH 到公网。可以使用:
- 企业 VPN;
- WireGuard;
- OpenVPN;
- 云厂商堡垒机;
- Teleport;
- JumpServer。
这样可以显著降低 SSH 被扫描和爆破的风险。
3. 最小化开放端口
数据库、Redis、Elasticsearch、Docker API 等服务不应直接暴露公网。尤其是 Redis、Docker API、MongoDB 等,一旦无认证或弱认证暴露,极易被入侵。
4. 配置集中日志与告警
建议将关键日志集中到日志平台,并设置告警规则,例如:
- root 登录告警;
- sudo 执行告警;
- SSH 登录失败次数异常;
- 防火墙封禁异常;
- 系统关键文件变更;
- 新增用户;
- 新增监听端口;
- CPU、内存、磁盘异常。
5. 定期安全巡检
建议每周或每月执行一次安全巡检,内容包括:
last
lastb
who
w
ss -tulnp
ps aux
systemctl --type=service --state=running
find / -perm -4000 -type f 2>/dev/null
重点关注异常登录、异常进程、异常端口、异常 SUID 文件和异常定时任务。
十一、常见问题与处理
1. 执行脚本后无法 SSH 登录怎么办?
可能原因:
- SSH 端口修改后未在云安全组放行;
- UFW 未放行新端口;
- SSH 配置错误;
- 禁止 root 登录但未创建普通用户;
- 密钥或密码认证方式配置错误。
处理方式:
- 通过云控制台 VNC 登录;
- 检查 SSH 配置:
sshd -t
nano /etc/ssh/sshd_config
- 检查防火墙:
ufw status
ufw allow 22/tcp
ufw allow 你的SSH端口/tcp
- 重启 SSH:
systemctl restart ssh
2. 是否一定要修改 SSH 默认端口?
不一定。修改端口不能替代真正的安全控制,但可以减少自动化扫描和低质量爆破日志。更重要的措施是:
- 禁止 root 登录;
- 使用密钥认证;
- 配置 fail2ban;
- 限制来源 IP;
- 使用堡垒机或 VPN。
3. 是否可以直接关闭密码登录?
可以,但必须先确认密钥登录正常。建议流程如下:
- 创建普通 sudo 用户;
- 配置该用户的 SSH 公钥;
- 测试密钥登录;
- 测试 sudo 权限;
- 修改
PasswordAuthentication no; - 重启 SSH;
- 保留当前会话,另开终端测试。
4. 自动安全更新是否有风险?
自动安全更新通常只安装安全补丁,风险较低。但在关键生产系统中,仍建议:
- 使用测试环境验证;
- 关注更新日志;
- 避免自动重启;
- 对内核升级后的重启进行维护窗口管理。
十二、安全加固检查清单
以下是一份简化版 Debian 安全加固检查清单:
| 检查项 | 是否完成 |
|---|---|
| 系统已更新 | ✅ |
| 已创建普通 sudo 用户 | ✅ |
| root SSH 登录已禁用 | ✅ |
| SSH 空密码登录已禁用 | ✅ |
| SSH 最大认证次数已限制 | ✅ |
| 防火墙已启用 | ✅ |
| 仅开放必要端口 | ✅ |
| fail2ban 已启用 | ✅ |
| 密码复杂度策略已配置 | ✅ |
| 自动安全更新已启用 | ✅ |
| 内核安全参数已优化 | ✅ |
| 日志服务正常运行 | ✅ |
| 时间同步正常运行 | ✅ |
| 关键文件权限已修复 | ✅ |
| 已生成加固报告 | ✅ |
| 已验证新 SSH 登录 | ✅ |
十三、总结
Debian 的安全加固并不是一次性工作,而是一个持续过程。本文提供的方案覆盖了服务器上线前最重要的基础安全项,包括系统更新、SSH 加固、防火墙、fail2ban、密码策略、内核参数、日志审计、自动安全更新和权限修复等内容。
对于普通 Web 服务器、业务应用服务器和中小型生产环境,这套加固方案可以显著提升系统的基础安全性,减少常见攻击带来的风险。但对于高安全等级场景,还应结合堡垒机、集中日志、主机入侵检测、漏洞扫描、配置基线检查、最小权限访问控制以及定期应急演练。
最后需要强调的是:安全加固的核心不是盲目堆配置,而是在了解业务需求的前提下,尽可能减少攻击面、强化访问控制、提升审计能力,并确保出现问题时能够快速定位和恢复。