
摘要:Shell脚本作为Linux系统管理的重要工具,能够将重复性操作固化为可执行的命令序列,大幅提升运维效率。
然而,脚本编写不当会引入安全风险,如密码明文存储、输入验证缺失、权限控制松懈等问题。
本文旨在系统性地讲解如何通过Shell脚本对Linux系统进行安全加固,涵盖账号策略、密码复杂度、文件权限、服务管理、端口管控等核心环节,并提供经过实战检验的脚本示例,帮助读者构建一套完整的安全加固方案。
详细内容请参考下文。一、环境准备与脚本基础
1.登录系统与环境检查
在开始编写加固脚本之前,首先需要确认当前操作环境。通过SSH登录Linux服务器后,建议先查看系统版本和Shell环境信息:

2.Shell脚本编写规范
良好的编码规范是脚本安全可靠的基础。以下是三条核心规范:
(1)解释器声明
每个Shell脚本的第一行必须指定解释器路径,确保系统使用正确的Shell执行脚本:
# 一般写法
#!/bin/bash
# 或使用更通用的写法
#!/usr/bin/env bash(2)注释规范
单行注释使用#符号,多行注释建议使用以下格式:
# 这是单行注释,用于说明某行代码的作用
: <备注:: 是 Shell 的内置空命令(什么都不做),<
(3)错误处理机制
在脚本开头添加以下配置,可在遇到错误时立即终止执行,避免连锁反应:
set -e # 命令执行失败时退出
set -u # 使用未定义变量时退出
set -o pipefail # 管道命令中任一子命令失败则整体失败二、账号安全加固
账号安全是系统安全的第一道防线。本章通过脚本实现对密码有效期、密码复杂度、登录失败锁定、历史命令优化等策略的自动化配置。
1.密码有效期与长度策略
通过修改/etc/login.defs文件,可以统一控制全局密码策略。以下脚本以交互方式让管理员设置关键参数,并自动备份原配置文件:
#!/bin/bash
# 账号安全加固脚本
# 功能:配置密码有效期、最小长度、过期提醒
# 备份原始配置文件
cp /etc/login.defs /etc/login.defs.bak
echo "===== 密码安全策略配置 ====="
read -p "请输入密码有效天数(建议90天): " PASS_MAX_DAYS
read -p "请输入密码最小长度(建议8位): " PASS_MIN_LEN
read -p "请输入密码过期提醒天数(建议15天): " PASS_WARN_AGE
# 修改配置
sed -i "/^PASS_MAX_DAYS/c\PASS_MAX_DAYS $PASS_MAX_DAYS" /etc/login.defs
sed -i "/^PASS_MIN_LEN/c\PASS_MIN_LEN $PASS_MIN_LEN" /etc/login.defs
sed -i "/^PASS_WARN_AGE/c\PASS_WARN_AGE $PASS_WARN_AGE" /etc/login.defs
echo "✅ 密码策略加固完成!"备注:参数说明如下
PASS_MAX_DAYS:密码最大有效期,超过后强制修改
PASS_MIN_LEN:密码最小长度,低于该值不允许设置
PASS_WARN_AGE:过期前提醒天数,便于用户提前修改
2.密码复杂度策略
仅限制长度和有效期是不够的,还需强制密码包含大写字母、小写字母、数字和特殊字符。通过配置/etc/pam.d/system-auth中的pam_pwquality.so模块实现:
#!/bin/bash
# 密码复杂度加固脚本
# 备份原文件
cp /etc/pam.d/system-auth /etc/pam.d/system-auth.bak
echo "===== 密码复杂度策略配置 ====="
echo "要求:新密码必须同时包含大写字母、小写字母、数字,且不能与旧密码相同"
sed -i '/pam_pwquality.so/c\password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= difok=1 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1' /etc/pam.d/system-auth
echo "✅ 密码复杂度加固完成!"
备注:参数含义如下
difok=1 新密码与旧密码至少1个字符不同
minlen=8 密码最小长度8位
ucredit=-1 至少包含1个大写字母
lcredit=-1 至少包含1个小写字母
dcredit=-1 至少包含1个数字
retry=3 允许重试3次3.登录失败锁定策略
为防止暴力破解,应配置账户在多次登录失败后自动锁定:
#!/bin/bash
# 登录失败锁定脚本
echo "===== 登录失败锁定策略 ====="
echo "配置:连续10次登录失败后锁定账户300秒"
# 在system-auth中插入pam_tally.so模块
sed -i '/^auth required pam_deny.so/i\auth required pam_tally.so onerr=fail deny=10 unlock_time=300' /etc/pam.d/system-auth
echo "✅ 登录锁定策略加固完成!"
echo " 手动解锁命令: faillog -u 用户名 -r"备注:faillog -u 用户名 -r 是一个用于重置用户登录失败记录的系统管理命令,可用于解锁用户。常用相关命令
faillog -u 用户名 查看指定用户的失败登录记录
faillog -u 用户名 -r 重置指定用户的失败计数
faillog -a 显示所有用户的失败登录记录
faillog -m 3 设置最大失败次数为 3
4.历史命令与超时优化
合理配置/etc/profile中的历史命令记录数和终端超时时间,既能提高审计效率,又能防止闲置会话被滥用:
#!/bin/bash
# 历史命令和超时优化
echo "===== Shell环境优化 ====="
read -p "设置历史命令保存条数(建议1000): " HISTSIZE
read -p "设置终端自动注销超时秒数(建议300): " TMOUT
# 修改历史命令条数
sed -i "/^HISTSIZE/c\HISTSIZE=$HISTSIZE" /etc/profile
# 如果TMOUT已存在则修改,否则追加
if grep -q "^TMOUT" /etc/profile; then
sed -i "/^TMOUT/c\TMOUT=$TMOUT" /etc/profile
else
echo "TMOUT=$TMOUT" >> /etc/profile
fi
echo "✅ Shell环境优化完成!"
echo " 请执行 source /etc/profile 使配置生效"三、文件与目录权限加固
1.设置默认Umask值
umask决定了新创建文件和目录的默认权限。将umask设置为077,可确保新文件仅对所有者可读写,其他用户无任何权限:
#!/bin/bash
# 设置默认umask
echo "===== 设置umask值为077 ====="
sed -i "/^UMASK/c\UMASK 077" /etc/login.defs
echo "✅ umask加固完成!"2.关键文件权限检查
建议在加固脚本中增加对关键系统文件权限的检查和修正:
# 关键文件权限加固
chmod 644 /etc/passwd
chmod 600 /etc/shadow
chmod 644 /etc/group
chmod 600 /etc/gshadow
chmod 644 /etc/hosts.allow
chmod 644 /etc/hosts.deny四、服务与端口安全管理
1.禁用非必要服务
系统默认启用了许多非必需服务,关闭它们可以减小攻击面:
#!/bin/bash
# 禁用不需要的服务
echo "===== 禁用非必要服务 ====="
# 关闭IPv6防火墙(如未使用IPv6)
/sbin/chkconfig ip6tables off 2>/dev/null
# 关闭Avahi组播DNS服务
/sbin/chkconfig avahi-daemon off 2>/dev/null
/sbin/chkconfig avahi-dnsconfd off 2>/dev/null
# 关闭蓝牙服务
/sbin/chkconfig bluetooth off 2>/dev/null
# 停止当前运行的服务
/sbin/service ip6tables stop 2>/dev/null
/sbin/service avahi-daemon stop 2>/dev/null
echo "✅ 非必要服务已禁用!"备注:在生产环境执行前,请确认已安装并配置了firewalld或iptables作为替代防火墙。
2.配置防火墙开放必要端口
使用firewalld管理防火墙,仅开放业务必需的端口:
#!/bin/bash
# 防火墙端口管理脚本
echo "===== 配置防火墙开放端口 ====="
# 安装firewalld(如未安装)
yum install -y firewalld firewalld-config
# 启动防火墙并设置开机自启
systemctl start firewalld
systemctl enable firewalld
# 开放常用端口
firewall-cmd --zone=public --add-port=80/tcp --permanent # HTTP
firewall-cmd --zone=public --add-port=443/tcp --permanent # HTTPS
firewall-cmd --zone=public --add-port=22/tcp --permanent # SSH
firewall-cmd --zone=public --add-port=21/tcp --permanent # FTP
firewall-cmd --zone=public --add-port=53/udp --permanent # DNS
# 重新加载防火墙规则
firewall-cmd --reload
echo "✅ 端口配置完成!当前开放端口如下:"
firewall-cmd --list-ports3.SSH安全加固
SSH是服务器最常用的远程管理通道,建议额外进行加固:
#!/bin/bash
# SSH安全加固
echo "===== SSH安全加固 ====="
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 禁止root直接登录(建议使用普通用户+sudo)
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 禁用密码登录(仅使用密钥认证,需谨慎)
# sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# 修改默认端口(取消注释并修改)
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
systemctl restart sshd
echo "✅ SSH加固完成!"五、日志审计与监控
1.配置日志轮转
防止日志文件无限增长撑爆磁盘:
#!/bin/bash
# 配置日志轮转
cat > /etc/logrotate.d/system_audit <2.启用审计服务
# 安装并启用auditd
yum install -y audit
systemctl enable auditd #开机自启动审计服务
systemctl start auditd #启动审计服务六、一键执行安全加固脚本
将以上各章节的加固模块整合为一个完整的脚本,方便一次性执行全部加固操作:
#!/bin/bash
# ============================================
# Linux系统安全加固一键执行脚本
# 适用系统:CentOS 7/8
# 功能:账号安全、密码策略、文件权限、
# 服务管理、防火墙配置、日志审计
# ============================================
set -e
LOG_FILE="/var/log/security_hardening.log"
log_info() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
log_info "========== 开始执行系统安全加固 =========="
# 1. 账号安全加固
log_info "执行账号安全加固..."
# 此处调用2.1节代码
#!/bin/bash
# 账号安全加固脚本
# 功能:配置密码有效期、最小长度、过期提醒
# 备份原始配置文件
cp /etc/login.defs /etc/login.defs.bak
echo "===== 密码安全策略配置 ====="
read -p "请输入密码有效天数(建议90天): " PASS_MAX_DAYS
read -p "请输入密码最小长度(建议8位): " PASS_MIN_LEN
read -p "请输入密码过期提醒天数(建议15天): " PASS_WARN_AGE
# 修改配置
sed -i "/^PASS_MAX_DAYS/c\PASS_MAX_DAYS $PASS_MAX_DAYS" /etc/login.defs
sed -i "/^PASS_MIN_LEN/c\PASS_MIN_LEN $PASS_MIN_LEN" /etc/login.defs
sed -i "/^PASS_WARN_AGE/c\PASS_WARN_AGE $PASS_WARN_AGE" /etc/login.defs
echo "✅ 密码策略加固完成!"
# 2. 密码策略加固
log_info "执行密码策略加固..."
# 此处调用2.2节代码
#!/bin/bash
# 密码复杂度加固脚本
# 备份原文件
cp /etc/pam.d/system-auth /etc/pam.d/system-auth.bak
echo "===== 密码复杂度策略配置 ====="
echo "要求:新密码必须同时包含大写字母、小写字母、数字,且不能与旧密码相同"
sed -i '/pam_pwquality.so/c\password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= difok=1 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1' /etc/pam.d/system-auth
echo "✅ 密码复杂度加固完成!"
# 3. 登录锁定策略
log_info "执行登录锁定配置..."
# 此处调用2.3节代码
#!/bin/bash
# 登录失败锁定脚本
echo "===== 登录失败锁定策略 ====="
echo "配置:连续10次登录失败后锁定账户300秒"
# 在system-auth中插入pam_tally.so模块
sed -i '/^auth required pam_deny.so/i\auth required pam_tally.so onerr=fail deny=10 unlock_time=300' /etc/pam.d/system-auth
echo "✅ 登录锁定策略加固完成!"
echo " 手动解锁命令: faillog -u 用户名 -r"
# 4. umask设置
log_info "设置umask..."
# 此处调用3.1节代码
#!/bin/bash
# 设置默认umask
echo "===== 设置umask值为077 ====="
sed -i "/^UMASK/c\UMASK 077" /etc/login.defs
echo "✅ umask加固完成!"
# 5. 服务禁用
log_info "禁用非必要服务..."
# 此处调用4.1节代码
#!/bin/bash
# 禁用不需要的服务
echo "===== 禁用非必要服务 ====="
# 关闭IPv6防火墙(如未使用IPv6)
/sbin/chkconfig ip6tables off 2>/dev/null
# 关闭Avahi组播DNS服务
/sbin/chkconfig avahi-daemon off 2>/dev/null
/sbin/chkconfig avahi-dnsconfd off 2>/dev/null
# 关闭蓝牙服务
/sbin/chkconfig bluetooth off 2>/dev/null
# 停止当前运行的服务
/sbin/service ip6tables stop 2>/dev/null
/sbin/service avahi-daemon stop 2>/dev/null
echo "✅ 非必要服务已禁用!"
# 6. 防火墙配置
log_info "配置防火墙端口..."
# 此处调用4.2节代码
#!/bin/bash
# 防火墙端口管理脚本
echo "===== 配置防火墙开放端口 ====="
# 安装firewalld(如未安装)
yum install -y firewalld firewalld-config
# 启动防火墙并设置开机自启
systemctl start firewalld
systemctl enable firewalld
# 开放常用端口
firewall-cmd --zone=public --add-port=80/tcp --permanent # HTTP
firewall-cmd --zone=public --add-port=443/tcp --permanent # HTTPS
firewall-cmd --zone=public --add-port=22/tcp --permanent # SSH
firewall-cmd --zone=public --add-port=21/tcp --permanent # FTP
firewall-cmd --zone=public --add-port=53/udp --permanent # DNS
# 重新加载防火墙规则
firewall-cmd --reload
echo "✅ 端口配置完成!当前开放端口如下:"
firewall-cmd --list-ports
# 7. SSH加固
log_info "执行SSH安全加固..."
# 此处调用4.3节代码
#!/bin/bash
# SSH安全加固
echo "===== SSH安全加固 ====="
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 禁止root直接登录(建议使用普通用户+sudo)
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 禁用密码登录(仅使用密钥认证,需谨慎)
# sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# 修改默认端口(取消注释并修改)
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
systemctl restart sshd
echo "✅ SSH加固完成!"
log_info "========== 系统安全加固全部完成!=========="
log_info "详细日志请查看: $LOG_FILE"七、经验总结
1.脚本安全建议
2. 安全加固流程
更新时间:2026-07-16
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight All Rights Reserved.
Powered By 71396.com 闽ICP备11008920号
闽公网安备35020302034903号