Appearance
系统初始化基线
新服务器投入使用前,基础状态需要先统一:主机身份、名称解析、时间同步、软件源、基础工具、登录方式、防火墙策略、系统参数和资源限制。基线配置不等于完整安全加固,它更接近机器交付前的最低可用状态。后续排查日志时间、证书校验、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 statushostnamectl 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-01getent hosts 会按系统的名称解析顺序查询,结果比单独 cat /etc/hosts 更接近真实应用看到的解析结果。解析顺序由 /etc/nsswitch.conf 控制,常见配置是先查本地文件,再查 DNS:
bash
grep '^hosts:' /etc/nsswitch.conf常见输出:
text
hosts: files dnsfiles 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-completionUbuntu / Debian 常见基础工具:
bash
apt update
apt install -y vim curl wget tar unzip lsof net-tools dnsutils bash-completionbind-utils / dnsutils 提供 dig、nslookup 等命令。网络排障时这些工具很基础,初始化阶段装好,现场排查时会少一层阻塞。
四、时区和时间同步
系统时间是很多问题的共同前提。日志时间错乱、TLS 证书还没生效或已经过期、定时任务提前执行、Kubernetes 节点证书校验异常、数据库主从复制延迟判断不准,都可能和时间有关。
时区设置:
bash
timedatectl status
timedatectl set-timezone Asia/Shanghai
timedatectl statustimedatectl status 里重点看 Time zone、System clock synchronized 和 NTP 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 chronydUbuntu / Debian 安装和启用:
bash
apt update
apt install -y chrony
# Ubuntu / Debian 常见服务名是 chrony
systemctl enable --now chrony
systemctl is-enabled chrony
systemctl is-active chronychrony 的关键配置通常在 /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
# 同步系统时间到硬件时钟,减少重启后的初始偏差
rtcsynciburst 会在服务启动初期快速发送几次请求,使首次同步更快。makestep 1.0 3 表示启动后前 3 次同步里,如果系统时间偏差超过 1 秒,允许直接跳变校正;服务稳定运行后,chrony 更倾向于通过微调慢慢修正时间,避免运行中的系统时间频繁跳变。
修改配置后重启并检查:
bash
systemctl restart chronyd
timedatectl status --no-pager
chronyc sources -v
chronyc trackingchronyc sources -v 里常见符号:
| 符号 | 含义 |
|---|---|
^* | 当前正在使用的时间源 |
^+ | 可用候选时间源 |
^- | 可用但未被选中 |
^? | 暂时无法访问或状态未知 |
测试环境如果频繁恢复虚拟机快照,系统时间可能和真实时间差得比较多,这时可以在恢复后用上面的 timedatectl 和 chronyc 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 opsUbuntu / Debian 上 sudo 组通常是 sudo:
bash
usermod -aG sudo ops
id ops修改 SSH 配置后,用服务自带检查命令确认语法:
bash
sshd -t
systemctl reload sshdreload 会重新加载配置,不会断开已有连接。改 SSH 登录策略时保留一个当前会话,再开一个新会话验证登录,比直接断开重连更稳。
六、防火墙和 SELinux 状态
防火墙基线不是简单地开或关,而是确认当前由谁管理规则,以及哪些端口应该暴露。
bash
systemctl is-active firewalld || true
firewall-cmd --state 2>/dev/null || true
iptables -S 2>/dev/null | head
ss -lntupRHEL 系常见 firewalld,底层可能使用 iptables 或 nftables。系统里同时出现 firewalld、iptables 脚本、云安全组时,排查端口不通要把这几层都列出来。
开放一个服务端口的示例:
bash
# 添加 HTTP 端口到 public zone,并写入永久配置
firewall-cmd --permanent --zone=public --add-service=http
# 重新加载永久规则
firewall-cmd --reload
# 查看当前 zone 的生效规则
firewall-cmd --list-allSELinux 是强制访问控制机制。它和传统文件权限是两套系统:文件权限允许,不代表 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_netfilter 和 overlay。如果模块没加载,网络转发和容器存储相关功能可能表现异常。
九、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 --versionjournald 管 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这段脚本只读取信息,不修改系统。交接机器、批量扩容节点、变更后复查时,都可以用类似脚本确认基线是否还在。更完整的初始化脚本可以参考 服务器初始化脚本。