作为从业15年的Linux系统工程师,我见过太多因基础安全疏忽导致的重大事故。Linux系统安全绝非简单的命令堆砌,而是需要建立完整的防御体系。让我们从最基础的账户安全开始,逐步构建系统防护能力。
Linux系统的安全性建立在严格的权限管理基础上。不同于Windows系统,Linux从设计之初就采用了多用户架构,每个进程、文件、操作都有明确的归属关系。这种设计理念使得Linux在安全性上具有先天优势,但同时也对管理员提出了更高要求。
重要提示:任何安全措施都应当遵循"最小权限原则",即只授予必要的权限,而非一味追求便利性。
root用户是Linux系统的上帝账户,拥有以下特性:
在实际运维中,我强烈建议:
这些账户通常具有以下特征:
常见系统用户示例:
运维经验:永远不要修改系统用户的默认配置,特别是不要给它们可登录shell。我曾见过因为给mysql用户设置/bin/bash导致数据库被攻破的案例。
普通用户是我们日常工作的主力账户,特点包括:
创建用户时的安全建议:
bash复制# 创建用户时指定附加组和过期时间
useradd -m -s /bin/bash -G developers -e 2024-12-31 alice
# 设置强密码(交互式)
passwd alice
这个文件包含所有用户的基本信息,每行格式为:
code复制username:password:UID:GID:comment:homedir:shell
典型示例:
code复制alice:x:1001:1001:Alice Chen:/home/alice:/bin/bash
mysql:x:27:27:MySQL Server:/var/lib/mysql:/sbin/nologin
安全注意事项:
这才是真正的密码存储文件,格式为:
code复制username:encrypted_password:last_change:min_age:max_age:warn:inactive:expire:reserved
关键字段说明:
查看shadow文件权限:
bash复制ls -l /etc/shadow
# 正确权限应为-rw-r----- 1 root shadow
编辑/etc/pam.d/system-auth(RHEL系)或/etc/pam.d/common-password(Debian系):
bash复制# 密码长度至少12位,包含大小写、数字和特殊字符
password requisite pam_pwquality.so try_first_pass retry=3 minlen=12 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 enforce_for_root
参数说明:
使用chage命令进行精细控制:
bash复制# 查看当前策略
chage -l alice
# 设置密码30天后过期,过期前7天提醒,过期后2天锁定
chage -M 30 -W 7 -I 2 alice
企业级建议配置:
通过pam_tally2模块实现失败锁定:
bash复制# 编辑/etc/pam.d/sshd
auth required pam_tally2.so deny=5 unlock_time=900 onerr=fail audit silent
# 查看失败次数
pam_tally2 --user=alice
# 手动解锁
pam_tally2 --user=alice --reset
bash复制ssh-keygen -t ed25519 -a 100 -f ~/.ssh/admin_key
bash复制# 禁用密码认证
PasswordAuthentication no
# 限制密钥算法
PubkeyAcceptedKeyTypes ssh-ed25519,rsa-sha2-512
bash复制# ~/.ssh/config
Host production
HostName 192.168.1.100
User admin
IdentityFile ~/.ssh/admin_key
IdentitiesOnly yes
bash复制#!/bin/bash
# 找出180天未登录的普通用户
inactive_users=$(lastlog -b 180 | awk 'NR>1 && $1!="root" {print $1}')
for user in $inactive_users; do
# 锁定账户
usermod -L $user
# 移动家目录备份
tar -czf /backup/${user}_$(date +%F).tar.gz /home/$user
# 删除用户
userdel -r $user
echo "Removed inactive user: $user"
done
/etc/sudoers示例:
code复制# 允许开发组重启web服务
%developers ALL=(root) /bin/systemctl restart nginx, /bin/systemctl restart apache
# 允许DBA组管理MySQL
%dba ALL=(root) /usr/bin/systemctl * mysql*, /usr/bin/mysqladmin*
# 允许admin组有完整权限但需要密码
%admin ALL=(ALL) ALL
# 允许jump用户无密码执行特定命令
jump ALL=(ALL) NOPASSWD: /usr/bin/rsync, /usr/bin/scp
bash复制grub2-mkpasswd-pbkdf2
# 输入密码后得到加密字符串
bash复制set superusers="grubadmin"
password_pbkdf2 grubadmin grub.pbkdf2.sha512.10000.长字符串
bash复制menuentry "Single User Mode" --users "" {
# 需要密码才能进入
}
防止通过编辑内核参数绕过认证:
bash复制# 在/etc/default/grub中添加
GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 audit=1"
GRUB_CMDLINE_LINUX="enforcing=1"
# 更新配置
grub2-mkconfig -o /boot/grub2/grub.cfg
/etc/securetty最佳实践:
bash复制# 只允许从tty1本地登录
tty1
# 或者完全禁用root本地登录(空文件)
> /etc/securetty
全局配置/etc/profile:
bash复制# 设置300秒无操作超时
readonly TMOUT=300
export TMOUT
# 防止用户修改
readonly HISTFILE
readonly HISTSIZE
readonly HISTFILESIZE
readonly HISTCONTROL
readonly HISTIGNORE
自定义规则破解:
bash复制# 创建自定义规则/etc/john/john.conf
[List.Rules:Custom]
Az"[0-9]" ^[!@#]
c
# 使用规则破解
john --rules=Custom hash.txt
分布式破解:
bash复制# 主节点
john --session=cluster --node=1/4 hash.txt
# 从节点
john --session=cluster --node=2/4 hash.txt
bash复制# 使用16线程,超时30秒,每次尝试间隔500ms
hydra -L users.txt -P passwords.txt -t 16 -w 30 -W 500 ssh://192.168.1.100
bash复制# 隐蔽扫描(避免触发IDS)
nmap -T2 -sS -Pn --scan-delay 1s --max-retries 1 -D RND:10 192.168.1.100
# 全端口服务识别
nmap -p- -sV -sC -O -T4 -A -v -oA full_scan 192.168.1.100
bash复制# 默认拒绝所有
iptables -P INPUT DROP
iptables -P FORWARD DROP
# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 按需开放端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 限制SSH访问源
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# 防暴力破解
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --set
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --update --seconds 60 --hitcount 5 -j DROP
当怀疑系统被入侵时,立即执行:
bash复制# 检查异常进程
ps auxf | grep -E '(\.tmp|\.var|/dev/shm)'
# 检查SUID文件变化
find / -perm -4000 -type f -exec ls -la {} \; | sort -k3
# 检查网络连接
ss -tanp | grep ESTAB
# 检查最近修改的文件
find / -mtime -3 -type f ! -path "/proc/*" ! -path "/sys/*" -exec ls -la {} \;
bash复制#!/bin/bash
# 账户安全
sed -i 's/PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sed -i 's/PASS_MIN_DAYS.*/PASS_MIN_DAYS 1/' /etc/login.defs
sed -i 's/PASS_WARN_AGE.*/PASS_WARN_AGE 7/' /etc/login.defs
# SSH加固
sed -i 's/#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
echo "AllowUsers alice bob" >> /etc/ssh/sshd_config
# 系统加固
echo "* hard core 0" >> /etc/security/limits.conf
echo "fs.suid_dumpable = 0" >> /etc/sysctl.conf
sysctl -p
# 重启服务
systemctl restart sshd
bash复制# 安装auditd
yum install audit -y # RHEL
apt install auditd -y # Debian
# 关键配置/etc/audit/audit.rules
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k privilege
-w /var/log/audit/ -p wa -k auditlog
-a always,exit -F arch=b64 -S execve -k execution
-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat,unlink -k file-access
在15年的Linux运维生涯中,我发现安全防护最重要的不是技术手段,而是持续的安全意识和规范的流程。建议每月进行一次安全检查,每季度做一次渗透测试,每年做一次安全审计。记住:安全不是一次性的工作,而是一个持续改进的过程。