Skip to content

系统初始化基线

新服务器投入使用前,基础状态需要先统一:主机身份、名称解析、时间同步、软件源、基础工具、登录方式、防火墙策略、系统参数和资源限制。基线配置不等于完整安全加固,它更接近机器交付前的最低可用状态。后续排查日志时间、证书校验、Kubernetes 节点状态、数据库复制延迟、监控采集异常时,这些基础项会反复出现。

一、基线项清单

系统初始化可以按下面几类整理。不同公司会把安全、审计、账号、监控 Agent 也纳入基线,下面记录操作系统层面最常见的一组。

分类配置项常见用途
主机身份hostname、/etc/hosts批量管理、日志识别、集群节点互相解析
网络解析DNS、NSS 顺序软件安装、域名访问、内网服务解析
时间同步时区、chrony、硬件时钟日志排序、证书校验、集群一致性
软件环境软件源、EPEL、基础工具后续安装和排障命令可用
登录访问SSH、sudo、密钥远程管理入口
网络策略firewalld / iptables控制端口暴露范围
系统参数sysctl、limits、systemd limit网络连接、文件句柄、进程资源
存储基础swap、fstab、挂载检查避免重启后挂载丢失或启动失败
日志审计journald、rsyslog、logrotate保留操作和故障现场信息

二、主机名和本机解析

主机名是机器身份的一部分。批量执行命令、监控告警、日志检索时,如果所有机器都叫 localhost,很难判断告警到底来自哪台服务器。

bash
hostnamectl status
hostnamectl set-hostname k3s-server-01
hostnamectl status

hostnamectl set-hostname 会写入系统的静态主机名,重启后仍然保留。虚拟机模板批量克隆时,主机名尤其容易重复,需要在初始化阶段改掉。

本机名解析通常写在 /etc/hosts。小规模实验环境没有内部 DNS 时,/etc/hosts 很常用;生产环境如果有统一 DNS,/etc/hosts 只保留必要的本机解析和临时兜底记录。

bash
cat >> /etc/hosts <<'EOF'
# 集群节点解析;小规模环境可直接用 hosts 管理
192.168.10.11 k3s-server-01
192.168.10.12 k3s-server-02
192.168.10.13 k3s-server-03
EOF

getent hosts k3s-server-01

getent hosts 会按系统的名称解析顺序查询,结果比单独 cat /etc/hosts 更接近真实应用看到的解析结果。解析顺序由 /etc/nsswitch.conf 控制,常见配置是先查本地文件,再查 DNS:

bash
grep '^hosts:' /etc/nsswitch.conf

常见输出:

text
hosts:      files dns

files dns 表示先查 /etc/hosts,再查 DNS。排查“命令能 ping IP,服务名却解析失败”时,这一项经常要看。

三、DNS 和软件源可用性

DNS 配置影响软件安装、镜像拉取、证书申请和访问外部 API。不同发行版和网络管理工具写法不同,systemd-resolved、NetworkManager、传统网卡配置文件都可能接管 DNS。

基础检查通常从解析文件和实际解析结果开始:

bash
cat /etc/resolv.conf
getent hosts mirrors.aliyun.com
curl -I https://mirrors.aliyun.com/ 2>/dev/null | head

/etc/resolv.conf 里能看到当前 nameserver,但它不一定是最终配置源。有些系统中这个文件是软链接,由 NetworkManager 或 systemd-resolved 生成。直接编辑后被覆盖,通常是因为上层网络管理服务重新生成了它。

RHEL 系发行版常见基础工具:

bash
yum install -y epel-release
yum install -y vim curl wget tar unzip lsof net-tools bind-utils bash-completion

Ubuntu / Debian 常见基础工具:

bash
apt update
apt install -y vim curl wget tar unzip lsof net-tools dnsutils bash-completion

bind-utils / dnsutils 提供 dignslookup 等命令。网络排障时这些工具很基础,初始化阶段装好,现场排查时会少一层阻塞。

四、时区和时间同步

系统时间是很多问题的共同前提。日志时间错乱、TLS 证书还没生效或已经过期、定时任务提前执行、Kubernetes 节点证书校验异常、数据库主从复制延迟判断不准,都可能和时间有关。

时区设置:

bash
timedatectl status
timedatectl set-timezone Asia/Shanghai
timedatectl status

timedatectl status 里重点看 Time zoneSystem clock synchronizedNTP service。时区只是显示规则,真正决定各节点时间是否一致的是 NTP 同步。

chrony 是现在 Linux 服务器上很常用的时间同步服务。RHEL 系服务名一般是 chronyd,Debian / Ubuntu 上包名是 chrony,服务名也常见为 chrony

RHEL 系安装和启用:

bash
yum install -y chrony

# enable 保证开机自动启动,--now 表示立即启动
systemctl enable --now chronyd

systemctl is-enabled chronyd
systemctl is-active chronyd

Ubuntu / Debian 安装和启用:

bash
apt update
apt install -y chrony

# Ubuntu / Debian 常见服务名是 chrony
systemctl enable --now chrony

systemctl is-enabled chrony
systemctl is-active chrony

chrony 的关键配置通常在 /etc/chrony.conf/etc/chrony/chrony.conf。时间源按内网优先,内网没有 NTP 时再使用公网时间源。

conf
# 内网 NTP;生产环境通常使用公司统一时间源
server 192.168.10.1 iburst

# 公网 NTP;实验环境可按网络情况选择可访问的源
server ntp.aliyun.com iburst
server time1.cloud.tencent.com iburst

# 启动初期时间偏差超过 1 秒时允许直接校正,后续尽量通过微调修正
makestep 1.0 3

# 同步系统时间到硬件时钟,减少重启后的初始偏差
rtcsync

iburst 会在服务启动初期快速发送几次请求,使首次同步更快。makestep 1.0 3 表示启动后前 3 次同步里,如果系统时间偏差超过 1 秒,允许直接跳变校正;服务稳定运行后,chrony 更倾向于通过微调慢慢修正时间,避免运行中的系统时间频繁跳变。

修改配置后重启并检查:

bash
systemctl restart chronyd
timedatectl status --no-pager
chronyc sources -v
chronyc tracking

chronyc sources -v 里常见符号:

符号含义
^*当前正在使用的时间源
^+可用候选时间源
^-可用但未被选中
^?暂时无法访问或状态未知

测试环境如果频繁恢复虚拟机快照,系统时间可能和真实时间差得比较多,这时可以在恢复后用上面的 timedatectlchronyc tracking 复查同步状态;生产基线仍然按固定 NTP 源、服务开机自启和启动初期校正来处理。

五、SSH 和 sudo 基础

SSH 是远程运维入口。安全加固会在 系统安全加固 里展开,初始化阶段至少要确认服务状态、登录方式和 sudo 权限。

bash
systemctl status sshd --no-pager
ss -lntp | grep ':22'
grep -E '^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication)' /etc/ssh/sshd_config

生产环境通常会逐步收敛到普通用户 + sudo + 密钥登录。实验环境可能临时使用 root 密码,后续接入堡垒机或自动化工具时,再统一管理账号、密钥和审计。

创建普通运维用户的基本命令:

bash
useradd ops
passwd ops

# wheel 组在 RHEL 系通常拥有 sudo 权限
usermod -aG wheel ops

# 验证用户和组关系
id ops

Ubuntu / Debian 上 sudo 组通常是 sudo

bash
usermod -aG sudo ops
id ops

修改 SSH 配置后,用服务自带检查命令确认语法:

bash
sshd -t
systemctl reload sshd

reload 会重新加载配置,不会断开已有连接。改 SSH 登录策略时保留一个当前会话,再开一个新会话验证登录,比直接断开重连更稳。

六、防火墙和 SELinux 状态

防火墙基线不是简单地开或关,而是确认当前由谁管理规则,以及哪些端口应该暴露。

bash
systemctl is-active firewalld || true
firewall-cmd --state 2>/dev/null || true
iptables -S 2>/dev/null | head
ss -lntup

RHEL 系常见 firewalld,底层可能使用 iptables 或 nftables。系统里同时出现 firewalld、iptables 脚本、云安全组时,排查端口不通要把这几层都列出来。

开放一个服务端口的示例:

bash
# 添加 HTTP 端口到 public zone,并写入永久配置
firewall-cmd --permanent --zone=public --add-service=http

# 重新加载永久规则
firewall-cmd --reload

# 查看当前 zone 的生效规则
firewall-cmd --list-all

SELinux 是强制访问控制机制。它和传统文件权限是两套系统:文件权限允许,不代表 SELinux 一定允许。Web 服务访问新目录、数据库写入新路径、容器挂载宿主机目录时,经常碰到 SELinux 上下文问题。

bash
getenforce 2>/dev/null || true
sestatus 2>/dev/null || true

常见状态:

状态含义
Enforcing策略生效并拦截违规访问
Permissive只记录日志,不拦截
Disabled关闭 SELinux

排查访问被拒绝时,常见检查路径:

bash
ausearch -m avc -ts recent 2>/dev/null | tail -n 20
ls -Z /var/www/html 2>/dev/null || true

初始化时记录 SELinux 状态,比出现故障后临时猜测更可靠。需要关闭、宽松还是保持强制模式,通常由业务软件兼容性和团队安全要求决定。

七、swap、fstab 和挂载检查

swap 是磁盘上的交换空间。内存不足时,内核可以把一部分不活跃内存页换到 swap。它不能替代真实内存,性能也远低于内存,但能降低小内存机器因为瞬时内存压力直接 OOM 的概率。

查看当前 swap:

bash
swapon --show
free -h

创建 2G swap 文件:

bash
fallocate -l 2G /swapfile
chmod 600 /swapfile              # swap 文件不能给其他用户读写
mkswap /swapfile
swapon /swapfile
swapon --show

持久化到 /etc/fstab

bash
cp -a /etc/fstab "/etc/fstab.$(date +%F-%H%M%S).bak"
echo '/swapfile none swap sw 0 0' >> /etc/fstab
mount -a                         # 检查 fstab 语法和可挂载性

/etc/fstab 写错可能导致系统启动卡住。改完后执行 mount -a,能在当前会话里提前暴露多数格式或路径错误。

Kubernetes 节点通常会关闭 swap,普通 Linux 主机是否启用要看业务类型和内存规模。数据库服务器更关注稳定延迟,swap 策略会比普通 Web 服务器更谨慎。

八、sysctl 和内核模块

sysctl 用来调整内核运行参数。网络转发、连接跟踪、TCP 队列、文件句柄等都可能在这里配置。初始化阶段不适合盲目套很大的“万能优化参数”,更适合按实际用途记录必需项。

查看当前参数:

bash
sysctl net.ipv4.ip_forward
sysctl fs.file-max
sysctl vm.swappiness

写入持久配置:

bash
cat >/etc/sysctl.d/99-base.conf <<'EOF'
# 开启 IPv4 转发;LVS、容器网络、路由转发场景会用到
net.ipv4.ip_forward = 1

# 降低系统主动使用 swap 的倾向;具体值要结合业务和内存情况
vm.swappiness = 10
EOF

sysctl --system

/etc/sysctl.d/*.conf 比直接改 /etc/sysctl.conf 更方便分组管理。比如基础参数放 99-base.conf,Kubernetes 节点参数放 99-kubernetes.conf

加载内核模块:

bash
modprobe br_netfilter
modprobe overlay

cat >/etc/modules-load.d/container.conf <<'EOF'
# 容器网络常用模块
br_netfilter
overlay
EOF

lsmod | grep -E 'br_netfilter|overlay'

容器和 Kubernetes 环境经常用到 br_netfilteroverlay。如果模块没加载,网络转发和容器存储相关功能可能表现异常。

九、limits 和 systemd 限制

ulimit 控制单个进程可使用的资源,比如最大打开文件数、最大进程数。高并发服务、数据库、代理服务经常会碰到 too many open files

查看当前限制:

bash
ulimit -n
ulimit -u

通过 /etc/security/limits.d/ 配置登录会话限制:

conf
# /etc/security/limits.d/99-ops.conf
# nofile 表示最大打开文件数,nproc 表示最大进程数
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535

这个配置主要影响 PAM 登录会话。systemd 管理的服务还要看 unit 自己的限制:

bash
systemctl show nginx -p LimitNOFILE
systemctl cat nginx

给某个服务单独设置文件句柄:

bash
systemctl edit nginx

写入 override:

ini
[Service]
# Nginx worker 打开大量连接时需要更高的文件句柄上限
LimitNOFILE=65535

重新加载并重启服务:

bash
systemctl daemon-reload
systemctl restart nginx
systemctl show nginx -p LimitNOFILE

排查 too many open files 时,只改 /etc/security/limits.conf 可能对 systemd 服务无效。服务自身的 LimitNOFILE、进程实际限制和应用配置要一起看。

十、日志和轮转基础

初始化阶段至少确认系统日志服务和日志轮转可用。

bash
systemctl is-active rsyslog || true
systemctl is-active systemd-journald || true
journalctl -n 20 --no-pager
logrotate --version

journald 管 systemd 日志,rsyslog 常用于把系统日志写入 /var/log/messages/var/log/syslog。不同发行版默认组合不同。

查看 journald 磁盘占用:

bash
journalctl --disk-usage

限制 journald 空间可以写入 /etc/systemd/journald.conf

ini
[Journal]
# 限制 journald 最多使用 1G 磁盘空间
SystemMaxUse=1G

# 单个日志文件最大 100M,便于轮转和清理
SystemMaxFileSize=100M

修改后重启:

bash
systemctl restart systemd-journald
journalctl --disk-usage

应用日志通常还需要 logrotate。没有轮转的访问日志、错误日志、任务日志,很容易把 /var 撑满。

十一、基线检查脚本片段

初始化完成后可以跑一段只读检查,确认关键项是否生效:

bash
#!/usr/bin/env bash
set -euo pipefail

echo "== system =="
cat /etc/os-release | grep -E '^(NAME|VERSION)='
uname -r
hostnamectl --static

echo
echo "== time =="
timedatectl status --no-pager | grep -E 'Time zone|System clock synchronized|NTP service'
chronyc tracking 2>/dev/null | grep -E 'Reference ID|Leap status' || true

echo
echo "== network =="
ip -brief addr
ip route | head -n 5
getent hosts "$(hostname)" || true

echo
echo "== storage =="
df -h
swapon --show || true

echo
echo "== security =="
ss -lntup
getenforce 2>/dev/null || true
systemctl is-active firewalld 2>/dev/null || true

echo
echo "== limits =="
ulimit -n
sysctl net.ipv4.ip_forward vm.swappiness 2>/dev/null || true

这段脚本只读取信息,不修改系统。交接机器、批量扩容节点、变更后复查时,都可以用类似脚本确认基线是否还在。更完整的初始化脚本可以参考 服务器初始化脚本