尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Debian 12 服务器初始化与安全加固实战指南

Debian 12 服务器初始化与安全加固实战指南 刚拿到一台空白的 Debian 12 服务器多数人的第一反应是赶紧把业务装上去跑起来我踩过足够多的坑之后才明白真正耗时间的从来不是装软件而是那些没做好、后面反复来烦你的基础配置。Debian 12代号 bookworm是目前非常稳的长期支持版本它的默认策略比很多人想象中更克制系统只装最基础的一组包SSH 默认允许密码登录防火墙默认不开时间同步交给 systemd-timesyncd 简单打点。这套默认值放在家里的测试机上问题不大一旦放到公网环境基本等于把门虚掩着谁都能顺手推一下。所以这篇就把我这些年反复打磨的一套 Debian 12 服务器初始化配置流程完整写出来从账户、SSH、网络、时间、防火墙一直讲到磁盘、容器环境和备份脚本。它适合刚接触 Linux 运维的新手照着抄也适合有经验的老手拿来当检查清单看自己哪一步偷懒了。我尽量把每一步“为什么这么做”讲透而不是丢一条命令让你自己猜。1. 全新 Debian 12 到手先建立一套可回退的基线1.1 为什么初始化最忌讳“边装服务边调基础”我见过太多新手上来就装 Nginx、装数据库等跑了两天发现时区不对、日志时间全是 UTC或者某个服务因为 hostname 没配对导致集群里互相找不到再回头改的时候数据已经写进去了迁移成本比一开始就配好高出一个量级。初始化的本质不是装东西而是把一台机器从“能开机”变成“状态可控、可复现、出问题能退回去”。所以我的原则永远是先确立基线再分层加固最后才装业务运行时。基线的意思是——我知道这台机器的每个关键配置在哪、值是什么、为什么是这个值。任何一处说不清楚就说明还没初始化完。1.2 系统更新与软件源的确认拿到机器第一步不是改配置而是先把包索引和已有软件升到最新。Debian 12 默认的软件源通常指向官方镜像国内机器上如果没换源apt update会慢到让人怀疑人生。apt update apt full-upgrade -y apt install -y sudo curl wget vim git htop net-toolsfull-upgrade和upgrade的区别值得说一句upgrade不会因为依赖变化而删除包full-upgrade会全新机器上用它更彻底。至于换源Debian 12 仍然以传统的/etc/apt/sources.list为主但已经支持 deb822 新格式。传统写法长这样deb https://mirrors.example.org/debian bookworm main contrib non-free non-free-firmware deb https://mirrors.example.org/debian bookworm-updates main contrib non-free non-free-firmware deb https://mirrors.example.org/debian-security bookworm-security main contrib non-free non-free-firmware注意non-free-firmware这个组件是 Debian 12 才正式拆分出来的很多驱动的固件包都在这里老教程里没写照着抄可能装不上网卡或显卡固件。换完源记得再跑一遍apt update确认没有 GPG 报错再往下走。提示改源之前先备份/etc/apt/sources.list改坏了至少能cp回来别问我怎么知道的。1.3 用 sudo 而不是直接 rootDebian 12 安装时如果设置了 root 密码默认不会创建普通用户如果创建了普通用户那这个用户通常已经在sudo组里。这里有个容易被忽略的变化从 Debian 12 开始安装器创建的首个用户默认加入sudo组而早期版本是直接写进/etc/sudoers。两种方式结果类似但用组管理更好维护。我个人的习惯是绝对不用 root 直接登录操作root 只保留一条本地恢复通道所有日常操作走带 sudo 的普通账户。原因很实际误删文件时root 删了就是删了普通用户删除还有权限提示兜底审计日志里也能看出是谁在操作。2. 账户、密钥与 SSH 入口的第一轮收敛2.1 建立专职管理员账户如果系统里还没有合适的账户先建一个。我一般用一个语义明确的名字比如deploy或ops而不是admin这种谁都想抢的名字。adduser deploy usermod -aG sudo deployadduser是 Debian 上更友好的交互式脚本会顺带创建家目录、设置密码。useradd不带参数的话连家目录都不建新手最容易在这里栽跟头建完用户 SSH 登进去发现没有家目录、没有 shell 配置一脸茫然。2.2 公钥登录与私钥的存放密码登录在公网环境下几乎等于裸奔扫描器一天能撞几万次。正确做法是本地生成密钥对把公钥放到服务器上。ssh-keygen -t ed25519 -C deployweb01现在默认推荐 ed25519 而不是 RSA密钥更短、安全性更好。生成后把公钥贴到服务器的~/.ssh/authorized_keysmkdir -p ~/.ssh chmod 700 ~/.ssh vim ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys权限这步极其关键。SSH 对权限非常挑剔authorized_keys或家目录权限过松它会直接拒绝用这把钥匙登录而且默认只给一句含糊的Permission denied (publickey)让你以为是密钥贴错了。这是我见过新手卡最久的坑之一。注意本地私钥文件id_ed25519永远不要上传到服务器也不要放进 git 仓库。服务器上只需要公钥。2.3 sshd_config 逐项收紧接下来编辑/etc/ssh/sshd_config。我贴一份我常用的关键项并解释每一项在防什么配置项建议值作用PermitRootLoginno禁止 root 直接 SSH 登录PasswordAuthenticationno关闭密码登录只认密钥PubkeyAuthenticationyes开启公钥认证KbdInteractiveAuthenticationno关闭键盘交互式认证防止绕过密码策略MaxAuthTries3限制认证尝试次数LoginGraceTime30缩短登录宽限期AllowUsersdeploy白名单只允许指定用户登录改完不是直接重启服务而是先用sshd -t做语法检查sshd -t systemctl restart ssh这里有个常识但很致命的操作纪律改 SSH 配置时千万不要关掉当前这个连接一定要新开一个终端窗口验证新配置能登录成功确认无误后再关旧连接。否则配置写错、服务重启失败你就把自己锁在门外了只能去控制台救场。3. 主机名、时区与时间同步这些地基配置3.1 hostname 与 /etc/hosts 的配合主机名看似无关紧要但很多分布式组件、监控系统、日志系统都靠它做标识。设置很简单hostnamectl set-hostname web01但光设 hostname 不够还要同步/etc/hosts。因为不少程序在解析自己的主机名时会先查 hosts 文件如果里面只有一条127.0.1.1 your-old-hostname解析会变慢甚至报错。我通常这样改127.0.0.1 localhost 127.0.1.1 web01127.0.1.1这一行是 Debian 系的传统指向本机主机名保留它是为了兼容。有些服务启动慢、sudo提示卡顿根源就是这里解析超时。3.2 时区从 UTC 改到本地云服务器默认时区常年是 UTC这本身没错甚至很多人主张服务器就该用 UTC。但如果你看日志、对业务时间点UTC 会让人每次都心算加减容易出错。我的折中是生产服务器保持 UTC 便于统一但日志展示层做转换个人或小团队机器直接设成本地时区省心。timedatectl set-timezone Asia/Shanghai timedatectl3.3 NTP 时间同步为什么不能省时间不同步的后果新手往往体会不深直到有一天发现HTTPS 证书校验失败、数据库主从复制报错、分布式日志时间戳乱序、TOTP 两步验证永远验证不过。这些几乎都和系统时钟漂移有关。Debian 12 默认用 systemd-timesyncd轻量够用timedatectl set-ntp true timedatectl timesync-status如果对时间精度要求更高比如要跑集群、做金融类业务就换成 chrony它能更平滑地校准时钟、支持更多上游源apt install -y chrony systemctl enable --now chrony chronyc sources -v chronyc trackingchronyc tracking里的System time那个值正常应该接近 0如果显示几秒甚至几分钟的偏移说明同步根本没生效优先检查 UDP 123 端口有没有被防火墙挡住。4. 网络配置从动态地址到固定地址4.1 先看清楚网卡与当前状态动手改网络前必须先确认网卡名字。Debian 12 默认采用可预测网卡命名名字可能是ens18、enp3s0这种不再是老掉牙的eth0。ip addr show ip route showip route里default via后面就是当前网关这些信息改静态地址时都要用上。很多人改网络改到失联就是因为把网关或子网掩码写错一个字符之差就连不上了。4.2 用 ifupdown 配置静态地址Debian 12 传统安装默认用 ifupdown配置文件是/etc/network/interfaces。典型静态配置auto ens18 iface ens18 inet static address 192.168.1.50/24 gateway 192.168.1.1 dns-nameservers 223.5.5.5 119.29.29.29改完执行ifdown ens18 ifup ens18如果是云主机很多平台用 cloud-init 或 systemd-networkd 管理网络直接手改 interfaces 可能不生效重启就被覆盖。这种情况要改/etc/systemd/network/下的.network文件或修改 cloud-init 的网络配置。4.3 DNS 与 resolv.conf 被覆盖的坑新手最常见的困惑是明明改了/etc/resolv.conf重启后又变回去了。原因是这个文件现在常常是符号链接实际由systemd-resolved或resolvconf管理你直接改它当然无效。正确做法是去改/etc/systemd/resolved.conf里的DNS项然后systemctl restart systemd-resolved提示ls -l /etc/resolv.conf看一眼它是不是软链能省你半小时的困惑。5. 防火墙、内核参数与自动安全更新5.1 nftables 与 ufw 怎么选Debian 12 底层包过滤框架已经是 nftablesiptables 是兼容层。对新手我推荐用ufw这个前端规则直观对要写复杂规则的老手直接用 nftables 更灵活。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 ufw status verbose先放行 SSH 端口再启用这个顺序非常重要。你要是先ufw enable再放行 22那你当前连接立刻被切断又是一次控制台之旅。云服务器还有一层安全组两层要配合着开别只开一层然后怀疑人生。5.2 内核参数的加固基线通过 sysctl 调整内核参数能在网络层挡掉一大批常见扫描和攻击。我一般新建一个独立文件不直接改/etc/sysctl.conf方便管理和回退vim /etc/sysctl.d/99-hardening.confnet.ipv4.conf.all.rp_filter 1 net.ipv4.tcp_syncookies 1 net.ipv4.conf.all.accept_redirects 0 net.ipv6.conf.all.accept_redirects 0 net.ipv4.conf.all.accept_source_route 0 net.ipv4.icmp_echo_ignore_broadcasts 1 kernel.dmesg_restrict 1rp_filter做反向路径校验能防 IP 欺骗tcp_syncookies缓解 SYN Floodaccept_redirects关闭 ICMP 重定向防止路由被恶意篡改。改完执行sysctl --system生效。5.3 自动安全更新手动升级系统最容易忘记安全补丁拖几个月不打的机器一抓一大把。unattended-upgrades 可以自动只打安全更新既及时又不会把系统升乱apt install -y unattended-upgrades dpkg-reconfigure --prioritylow unattended-upgrades它默认只处理安全源这个策略我很认可——自动升级最怕把业务依赖的版本一起升上去只打安全补丁是风险最低的折中。6. 常用工具链与运行环境的准备6.1 必备命令行工具基础工具要不要装齐取决于你后面怎么用。我列一组几乎每台机器都会用到的apt install -y curl wget git vim htop tmux jq unzip rsync其中tmux值得单独说。你 SSH 上去跑一个耗时半小时的编译或数据同步网络一抖连接断开进程跟着被 SIGHUP 杀掉前面全白干。用 tmux 起一个会话断线后重连还能接上这是运维里保命的习惯。6.2 Docker 与容器运行时Debian 官方源里的 Docker 版本偏旧我建议用官方仓库装install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc chmod ar /etc/apt/keyrings/docker.asc然后添加源、apt update、装docker-ce。装完把需要用的用户加入docker组usermod -aG docker deploy注意需要重新登录才生效。另外要清楚加入 docker 组等于给了接近 root 的权限因为它能挂载宿主机目录这点在多人共用的服务器上要谨慎。6.3 多版本运行时环境如果机器上要跑 PythonDebian 12 自带 Python 3.11但系统 Python 是给系统工具用的你在上面pip install一堆包很容易把系统工具搞崩。稳妥做法是用 venv 隔离apt install -y python3-venv python3-pip python3 -m venv /opt/app/venv source /opt/app/venv/bin/activateNode 那边同理优先用 nvm 或 NodeSource 管理多版本不要和系统包管理器混着装否则后面版本冲突能查到你崩溃。7. 磁盘、Swap 与数据盘规划7.1 先摸清磁盘与挂载现状lsblk -f df -hlsblk -f能一眼看清每块盘的容量、分区、文件系统和挂载点。新手最容易忽略的是云主机常挂一块数据盘但默认没格式化也没挂载你把数据写进去其实是写到了系统盘。所以初始化时确认每块盘的去向比什么优化都重要。7.2 按需创建 Swap 文件Debian 12 安装时如果没划 swap 分区或者容器里默认不给 swap可以手动加一个 swap 文件。注意fallocate在某些文件系统上创建的文件可能不能直接用遇到问题换ddfallocate -l 2G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo /swapfile none swap sw 0 0 /etc/fstab顺手调一下 swappiness。默认值 60 对服务器偏高容易频繁换出内存影响性能我一般设成 10vm.swappiness 107.3 数据盘格式化和持久挂载新数据盘先分区或直接整盘用格式化成 ext4 或 xfsmkfs.ext4 /dev/sdb1 mkdir -p /data持久挂载强烈建议用 UUID 而不是设备名因为设备名在重启或加盘后可能变blkid /dev/sdb1 echo UUIDxxxx-xxxx /data ext4 defaults,noatime 0 2 /etc/fstab mount -anoatime能减少每次读文件的元数据写入对高并发读的场景有实打实的提升。改完 fstab 一定要mount -a验证写错了会导致系统起不来那就麻烦了。8. 登录防护、连接审计与故障定位8.1 用 fail2ban 挡住暴力破解即使关了密码登录日志里依然会刷满来自全网的连接尝试。fail2ban 会监控日志对反复失败的 IP 自动加临时封禁apt install -y fail2ban在/etc/fail2ban/jail.local里配一段针对 SSH 的策略比如最大重试 5 次、封禁 1 小时。它本质上是给系统加了一层自动反应能力效果比人工看日志好得多。8.2 别到出事才想起看日志初始化阶段就把日志习惯养起来出问题时你会感谢自己journalctl -u ssh -n 50 --no-pager journalctl -p err -b last -a | headjournalctl -p err -b只列本次启动以来的错误级别日志排查问题非常高效。last能看到最近的登录记录如果出现你没见过的 IP 登录成功那就是要紧事了立刻改密钥、查进程。8.3 长时间会话的保持前面提了 tmux这里补一个客户端侧的小技巧在本地~/.ssh/config里加心跳防止长时间无操作被中间设备掐断Host web01 HostName 192.168.1.50 User deploy ServerAliveInterval 60 ServerAliveCountMax 3这样每 60 秒发一次心跳会话能稳定保持配合 tmux 基本做到断线无感。9. 快照、备份与把整套初始化脚本化9.1 动手之前先留一条退路云主机要充分利用快照功能在动网络、动 fstab、动 SSH 之前先打一个快照。我年轻的时候改 fstab 挂载把系统改成起不来的状态最后只能重装代价是半天时间和一堆没备份的配置。有了快照改坏了直接回滚几分钟的事。这个习惯在我看来比任何优化技巧都值钱。9.2 写一个可复用的 bootstrap 脚本一次初始化做完如果你以后还要开第二台、第三台就不该再手敲一遍。把上面这些步骤整理成一个脚本参数化的部分抽成变量比如主机名、IP、时区。脚本里加上set -euo pipefail任何一步失败立刻停避免带着半成品状态继续跑下去。这个脚本本质上是你团队的知识沉淀新人拿到它就能拉起一台合格的机器。9.3 收尾的检查清单初始化做完我会对着清单过一遍SSH 是否已禁密码登录且新连接验证通过防火墙是否已启用且放行了必要端口时间是否同步防火墙和云安全组是否两层都开了/etc/fstab是否mount -a无报错自动安全更新是否生效有没有做快照。这份清单看着啰嗦但每一条背后都是我或者同行真实踩过的坑。我自己习惯把这份清单存成一台机器的 README放在/root/或者仓库里下次维护时直接照着核对。最后分享一个我用了很多年的小习惯每台机器初始化完我会把关键配置文件sshd_config、interfaces、fstab、sysctl 那几份复制到一个统一目录或者直接进 git。这样半年后你回来改东西不用去猜当初设了什么值一对比就知道。运维这行能省下的从来不是敲命令的时间而是回忆和排查的时间。
返回列表