Linux服务器安全加固实战指南:从基础配置到高级防护的完整方案 前言 随着网络安全威胁的日益增加,Linux服务器的安全加固已成为运维工作的重中之重。一个安全的Linux服务器不仅能保护重要数据,还能确保业务的连续性和稳定性。本文基于实际生产环境经验,提供了一套完整的Linux安全加固方案,涵盖从基础配置到高级防护的各个方面。
一、安全加固基础理论 1.1 安全加固的基本原则
最小权限原则 :用户和进程只获得完成任务所需的最小权限
纵深防御 :建立多层安全防护体系
定期更新 :及时安装安全补丁和更新
监控审计 :建立完善的日志记录和监控机制
备份恢复 :制定完善的备份和灾难恢复计划
安全意识 :提高管理员和用户的安全意识
1.2 安全威胁分析 常见安全威胁 :
暴力破解攻击
权限提升攻击
恶意软件感染
数据泄露
拒绝服务攻击
内部威胁
配置错误导致的安全漏洞
1.3 安全加固检查清单 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 echo "=== Linux Security Check Report ===" echo "Date: $(date) " echo "Hostname: $(hostname) " echo "OS Version: $(cat /etc/os-release | grep PRETTY_NAME) " echo echo "1. System Updates:" if command -v yum &> /dev/null; then yum check-update | wc -l elif command -v apt &> /dev/null; then apt list --upgradable 2>/dev/null | wc -l fi echo echo "2. User Accounts:" echo "Total users: $(cat /etc/passwd | wc -l) " echo "Users with UID 0: $(awk -F: '$3 == 0 {print $1}' /etc/passwd) " echo "Users with empty passwords: $(awk -F: '$2 == "" {print $1}' /etc/shadow) " echo echo "3. SSH Configuration:" echo "Root login: $(grep '^PermitRootLogin' /etc/ssh/sshd_config || echo 'Not configured') " echo "Password authentication: $(grep '^PasswordAuthentication' /etc/ssh/sshd_config || echo 'Not configured') " echo "SSH port: $(grep '^Port' /etc/ssh/sshd_config || echo 'Default 22') " echo echo "4. Firewall Status:" if systemctl is-active --quiet firewalld; then echo "Firewalld: Active" elif systemctl is-active --quiet ufw; then echo "UFW: Active" else echo "Firewall: Inactive or Unknown" fi echo echo "5. Running Services:" systemctl list-units --type =service --state=running | grep -E '(ssh|http|mysql|ftp)' | wc -l echo echo "=== End of Security Check ==="
二、系统基础安全配置 2.1 系统更新和补丁管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 yum install -y yum-cron systemctl enable yum-cron systemctl start yum-cron vi /etc/yum/yum-cron.conf apply_updates = yes update_cmd = security update_messages = yes download_updates = yes apt install -y unattended-upgrades dpkg-reconfigure -plow unattended-upgrades vi /etc/apt/apt.conf.d/50unattended-upgrades Unattended-Upgrade::Allowed-Origins { "${distro_id} :${distro_codename} -security" ; }; yum update -y yum install -y epel-release apt update && apt upgrade -y apt install -y software-properties-common yum check-update apt list --upgradable
2.2 内核参数安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 cat > /etc/sysctl.d/99-security.conf << EOF # 网络安全参数 # 禁用IP转发 net.ipv4.ip_forward = 0 net.ipv6.conf.all.forwarding = 0 # 禁用源路由 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv6.conf.default.accept_source_route = 0 # 禁用ICMP重定向 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 # 禁用发送ICMP重定向 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # 启用反向路径过滤 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # 忽略ICMP ping请求 net.ipv4.icmp_echo_ignore_all = 1 # 忽略广播ping net.ipv4.icmp_echo_ignore_broadcasts = 1 # 启用SYN Cookies net.ipv4.tcp_syncookies = 1 # 记录欺骗、源路由和重定向包 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 # 系统安全参数 # 禁用magic-sysrq键 kernel.sysrq = 0 # 限制core dump fs.suid_dumpable = 0 # 限制dmesg访问 kernel.dmesg_restrict = 1 # 限制内核指针访问 kernel.kptr_restrict = 2 # 启用ASLR kernel.randomize_va_space = 2 EOF sysctl -p /etc/sysctl.d/99-security.conf
2.3 文件系统安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 cat >> /etc/fstab << EOF # 安全挂载选项 /tmp /tmp tmpfs defaults,nodev,nosuid,noexec 0 0 /var/tmp /var/tmp tmpfs defaults,nodev,nosuid,noexec 0 0 /dev/shm /dev/shm tmpfs defaults,nodev,nosuid,noexec 0 0 EOF mkdir -p /tmp_securechmod 1777 /tmp_securechown root:root /tmp_securechmod 600 /etc/shadowchmod 600 /etc/gshadowchmod 644 /etc/passwdchmod 644 /etc/groupchmod 600 /boot/grub2/grub.cfgchmod 700 /rootfind / -type f -perm -002 -exec ls -la {} \; 2>/dev/null find / -type f -perm -4000 -exec ls -la {} \; 2>/dev/null find / -type f -perm -2000 -exec ls -la {} \; 2>/dev/null echo "umask 027" >> /etc/profileecho "umask 027" >> /etc/bashrc
三、用户账户和权限管理 3.1 用户账户安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 for user in games news uucp operator gopher ftp; do if id "$user " &>/dev/null; then usermod -L -s /sbin/nologin "$user " echo "Disabled user: $user " fi done cat > /etc/security/pwquality.conf << EOF # 密码最小长度 minlen = 12 # 至少包含一个小写字母 lcredit = -1 # 至少包含一个大写字母 ucredit = -1 # 至少包含一个数字 dcredit = -1 # 至少包含一个特殊字符 ocredit = -1 # 最多连续相同字符数 maxrepeat = 2 # 与旧密码的最大相同字符数 maxclasschg = 0 # 密码不能包含用户名 usercheck = 1 EOF cat >> /etc/login.defs << EOF # 密码有效期配置 PASS_MAX_DAYS 90 PASS_MIN_DAYS 1 PASS_WARN_AGE 7 PASS_MIN_LEN 12 EOF cat > /etc/security/faillock.conf << EOF # 失败尝试次数 deny = 5 # 锁定时间(秒) unlock_time = 900 # 失败计数重置时间 fail_interval = 900 # 即使root也受限制 even_deny_root EOF useradd -m -s /bin/bash -G wheel secadmin passwd secadmin echo "secadmin ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/secadminchmod 440 /etc/sudoers.d/secadmin
3.2 SSH安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backupcat > /etc/ssh/sshd_config << EOF # SSH安全配置 Port 2222 Protocol 2 # 认证配置 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys # 连接限制 MaxAuthTries 3 MaxSessions 2 MaxStartups 2 LoginGraceTime 60 # 用户限制 AllowUsers secadmin DenyUsers root # 网络配置 ListenAddress 0.0.0.0 AddressFamily inet # 安全选项 PermitEmptyPasswords no ChallengeResponseAuthentication no UsePAM yes X11Forwarding no AllowTcpForwarding no GatewayPorts no PermitTunnel no # 日志配置 SyslogFacility AUTHPRIV LogLevel VERBOSE # 加密算法 Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512 KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512 EOF ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" mkdir -p /home/secadmin/.sshchmod 700 /home/secadmin/.sshtouch /home/secadmin/.ssh/authorized_keyschmod 600 /home/secadmin/.ssh/authorized_keyschown -R secadmin:secadmin /home/secadmin/.sshsystemctl restart sshd systemctl enable sshd cat > ~/.ssh/config << EOF Host * Protocol 2 Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com KexAlgorithms curve25519-sha256@libssh.org ServerAliveInterval 300 ServerAliveCountMax 2 EOF chmod 600 ~/.ssh/config
3.3 sudo权限精细化配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 groupadd webadmin groupadd dbadmin groupadd netadmin cat > /etc/sudoers.d/custom-permissions << EOF # Web管理员权限 %webadmin ALL=(ALL) /bin/systemctl restart nginx, /bin/systemctl reload nginx, /bin/systemctl status nginx %webadmin ALL=(ALL) /usr/sbin/nginx -t, /bin/tail /var/log/nginx/* # 数据库管理员权限 %dbadmin ALL=(ALL) /bin/systemctl restart mysqld, /bin/systemctl status mysqld %dbadmin ALL=(ALL) /usr/bin/mysql, /usr/bin/mysqldump # 网络管理员权限 %netadmin ALL=(ALL) /sbin/iptables, /bin/systemctl restart firewalld %netadmin ALL=(ALL) /bin/ss, /bin/netstat, /sbin/tcpdump # 禁用危险命令 Cmnd_Alias DANGEROUS = /bin/su, /usr/bin/passwd root, /sbin/shutdown, /sbin/reboot ALL ALL = !DANGEROUS EOF chmod 440 /etc/sudoers.d/custom-permissionsecho "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers.d/loggingecho "Defaults log_input, log_output" >> /etc/sudoers.d/logging
四、防火墙和网络安全 4.1 Firewalld防火墙配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 yum install -y firewalld systemctl enable firewalld systemctl start firewalld firewall-cmd --set-default-zone=public firewall-cmd --permanent --remove-service=dhcpv6-client firewall-cmd --permanent --remove-service=cockpit firewall-cmd --permanent --add-service=ssh firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --permanent --remove-service=ssh firewall-cmd --permanent --add-port=2222/tcp firewall-cmd --permanent --new-zone=dmz-web firewall-cmd --permanent --zone=dmz-web --add-service=http firewall-cmd --permanent --zone=dmz-web --add-service=https firewall-cmd --permanent --zone=dmz-web --add-port=2222/tcp firewall-cmd --permanent --add-rich-rule='rule service name=ssh limit value=3/m accept' firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.100 port port=3306 protocol=tcp accept' firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source ipset=country-cn drop' firewall-cmd --reload firewall-cmd --list-all firewall-cmd --list-all-zones
4.2 iptables防火墙配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 cat > /etc/firewall-rules.sh << 'EOF' iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 2222 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp --dport 2222 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --name SSH -j DROP iptables -A INPUT -p tcp --dport 2222 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 3306 -j ACCEPT iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP iptables -A INPUT -m recent --name portscan --remove iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:" iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 if command -v iptables-save &> /dev/null; then iptables-save > /etc/iptables/rules.v4 fi echo "Firewall rules applied successfully" EOF chmod +x /etc/firewall-rules.sh/etc/firewall-rules.sh cat > /etc/systemd/system/iptables-restore.service << EOF [Unit] Description=Restore iptables rules After=network.target [Service] Type=oneshot ExecStart=/etc/firewall-rules.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF systemctl enable iptables-restore
4.3 网络入侵检测 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 yum install -y epel-release yum install -y fail2ban cat > /etc/fail2ban/jail.local << EOF [DEFAULT] # 默认配置 bantime = 3600 findtime = 600 maxretry = 3 backend = systemd # SSH保护 [sshd] enabled = true port = 2222 logpath = /var/log/secure maxretry = 3 bantime = 3600 # HTTP保护 [nginx-http-auth] enabled = true filter = nginx-http-auth logpath = /var/log/nginx/error.log maxretry = 3 bantime = 3600 # 防止暴力破解 [nginx-noscript] enabled = true filter = nginx-noscript logpath = /var/log/nginx/access.log maxretry = 6 bantime = 86400 # 防止恶意爬虫 [nginx-badbots] enabled = true filter = nginx-badbots logpath = /var/log/nginx/access.log maxretry = 2 bantime = 86400 EOF systemctl enable fail2ban systemctl start fail2ban fail2ban-client status fail2ban-client status sshd
五、服务安全配置 5.1 Web服务器安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 cat > /etc/nginx/conf.d/security.conf << EOF # 隐藏版本信息 server_tokens off; # 安全头配置 add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"; # 限制请求方法 if (\$request_method !~ ^(GET|HEAD|POST)\$ ) { return 405; } # 限制文件上传大小 client_max_body_size 10M; # 限制请求频率 limit_req_zone \$binary_remote_addr zone=login:10m rate=1r/s; limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s; # 禁止访问敏感文件 location ~ /\. { deny all; access_log off; log_not_found off; } location ~ ~\$ { deny all; access_log off; log_not_found off; } # 禁止执行PHP文件的目录 location /uploads { location ~ \.php\$ { deny all; } } EOF cat > /etc/httpd/conf.d/security.conf << EOF # 隐藏版本信息 ServerTokens Prod ServerSignature Off # 安全头配置 Header always set X-Frame-Options DENY Header always set X-Content-Type-Options nosniff Header always set X-XSS-Protection "1; mode=block" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" # 禁用不安全的HTTP方法 <LimitExcept GET POST HEAD> Require all denied </LimitExcept> # 禁止访问敏感文件 <FilesMatch "^\.(htaccess|htpasswd|ini|log|sh|inc|bak)\$"> Require all denied </FilesMatch> # 禁止目录浏览 Options -Indexes # 限制请求大小 LimitRequestBody 10485760 EOF
5.2 数据库安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 mysql_secure_installation cat >> /etc/my.cnf << EOF [mysqld] # 网络安全 bind-address = 127.0.0.1 skip-networking = 0 port = 3306 # 禁用危险功能 local-infile = 0 show-database = 0 # 日志配置 log-error = /var/log/mysqld.log general-log = 1 general-log-file = /var/log/mysql-general.log slow-query-log = 1 slow-query-log-file = /var/log/mysql-slow.log long-query-time = 2 # 安全配置 sql-mode = STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO validate-password = ON validate-password-policy = MEDIUM validate-password-length = 12 EOF cat > /root/mysql_security.sql << EOF -- 删除匿名用户 DELETE FROM mysql.user WHERE User=''; -- 删除test数据库 DROP DATABASE IF EXISTS test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'; -- 禁用root远程登录 DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); -- 创建应用用户 CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'StrongPassword123!'; GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'appuser'@'localhost'; -- 创建备份用户 CREATE USER 'backupuser'@'localhost' IDENTIFIED BY 'BackupPassword123!'; GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'backupuser'@'localhost'; -- 刷新权限 FLUSH PRIVILEGES; EOF mysql -u root -p < /root/mysql_security.sql
5.3 邮件服务安全配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 cat >> /etc/postfix/main.cf << EOF # 安全配置 smtpd_banner = \$myhostname ESMTP disable_vrfy_command = yes smtpd_helo_required = yes # 限制连接 smtpd_client_connection_count_limit = 10 smtpd_client_connection_rate_limit = 30 smtpd_client_message_rate_limit = 100 # SASL认证 smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = \$myhostname # TLS配置 smtpd_use_tls = yes smtpd_tls_cert_file = /etc/ssl/certs/postfix.pem smtpd_tls_key_file = /etc/ssl/private/postfix.key smtpd_tls_security_level = may smtpd_tls_protocols = !SSLv2, !SSLv3 EOF systemctl restart postfix
六、日志监控和审计 6.1 系统日志配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 cat > /etc/rsyslog.d/50-security.conf << EOF # 安全日志配置 # SSH登录日志 auth,authpriv.* /var/log/auth.log # sudo命令日志 local0.* /var/log/sudo.log # 防火墙日志 kern.* /var/log/firewall.log # 系统安全事件 *.emerg /var/log/emergency.log # 远程日志服务器(可选) *.* @@logserver.example.com:514 EOF systemctl restart rsyslog cat > /etc/logrotate.d/security << EOF /var/log/auth.log /var/log/sudo.log /var/log/firewall.log /var/log/emergency.log { daily rotate 30 compress delaycompress missingok notifempty create 640 root root postrotate systemctl reload rsyslog endscript } EOF
6.2 审计系统配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 yum install -y audit systemctl enable auditd cat > /etc/audit/rules.d/audit.rules << EOF # 删除所有现有规则 -D # 设置缓冲区大小 -b 8192 # 设置失败模式 -f 1 # 监控系统调用 -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change -a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change -a always,exit -F arch=b64 -S clock_settime -k time-change -a always,exit -F arch=b32 -S clock_settime -k time-change # 监控用户和组管理 -w /etc/group -p wa -k identity -w /etc/passwd -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity # 监控网络配置 -a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale -a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale -w /etc/issue -p wa -k system-locale -w /etc/issue.net -p wa -k system-locale -w /etc/hosts -p wa -k system-locale -w /etc/sysconfig/network -p wa -k system-locale # 监控权限变更 -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod # 监控文件访问 -a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access -a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access -a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access -a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access # 监控特权命令 -w /usr/bin/passwd -p x -k privileged-passwd -w /usr/sbin/groupadd -p x -k privileged-groupadd -w /usr/sbin/groupmod -p x -k privileged-groupmod -w /usr/sbin/addgroup -p x -k privileged-addgroup -w /usr/sbin/useradd -p x -k privileged-useradd -w /usr/sbin/usermod -p x -k privileged-usermod -w /usr/sbin/adduser -p x -k privileged-adduser # 监控sudo使用 -w /etc/sudoers -p wa -k scope -w /etc/sudoers.d/ -p wa -k scope # 监控内核模块 -w /sbin/insmod -p x -k modules -w /sbin/rmmod -p x -k modules -w /sbin/modprobe -p x -k modules -a always,exit -F arch=b64 -S init_module -S delete_module -k modules # 使规则不可变 -e 2 EOF systemctl restart auditd auditctl -l ausearch -k identity ausearch -k privileged-passwd
6.3 安全监控脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 cat > /usr/local/bin/security_monitor.sh << 'EOF' LOGFILE="/var/log/security_monitor.log" ALERT_EMAIL="admin@example.com" DATE=$(date '+%Y-%m-%d %H:%M:%S' ) check_ssh_failures () { local failures=$(grep "Failed password" /var/log/secure | grep "$(date '+%b %d') " | wc -l) if [ $failures -gt 10 ]; then echo "$DATE : WARNING - $failures SSH login failures detected" >> $LOGFILE echo "High number of SSH failures: $failures " | mail -s "SSH Security Alert" $ALERT_EMAIL fi } check_new_users () { local new_users=$(grep "new user" /var/log/secure | grep "$(date '+%b %d') " | wc -l) if [ $new_users -gt 0 ]; then echo "$DATE : INFO - $new_users new users created" >> $LOGFILE grep "new user" /var/log/secure | grep "$(date '+%b %d') " | mail -s "New User Alert" $ALERT_EMAIL fi } check_sudo_usage () { local sudo_commands=$(grep "COMMAND" /var/log/sudo.log | grep "$(date '+%b %d') " | wc -l) if [ $sudo_commands -gt 50 ]; then echo "$DATE : WARNING - High sudo usage: $sudo_commands commands" >> $LOGFILE fi } check_disk_usage () { local disk_usage=$(df / | awk 'NR==2 {print $5}' | cut -d'%' -f1) if [ $disk_usage -gt 90 ]; then echo "$DATE : CRITICAL - Disk usage at ${disk_usage} %" >> $LOGFILE echo "Disk usage critical: ${disk_usage} %" | mail -s "Disk Space Alert" $ALERT_EMAIL fi } check_suspicious_processes () { local high_cpu=$(ps aux --sort =-%cpu | head -2 | tail -1 | awk '{print $3}' ) if (( $(echo "$high_cpu > 80 " | bc -l) )); then echo "$DATE : WARNING - High CPU usage process detected: $high_cpu %" >> $LOGFILE fi local suspicious=$(ps aux | grep -E '(nc|netcat|ncat|socat|telnet)' | grep -v grep) if [ -n "$suspicious " ]; then echo "$DATE : ALERT - Suspicious process detected: $suspicious " >> $LOGFILE echo "Suspicious process: $suspicious " | mail -s "Process Security Alert" $ALERT_EMAIL fi } check_ssh_failures check_new_users check_sudo_usage check_disk_usage check_suspicious_processes echo "$DATE : Security monitoring completed" >> $LOGFILE EOF chmod +x /usr/local/bin/security_monitor.shecho "*/15 * * * * /usr/local/bin/security_monitor.sh" | crontab -
七、高级安全防护 7.1 入侵检测系统(IDS) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 yum install -y aide aide --init mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gzcat >> /etc/aide.conf << EOF # 自定义监控规则 /etc/passwd f+p+u+g+s+m+c+md5+sha1 /etc/shadow f+p+u+g+s+m+c+md5+sha1 /etc/group f+p+u+g+s+m+c+md5+sha1 /etc/sudoers f+p+u+g+s+m+c+md5+sha1 /etc/ssh/sshd_config f+p+u+g+s+m+c+md5+sha1 /boot f+p+u+g+s+m+c+md5+sha1 /bin f+p+u+g+s+m+c+md5+sha1 /sbin f+p+u+g+s+m+c+md5+sha1 /usr/bin f+p+u+g+s+m+c+md5+sha1 /usr/sbin f+p+u+g+s+m+c+md5+sha1 EOF cat > /usr/local/bin/aide_check.sh << 'EOF' LOGFILE="/var/log/aide_check.log" DATE=$(date '+%Y-%m-%d %H:%M:%S' ) echo "$DATE : Starting AIDE check" >> $LOGFILE aide --check > /tmp/aide_report.txt 2>&1 if [ $? -eq 0 ]; then echo "$DATE : AIDE check completed - No changes detected" >> $LOGFILE else echo "$DATE : AIDE check completed - Changes detected" >> $LOGFILE cat /tmp/aide_report.txt >> $LOGFILE mail -s "AIDE File Integrity Alert" admin@example.com < /tmp/aide_report.txt fi rm -f /tmp/aide_report.txtEOF chmod +x /usr/local/bin/aide_check.shecho "0 2 * * * /usr/local/bin/aide_check.sh" >> /var/spool/cron/root
7.2 恶意软件检测 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 yum install -y epel-release yum install -y clamav clamav-update freshclam cat > /usr/local/bin/malware_scan.sh << 'EOF' LOGFILE="/var/log/malware_scan.log" DATE=$(date '+%Y-%m-%d %H:%M:%S' ) SCAN_DIRS="/home /var/www /tmp /var/tmp" echo "$DATE : Starting malware scan" >> $LOGFILE freshclam >> $LOGFILE 2>&1 for dir in $SCAN_DIRS ; do if [ -d "$dir " ]; then echo "$DATE : Scanning $dir " >> $LOGFILE clamscan -r --infected --remove=yes "$dir " >> $LOGFILE 2>&1 fi done echo "$DATE : Scanning system directories" >> $LOGFILE clamscan -r --infected /bin /sbin /usr/bin /usr/sbin >> $LOGFILE 2>&1 echo "$DATE : Malware scan completed" >> $LOGFILE if grep -q "FOUND" $LOGFILE ; then echo "Malware detected on $(hostname) " | mail -s "Malware Alert" admin@example.com fi EOF chmod +x /usr/local/bin/malware_scan.shecho "0 3 * * 0 /usr/local/bin/malware_scan.sh" >> /var/spool/cron/root
7.3 网络流量监控 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 yum install -y epel-release yum install -y ntopng cat > /etc/ntopng/ntopng.conf << EOF # ntopng配置 -i=eth0 -P=/var/lib/ntopng/ntopng.pid -d=/var/lib/ntopng -w=3000 -U=ntopng -u=nobody --local-networks="192.168.1.0/24,10.0.0.0/8,172.16.0.0/12" --interface-name=eth0@Internal EOF systemctl enable ntopng systemctl start ntopng cat > /usr/local/bin/traffic_monitor.sh << 'EOF' LOGFILE="/var/log/traffic_monitor.log" DATE=$(date '+%Y-%m-%d %H:%M:%S' ) INTERFACE="eth0" THRESHOLD_MBPS=100 RX_BYTES=$(cat /sys/class/net/$INTERFACE /statistics/rx_bytes) TX_BYTES=$(cat /sys/class/net/$INTERFACE /statistics/tx_bytes) sleep 1RX_BYTES_NEW=$(cat /sys/class/net/$INTERFACE /statistics/rx_bytes) TX_BYTES_NEW=$(cat /sys/class/net/$INTERFACE /statistics/tx_bytes) RX_RATE=$(( (RX_BYTES_NEW - RX_BYTES) * 8 / 1000000 )) TX_RATE=$(( (TX_BYTES_NEW - TX_BYTES) * 8 / 1000000 )) echo "$DATE : RX: ${RX_RATE} Mbps, TX: ${TX_RATE} Mbps" >> $LOGFILE if [ $RX_RATE -gt $THRESHOLD_MBPS ] || [ $TX_RATE -gt $THRESHOLD_MBPS ]; then echo "$DATE : WARNING - High traffic detected: RX=${RX_RATE} Mbps, TX=${TX_RATE} Mbps" >> $LOGFILE echo "High network traffic detected on $(hostname) : RX=${RX_RATE} Mbps, TX=${TX_RATE} Mbps" | mail -s "Traffic Alert" admin@example.com fi EOF chmod +x /usr/local/bin/traffic_monitor.shecho "*/5 * * * * /usr/local/bin/traffic_monitor.sh" >> /var/spool/cron/root
八、备份和恢复 8.1 系统备份策略 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 cat > /usr/local/bin/system_backup.sh << 'EOF' BACKUP_DIR="/backup" DATE=$(date '+%Y%m%d_%H%M%S' ) LOGFILE="/var/log/backup.log" RETENTION_DAYS=30 mkdir -p $BACKUP_DIR echo "$(date) : Starting system backup" >> $LOGFILE echo "$(date) : Backing up system configuration" >> $LOGFILE tar -czf $BACKUP_DIR /system_config_$DATE .tar.gz \ /etc \ /boot/grub2 \ /var/spool/cron \ /root/.ssh \ --exclude=/etc/shadow- \ --exclude=/etc/passwd- \ --exclude=/etc/group- 2>> $LOGFILE echo "$(date) : Backing up user data" >> $LOGFILE tar -czf $BACKUP_DIR /user_data_$DATE .tar.gz \ /home \ --exclude=/home/*/.cache \ --exclude=/home/*/.tmp 2>> $LOGFILE echo "$(date) : Backing up log files" >> $LOGFILE tar -czf $BACKUP_DIR /logs_$DATE .tar.gz \ /var/log 2>> $LOGFILE if systemctl is-active --quiet mysqld; then echo "$(date) : Backing up MySQL databases" >> $LOGFILE mysqldump --all-databases --single-transaction --routines --triggers > $BACKUP_DIR /mysql_$DATE .sql gzip $BACKUP_DIR /mysql_$DATE .sql fi echo "$(date) : Cleaning old backups" >> $LOGFILE find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete echo "$(date) : Backup completed" >> $LOGFILE echo "Backup files:" >> $LOGFILE ls -lh $BACKUP_DIR /*$DATE * >> $LOGFILE tail -20 $LOGFILE | mail -s "Backup Report - $(hostname) " admin@example.comEOF chmod +x /usr/local/bin/system_backup.shecho "0 1 * * * /usr/local/bin/system_backup.sh" >> /var/spool/cron/root
8.2 灾难恢复计划 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 cat > /usr/local/bin/system_restore.sh << 'EOF' BACKUP_DIR="/backup" LOGFILE="/var/log/restore.log" if [ $# -ne 1 ]; then echo "Usage: $0 <backup_date>" echo "Example: $0 20240310_120000" exit 1 fi BACKUP_DATE=$1 echo "$(date) : Starting system restore from backup $BACKUP_DATE " >> $LOGFILE if [ ! -f "$BACKUP_DIR /system_config_$BACKUP_DATE .tar.gz" ]; then echo "Error: Backup file not found" >> $LOGFILE exit 1 fi echo "$(date) : Backing up current configuration" >> $LOGFILE cp -r /etc /etc.backup.$(date +%Y%m%d_%H%M%S)echo "$(date) : Restoring system configuration" >> $LOGFILE tar -xzf $BACKUP_DIR /system_config_$BACKUP_DATE .tar.gz -C / 2>> $LOGFILE if [ -f "$BACKUP_DIR /user_data_$BACKUP_DATE .tar.gz" ]; then echo "$(date) : Restoring user data" >> $LOGFILE tar -xzf $BACKUP_DIR /user_data_$BACKUP_DATE .tar.gz -C / 2>> $LOGFILE fi if [ -f "$BACKUP_DIR /mysql_$BACKUP_DATE .sql.gz" ]; then echo "$(date) : Restoring MySQL databases" >> $LOGFILE zcat $BACKUP_DIR /mysql_$BACKUP_DATE .sql.gz | mysql 2>> $LOGFILE fi echo "$(date) : Restarting services" >> $LOGFILE systemctl restart sshd systemctl restart firewalld systemctl restart rsyslog echo "$(date) : System restore completed" >> $LOGFILE echo "Please reboot the system to ensure all changes take effect" EOF chmod +x /usr/local/bin/system_restore.sh
九、安全合规和最佳实践 9.1 安全基线检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 cat > /usr/local/bin/security_baseline.sh << 'EOF' REPORT_FILE="/tmp/security_baseline_report.txt" DATE=$(date '+%Y-%m-%d %H:%M:%S' ) echo "=== Security Baseline Check Report ===" > $REPORT_FILE echo "Date: $DATE " >> $REPORT_FILE echo "Hostname: $(hostname) " >> $REPORT_FILE echo >> $REPORT_FILE echo "1. Account Security:" >> $REPORT_FILE echo " Users with UID 0: $(awk -F: '$3 == 0 {print $1}' /etc/passwd | tr '\n' ' ') " >> $REPORT_FILE echo " Users with empty passwords: $(awk -F: '$2 == "" {print $1}' /etc/shadow | tr '\n' ' ') " >> $REPORT_FILE echo " Password aging enabled: $(grep PASS_MAX_DAYS /etc/login.defs | grep -v '#') " >> $REPORT_FILE echo >> $REPORT_FILE echo "2. SSH Security:" >> $REPORT_FILE echo " Root login disabled: $(grep '^PermitRootLogin no' /etc/ssh/sshd_config && echo 'YES' || echo 'NO') " >> $REPORT_FILE echo " Password auth disabled: $(grep '^PasswordAuthentication no' /etc/ssh/sshd_config && echo 'YES' || echo 'NO') " >> $REPORT_FILE echo " Default port changed: $(grep '^Port' /etc/ssh/sshd_config | grep -v '22' && echo 'YES' || echo 'NO') " >> $REPORT_FILE echo >> $REPORT_FILE echo "3. Firewall Status:" >> $REPORT_FILE if systemctl is-active --quiet firewalld; then echo " Firewalld: Active" >> $REPORT_FILE echo " Active zones: $(firewall-cmd --get-active-zones | grep -v interfaces) " >> $REPORT_FILE elif systemctl is-active --quiet ufw; then echo " UFW: Active" >> $REPORT_FILE else echo " Firewall: Inactive" >> $REPORT_FILE fi echo >> $REPORT_FILE echo "4. System Updates:" >> $REPORT_FILE if command -v yum &> /dev/null; then echo " Available updates: $(yum check-update 2>/dev/null | grep -c '^[a-zA-Z]') " >> $REPORT_FILE elif command -v apt &> /dev/null; then echo " Available updates: $(apt list --upgradable 2>/dev/null | grep -c upgradable) " >> $REPORT_FILE fi echo >> $REPORT_FILE echo "5. Running Services:" >> $REPORT_FILE echo " Critical services status:" >> $REPORT_FILE for service in sshd firewalld rsyslog auditd; do if systemctl is-active --quiet $service ; then echo " $service : Running" >> $REPORT_FILE else echo " $service : Stopped" >> $REPORT_FILE fi done echo >> $REPORT_FILE echo "6. File Permissions:" >> $REPORT_FILE echo " /etc/shadow permissions: $(ls -l /etc/shadow | awk '{print $1}') " >> $REPORT_FILE echo " /etc/passwd permissions: $(ls -l /etc/passwd | awk '{print $1}') " >> $REPORT_FILE echo " World-writable files: $(find / -type f -perm -002 2>/dev/null | wc -l) " >> $REPORT_FILE echo " SUID files: $(find / -type f -perm -4000 2>/dev/null | wc -l) " >> $REPORT_FILE echo >> $REPORT_FILE echo "7. Network Security:" >> $REPORT_FILE echo " IP forwarding disabled: $(sysctl net.ipv4.ip_forward | grep -q '= 0' && echo 'YES' || echo 'NO') " >> $REPORT_FILE echo " SYN cookies enabled: $(sysctl net.ipv4.tcp_syncookies | grep -q '= 1' && echo 'YES' || echo 'NO') " >> $REPORT_FILE echo " ICMP redirects disabled: $(sysctl net.ipv4.conf.all.accept_redirects | grep -q '= 0' && echo 'YES' || echo 'NO') " >> $REPORT_FILE echo >> $REPORT_FILE echo "=== End of Report ===" >> $REPORT_FILE cat $REPORT_FILE mail -s "Security Baseline Report - $(hostname) " admin@example.com < $REPORT_FILE EOF chmod +x /usr/local/bin/security_baseline.sh
9.2 合规性检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 cat > /usr/local/bin/cis_benchmark.sh << 'EOF' REPORT_FILE="/tmp/cis_benchmark_report.txt" SCORE=0 TOTAL=0 echo "=== CIS Benchmark Check Report ===" > $REPORT_FILE echo "Date: $(date) " >> $REPORT_FILE echo >> $REPORT_FILE check_item () { local description="$1 " local command ="$2 " local expected="$3 " echo -n "Checking: $description ... " >> $REPORT_FILE if eval "$command " | grep -q "$expected " ; then echo "PASS" >> $REPORT_FILE ((SCORE++)) else echo "FAIL" >> $REPORT_FILE fi ((TOTAL++)) } echo "1. Filesystem Configuration:" >> $REPORT_FILE check_item "Separate /tmp partition" "mount | grep '/tmp'" "/tmp" check_item "nodev option on /tmp" "mount | grep '/tmp'" "nodev" check_item "nosuid option on /tmp" "mount | grep '/tmp'" "nosuid" check_item "noexec option on /tmp" "mount | grep '/tmp'" "noexec" echo >> $REPORT_FILE echo "2. Software Updates:" >> $REPORT_FILE check_item "GPG keys configured" "rpm -q gpg-pubkey" "gpg-pubkey" echo >> $REPORT_FILE echo "3. Service Configuration:" >> $REPORT_FILE check_item "Telnet server disabled" "systemctl is-enabled telnet.socket 2>/dev/null" "disabled" check_item "RSH server disabled" "systemctl is-enabled rsh.socket 2>/dev/null" "disabled" check_item "NIS server disabled" "systemctl is-enabled ypserv 2>/dev/null" "disabled" echo >> $REPORT_FILE echo "4. Network Configuration:" >> $REPORT_FILE check_item "IP forwarding disabled" "sysctl net.ipv4.ip_forward" "= 0" check_item "Send redirects disabled" "sysctl net.ipv4.conf.all.send_redirects" "= 0" check_item "Source routed packets disabled" "sysctl net.ipv4.conf.all.accept_source_route" "= 0" check_item "ICMP redirects disabled" "sysctl net.ipv4.conf.all.accept_redirects" "= 0" check_item "Log martians enabled" "sysctl net.ipv4.conf.all.log_martians" "= 1" check_item "SYN cookies enabled" "sysctl net.ipv4.tcp_syncookies" "= 1" echo >> $REPORT_FILE echo "5. Logging and Auditing:" >> $REPORT_FILE check_item "rsyslog installed" "rpm -q rsyslog" "rsyslog" check_item "auditd enabled" "systemctl is-enabled auditd" "enabled" check_item "audit log file permissions" "ls -l /var/log/audit/audit.log" "^-rw-------" echo >> $REPORT_FILE echo "6. System Access, Authentication and Authorization:" >> $REPORT_FILE check_item "cron daemon enabled" "systemctl is-enabled crond" "enabled" check_item "SSH Protocol 2" "grep '^Protocol 2' /etc/ssh/sshd_config" "Protocol 2" check_item "SSH root login disabled" "grep '^PermitRootLogin no' /etc/ssh/sshd_config" "PermitRootLogin no" check_item "SSH empty passwords disabled" "grep '^PermitEmptyPasswords no' /etc/ssh/sshd_config" "PermitEmptyPasswords no" echo >> $REPORT_FILE echo "7. User Accounts and Environment:" >> $REPORT_FILE check_item "Password expiration" "grep '^PASS_MAX_DAYS' /etc/login.defs" "PASS_MAX_DAYS" check_item "Password minimum days" "grep '^PASS_MIN_DAYS' /etc/login.defs" "PASS_MIN_DAYS" check_item "Default umask" "grep 'umask 027' /etc/bashrc" "umask 027" echo >> $REPORT_FILE PERCENTAGE=$((SCORE * 100 / TOTAL)) echo "=== Summary ===" >> $REPORT_FILE echo "Score: $SCORE /$TOTAL ($PERCENTAGE %)" >> $REPORT_FILE if [ $PERCENTAGE -ge 80 ]; then echo "Status: GOOD" >> $REPORT_FILE elif [ $PERCENTAGE -ge 60 ]; then echo "Status: FAIR" >> $REPORT_FILE else echo "Status: POOR" >> $REPORT_FILE fi echo "=== End of Report ===" >> $REPORT_FILE cat $REPORT_FILE EOF chmod +x /usr/local/bin/cis_benchmark.sh
9.3 安全加固自动化脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 cat > /usr/local/bin/security_hardening.sh << 'EOF' LOGFILE="/var/log/security_hardening.log" DATE=$(date '+%Y-%m-%d %H:%M:%S' ) echo "$DATE : Starting security hardening" >> $LOGFILE echo "$DATE : Updating system packages" >> $LOGFILE if command -v yum &> /dev/null; then yum update -y >> $LOGFILE 2>&1 elif command -v apt &> /dev/null; then apt update && apt upgrade -y >> $LOGFILE 2>&1 fi echo "$DATE : Disabling unnecessary services" >> $LOGFILE for service in telnet rsh ypbind tftp; do if systemctl is-enabled $service &>/dev/null; then systemctl disable $service >> $LOGFILE 2>&1 systemctl stop $service >> $LOGFILE 2>&1 echo "Disabled service: $service " >> $LOGFILE fi done echo "$DATE : Configuring firewall" >> $LOGFILE if command -v firewall-cmd &> /dev/null; then systemctl enable firewalld >> $LOGFILE 2>&1 systemctl start firewalld >> $LOGFILE 2>&1 firewall-cmd --set-default-zone=public >> $LOGFILE 2>&1 firewall-cmd --permanent --remove-service=dhcpv6-client >> $LOGFILE 2>&1 firewall-cmd --reload >> $LOGFILE 2>&1 fi echo "$DATE : Configuring SSH security" >> $LOGFILE cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backupsed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config sed -i 's/#MaxAuthTries 6/MaxAuthTries 3/' /etc/ssh/sshd_config echo "Protocol 2" >> /etc/ssh/sshd_configsystemctl restart sshd >> $LOGFILE 2>&1 echo "$DATE : Setting file permissions" >> $LOGFILE chmod 600 /etc/shadowchmod 600 /etc/gshadowchmod 644 /etc/passwdchmod 644 /etc/groupchmod 700 /rootecho "$DATE : Configuring kernel parameters" >> $LOGFILE cat > /etc/sysctl.d/99-security.conf << EOSYSCTL net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 net.ipv4.tcp_syncookies = 1 kernel.sysrq = 0 fs.suid_dumpable = 0 EOSYSCTL sysctl -p /etc/sysctl.d/99-security.conf >> $LOGFILE 2>&1 echo "$DATE : Configuring password policy" >> $LOGFILE if [ -f /etc/security/pwquality.conf ]; then sed -i 's/# minlen = 8/minlen = 12/' /etc/security/pwquality.conf sed -i 's/# lcredit = 1/lcredit = -1/' /etc/security/pwquality.conf sed -i 's/# ucredit = 1/ucredit = -1/' /etc/security/pwquality.conf sed -i 's/# dcredit = 1/dcredit = -1/' /etc/security/pwquality.conf sed -i 's/# ocredit = 1/ocredit = -1/' /etc/security/pwquality.conf fi echo "$DATE : Enabling audit" >> $LOGFILE if command -v auditd &> /dev/null; then systemctl enable auditd >> $LOGFILE 2>&1 systemctl start auditd >> $LOGFILE 2>&1 fi echo "$DATE : Installing security tools" >> $LOGFILE if command -v yum &> /dev/null; then yum install -y fail2ban aide rkhunter >> $LOGFILE 2>&1 elif command -v apt &> /dev/null; then apt install -y fail2ban aide rkhunter >> $LOGFILE 2>&1 fi echo "$DATE : Security hardening completed" >> $LOGFILE echo "Security hardening completed. Please review the log file: $LOGFILE " EOF chmod +x /usr/local/bin/security_hardening.sh
十、总结和建议 10.1 安全加固检查清单 基础安全配置 :
用户和权限管理 :
网络安全 :
SSH安全 :
日志和监控 :
备份和恢复 :
10.2 持续安全改进
定期安全评估 :每季度进行一次全面的安全评估
漏洞扫描 :定期使用自动化工具进行漏洞扫描
安全培训 :定期对管理员进行安全培训
事件响应 :建立完善的安全事件响应流程
合规检查 :定期进行合规性检查和审计
10.3 最佳实践建议
分层防御 :不要依赖单一的安全措施,建立多层防护体系
最小权限 :严格遵循最小权限原则,只给予必要的权限
定期更新 :及时安装安全补丁和更新
监控告警 :建立实时监控和告警机制
文档管理 :详细记录所有安全配置和变更
测试验证 :在生产环境应用前充分测试
备份恢复 :建立可靠的备份和恢复机制
安全意识 :提高所有相关人员的安全意识
10.4 常见安全误区
过度依赖防火墙 :防火墙只是安全防护的一部分
忽视内部威胁 :内部威胁往往比外部威胁更危险
配置后不维护 :安全配置需要持续维护和更新
缺乏监控 :没有监控就无法及时发现安全问题
备份不测试 :不测试的备份可能在关键时刻无法使用
通过系统性的安全加固措施,可以大大提升Linux服务器的安全性。记住,安全是一个持续的过程,需要不断地评估、改进和维护。建议根据实际环境和业务需求,制定适合的安全策略,并严格执行。
本文提供了一套完整的Linux服务器安全加固方案,涵盖了从基础配置到高级防护的各个方面。建议运维人员根据实际情况选择合适的安全措施,并建立持续的安全改进机制。安全无小事,预防胜于治疗。