核心目标是自动完成安全加固、基础服务配置和内核/系统调优,避免人工遗漏,提升交付一致性与安全性;聚焦首次部署后必须立即生效的关键项,如禁用root远程ssh、配置防火墙、更新系统、关闭非必要服务、设置时区/ntp/基础用户、调整内核参数与ulimit,并通过幂等性设计、安全敏感处理、版本场景适配及重启提示确保可靠执行。

编写系统初始化脚本的核心目标是:在新服务器首次启动后,自动完成安全加固、基础服务配置和内核/系统调优,避免人工遗漏,提升交付一致性与安全性。
明确初始化范围与执行时机
脚本不应覆盖所有运维工作,而是聚焦“首次部署后必须立即生效”的关键项。典型范围包括:
- 禁用 root 远程 SSH 登录、强制使用密钥认证
- 配置防火墙(firewalld 或 ufw),仅放行必要端口(如 22、80、443)
- 更新系统并安装基础安全工具(fail2ban、auditd、unattended-upgrades)
- 关闭非必要服务(telnet、rsh、rpcbind 等)
- 设置时区、NTP 同步、基础用户(如 deploy)及 sudo 权限
- 调整内核参数(如 net.ipv4.tcp_tw_reuse、vm.swappiness)和 ulimit 限制
推荐将脚本设为 systemd 一次性服务(Type=oneshot + RemainAfterExit=yes),确保仅执行一次且不重复触发。
用幂等性设计避免重复执行风险
生产环境常需重跑脚本验证或修复,因此每项操作都应判断是否已生效。例如:
- 修改 SSH 配置前,先 grep "PermitRootLogin no" /etc/ssh/sshd_config
- 启用防火墙规则前,检查是否已存在对应 rich rule
- 添加用户前,用 id -u username >/dev/null 判断用户是否存在
- 写入 sysctl 参数前,用 sysctl -n key 与预期值比对
可统一用标记文件(如 /var/lib/system-init-done)记录完成状态,脚本开头检测该文件直接退出。
安全加固的关键细节不能硬编码
避免在脚本中写死密码、密钥或敏感配置。正确做法是:
- SSH 密钥通过传参或环境变量注入(如 ./init.sh --ssh-key "$KEY"),或从可信配置中心拉取
- 防火墙开放端口由变量控制(PORTS="22 80 443"),便于不同环境复用
- 禁止在脚本中 echo "root:password" | chpasswd;改用 openssl rand -base64 12 生成临时密码并写入安全位置
- 所有下载操作校验 checksum(如 curl -fsSL url | sha256sum -c -)
对 /etc/shadow、/etc/ssh/sshd_config 等关键文件修改前,自动备份(cp -a /etc/ssh/sshd_config{,.init.bak})。
调优参数要区分场景与版本兼容性
内核和系统参数不是越多越好,需结合服务器角色(Web、DB、中间件)和 OS 版本选择性启用:
- RHEL/CentOS 7+ 默认使用 firewalld,Ubuntu 20.04+ 推荐 ufw,脚本需先检测发行版再调用对应命令
- vm.swappiness=1 适合内存充足的服务型主机;若运行 Redis 或 Elasticsearch,建议设为 0
- net.core.somaxconn 应 ≥ 应用层连接队列长度(如 Nginx 的 listen backlog),通常设为 65535
- ulimit -n 建议设为 65535,但需同步写入 /etc/security/limits.d/90-nproc.conf 并重启对应服务(如 systemd-logind)
所有 sysctl 设置写入 /etc/sysctl.d/99-custom.conf 并执行 sysctl --system 生效,而非仅 sysctl -w。
不复杂但容易忽略:脚本末尾加入 reboot -f 或 systemctl reboot --no-wall 提示重启(可选),并输出初始化摘要(如“SSH 已禁用密码登录|防火墙已启用|共应用 7 项内核调优”),方便审计与交接。











