服务器入坑指北:从连上到跑通
新机器到手,多数人的第一反应是
ssh root@<IP>上去就把服务跑起来——能用就行。真正让人半夜爬起来的是另外几件事:口令登录忘了关,防火墙规则一改就再也连不上,swap 写进fstab却把系统拖进紧急模式,日志悄无声息写满磁盘。
这些事都不难,难在顺序:先验证密钥再关密码登录,先放行新端口再删旧端口,先
swapoff再动fstab。顺序反了,代价就是从「改一行配置」变成「重做一台机器」。
本篇按我个人的顺序走一遍:连接 → 系统配置 → SWAP 与 zRAM → 调优 → 安全 → 容器。每条给出可以直接抄的配置片段和验证命令
1. 连接:先能安全地登进去
1.1 SSH 密钥登录与加固的顺序
公钥就位 → 新终端确认免密登录成功 → 再关密码登录。顺序反了就是自己锁门。
# 本地:生成密钥对(已有密钥务必 -f 换文件名,避免覆盖掉 GitHub 免密那类配置)
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_srv -C "ops@example"
ssh-copy-id -i ~/.ssh/id_ed25519_srv.pub ops@<服务器地址>
# 服务器:目录 700、文件 600 是硬要求,权限放宽 sshd 会直接拒绝这把钥匙
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
# /etc/ssh/sshd_config.d/99-hardening.conf(RHEL 系写主配置并同步 SELinux 上下文)
PubkeyAuthentication yes
PermitRootLogin prohibit-password
MaxAuthTries 3
UseDNS no
# PasswordAuthentication no ← 新终端验证免密成功后再打开这一行
sshd -t && systemctl reload ssh # RHEL 系:systemctl reload sshd
last -n 5; lastb -n 5 # 本次登录 / 失败尝试
2. 系统配置
2.1 时区、时间同步与主机名
chrony 与 systemd-timesyncd 二选一——同时运行会互相争抢时间源。时区要同时落到 /etc/timezone 与 /etc/localtime,只改一个会出现「命令行时间对、服务日志时间不对」。
timedatectl set-timezone Asia/Shanghai && timedatectl set-ntp true && timedatectl status
hostnamectl set-hostname app-01
# /etc/chrony/chrony.conf:只保留一组时间源
pool <内网或就近 NTP 源> iburst
2.2 日志不会自己停下来
journald 设整体占用上限;轮转配置存在不等于轮转在跑——确认可执行文件与定时任务都在,再相信那份配置。
# /etc/systemd/journald.conf
SystemMaxUse=2G # 按磁盘容量定
MaxRetentionSec=30day
# /etc/logrotate.d/<服务名>
/var/log/<服务名>/*.log {
weekly
rotate 8
compress
missingok
notifempty
copytruncate
}
logrotate -d /etc/logrotate.conf 2>&1 | tail -5 # 干跑,看命中哪些文件
3. SWAP 与 zRAM
3.1 交换空间的两个坑
fallocate 在个别文件系统上会生成空洞文件,dd 慢一些更稳妥;fstab 用路径并加 nofail(swap 文件是固定路径,不像设备名会漂移),否则单盘异常会把系统拖进紧急模式。改大小或删除时顺序不能反:先 swapoff → 删 fstab 条目 → 再删文件。
dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
swapon --show
cp /etc/fstab /etc/fstab.bak
echo '/swapfile none swap sw,nofail 0 0' | tee -a /etc/fstab
findmnt --verify
# 改大小 / 删除
swapoff /swapfile
sed -i '/\/swapfile/d' /etc/fstab
rm /swapfile
vm.swappiness 控制换出倾向,盲目调高会放大抖动。
3.2 zram:交给 zram-generator 管
zRAM 是在内存里划出的压缩交换设备,比磁盘 swap 快得多,代价是吃 CPU、掉电即丢。别和 zramswap、zram-tools 一类脚本同时用——它们都会去建 /dev/zram0。
# /etc/systemd/zram-generator.conf
[zram0]
zram-size = ram / 2 # 默认 min(ram / 2, 4096),推荐 0.1–0.5 倍内存
compression-algorithm = zstd # 压缩率高选 zstd,速度优先选 lz4;不写则用内核默认
swap-priority = 100 # 默认即 100,高于 fstab 里没写 pri 的磁盘 swap
# fs-type 不写就是 swap
apt install -y systemd-zram-generator # Debian 12+;Fedora/RHEL:dnf install -y zram-generator
systemctl daemon-reload
systemctl start /dev/zram0
zramctl; swapon --show # 确认设备、算法与优先级
生成器在开机早期由 systemd 调用,配好之后不需要额外动作。看实际压缩效果:
zramctl --output-all
awk '{printf "压缩率 %.2fx\n", $1/$2}' /sys/block/zram0/mm_stat
# /etc/sysctl.d/99-swap.conf:zram 场景下把预读关掉,省掉解压前的无谓读盘
vm.swappiness = <按本机规格定>
vm.page-cluster = 0
4. 调优
4.1 内核参数先读再改
当前值往往不是发行版默认值——容器运行时、平台镜像、此前的调优都会写入。
sysctl -n vm.swappiness vm.vfs_cache_pressure vm.overcommit_memory
# /etc/sysctl.d/99-tuning.conf
vm.swappiness = <按本机规格定>
vm.vfs_cache_pressure = <按本机规格定>
# 加载并复核
# sysctl --system
改动统一放 /etc/sysctl.d/ 下的独立文件,便于审计与迁移。
4.2 拥塞控制看内核接口,不看配置文件
算法出现在可用列表里、且当前值等于目标值,才算真的启用。
sysctl net.ipv4.tcp_available_congestion_control net.ipv4.tcp_congestion_control
# /etc/sysctl.d/99-net-tuning.conf
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
# 加载并复核:sysctl --system
容器内部分参数不可见属命名空间裁剪,不是配置错误。本文不给任何吞吐或延迟数字承诺。
5. 安全加固
5.1 默认拒绝 + 来源收敛
管理端口来源限定为固定出口 IP 或运维网段,不对任意来源放通;只调整规则,不停用防火墙。
# Debian 系(ufw)
ufw default deny incoming && ufw default allow outgoing
ufw allow from <固定出口IP或运维网段> to any port 22 proto tcp
ufw status verbose # 确认不会掐断当前会话
# RHEL 系(firewalld)
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=<固定出口IP或运维网段> port port=22 protocol=tcp accept'
firewall-cmd --reload
# 直接写 nftables 时:-c 只做语法检查,不实际加载
nft -c -f /etc/nftables.conf
5.2 别让几套工具互相覆盖
ufw/firewalld、nftables/iptables、自动封禁、容器运行时都在写规则。自定义放行写在 ufw 或运行时提供的专用链里,不直接改别人管理的链。规则互相覆盖的表现是「状态显示已关,外部仍能连上」。
# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
backend = systemd # Debian 12 起弃用 rsyslog,走 systemd journal
maxretry = 3
bantime = 1h
banaction = ufw
ignoreip = <运维网段>
5.3 强制访问控制只调策略
先确认是谁在拦截,再针对具体操作放宽;保持 enforcing,不要整体关掉。
getenforce; sestatus | head -5 # RHEL 系
aa-status # Debian 系
setsebool -P <被拦截项对应的布尔开关> on # 只放行这一项
6. 容器(不用容器整节跳过)
6.1 控制套接字等于主机 root
ls -l /var/run/docker.sock; docker info | head -20
// /etc/docker/daemon.json
{
"icc": false,
"no-new-privileges": true
}
需要设备访问时按最小能力集授予,不用 --privileged;有条件时启用用户命名空间或 rootless(userns-remap 会改变卷属主语义,先测试再上),并统一 cgroup v2 保持资源限制一致。
6.2 防火墙与容器转发的顺序
容器运行时会自行写入转发与地址转换规则,顺序不当就会出现「防火墙显示端口已关、外部仍能连上」。主机防火墙管入站链,运行时管转发链。
ufw status verbose; nft list ruleset | head -20
firewall-cmd --list-all # RHEL 系
firewall-cmd --permanent --zone=<受控zone> --add-interface=<容器网桥>
结语
顺序本身就是内容。先验证密钥再关口令登录、先放行新端口再删旧端口、先 swapoff 再删 fstab 条目——这几件事都是「顺序反了就失联或起不来」。连接与访问面收口、系统与内存打好底、再调优,最后才该把时间花在服务上。
避坑清单
- 密钥还没验证就关掉口令登录:先新开会话确认免密成功。
- 改完 sshd 直接 restart:先
sshd -t再 reload,并保留一个已登录会话。 - 把改端口当安全加固:它只减少扫描噪音,真正的边界是来源收敛。
- 管理端口对任意来源放通:限定为固定出口 IP 或运维网段。
- 改 swap 顺序颠倒:先
swapoff→ 删fstab条目 → 删文件,反了就是紧急模式。 - zram 和 zramswap/zram-tools 同时用:两套都会建
/dev/zram0,只留一个。 - 随手放宽强制访问控制:保持 enforcing,只调被拦截的那条策略。
- 装完安全更新不看
/var/run/reboot-required:内核与核心库补丁要重启才生效。 - 只做备份从不还原:没演练过的备份不算备份。
- 把易变内容写死:镜像源地址、证书签发渠道、价格与额度数值,只留判定原则与官方入口。
- 占位符必须换成自己的值;标了「按本机规格定」的数值不要照抄别人的。
- 点赞
- 收藏
- 关注作者
评论(0)