上一篇 下一篇 分享链接 返回 返回顶部

Debian 服务器上线前安全加固:附一键部署脚本

发布人:慈云数据-客服中心 发布时间:11小时前 阅读量:4

Debian 安全加固方案|一键部署

在生产环境中,Debian 服务器常被用于部署 Web 服务、数据库、缓存、文件服务、CI/CD、容器平台等关键业务。由于其稳定、轻量、软件仓库成熟,Debian 一直是服务器系统中的热门选择。但稳定并不意味着天然安全,任何暴露在公网或企业内网中的服务器,都可能面临口令爆破、漏洞利用、权限滥用、恶意进程驻留、日志篡改、弱配置等风险。

本文将围绕 Debian 安全加固 展开,提供一套适合大多数服务器的通用安全加固思路,并附带一个可直接使用的 一键部署脚本。该方案主要面向 Debian 11 / Debian 12 系统,适用于云服务器、物理机、虚拟机以及基础业务服务器。

说明:本文方案以“通用安全基线”为目标,不代表所有场景都可无脑套用。若服务器承载数据库、容器集群、堡垒机、VPN、Kubernetes、邮件服务等特殊业务,请在执行前做好评估与备份。


一、为什么 Debian 服务器需要安全加固?

Debian 默认安装完成后,系统通常处于“可用但未充分加固”的状态。例如:

  • SSH 可能允许 root 远程登录;
  • 默认 SSH 端口暴露在公网;
  • 系统未配置自动安全更新;
  • 防火墙策略不完善;
  • 用户密码复杂度要求不足;
  • 日志审计能力有限;
  • 无登录失败封禁策略;
  • 内核参数未针对网络攻击做优化;
  • 不必要的软件包、服务可能处于开启状态;
  • 文件权限和账号权限可能缺乏检查。

攻击者最常见的入侵方式并不总是复杂的 0day,而是利用以下问题:

  1. 弱口令或复用密码;
  2. SSH 暴力破解;
  3. 未修复的系统漏洞;
  4. 服务错误配置;
  5. Web 应用漏洞导致权限扩大;
  6. 过度授权的普通用户;
  7. 日志缺失导致问题无法追踪。

因此,服务器上线前进行安全加固,是基础运维工作中非常重要的一环。


二、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 上常用防火墙工具包括 iptablesnftablesufw。对于普通服务器,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 登录但未创建普通用户;
  • 密钥或密码认证方式配置错误。

处理方式:

  1. 通过云控制台 VNC 登录;
  2. 检查 SSH 配置:
sshd -t
nano /etc/ssh/sshd_config
  1. 检查防火墙:
ufw status
ufw allow 22/tcp
ufw allow 你的SSH端口/tcp
  1. 重启 SSH:
systemctl restart ssh

2. 是否一定要修改 SSH 默认端口?

不一定。修改端口不能替代真正的安全控制,但可以减少自动化扫描和低质量爆破日志。更重要的措施是:

  • 禁止 root 登录;
  • 使用密钥认证;
  • 配置 fail2ban;
  • 限制来源 IP;
  • 使用堡垒机或 VPN。

3. 是否可以直接关闭密码登录?

可以,但必须先确认密钥登录正常。建议流程如下:

  1. 创建普通 sudo 用户;
  2. 配置该用户的 SSH 公钥;
  3. 测试密钥登录;
  4. 测试 sudo 权限;
  5. 修改 PasswordAuthentication no
  6. 重启 SSH;
  7. 保留当前会话,另开终端测试。

4. 自动安全更新是否有风险?

自动安全更新通常只安装安全补丁,风险较低。但在关键生产系统中,仍建议:

  • 使用测试环境验证;
  • 关注更新日志;
  • 避免自动重启;
  • 对内核升级后的重启进行维护窗口管理。

十二、安全加固检查清单

以下是一份简化版 Debian 安全加固检查清单:

检查项 是否完成
系统已更新
已创建普通 sudo 用户
root SSH 登录已禁用
SSH 空密码登录已禁用
SSH 最大认证次数已限制
防火墙已启用
仅开放必要端口
fail2ban 已启用
密码复杂度策略已配置
自动安全更新已启用
内核安全参数已优化
日志服务正常运行
时间同步正常运行
关键文件权限已修复
已生成加固报告
已验证新 SSH 登录

十三、总结

Debian 的安全加固并不是一次性工作,而是一个持续过程。本文提供的方案覆盖了服务器上线前最重要的基础安全项,包括系统更新、SSH 加固、防火墙、fail2ban、密码策略、内核参数、日志审计、自动安全更新和权限修复等内容。

对于普通 Web 服务器、业务应用服务器和中小型生产环境,这套加固方案可以显著提升系统的基础安全性,减少常见攻击带来的风险。但对于高安全等级场景,还应结合堡垒机、集中日志、主机入侵检测、漏洞扫描、配置基线检查、最小权限访问控制以及定期应急演练。

最后需要强调的是:安全加固的核心不是盲目堆配置,而是在了解业务需求的前提下,尽可能减少攻击面、强化访问控制、提升审计能力,并确保出现问题时能够快速定位和恢复。

目录结构
全文