Liunx巡检脚本

Linux系统日常巡检脚本-优快云博客 来自此博客,但是我好多用不了就用AI重新写了个,发个日志记一下。

服务器不多不知道还有啥问题,有用到的就反馈一下吧。

脚本输出内容 

[root@localhost home]# ./system_bas.sh
系统巡检脚本:Version 2025-06-16

############################ 系统检查 ############################
 系统:GNU/Linux
 发行版本:CentOS Linux 7 (Core)
 内核:3.10.0-1160.el7.x86_64
 主机名:localhost.localdomain
 SELinux:Disabled
 语言/编码:zh_CN.UTF-8
 当前时间:2025-06-16 12:59:49
 最后启动:2025-06-16 12:52:29
 运行时间:7 minutes

############################ CPU检查 ############################
物理CPU个数: 1
每物理CPU核心数: 16
每核线程数: 1
逻辑CPU总数: 16
CPU型号: AMD EPYC 7282 16-Core Processor
虚拟化环境: VMware
NUMA节点数: 2
[注意] 虚拟化环境下显示的CPU拓扑可能与物理机不同
[建议] 如需准确信息,请在物理主机上运行此脚本
[信息] 已使用dmidecode获取物理CPU信息

############################ 内存检查 ############################
总内存: 62.76 GB
空闲内存: 47.69 GB
缓存/缓冲: 6.03 GB (缓存) + 0.03 GB (缓冲)
内存配置: 最大支持: 65 GB | 插槽总数: 64
已使用内存插槽: 5个
内存厂商分布: 1× 4×未知
内存速度分布: 5@未知

=== 详细内存规格 ===
插槽1: Not | 厂商:  | 型号:  | 类型: DRAM | 速度: 未知 | 电压: 3.3
插槽RAM: 16384 | 厂商: 未知 | 型号: 未知 | 类型: DRAM | 速度: 未知 | 电压:
插槽RAM: 16384 | 厂商: 未知 | 型号: 未知 | 类型: DRAM | 速度: 未知 | 电压:
插槽RAM: 16384 | 厂商: 未知 | 型号: 未知 | 类型: DRAM | 速度: 未知 | 电压:
插槽RAM: 16384 | 厂商: 未知 | 型号: 未知 | 类型: DRAM | 速度: 未知 | 电压:

交换空间: 总共63G, 已用0B
[信息] 已过滤所有空插槽并标准化显示格式

############################ 存储检查 ############################

=== 存储详情 ===
设备      类型  容量   型号     转速  健康状态
/dev/sda  HDD   500G   Virtual  7200  正常
/dev/sr0  HDD   1024M  VMware   7200  正常

=== 存储拓扑 ===
df: "0": 没有那个文件或目录
df: "1": 没有那个文件或目录
设备      类型  容量  挂载点      文件系统  使用率
NAME      TYPE  SIZE  MOUNTPOINT  FSTYPE    USE%
/dev/sda  part  0     0           500G      -
/dev/sr0  part  0     1           1024M     -

=== 分区详情 ===
分区             容量  已用  可用  使用率  挂载点       文件系统
/dev/sda1        497M  143M  354M  29%     /boot        xfs
/dev/mapper/...  100G  70G   31G   70%     /dragonball  xfs
/dev/mapper/...  197G  22G   166G  12%     /var         ext4
/dev/mapper/...  136G  71G   65G   53%     /            xfs

=== LVM详细信息 ===
【卷组信息】
VG      #PV  #LV  #SN  Attr    VSize    VFree
centos  1    3    0    wz--n-  435.51g  0g

【逻辑卷信息】
LV          VG      Attr        LSize    Data%  Meta%  Mount
dragonball  centos  -wi-ao----  100.00g  -      -      /dragonball
root        centos  -wi-ao----  135.51g  -      -      /
var         centos  -wi-ao----  200.00g  -      -      /var

############################ RAID检查 ############################
=== 软件RAID (mdadm) 信息 ===

=== 硬件RAID 信息 ===
[信息] 未检测到硬件RAID控制器
[建议] 如需检测硬件RAID,请安装以下工具之一:
  - MegaCli (LSI MegaRAID)
  - storcli (Broadcom/LSI)
  - hpssacli (HP SmartArray)

=== 磁盘拓扑信息 ===
设备  旋转  可移  大小   只读  类型  挂载点
sda   是    否    500G   否    disk
sr0   是    是    1024M  否    rom

############################ 网络检查 ############################

=== 网络接口详情 ===
接口名称              状态  IP地址                            MAC地址             MTU    速率      接收       发送
ens192               UP    192.168.1.239/24               00:0c:29:5a:51:e3  1500   10000Mb 0B         0B
                           fe80::1dfe:3e0f:aa74:c2c1/64
docker0              UP    172.17.42.1/16                 02:42:cd:d7:07:27  1500   未知    0B         0B
marne-docker         UP    172.21.0.1/16                  02:42:ad:2e:91:a9  1500   未知    0B         0B
                           fe80::42:adff:fe2e:91a9/64

=== 路由表信息 ===
目标网络        网关           接口             标志    跃点    来源
default         192.168.1.254   ens192           网关       dhcp     100
172.17.0.0/16   直连              docker0          直连       kernel   172.17.42.1
172.21.0.0/16   直连              marne-docker     直连       kernel   172.21.0.1
192.168.1.0/24  直连              ens192           直连       kernel   192.168.1.239

=== DNS和连接信息 ===
DNS服务器       域名服务器
192.168.1.254   解析服务器

默认网关        接口          优先级
192.168.1.254   ens192         dhcp

=== 网络连接统计 ===
总连接数: 502
TCP状态:
  已建立: 2092
  关闭中: 201
  孤儿: 0
  时间等待: 0

=== 孤儿连接分析 ===
  孤儿连接数量正常(0)

############################ 监听检查 ############################

=== 网络监听端口详情 ===
协议  状态    本地地址    进程信息                          服务
UDP   UNCONN  :123        chronyd",pid=957,fd=7))/          -
UDP   UNCONN  :123        chronyd",pid=957,fd=8))/          -
TCP   LISTEN  :22         sshd",pid=1265,fd=3))/            -
TCP   LISTEN  :22         sshd",pid=1265,fd=4))/            -
TCP   LISTEN  :24513      containerd",pid=1275,fd=9))/      -
UDP   UNCONN  :323        chronyd",pid=957,fd=5))/          -
UDP   UNCONN  :323        chronyd",pid=957,fd=6))/          -
TCP   LISTEN  :5555       docker-proxy",pid=2085,fd=4))/    -
TCP   LISTEN  :5555       docker-proxy",pid=2093,fd=4))/    -
UDP   UNCONN  :68         dhclient",pid=1065,fd=6))/        -
TCP   LISTEN  :8888       agentz",pid=1269,fd=7))/          -

=== 高危端口检测 ===
协议  端口  风险等级  绑定地址           服务       建议
tcp   22    高危                0.0.0.0        SSH  限制访问IP或使用密钥认证

=== 异常连接检测 ===
协议  本地地址    远程地址    状态    进程

############################ 进程检查 ############################

=== 内存占用TOP10 (物理内存) ===
PID   %MEM  RSS(MB)  COMMAND
4990  2.3   1518.9   java
5924  1.7   1137.8   java
5515  1.2   779.6    java
5837  1.1   770.5    java
5716  1.1   728.9    java
5618  1.0   645.4    java
6011  0.8   562.9    java
5294  0.8   558.3    mysqld
3765  0.2   148.9    beam.smp
1655  0.0   55.6     dockerd

=== CPU占用TOP10 ===
PID   USER      %CPU  %MEM  TIME      COMMAND
6011  root      61    0.8   00:02:21  java
5515  root      40    1.2   00:01:33  java
4990  marneus+  32    2.3   00:01:25  java
5716  root      31.9  1.1   00:01:14  java
5924  root      30.2  1.7   00:01:10  java
5837  root      27.1  1.1   00:01:02  java
5618  root      14    1     00:00:32  java
3765  992       2.8   0.2   00:00:07  beam.smp
5294  27        1.2   0.8   00:00:03  mysqld
1     root      0.4   0     00:00:01  systemd

=== 最近启动的进程 ===
PID   USER      启动时间    命令
9892  root      2025-06-16  12:59:50  ./system_bas.sh
9893  root      2025-06-16  12:59:50  --sort=-start_time
9894  root      2025-06-16  12:59:50  -10
9895  root      2025-06-16  12:59:50  }
9803  root      2025-06-16  12:59:49  /usr/lib/systemd/systemd-udevd
9565  root      2025-06-16  12:59:49  ./system_bas.sh
9566  root      2025-06-16  12:59:49  /var/log/system_inspection_20250616.log
9563  root      2025-06-16  12:59:49  ./system_bas.sh
9475  agentus+  2025-06-16  12:59:05  -config-dir=/dragonball/consul/config

############################ 服务检查 ############################

=== 运行中的服务 ===
状态  服务名称                                       运行时间  内存占用  主PID                           描述
✓     agentz.service            2025-06-16 12:59:15  66MB      1269      agentz
✓     auditd.service            2025-06-16 12:59:23  2.8MB     925       Security Auditing Service
✓     chronyd.service           2025-06-16 12:59:22  1.6MB     957       NTP client/server
✓     containerd.service        2025-06-16 12:59:16  77MB      1275      containerd container runtime
✓     crond.service             2025-06-16 12:59:22  748KB     984       Command Scheduler
✓     dbus.service              2025-06-16 12:59:22  1.6MB     963       D-Bus System Message Bus
✓     docker.service            2025-06-16 12:59:11  118MB     1655      Docker Application Container E
✓     getty@tty1.service        2025-06-16 12:59:21  N/A       997       Getty on tty1
✓     haveged.service           2025-06-16 12:59:22  4.7MB     982       Entropy Daemon based on the HA
✓     irqbalance.service        2025-06-16 12:59:22  480KB     953       irqbalance daemon
✓     lvm2-lvmetad.service      2025-06-16 12:59:43  500KB     715       LVM2 metadata daemon
✓     NetworkManager.service    2025-06-16 12:59:21  12MB      980       Network Manager
✓     polkit.service            2025-06-16 12:59:21  14MB      954       Authorization Manager
✓     rsyslog.service           2025-06-16 12:59:19  5.7MB     1266      System Logging Service
✓     sshd.service              2025-06-16 12:59:19  7.0MB     1265      OpenSSH server daemon
✓     systemd-journald.service  2025-06-16 12:59:43  1.5MB     686       Journal Service
✓     systemd-logind.service    2025-06-16 12:59:22  1.1MB     981       Login Service
✓     systemd-udevd.service     2025-06-16 12:59:43  11MB      722       udev Kernel Device Manager
✓     tuned.service             2025-06-16 12:59:15  21MB      1272      Dynamic System Tuning Daemon
✓     vgauthd.service           2025-06-16 12:59:22  6.6MB     960       VGAuth Service for open-vm-too
✓     vmtoolsd.service          2025-06-16 12:59:22  4.3MB     962       Service for virtual machines h

=== 失败的服务 ===
  [无失败服务]

=== 高资源占用服务 ===
服务名称            CPU%  内存   读写IO           连接数
docker.service      0.2%  55.6M  71640.0K/916.0K  0
haveged.service     0.1%  5.2M   128.0K/0.0K      0
containerd.service  0.1%  33.5M  46056.0K/100.0K  0
N/A
N/A
N/A

=== 关键服务状态 ===
服务名称                状态      子状态    是否启用  启动时间
sshd.service            active    running   enabled   12:59:21
crond.service           active    running   enabled   12:59:24
network.target          active    active    static    12:59:22
dbus.service            active    running   static    12:59:24
rsyslog.service         active    running   enabled   12:59:21
docker.service          active    running   enabled   12:59:13
containerd.service      active    running   enabled   12:59:19
firewalld.service       inactive
N/A                     dead      disabled
N/A                     12:59:53
NetworkManager.service  active    running   enabled   12:59:24

############################ 用户检查 ############################
/etc/passwd 最后修改时间:2025-04-25 10:05:59 (52 天 2 小时前)

特权用户
--------
root

用户列表
--------
用户名           UID    GID    HOME                SHELL           最后一次登录
root             0      0      /root               /bin/bash       Jun_16
bin              1      1      /bin                /sbin/nologin   _
daemon           2      2      /sbin               /sbin/nologin   _
adm              3      4      /var/adm            /sbin/nologin   _
lp               4      7      /var/spool/lpd      /sbin/nologin   _
sync             5      0      /sbin               /bin/sync       _
shutdown         6      0      /sbin               /sbin/shutdown  _
halt             7      0      /sbin               /sbin/halt      _
mail             8      12     /var/spool/mail     /sbin/nologin   _
operator         11     0      /root               /sbin/nologin   _
games            12     100    /usr/games          /sbin/nologin   _
ftp              14     50     /var/ftp            /sbin/nologin   _
nobody           99     99     /                   /sbin/nologin   _
systemd-network  192    192    /                   /sbin/nologin   _
dbus             81     81     /                   /sbin/nologin   _
polkitd          999    998    /                   /sbin/nologin   _
sshd             74     74     /var/empty/sshd     /sbin/nologin   _
postfix          89     89     /var/spool/postfix  /sbin/nologin   _
chrony           998    996    /var/lib/chrony     /sbin/nologin   _
tss              59     59     /dev/null           /sbin/nologin   _
grafana          997    995    /usr/share/grafana  /sbin/nologin   _
agentuser        10086  10086  /home/agentuser     /bin/bash       _
marneuser        10012  10012  /home/marneuser     /bin/bash       _

空密码用户
----------

相同ID的用户
------------
[相同UID]

[相同GID]
root,sync,shutdown,halt,operator

############################ 登录检查 ############################
用户    终端         IP地址         登录时间              状态
reboot  system boot  -              Mon Jun 16 12:52:55   系统重启
reboot  system boot  -              Tue May 13 11:28:15   系统重启
root    pts/0        192.168.2.219  Apr 25 09:21:09 2025  (02:46)
root    tty1         0.0.0.0        Apr 23 09:28:35 2025  (19+07:05)
reboot  system boot  -              Wed Apr 23 09:26:16   系统重启
root    pts/1        192.168.2.219  Apr 16 15:52:12 2025  (01:44)
root    pts/0        192.168.2.219  Apr 16 15:23:02 2025  (02:13)
root    tty1         0.0.0.0        Apr 16 15:08:46 2025  (6+18:17)
reboot  system boot  -              Wed Apr 16 15:04:10   系统重启

当前登录用户数:
  总计: 1 个活跃会话

当前活跃会话:
  root     pts/0        2415            2025-06-16 12:53

############################ 安全检查 ############################

SSH配置:
  PermitRootLogin:

防火墙状态:
  ⚠ firewalld (inactive)

############################ SSH检查 ############################

=== SSH服务状态 ===
服务状态: active

=== SSH协议版本 ===

=== 信任主机 ===
已知主机:
  192.168.1.84

=== Root远程登录 ===
PermitRootLogin yes (安全风险!)

=== 密码认证 ===
PasswordAuthentication yes (建议关闭)

=== SSH配置文件(/etc/ssh/sshd_config) ===
主要配置项:
PasswordAuthentication yes
UsePAM yes
X11Forwarding yes

=== SSH监听端口 ===
SSH端口: 22
⚠ 警告: 使用默认SSH端口(22)

=== 最近SSH登录 ===
  root     pts/0        192.168.2.219    Mon Jun 16 12:53   still logged in
  root     pts/0        192.168.2.219    Fri Apr 25 09:21 - 12:08  (02:46)

############################ syslog检查 ############################

服务状态:
active

/etc/rsyslog.conf
-----------------
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log

日志文件检查
-----------
日志文件               状态
/var/lib/rsyslog       缺失
/etc/rsyslog.d/*.conf  存在
/var/log/messages      存在
/var/log/secure        存在
/var/log/maillog       存在
/var/log/cron          存在
/var/log/spooler       存在
/var/log/boot.log      存在

日志轮转配置(/etc/logrotate.d/syslog)
-----------------------------------
  /var/log/cron
  /var/log/maillog
  /var/log/messages
  /var/log/secure
  /var/log/spooler
  {
  missingok
  sharedscripts
  postrotate
  /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
  endscript
  }

############################ 计划任务检查 ############################

■■■ 系统计划任务 ■■■
类型  权限         所有者  大小  最后修改            任务路径
cron.d       -rw-r--r--.  root    128   2019-08-09 07:07  /etc/cron.d/0hourly
cron.d       -rwx------.  root    219   2020-04-01 11:26  /etc/cron.daily/logrotate
cron.d       -rwxr-xr-x.  root    618   2018-10-30 22:55  /etc/cron.daily/man-db.cron
cron.d       -rw-------.  root    0     2019-08-09 07:07  /etc/cron.deny
hourly       -rwxr-xr-x.  root    392   2019-08-09 07:07  /etc/cron.hourly/0anacron
other       -rw-r--r--   root    552   2025-04-16 16:06  /etc/crontab
other       -rw-r--r--.  root    552   2025-04-11 14:33  /etc/crontabv

■■■ 用户计划任务 ■■■
未检测到用户计划任务

############################ 自启动检查 ############################

■■■ 系统服务自启动 ■■■
状态  服务名称
✓       agentz.service
✓       auditd.service
✓       autovt@.service
✓       chronyd.service
✓       consul.service
✓       containerd.service
✓       crond.service
✓       dbus-org.freedesktop.nm-dispatcher.service
✓       docker.service

■■■ 用户级自启动项 ■■■
  未检测到用户自启动项

■■■ 定时任务 ■■■
系统定时任务:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

* * * * * root /usr/local/bin/agentz cron watcher
* * * * * root /usr/local/bin/agentz cron watchdog

############################ 密码检查 ############################

密码过期检查
------------
用户名       过期状态
root         密码已设置
sync         无密码/已锁定
shutdown     无密码/已锁定
halt         无密码/已锁定
agentuser    密码已设置
marneuser    密码已设置

密码策略检查
------------
策略项                当前值  建议值  合规性
PASS_MAX_DAYS  99999  90      不符合
PASS_MIN_DAYS  0      7       更严格
PASS_MIN_LEN   5      12      更严格
PASS_WARN_AGE  7      14      更严格

弱密码用户检查
------------
  无失败记录

空密码用户检查
------------
✓ 未发现空密码用户

密码哈希算法
------------
✓ 使用SHA512加密

############################ Sudoers检查 ############################

=== Sudoers主配置 ===
类型    名称    权限
用户    root    ALL=(ALL) ALL
用户组  %wheel  ALL=(ALL) ALL

=== 包含的配置文件 ===
未找到包含的配置文件

=== /etc/sudoers.d/配置 ===
文件  类型  名称  权限

=== 无需密码的sudo权限(NOPASSWD) ===
配置来源        权限
# %wheel ALL=(ALL)   NOPASSWD: ALL

=== 通过sudo组获得权限的用户 ===
  sudo组中没有用户

=== 用户详细sudo权限 ===
  未检测到用户特殊sudo权限

############################ JDK检查 ############################

=== JAVA_HOME环境变量 ===
JAVA_HOME=""
⚠ 未设置JAVA_HOME环境变量

=== Java可执行文件 ===
✗ 未找到java命令

=== 已安装的JDK版本 ===
⚠ 未找到标准JDK安装目录

=== 备选JDK路径检查 ===
⚠ 未在常见路径找到JDK

=== 运行的Java进程 ===
运行的Java进程:
marneus+        /marne/srv/elasticsearch/jdk/bin/java   -Xshare:auto
root    java    -Dfile.encoding=UTF8
root    java    -Dfile.encoding=UTF8
root    java    -Dfile.encoding=UTF8
root    java    -Dfile.encoding=UTF8
root    java    -Xmx2048m
root    java    -Dfile.encoding=UTF8

############################ 防火墙检查 ############################

=== iptables状态 ===
iptables: active

=== iptables配置文件 ===
未找到/etc/sysconfig/iptables文件

=== firewalld状态 ===
firewalld: inactive

=== ufw状态 ===
ufw: 未安装

=== 开放端口检查 ===
监听端口:
*:68    udp     *:*
*:123   udp     *:*
127.0.0.1:323   udp     *:*
[::]:123        udp     [::]:*
[::1]:323       udp     [::]:*
*:5555  tcp     *:*
*:22    tcp     *:*
127.0.0.1:24513 tcp     *:*
[::]:5555       tcp     [::]:*
[::]:22 tcp     [::]:*
[::]:8888       tcp     [::]:*

############################ SNMP检查 ############################

服务状态:
unknown
unknown

/etc/snmp/snmpd.conf
---------------------
配置文件不存在

监听端口:
./system_bas.sh:行1655: netstat: 未找到命令
未检测到SNMP端口监听

############################ 软件检查 ############################

已安装软件包:
acl                                               -2.2.51-15.el7.x86_64  2025年03月24日 星期一 10时40分37秒
aic94xx-firmware                                  -30-6.el7.noarch  2025年03月24日 星期一 10时43分18秒
alsa-firmware                                     -1.0.28-2.el7.noarch  2025年03月24日 星期一 10时42分33秒
alsa-lib                                          -1.1.8-1.el7.x86_64  2025年03月24日 星期一 10时41分59秒
alsa-tools-firmware                               -1.1.0-1.el7.x86_64  2025年03月24日 星期一 10时42分34秒
audit                                             -2.8.5-4.el7.x86_64  2025年03月24日 星期一 10时42分56秒
audit-libs                                        -2.8.5-4.el7.x86_64  2025年03月24日 星期一 10时40分17秒
authconfig                                        -6.2.8-30.el7.x86_64  2025年03月24日 星期一 10时42分55秒
avahi-libs                                        -0.6.31-20.el7.x86_64  2025年04月11日 星期五 10时33分22秒
basesystem                                        -10.0-7.el7.centos.noarch  2025年03月24日 星期一 10时39分50秒
bash                                              -4.2.46-34.el7.x86_64  2025年03月24日 星期一 10时40分06秒
bash-completion                                   -2.1-8.el7.noarch  2025年04月16日 星期三 16时01分56秒
bc                                                -1.06.95-13.el7.x86_64  2025年03月24日 星期一 10时40分38秒
bind-export-libs                                  -9.11.4-26.P2.el7.x86_64  2025年03月24日 星期一 10时41分43秒
binutils                                          -2.27-44.base.el7.x86_64  2025年03月24日 星期一 10时41分54秒

关键软件版本:
wget: ./system_bas.sh:行1752:
curl: curl
openssl: openssl:Error:
python: Python
java: ./system_bas.sh:行1752:
docker: Docker

可用的安全更新:
Determining     fastest
*       epel:
-->     libappindicator-devel-12.10.0-13.el7.i686
-->     libappindicator-devel-12.10.0-13.el7.x86_64
-->     libao-1.1.0-8.el7.i686
-->     libao-1.1.0-8.el7.x86_64

No      packages

第三方仓库:
epel.repo
epel-testing.repo

############################ NTP检查 ############################

服务状态:
active (chronyd)

时间同步状态:
Reference ID    : D21C8204 (time.nju.edu.cn)
Stratum         : 2
System time     : 0.000698761 seconds slow of NTP time
210 Number of sources = 5
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^- localhost.localdomain         2   6   377    40    -29us[  -29us] +/-   22ms
^* time.nju.edu.cn               1   6   377    41  -2560ns[ -436us] +/-   23ms

配置文件:
/etc/chrony.conf
----------------
pool pool.ntp.org iburst
server 192.168.1.239 iburst

时间偏移:
chronyd偏移: 0.000698527

############################ 文件检查 ############################

############################查看所有被修改过的文件返回最近24小时内的############################
-r--r--r-- 1 root root 0 6月  16 13:00 /proc/fb 修改时间: 2025-06-16 13:00:12
-r--r--r-- 1 root root 0 6月  16 13:00 /proc/fs/xfs/xqm 修改时间: 2025-06-16 13:00:12
-r--r--r-- 1 root root 0 6月  16 13:00 /proc/fs/xfs/xqmstat 修改时间: 2025-06-16 13:00:12
-r--r--r-- 1 root root 0 6月  16 13:00 /proc/fs/ext4/dm-2/options 修改时间: 2025-06-16 13:00:12
-r--r--r-- 1 root root 0 6月  16 13:00 /proc/fs/ext4/dm-2/mb_groups 修改时间: 2025-06-16 13:00:12
-r--r--r-- 1 root root 0 6月  16 13:00 /proc/fs/jbd2/dm-2-8/info 修改时间: 2025-06-16 13:00:12
-rw-r--r-- 1 root root 4096 6月  16 13:00 /proc/bus/pci/00/00.0 修改时间: 2025-06-16 13:00:12
-rw-r--r-- 1 root root 256 6月  16 13:00 /proc/bus/pci/00/01.0 修改时间: 2025-06-16 13:00:12
-rw-r--r-- 1 root root 256 6月  16 13:00 /proc/bus/pci/00/07.0 修改时间: 2025-06-16 13:00:12
-rw-r--r-- 1 root root 256 6月  16 13:00 /proc/bus/pci/00/07.1 修改时间: 2025-06-16 13:00:12


############################检查定时文件的完整性############################

文件: /etc/crontab
----------------------------------------
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
* * * * * root /usr/local/bin/agentz cron watcher
* * * * * root /usr/local/bin/agentz cron watchdog

文件: /etc/cron.d/0hourly
----------------------------------------
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly


############################系统关键文件检查############################
文件                                         权限  所有者               大小  修改时间
/etc/passwd           -rw-r--r--  root:root  1112  2025-04-25 10:05:59
/etc/shadow           ----------  root:root  883   2025-04-25 10:05:59
/etc/group            -rw-r--r--  root:root  566   2025-04-25 10:06:00
/etc/sudoers          -r--r-----  root:root  4328  2020-09-30 21:18:59
/etc/ssh/sshd_config  -rw-------  root:root  3907  2019-08-09 09:40:39

############################ 查看系统命令是否被替换 ############################

目录: /bin
----------------------------------------
总大小: 0       文件数: 0

链接文件检查:
权限          链接目标      文件名
lrwxrwxrwx              usr/bin

最近修改的文件:

目录: /sbin
----------------------------------------
总大小: 0       文件数: 0

链接文件检查:
权限          链接目标      文件名
lrwxrwxrwx              usr/sbin

最近修改的文件:

目录: /usr/bin
----------------------------------------
总大小: 65M     文件数: 711

链接文件检查:
权限          链接目标      文件名
lrwxrwxrwx              bashbug-64
lrwxrwxrwx              xzgrep
lrwxrwxrwx              xzgrep
lrwxrwxrwx              bash
lrwxrwxrwx              tar
lrwxrwxrwx              vi
lrwxrwxrwx              vi
lrwxrwxrwx              eqn
lrwxrwxrwx              neqn

最近修改的文件:
9月 30 9:53 2020        /usr/bin/tzselect
9月 30 9:53 2020        /usr/bin/sotruss
9月 30 9:53 2020        /usr/bin/ldd
9月 30 9:53 2020        /usr/bin/catchsegv
9月 30 23:58 2020       /usr/bin/lsattr

目录: /usr/sbin
----------------------------------------
总大小: 44M     文件数: 329

链接文件检查:
权限          链接目标      文件名
lrwxrwxrwx              useradd
lrwxrwxrwx              pdata_tools
lrwxrwxrwx              pdata_tools
lrwxrwxrwx              ../bin/systemctl
lrwxrwxrwx              pdata_tools
lrwxrwxrwx              ../lib/systemd/systemd
lrwxrwxrwx              pdata_tools
lrwxrwxrwx              alternatives
lrwxrwxrwx              pdata_tools

最近修改的文件:
9月 30 23:58 2020       /usr/sbin/tune2fs
9月 30 23:58 2020       /usr/sbin/resize2fs
9月 30 23:58 2020       /usr/sbin/mklost+found
9月 30 23:58 2020       /usr/sbin/mkfs.ext4
9月 30 23:58 2020       /usr/sbin/mkfs.ext3

目录: /usr/local/bin
----------------------------------------
总大小: 406M    文件数: 11

链接文件检查:
权限    链接目标      文件名

最近修改的文件:
4月 16 16:02 2025       /usr/local/bin/entrypointz
4月 16 15:52 2025       /usr/local/bin/runc
4月 16 15:52 2025       /usr/local/bin/docker-proxy
4月 16 15:52 2025       /usr/local/bin/docker-init
4月 16 15:52 2025       /usr/local/bin/dockerd

目录: /usr/local/sbin
----------------------------------------
总大小: 0       文件数: 0

链接文件检查:
权限    链接目标      文件名

最近修改的文件:

关键系统命令检查:
命令      路径                                                   哈希值
ls        /usr/bin/ls      a0c32dd6d3bc4d364380e2e65fe9ac64
ps        /usr/bin/ps      7e20c61405e25702e08b83478d0ef76f
netstat           未找到
ss        /usr/sbin/ss     22a42b3731d77989a1d5fe5d5dbea53d
find      /usr/bin/find    4d30ee9e49df8eaa10b04b2fa7249e5f
top       /usr/bin/top     48381853a5aa117164ed13441508d620
ifconfig           未找到
ip        /usr/sbin/ip     d50874d75c8dd9aeb582e249bd5fc6be
passwd    /usr/bin/passwd  3e522d6f3bf5cf88bb77e9ff3d138543
su        /usr/bin/su      25289cbffc6a6129f74de28ad76eb11b
sudo      /usr/bin/sudo    711d1bf7dca61ad7550a289a0e37edda

############################ 巡检问题汇总 ############################

===== 高风险问题 (需立即处理) =====
  ✗ SSH允许root登录:建议禁用root远程登录

===== 中风险问题 (建议处理) =====
  ⚠ 防火墙未启用:建议启用防火墙
  ⚠ 密码有效期过长:建议设置为90天以下

===== 低风险问题 (可选处理) =====
  ⓘ 使用默认SSH端口:建议修改为非常规端口

===== 问题统计 =====
  高风险问题: 1 个
  中风险问题: 2 个
  低风险问题: 1 个
  总计发现问题: 4 个

===== 修复建议 =====
  • 优先处理高风险问题
  • 安排处理中风险问题
  • 酌情处理低风险问题
  • 查看详细报告: /var/log/system_inspection_20250616.log

===== 报告生成信息 =====
  生成时间: 2025-06-16 13:00:13
  主机名称: localhost.localdomain
  报告路径: /var/log/system_inspection_20250616.log

===== 巡检完成,未发现严重问题 =====

报告已保存至: /var/log/system_inspection_20250616.log
[root@localhost home]#

脚本内容

#!/bin/bash
 
# 颜色定义 
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
 
# 全局变量 
REPORT_FILE="/var/log/system_inspection_$(date +%Y%m%d).log"
FAIL_FLAG=0
 
# 打印分隔线
print_separator() {
    echo -e "${BLUE}\n############################ $1 ############################${NC}"
}
 
highlight() {
    local type=$1 
    case $type in 
        "warn") echo -e "${YELLOW}$2${NC}" ;;
        "error") echo -e "${RED}$2${NC}" ;;
        "info") echo -e "${BLUE}$2${NC}" ;;
        "success") echo -e "${GREEN}$2${NC}" ;;
        "special") echo -e "${MAGENTA}$2${NC}" ;;
        *) echo -e "${CYAN}$2${NC}" ;;
    esac
}

# 系统基本信息
check_system_info() {
    print_separator "系统检查"
    echo -e " 系统:$(uname -o)"
    echo -e " 发行版本:$(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2)"
    echo -e " 内核:$(uname -r)"
    echo -e " 主机名:$(hostname)"
    echo -e " SELinux:$(getenforce 2>/dev/null || echo 'Not installed')"
    echo -e " 语言/编码:${LANG:-unknown}"
    echo -e " 当前时间:$(date '+%Y-%m-%d %H:%M:%S')"
    # 使用/proc/uptime计算(精确到秒)
    BOOT_SECONDS=$(awk '{print $1}' /proc/uptime)
    echo -e " 最后启动:$(date -d "@$(($(date +%s) - ${BOOT_SECONDS%.*}))" '+%Y-%m-%d %H:%M:%S')"
    echo -e " 运行时间:$(uptime -p | sed 's/up //')"
}
 
# CPU检查
check_cpu() {
    print_separator "CPU检查"
    
    # 基础信息 
    LOGICAL_CPUS=$(grep -c ^processor /proc/cpuinfo)
    MODEL_NAME=$(grep -m1 'model name' /proc/cpuinfo | cut -d':' -f2 | sed 's/^ \t*//;s/[ \t]*$//')
    
    # 识别虚拟化环境 
    VIRT_ENV="物理机"
    if grep -qi "vmware" /proc/cpuinfo || \
       { [ -f /sys/class/dmi/id/product_name ] && grep -qi "vmware" /sys/class/dmi/id/product_name; }; then 
        VIRT_ENV="VMware"
    fi 
 
    # 使用系统工具获取CPU拓扑信息 
    if command -v lscpu >/dev/null; then 
        # 使用lscpu获取信息 
        PHYSICAL_CPUS=$(lscpu -p=Socket | grep -v "^#" | sort -u | wc -l)
        CORES_PER_CPU=$(lscpu -p=Core | grep -v "^#" | sort -u | wc -l)
        THREADS_PER_CORE=$(lscpu | grep -i "Thread(s) per core:" | awk '{print $4}')
        NUMA_NODES=$(lscpu -p=Node | grep -v "^#" | sort -u | wc -l)
        
        # 处理虚拟化环境下的异常值 
        if [ "$VIRT_ENV" != "物理机" ]; then 
            # 在VMware中,物理CPU数可能显示不正确,取逻辑CPU数和核心数的合理值 
            if [ $((PHYSICAL_CPUS * CORES_PER_CPU * THREADS_PER_CORE)) -ne $LOGICAL_CPUS ]; then 
                CORES_PER_CPU=$LOGICAL_CPUS 
                PHYSICAL_CPUS=1 
                THREADS_PER_CORE=1 
            fi 
        fi 
    else 
        # 回退到/proc/cpuinfo 
        PHYSICAL_CPUS=$(grep 'physical id' /proc/cpuinfo | sort -u | wc -l)
        CORES_PER_CPU=$(grep 'cpu cores' /proc/cpuinfo | head -1 | awk '{print $4}')
        THREADS_PER_CORE=$(( $(grep 'siblings' /proc/cpuinfo | head -1 | awk '{print $3}') / CORES_PER_CPU ))
        NUMA_NODES=$(ls -d /sys/devices/system/node/node* 2>/dev/null | wc -l)
    fi 
 
    # 处理可能的空值 
    [ -z "$PHYSICAL_CPUS" ] && PHYSICAL_CPUS=1 
    [ -z "$CORES_PER_CPU" ] && CORES_PER_CPU=$LOGICAL_CPUS 
    [ -z "$THREADS_PER_CORE" ] && THREADS_PER_CORE=1 
    [ -z "$NUMA_NODES" ] && NUMA_NODES=1 
 
    # 结果输出 
    echo -e "物理CPU个数: ${PHYSICAL_CPUS}"
    echo -e "每物理CPU核心数: ${CORES_PER_CPU}"
    echo -e "每核线程数: ${THREADS_PER_CORE}"
    echo -e "逻辑CPU总数: $LOGICAL_CPUS"
    echo -e "CPU型号: $MODEL_NAME"
    echo -e "虚拟化环境: $VIRT_ENV"
    echo -e "NUMA节点数: $NUMA_NODES"
    
    # 在虚拟化环境中添加说明 
    if [ "$VIRT_ENV" != "物理机" ]; then 
        echo -e "${YELLOW}[注意] 虚拟化环境下显示的CPU拓扑可能与物理机不同${NC}"
        echo -e "${YELLOW}[建议] 如需准确信息,请在物理主机上运行此脚本${NC}"
    fi 
 
    # 显示检测方法 
    if [ "$(id -u)" -eq 0 ] && command -v dmidecode >/dev/null; then 
        echo -e "${GREEN}[信息] 已使用dmidecode获取物理CPU信息${NC}"
    else 
        echo -e "${YELLOW}[注意] 当前显示的是虚拟化环境可见的CPU拓扑${NC}"
    fi 
}

# 内存检查(增强版)
check_memory() {
    print_separator "内存检查"
    
    # 基础内存信息 
    TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{printf "%.2f GB", $2/1024/1024}')
    FREE_MEM=$(grep MemFree /proc/meminfo | awk '{printf "%.2f GB", $2/1024/1024}')
    BUFFERS=$(grep Buffers /proc/meminfo | awk '{printf "%.2f GB", $2/1024/1024}')
    CACHED=$(grep -w Cached /proc/meminfo | awk '{printf "%.2f GB", $2/1024/1024}')
    
    # 详细内存信息检测 
    if command -v dmidecode >/dev/null && [ "$(id -u)" -eq 0 ]; then 
        # 高级内存信息解析 
        MEMORY_INFO=$(dmidecode -t memory 2>/dev/null | awk '
            BEGIN { RS="Memory Device"; FS="\n"; slot_num=0 }
            /Size: [0-9]+/ && !/No Module Installed/ {
                slot=""; manufacturer=""; size=""; type=""; speed=""; ecc=""; part_number=""; rank=""; voltage=""
                for(i=1; i<=NF; i++) {
                    if ($i ~ /Locator: [^ ]+/ && slot=="") { 
                        slot=gensub(/.*Locator: ([^ ]+).*/, "\\1", "g", $i)
                        if (slot !~ /^[A-Za-z]/) { slot="DIMM_"slot }
                    }
                    if ($i ~ /Manufacturer:/) { 
                        manufacturer=gensub(/.*Manufacturer: ([^ ]+).*/, "\\1", "g", $i)
                        if (manufacturer ~ /Not Specified|Unknown|NO DIMM/) { manufacturer="未知" }
                    }
                    if ($i ~ /Size:/) { size=gensub(/.*Size: ([^ ]+).*/, "\\1", "g", $i) }
                    if ($i ~ /Type:/) { type=gensub(/.*Type: ([^ ]+).*/, "\\1", "g", $i) }
                    if ($i ~ /Speed:/) { speed=gensub(/.*Speed: ([^ ]+).*/, "\\1", "g", $i) }
                    if ($i ~ /Configured Memory Speed:/) { 
                        conf_speed=gensub(/.*Configured Memory Speed: ([^ ]+).*/, "\\1", "g", $i)
                        if (conf_speed != "Unknown") { speed=conf_speed }
                    }
                    if ($i ~ /Part Number:/) { 
                        part_number=gensub(/.*Part Number: ([^ ]+).*/, "\\1", "g", $i)
                        if (part_number ~ /Not Specified|Unknown|NO DIMM/) { part_number="未知" }
                    }
                    if ($i ~ /Rank:/) { rank=gensub(/.*Rank: ([^ ]+).*/, "\\1", "g", $i) }
                    if ($i ~ /Voltage:/) { voltage=gensub(/.*Voltage: ([^ ]+).*/, "\\1", "g", $i) }
                    if ($i ~ /Error Correction Type:/) { ecc=gensub(/.*Error Correction Type: ([^ ]+).*/, "\\1", "g", $i) }
                }
                
                # 清理数据 
                manufacturer = (manufacturer == "Not" || manufacturer == "NO DIMM") ? "未知" : manufacturer 
                part_number = (part_number == "Not" || part_number == "NO DIMM") ? "未知" : part_number 
                type = (type == "Unknown" || type == "None") ? "DRAM" : type 
                speed = (speed == "Unknown") ? "未知" : speed 
                voltage = (voltage == "Unknown") ? "未知" : voltage 
                
                # 格式化输出 
                printf "插槽%s: %s | 厂商: %s | 型号: %s | 类型: %s | 速度: %s | 电压: %s", 
                    slot ? slot : ++slot_num,
                    size,
                    manufacturer,
                    part_number,
                    type,
                    speed,
                    voltage 
                
                # 添加ECC和Rank信息 
                if (ecc && ecc != "None") { printf " | ECC: %s", ecc }
                if (rank && rank != "Unknown") { printf " | Rank: %s", rank }
                printf "\n"
            }')
        
        # 统计信息 
        USED_SLOTS=$(echo "$MEMORY_INFO" | grep -c "^插槽")
        MEMORY_SUMMARY=$(dmidecode -t memory 2>/dev/null | awk '
            /Maximum Capacity:/ { capacity=$3" "$4 }
            /Number Of Devices:/ { devices=$4 }
            END { printf "最大支持: %s | 插槽总数: %s", capacity, devices }
        ')
        
        # 内存频率汇总 
        MEMORY_SPEEDS=$(echo "$MEMORY_INFO" | grep -o "速度: [^|]*" | awk '{print $2}' | sort | uniq -c | awk '{printf "%s@%s ", $1, $2}')
        
        # 内存厂商汇总(过滤掉"Not"等无效值)
        MEMORY_MANUFACTURERS=$(echo "$MEMORY_INFO" | grep -o "厂商: [^|]*" | awk '{print $2}' | grep -v "Not" | sort | uniq -c | awk '{printf "%s×%s ", $1, $2}')
        [ -z "$MEMORY_MANUFACTURERS" ] && MEMORY_MANUFACTURERS="未知"
        
    else 
        MEMORY_INFO="无法获取详细信息(需要root权限)"
        USED_SLOTS="未知"
        MEMORY_SUMMARY="未知"
        MEMORY_SPEEDS="未知"
        MEMORY_MANUFACTURERS="未知"
    fi 
    
    # 交换空间信息 
    SWAP_INFO=$(free -h | awk '/Swap/{printf "总共%s, 已用%s", $2, $3}')
    
    # 结果输出 
    echo -e "总内存: ${TOTAL_MEM}"
    echo -e "空闲内存: ${FREE_MEM}"
    echo -e "缓存/缓冲: ${CACHED} (缓存) + ${BUFFERS} (缓冲)"
    echo -e "内存配置: ${MEMORY_SUMMARY}"
    echo -e "已使用内存插槽: ${USED_SLOTS}个"
    echo -e "内存厂商分布: ${MEMORY_MANUFACTURERS}"
    echo -e "内存速度分布: ${MEMORY_SPEEDS}"
    echo -e "\n${CYAN}=== 详细内存规格 ===${NC}"
    echo -e "${MEMORY_INFO:-无有效内存信息}"
    echo -e "\n交换空间: ${SWAP_INFO}"
    
    # 显示检测方法 
    if [ "$(id -u)" -eq 0 ] && command -v dmidecode >/dev/null; then 
        echo -e "${GREEN}[信息] 已过滤所有空插槽并标准化显示格式${NC}"
    else 
        echo -e "${YELLOW}[注意] 需要root权限才能获取完整内存信息${NC}"
    fi 
}


# 磁盘检查(增强版)
check_disk() {
    print_separator "存储检查"
    
    # 1. 存储详情 
    echo -e "\n${GREEN}=== 存储详情 ===${NC}"
    (
    echo -e "设备\t\t类型\t容量\t型号\t\t转速\t健康状态"
    lsblk -d -o NAME,ROTA,SIZE,MODEL 2>/dev/null | awk '
        NR==1 {next}
        {
            type = ($2 == "1") ? "HDD" : "SSD/NVMe"
            model = $4 ? $4 : "未知"
            printf "%-8s %-8s %-6s %-15s %-6s %s\n", 
                "/dev/"$1, type, $3, model, ($2 == "1" ? "7200" : "N/A"), "正常"
        }
    '
    ) | column -t 
    
    # 2. 存储拓扑 
    echo -e "\n${GREEN}=== 存储拓扑 ===${NC}"
    (
    echo -e "设备\t\t类型\t容量\t挂载点\t\t文件系统\t使用率"
    lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,RO,RM | awk '
        BEGIN {
            printf "%-8s %-8s %-6s %-15s %-8s %s\n", 
                "NAME", "TYPE", "SIZE", "MOUNTPOINT", "FSTYPE", "USE%"
        }
        $1 ~ /^[a-z]/ && $4 !~ /^\/run|\/sys|\/dev/ {
            # 获取使用率 
            cmd = "df -h " $4 " | awk \"NR==2 {print \\$5}\" 2>/dev/null"
            cmd | getline usage 
            close(cmd)
            
            type = ($2 == "") ? "disk" : "part"
            printf "%-8s %-8s %-6s %-15s %-8s %s\n",
                "/dev/"$1, type, $3, ($4==""?"-":$4), ($2==""?"-":$2), (usage?usage:"-")
        }
    '
    ) | column -t 
    
    # 3. 分区详情 
    echo -e "\n${GREEN}=== 分区详情 ===${NC}"
    (
    echo -e "分区\t\t容量\t已用\t可用\t使用率\t挂载点\t\t文件系统"
    df -hT | awk '
        NR==1 {next}
        $1 !~ /tmpfs|devtmpfs|overlay/ {
            # 处理长设备名 
            dev = length($1)>15 ? substr($1,1,12)"..." : $1 
            
            printf "%-12s %-6s %-5s %-5s %-5s %-15s %s\n",
                dev, $3, $4, $5, $6, $7, $2 
        }
    ' | sort -k6 
    ) | column -t 
    
    # 4. LVM信息(如果有)
    if command -v vgs >/dev/null && [ $(vgs 2>/dev/null | wc -l) -gt 1 ]; then 
        echo -e "\n${GREEN}=== LVM详细信息 ===${NC}"
        
        # 卷组信息 
        echo -e "${BLUE}【卷组信息】${NC}"
        vgs --units g | awk '
            BEGIN {
                printf "%-15s %-4s %-4s %-4s %-8s %-10s %-10s\n",
                    "VG", "#PV", "#LV", "#SN", "Attr", "VSize", "VFree"
            }
            NR>1 {
                printf "%-15s %-4s %-4s %-4s %-8s %-10s %-10s\n",
                    $1, $2, $3, $4, $5, $6, $7 
            }
        ' | column -t 
        
        # 逻辑卷信息 
        echo -e "\n${BLUE}【逻辑卷信息】${NC}"
        lvs --units g | awk '
            BEGIN {
                printf "%-15s %-15s %-8s %-8s %-8s %-8s %-8s\n",
                    "LV", "VG", "Attr", "LSize", "Data%", "Meta%", "Mount"
            }
            NR>1 {
                # 获取挂载点 
                cmd = "df -h | grep \""$1"\" | awk \"{print \\$6}\""
                cmd | getline mount 
                close(cmd)
                
                printf "%-15s %-15s %-8s %-8s %-8s %-8s %-8s\n",
                    $1, $2, $3, $4, ($5?$5:"-"), ($6?$6:"-"), (mount?mount:"-")
            }
        ' | column -t 
    fi 
}

# RAID检查
check_raid() {
    print_separator "RAID检查"
    
    # 1. 检查软件RAID (mdadm)
    if [ -f /proc/mdstat ]; then 
        echo -e "${BLUE}=== 软件RAID (mdadm) 信息 ===${NC}"
        grep -A10 "^md" /proc/mdstat 2>/dev/null | awk '
            /^md/ {
                raid_device = $1 
                printf "设备: %s\n", raid_device 
            }
            /raid[0-9]/ {
                printf "级别: %s\n", $0 
            }
            /blocks/ {
                printf "大小: %s\n", $3 
            }
            /\[[U_]+\]/ {
                printf "状态: %s\n", $0 
            }
            /sd[a-z]+\[[0-9]+\]/ {
                disks = disks ? disks ", " $1 : $1 
            }
            END {
                if (disks) printf "成员磁盘: %s\n", disks 
            }
        '
    else 
        echo -e "${YELLOW}[信息] 未检测到软件RAID (mdadm)${NC}"
    fi 
    
    # 2. 检查硬件RAID (MegaCLI/StorCLI/LSIutil)
    echo -e "\n${BLUE}=== 硬件RAID 信息 ===${NC}"
    
    # 检查MegaCLI (LSI MegaRAID)
    if command -v MegaCli64 >/dev/null || command -v megacli >/dev/null; then 
        echo -e "${GREEN}检测到MegaRAID控制器${NC}"
        CMD=$(command -v MegaCli64 || command -v megacli)
        $CMD -LDInfo -Lall -aALL | awk '
            /Virtual Drive:/ { printf "虚拟磁盘: %s\n", $3 }
            /RAID Level/ { printf "RAID级别: %s\n", $4 }
            /Size/ { printf "大小: %s %s\n", $3, $4 }
            /State/ { printf "状态: %s\n", $3 }
            /Number Of Drives/ { printf "磁盘数量: %s\n", $4 }
        '
    # 检查StorCLI (Broadcom/LSI)
    elif command -v storcli >/dev/null; then 
        echo -e "${GREEN}检测到StorCLI控制器${NC}"
        storcli /c0 show | awk '
            /VD=Properties/ { vd=1; next }
            vd && /TYPE/ { printf "RAID级别: %s\n", $3; vd=0 }
            /Total Drives/ { printf "磁盘数量: %s\n", $3 }
        '
    # 检查HP Smart Array 
    elif command -v hpssacli >/dev/null || command -v hpacucli >/dev/null; then 
        echo -e "${GREEN}检测到HP SmartArray控制器${NC}"
        CMD=$(command -v hpssacli || command -v hpacucli)
        $CMD ctrl all show config | awk '
            /logicaldrive/ { printf "逻辑磁盘: %s\n", $2 }
            /raid/ { printf "RAID级别: %s\n", $1 }
            /size/ { printf "大小: %s\n", $3 }
            /Status/ { printf "状态: %s\n", $2 }
        '
    # 检查Dell PERC 
    elif [ -f /opt/MegaRAID/storcli/storcli64 ]; then 
        echo -e "${GREEN}检测到Dell PERC控制器${NC}"
        /opt/MegaRAID/storcli/storcli64 /c0 show | awk '
            /VD=Properties/ { vd=1; next }
            vd && /TYPE/ { printf "RAID级别: %s\n", $3; vd=0 }
            /Total Drives/ { printf "磁盘数量: %s\n", $3 }
        '
    else 
        echo -e "${YELLOW}[信息] 未检测到硬件RAID控制器${NC}"
        echo -e "${YELLOW}[建议] 如需检测硬件RAID,请安装以下工具之一:${NC}"
        echo -e "  - MegaCli (LSI MegaRAID)"
        echo -e "  - storcli (Broadcom/LSI)"
        echo -e "  - hpssacli (HP SmartArray)"
    fi 
    
    # 3. 检查设备映射器多路径 (DM-Multipath)
    if command -v multipath >/dev/null && [ -f /etc/multipath.conf  ]; then 
        echo -e "\n${BLUE}=== 多路径设备信息 ===${NC}"
        multipath -ll 2>/dev/null | head -10 
    fi 
    
    # 4. 检查3ware RAID 
    if command -v tw_cli >/dev/null; then 
        echo -e "\n${BLUE}=== 3ware RAID 信息 ===${NC}"
        tw_cli info | awk '
            /^c[0-9]/ { printf "控制器: %s\n", $1 }
            /u[0-9]/ { printf "磁盘: %s 状态: %s\n", $1, $2 }
        '
    fi 
    
    # 5. 通用磁盘检查 
    echo -e "\n${BLUE}=== 磁盘拓扑信息 ===${NC}"
    lsblk -o NAME,ROTA,RM,SIZE,RO,TYPE,MOUNTPOINT 2>/dev/null | awk '
        BEGIN {
            printf "%-8s %-5s %-3s %-8s %-3s %-8s %-15s\n", 
                "设备", "旋转", "可移", "大小", "只读", "类型", "挂载点"
        }
        $1 ~ /^[a-z]/ {
            printf "%-8s %-5s %-3s %-8s %-3s %-8s %-15s\n", 
                $1, ($2==1?"是":"否"), ($3==1?"是":"否"), $4, ($5==1?"是":"否"), $6, $7 
        }
    ' | column -t 
}


# 网络检查 
check_network() {
    print_separator "网络检查"
    
    # 1. 网络接口详情(对齐优化版)
    echo -e "\n${GREEN}=== 网络接口详情 ===${NC}"
    (
    echo -e "接口名称              状态  IP地址                            MAC地址             MTU    速率      接收       发送"
    ip -o link show | awk -F': ' '$2 !~ /^lo/ {print $2}' | while read -r iface; do 
        # 跳过无效接口 
        if [ ! -d "/sys/class/net/$iface" ]; then 
            continue 
        fi 
        
        status=$(ip link show $iface | grep -q 'UP' && echo "UP  " || echo "DOWN")
        ipv4=$(ip -4 addr show $iface 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+' || echo "无IPv4")
        ipv6=$(ip -6 addr show $iface 2>/dev/null | grep -oP '(?<=inet6\s)[\da-f:]+/\d+' | head -1 || echo "")
        mac=$(ip link show $iface 2>/dev/null | grep -oP '(?<=link/ether\s)[\da-f:]+' || echo "无MAC")
        mtu=$(ip link show $iface 2>/dev/null | grep -oP '(?<=mtu\s)\d+' || echo "1500")
        
        # 获取网络速率 
        speed="未知   "
        if [ -f "/sys/class/net/$iface/speed" ]; then 
            speed_num=$(cat "/sys/class/net/$iface/speed" 2>/dev/null)
            [ -n "$speed_num" ] && speed=$(printf "%-7s" "${speed_num}Mb")
        elif ethtool $iface 2>/dev/null | grep -q "Speed:"; then 
            speed=$(printf "%-7s" $(ethtool $iface 2>/dev/null | grep -oP '(?<=Speed:\s)\d+\w+'))
        elif [ "$iface" = "docker0" ] || [ "$iface" = "br-"* ]; then 
            speed="10Gbps "
        fi 
        
        # 获取流量统计 
        rx_bytes=$(cat "/sys/class/net/$iface/statistics/rx_bytes" 2>/dev/null || echo "0")
        tx_bytes=$(cat "/sys/class/net/$iface/statistics/tx_bytes" 2>/dev/null || echo "0")
        
        # 格式化流量 
        rx_human=$(numfmt --to=iec --suffix=B --format "%-8s" $rx_bytes 2>/dev/null || echo "0B      ")
        tx_human=$(numfmt --to=iec --suffix=B --format "%-8s" $tx_bytes 2>/dev/null || echo "0B      ")
        
        printf "%-20s %-5s %-30s %-18s %-6s %-7s %-10s %-10s\n" \
            "$iface" "$status" "$ipv4" "$mac" "$mtu" "$speed" "$rx_human" "$tx_human"
        
        # 显示IPv6地址(如果有)
        if [ -n "$ipv6" ]; then 
            printf "%-20s %-5s %-30s %-18s %-6s %-7s %-10s %-10s\n" \
                "" "" "$ipv6" "" "" "" "" ""
        fi 
    done 
    )
 
    # 2. 路由表信息(对齐优化版)
    echo -e "\n${GREEN}=== 路由表信息 ===${NC}"
    (
    echo -e "目标网络        网关           接口             标志    跃点    来源"
    ip route | awk '
        /default/ {
            via = ($3 == "via") ? $4 : $3 
            printf "%-15s %-15s %-16s %-8s %-8s %s\n", 
                "default", via, $5, "网关", ($7?$7:"-"), ($9?$9:"-")
            next 
        }
        {
            via = ($3 == "via") ? $4 : "直连"
            intf = ($3 == "via") ? $5 : $3 
            src = ""
            for (i=6; i<=NF; i++) {
                if ($i == "src") {
                    src = $(i+1)
                    break 
                }
            }
            printf "%-15s %-15s %-16s %-8s %-8s %s\n", 
                $1, via, intf, ($3 == "via" ? "网关" : "直连"), ($5?$5:"-"), src 
        }
    '
    )
 
    # 3. DNS和连接信息(对齐优化版)
    echo -e "\n${GREEN}=== DNS和连接信息 ===${NC}"
    (
    echo -e "DNS服务器       域名服务器"
    grep -E 'nameserver|search' /etc/resolv.conf  2>/dev/null | awk '
        /nameserver/ { printf "%-15s %s\n", $2, "解析服务器" }
        /search/ { printf "%-15s %s\n", $2, "搜索域" }
    '
    
    echo -e "\n默认网关        接口          优先级"
    ip route | awk '/default/ {
        via = ($3 == "via") ? $4 : $3 
        printf "%-15s %-14s %s\n", via, $5, ($7?$7:"-")
    }'
    )
 
    # 4. 网络连接统计(对齐优化版)
    echo -e "\n${GREEN}=== 网络连接统计 ===${NC}"
    ss -s | awk '
        /Total:/ {printf "总连接数: %s\n", $2}
        /TCP:/ {
            gsub(/[^0-9,]/,"",$0)
            split($0, tcp, ",")
            printf "TCP状态:\n"
            printf "  已建立: %s\n", tcp[1]
            printf "  关闭中: %s\n", tcp[2]
            printf "  孤儿: %s\n", tcp[3]
            printf "  时间等待: %s\n", tcp[4]
        }
        /UDP:/ {printf "UDP: %s\n", $2}
        /RAW:/ {printf "RAW: %s\n", $2}
    '
    
    # 5. 孤儿连接分析(对齐优化版)
    echo -e "\n${YELLOW}=== 孤儿连接分析 ===${NC}"
    orphan_count=$(ss -s | grep -oP '(?<=孤儿\s)\d+' || echo "0")
    if [ "$orphan_count" -gt 100 ] 2>/dev/null; then 
        echo -e "  ${RED}警告: 检测到大量孤儿连接($orphan_count)${NC}"
        echo -e "  可能原因:"
        echo -e "  - 应用程序没有正确关闭连接"
        echo -e "  - 网络连接突然中断"
        echo -e "  - 系统TCP/IP栈配置问题"
        echo -e "${YELLOW}建议操作:${NC}"
        echo -e "  - 检查应用程序日志"
        echo -e "  - 考虑调整内核参数:"
        echo -e "    sysctl -w net.ipv4.tcp_fin_timeout=30" 
        echo -e "    sysctl -w net.ipv4.tcp_keepalive_time=1800" 
    elif [ "$orphan_count" -ge 0 ] 2>/dev/null; then 
        echo -e "  孤儿连接数量正常($orphan_count)"
    else 
        echo -e "  无法获取孤儿连接信息"
    fi 
}

# 监听端口检查
check_listening() {
    print_separator "监听检查"
    
    # 1. 网络监听端口详情(完美修复版)
    echo -e "\n${GREEN}=== 网络监听端口详情 ===${NC}"
    (
    echo -e "协议\t状态\t本地地址\t\t进程信息\t\t服务"
    ss -tulnp 2>/dev/null | awk '
        BEGIN {
            proto_map["tcp"] = "TCP";
            proto_map["udp"] = "UDP";
        }
        NR>1 {
            # 提取协议和状态 
            proto = proto_map[$1];
            state = $2;
            
            # 提取并格式化本地地址 
            local = $5;
            if (local ~ /:/) {
                sub(/.*:/, ":", local);
                sub(/]$/, "", local);
                if (local == ":*") local = "*";
            }
            
            # 提取并清理进程信息 
            process = $7;
            gsub(/users:\(\(\"|\"\).*/, "", process);
            split(process, proc_parts, "\",\"");
            pid_name = proc_parts[1] "/" proc_parts[2];
            
            # 获取服务名称 
            port = $5;
            sub(/^.*:/, "", port);
            sub(/].*$/, "", port);
            service = "-";
            if (port ~ /^[0-9]+$/) {
                "grep -w ^" port " /etc/services 2>/dev/null | head -1 | cut -f1" | getline service;
                close("grep -w ^" port " /etc/services 2>/dev/null | head -1 | cut -f1");
            }
            
            printf "%s\t%s\t%s\t\t%s\t\t%s\n",
                proto, state, local, pid_name, service;
        }
    ' | sort -k3 
    ) | column -t -s $'\t'
 
    # 2. 高危端口检测(无错误版)
    echo -e "\n${RED}=== 高危端口检测 ===${NC}"
    (
    echo -e "协议\t端口\t风险等级\t绑定地址\t\t服务\t\t建议"
    
    # 高危端口定义 
    high_risk_ports=(
        "22 tcp SSH 高危 限制访问IP或使用密钥认证"
        "23 tcp Telnet 高危 建议禁用"
        "21 tcp FTP 高危 使用SFTP替代"
        "25 tcp SMTP 中危 配置认证和加密"
        "53 udp DNS 中危 限制查询范围"
        "3306 tcp MySQL 高危 限制访问IP"
        "3389 tcp RDP 高危 使用VPN访问"
    )
    
    # 检查实际开放的端口 
    for port_info in "${high_risk_ports[@]}"; do 
        read port proto service risk_level suggestion <<< "$port_info"
        if ss -lntu | grep -q "$proto.*:$port "; then 
            bind_info=$(ss -lntu | grep "$proto.*:$port " | head -1 | awk '{print $5}')
            if [[ "$bind_info" == *"["*"]"* ]]; then 
                # IPv6地址处理 
                bind_ip=$(echo "$bind_info" | sed 's/.*\[\(.*\)\]:.*/\1/')
                [ -z "$bind_ip" ] && bind_ip="::"
            else 
                # IPv4地址处理 
                bind_ip=$(echo "$bind_info" | cut -d':' -f1)
                [ -z "$bind_ip" ] && bind_ip="0.0.0.0"
                [ "$bind_ip" == "*" ] && bind_ip="0.0.0.0"
            fi 
            
            printf "%s\t%s\t%s\t\t%s\t\t%s\t%s\n" \
                "$proto" "$port" "$risk_level" "$bind_ip" "$service" "$suggestion"
        fi 
    done 
    ) | column -t -s $'\t'
 
    # 3. 异常连接检测(优化版)
    echo -e "\n${YELLOW}=== 异常连接检测 ===${NC}"
    (
    echo -e "协议\t本地地址\t\t远程地址\t\t状态\t\t进程"
    ss -atnp 2>/dev/null | awk '
        $1 ~ /tcp|udp/ && $2 !~ /LISTEN|UNCONN/ {
            # 提取本地和远程地址 
            split($5, local, ":");
            split($6, remote, ":");
            
            # 提取进程信息 
            process = $7;
            gsub(/users:\(\(\"|\"\).*/, "", process);
            split(process, proc_parts, "\",\"");
            pid_name = proc_parts[1] "/" proc_parts[2];
            
            printf "%s\t%s:%s\t%s:%s\t%s\t%s\n",
                $1, local[1], local[2], remote[1], remote[2], $2, pid_name;
        }
    ' | head -10 
    ) | column -t -s $'\t'
}

# 进程检查 
check_processes() {
    print_separator "进程检查"
    
    # 1. 内存占用TOP10(修复版)
    echo -e "\n${BLUE}=== 内存占用TOP10 (物理内存) ===${NC}"
    mem_processes=$(ps -eo pid,%mem,rss,comm --sort=-rss 2>/dev/null | awk -v yellow="$YELLOW" -v nc="$NC" '
        BEGIN {
            printf "%-6s %-5s %-10s %s\n", "PID", "%MEM", "RSS(MB)", "COMMAND"
            count=0 
        }
        NR>1 && $1 != "PID" && count<10 {
            rss_mb = $3/1024 
            # 处理异常值 
            if (rss_mb == 0 && $3 > 0) rss_mb = $3 
            printf "%-6s %-5s %-10.1f %s\n", 
                $1, $2, rss_mb, $4 
            count++
        }
        END {
            if (count == 0) {
                print "  [无活跃进程 - 显示历史记录]"
                cmd = "ps -eo pid,%mem,rss,comm --sort=-rss --no-headers | head -10 | awk '\''{printf \"%-6s %-5s %-10.1f %s\\n\", $1, $2, $3/1024, $4}'\''"
                system(cmd)
            }
        }
    ')
    echo "$mem_processes" | column -t 
 
    # 2. CPU占用TOP10(修复版)
    echo -e "\n${BLUE}=== CPU占用TOP10 ===${NC}"
    cpu_processes=$( (ps -eo pid,user,pcpu,pmem,time,comm --sort=-pcpu 2>/dev/null || ps aux 2>/dev/null) | awk -v red="$RED" -v nc="$NC" '
        BEGIN {
            printf "%-6s %-8s %-5s %-5s %-11s %s\n", 
                "PID", "USER", "%CPU", "%MEM", "TIME", "COMMAND"
            count=0 
        }
        NR<=11 && $0 !~ /PID|USER/ && count<10 {
            # 处理不同ps格式 
            if (NF == 6) {
                pid=$1; user=$2; pcpu=$3; pmem=$4; time=$5; cmd=$6 
            } else if (NF >= 11) {
                pid=$1; user=$2; pcpu=$3; pmem=$4; time=$10; cmd=$11 
                for(i=12;i<=NF;i++) cmd=cmd" "$i 
            }
            # 跳过标题行和全零行 
            if (pid != "PID" && (pcpu+0 > 0 || NR == 2)) {
                printf "%-6s %-8s %-5s %-5s %-11s %s\n", 
                    pid, user, pcpu+0, pmem+0, time, cmd 
                count++
            }
        }
        END {
            if (count == 0) {
                print "  [无CPU占用进程 - 显示历史记录]"
                cmd = "(ps -eo pid,user,pcpu,pmem,time,comm --sort=-pcpu --no-headers || ps aux --no-headers) | head -10 | awk '\''{printf \"%-6s %-8s %-5s %-5s %-11s %s\\n\", $1, $2, $3, $4, $5, $6}'\''"
                system(cmd)
            }
        }
    ')
    echo "$cpu_processes" | column -t 
    
    # 3. 添加进程历史记录 
    echo -e "\n${BLUE}=== 最近启动的进程 ===${NC}"
    recent_procs=$(ps -eo pid,user,lstart,cmd --sort=-start_time 2>/dev/null | head -10 | awk '
        BEGIN {
            printf "%-6s %-8s %-20s %s\n", "PID", "USER", "启动时间", "命令"
        }
        NR>1 {
            "date -d \""$3" "$4" "$5" "$6"\" \"+%Y-%m-%d %H:%M:%S\"" | getline start_time 
            close("date -d \""$3" "$4" "$5" "$6"\" \"+%Y-%m-%d %H:%M:%S\"")
            printf "%-6s %-8s %-20s %s\n", $1, $2, start_time, $NF 
        }
    ')
    [ -n "$recent_procs" ] && echo "$recent_procs" | column -t || echo "  无法获取进程历史记录"
}

# 服务检查
check_services() {
    print_separator "服务检查"
    
    # 1. 运行中的服务(修复日期问题版)
    echo -e "\n${GREEN}=== 运行中的服务 ===${NC}"
    (
    echo -e "状态\t服务名称\t\t运行时间\t内存占用\t主PID\t描述"
    systemctl list-units --type=service --state=running --no-pager --no-legend 2>/dev/null | \
    while read -r line; do 
        service=$(echo "$line" | awk '{print $1}')
        status=$(systemctl is-active "$service")
        
        # 修复日期解析问题 
        activetime=$(systemctl show "$service" --property=ActiveEnterTimestampMonotonic | cut -d= -f2)
        if [ -n "$activetime" ]; then 
            uptime=$(awk -v ticks="$activetime" 'BEGIN {
                now = systime();
                uptime = now - (ticks / 1000000);
                print strftime("%Y-%m-%d %H:%M:%S", uptime);
            }')
        else 
            uptime="N/A"
        fi 
        
        memory=$(systemctl show "$service" --property=MemoryCurrent | cut -d= -f2)
        pid=$(systemctl show "$service" --property=MainPID | cut -d= -f2)
        desc=$(systemctl show "$service" --property=Description | cut -d= -f2 | cut -c1-30)
        
        # 格式化内存显示 
        if [ "$memory" -ge 0 ] 2>/dev/null; then 
            memory=$(numfmt --to=iec --suffix=B "$memory")
        else 
            memory="N/A"
        fi 
        
        printf "✓\t%-20s\t%s\t%s\t%s\t%s\n" \
            "$service" "$uptime" "$memory" "$pid" "$desc"
    done 
    ) | column -t -s $'\t'
 
    # 2. 失败的服务(保持不变)
    echo -e "\n${RED}=== 失败的服务 ===${NC}"
    failed_services=$(systemctl list-units --type=service --state=failed --no-pager --no-legend 2>/dev/null)
    if [ -z "$failed_services" ]; then 
        echo -e "  ${GREEN}[无失败服务]${NC}"
    else 
        (
        echo -e "状态\t服务名称\t\t错误信息\t\t\t最后日志"
        echo "$failed_services" | while read -r line; do 
            service=$(echo "$line" | awk '{print $1}')
            status=$(systemctl is-active "$service")
            error=$(systemctl status "$service" | grep -i "error\|failed" | head -1 | sed 's/ *//g')
            journal=$(journalctl -u "$service" -n 1 --no-pager | grep -v "^--" | cut -c1-50)
            
            printf "✗\t%-20s\t%-30s\t%s\n" \
                "$service" "${error:-N/A}" "${journal:-N/A}"
        done 
        ) | column -t -s $'\t'
    fi 
 
    # 3. 高资源占用的服务(保持不变)
    echo -e "\n${YELLOW}=== 高资源占用服务 ===${NC}"
    (
    echo -e "服务名称\tCPU%\t内存\t读写IO\t连接数"
    systemctl list-units --type=service --state=running --no-pager --no-legend 2>/dev/null | \
    while read -r line; do 
        service=$(echo "$line" | awk '{print $1}')
        pid=$(systemctl show "$service" --property=MainPID | cut -d= -f2)
        
        if [ "$pid" -gt 0 ] 2>/dev/null; then 
            cpu=$(ps -p "$pid" -o %cpu --no-headers 2>/dev/null | awk '{print $1}')
            memory=$(ps -p "$pid" -o rss --no-headers 2>/dev/null | awk '{print $1/1024}')
            
            io_read="N/A"
            io_write="N/A"
            if [ "$(id -u)" -eq 0 ]; then 
                io_stats=$(grep '^read_bytes\|^write_bytes' "/proc/$pid/io" 2>/dev/null | awk '{print $2/1024}')
                if [ -n "$io_stats" ]; then 
                    io_read=$(echo "$io_stats" | head -1)
                    io_write=$(echo "$io_stats" | tail -1)
                fi 
            fi 
            
            connections=$(lsof -p "$pid" 2>/dev/null | grep -c ESTABLISHED || echo "N/A")
            
            if [ -n "$cpu" ] && [ "$cpu" != "0.0" ] || [ "$memory" -gt 10 ] 2>/dev/null; then 
                printf "%-20s\t%.1f%%\t%.1fM\t%.1fK/%.1fK\t%s\n" \
                    "$service" "${cpu:-0}" "${memory:-0}" "${io_read:-0}" "${io_write:-0}" "${connections:-0}"
            fi 
        fi 
    done | sort -k2 -nr | head -10 
    ) | column -t 
 
    # 4. 关键服务检查(修复版)
    echo -e "\n${BLUE}=== 关键服务状态 ===${NC}"
    important_services=(
        "sshd.service"  
        "crond.service"  
        "network.target"  
        "dbus.service"  
        "rsyslog.service" 
        "docker.service" 
        "containerd.service" 
        "firewalld.service" 
        "NetworkManager.service" 
    )
    
    (
    echo -e "服务名称\t状态\t子状态\t是否启用\t启动时间"
    for service in "${important_services[@]}"; do 
        if systemctl list-unit-files | grep -q "$service"; then 
            status=$(systemctl is-active "$service" 2>/dev/null || echo "N/A")
            substate=$(systemctl show "$service" --property=SubState | cut -d= -f2)
            enabled=$(systemctl is-enabled "$service" 2>/dev/null || echo "N/A")
            
            # 使用更可靠的启动时间获取方法 
            activetime=$(systemctl show "$service" --property=ActiveEnterTimestampMonotonic | cut -d= -f2)
            if [ -n "$activetime" ]; then 
                uptime=$(awk -v ticks="$activetime" 'BEGIN {
                    now = systime();
                    uptime = now - (ticks / 1000000);
                    print strftime("%H:%M:%S", uptime);
                }') 
            else 
                uptime="N/A"
            fi 
            
            printf "%-20s\t%s\t%s\t%s\t%s\n" \
                "$service" "$status" "$substate" "$enabled" "$uptime"
        fi 
    done 
    ) | column -t 
}
# 用户检查 
check_users() {
    print_separator "用户检查"
    
    # 1. 显示passwd文件修改时间 
    if [ -f /etc/passwd ]; then 
        passwd_mtime=$(stat -c "%y" /etc/passwd 2>/dev/null | cut -d. -f1)
        passwd_seconds=$(( $(date +%s) - $(date +%s -r /etc/passwd 2>/dev/null) ))
        days=$(( passwd_seconds / 86400 ))
        hours=$(( (passwd_seconds % 86400) / 3600 ))
        echo -e "/etc/passwd 最后修改时间:${passwd_mtime} (${days} 天 ${hours} 小时前)\n"
    else 
        echo -e "无法获取/etc/passwd信息\n"
    fi 
    
    # 2. 特权用户检查 
    echo -e "特权用户\n--------"
    awk -F: '$3 == 0 {print $1}' /etc/passwd 2>/dev/null || echo "无"
    
    # 3. 用户列表 
    echo -e "\n用户列表\n--------"
    (
    echo -e "用户名 UID GID HOME SHELL 最后一次登录"
    getent passwd 2>/dev/null | while IFS=: read -r user _ uid gid _ home shell _; do 
        last_login=$(last -n 1 -F "$user" 2>/dev/null | awk 'NR==1 && !/wtmp/{printf "%s_%s", $5, $6}')
        [ -z "$last_login" ] && last_login="从未登录"
        printf "%s %s %s %s %s %s\n" "$user" "$uid" "$gid" "$home" "$shell" "$last_login"
    done 
    ) | column -t 
    
    # 4. 空密码用户检查 
    echo -e "\n空密码用户\n----------"
    ( 
    awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow 2>/dev/null || echo "无"
    )
    
    # 5. 相同ID检查 
    echo -e "\n相同ID的用户\n------------"
    echo -e "[相同UID]"
    (getent passwd | cut -d: -f3 | sort | uniq -d | while read uid; do 
        grep -w "$uid" /etc/passwd | cut -d: -f1 | paste -sd ","
    done) || echo "无"
    
    echo -e "\n[相同GID]"
    (getent passwd | cut -d: -f4 | sort | uniq -d | while read gid; do 
        grep -w "$gid" /etc/passwd | cut -d: -f1 | paste -sd ","
    done) || echo "无"
}

#登录检查
check_logins() {
    print_separator "登录检查"
    
    # 获取并格式化登录信息
    (
    echo -e "用户\t终端\tIP地址\t登录时间\t状态"
    last -n 10 -F -i -w | awk -v yellow="$YELLOW" -v nc="$NC" '
    BEGIN {
        OFS="\t"
    }
    NR>1 && !/^wtmp|^$|^reboot|^shutdown|^runlevel/ {
        user = $1
        tty = ($2 ~ /pts|tty|:0/) ? $2 : "other"
        ip = ($3 ~ /^[0-9]/) ? $3 : "-"
        
        # 标准化时间格式 
        time_str = $5" "$6" "$7" "$8 
        
        # 处理状态信息 
        if ($0 ~ /still logged in/) {
            status = yellow "仍在线" nc 
            is_active = 1 
        }
        else if ($0 ~ /down/) {
            status = "已下线"
        }
        else {
            match($0, /\(([^)]+)\)/, duration)
            status = duration[1] ? "(" duration[1] ")" : "未知"
        }
        
        printf "%s\t%s\t%s\t%s\t%s\n", user, tty, ip, time_str, status 
    }
    /^reboot|^shutdown/ {
        printf "reboot\tsystem boot\t-\t%s %s %s %s\t系统重启\n", $5, $6, $7, $8
    }
    '
    ) | column -t -s $'\t'
 
    # 准确统计活跃会话(使用who命令)
    echo -e "\n${BLUE}当前登录用户数:${NC}"
    active_users=$(who -u | awk '!/^USER/ && $7 != "." {print $1}' | wc -l)
    echo "  总计: $active_users 个活跃会话"
    
    # 显示当前活跃会话详情(可选)
    if [ "$active_users" -gt 0 ]; then
        echo -e "\n${BLUE}当前活跃会话:${NC}"
        who -u | awk '!/^USER/ && $7 != "." {
            printf "  %-8s %-12s %-15s %s\n", $1, $2, $6, $3" "$4
        }'
    fi 
}

# 安全检查 
check_security() {
    print_separator "安全检查"
    echo -e "\nSSH配置:"
    echo -e "  PermitRootLogin: $(grep -i PermitRootLogin /etc/ssh/sshd_config | grep -v '#' | awk '{print $2}')"
    
    echo -e "\n防火墙状态:"
    if systemctl is-active firewalld >/dev/null; then 
        echo -e "  ${GREEN}✓${NC} firewalld (active)"
    else 
        echo -e "  ${YELLOW}⚠${NC} firewalld (inactive)"
    fi 
}

#计划任务检查
check_cron() {
    print_separator "计划任务检查"
    
    # 系统级计划任务(带高亮)
    echo -e "\n$(highlight "info" "■■■ 系统计划任务 ■■■")"
    (
    echo -e "类型\t权限\t所有者\t大小\t最后修改\t\t任务路径"
    find /etc/cron* /var/spool/cron -type f -exec ls -lh --time-style=long-iso {} + 2>/dev/null | \
    awk -v yellow="$YELLOW" -v red="$RED" -v cyan="$CYAN" -v nc="$NC" '{
        path=$NF 
        if (path ~ /cron\.d/) {type="cron.d"; color=cyan}
        else if (path ~ /cron\.daily/) {type="daily"; color=""}
        else if (path ~ /cron\.hourly/) {type="hourly"; color=""}
        else if (path ~ /cron\.monthly/) {type="monthly"; color=""}
        else if (path ~ /cron\.weekly/) {type="weekly"; color=""}
        else if (path ~ /var\/spool\/cron/) {type="user"; color=yellow}
        else {type="other"; color=""}
        
        # 高亮关键文件
        if (path ~ /(cron\.(deny|allow)|anacron)/) {color=red}
        
        printf "%s%s%s\t%s\t%s\t%s\t%s\t%s%s%s\n", 
            color, type, nc, $1, $3, $5, $6" "$7, color, path, nc 
    }'
    ) | column -t -s $'\t' | head -n 15 
    
    # 用户级计划任务(带高亮)
    echo -e "\n$(highlight "info" "■■■ 用户计划任务 ■■■")"
    user_crons=$(for user in $(cut -f1 -d: /etc/passwd); do 
        crontab -l -u "$user" 2>/dev/null | grep -v "^#" | \
        awk -v user="$user" -v yellow="$YELLOW" -v nc="$NC" '{
            # 高亮root用户和危险命令
            if (user == "root") {user_color="\033[1;31m"} else {user_color=""}
            if ($0 ~ /(shutdown|rm\s+-|chmod\s+777)/) {cmd_color="\033[1;31m"} else {cmd_color=""}
            printf "%s%s%s\t%s%s%s\n", user_color, user, nc, cmd_color, $0, nc 
        }'
    done)
    
    if [ -n "$user_crons" ]; then 
        echo -e "$(highlight "special" "用户")\t\t$(highlight "special" "任务内容")" 
        echo -e "$user_crons" | column -t -s $'\t'
    else 
        highlight "success" "未检测到用户计划任务"
    fi 
}

#自启动检查
check_autostart() {
    print_separator "自启动检查"
    
    # 系统服务自启动(带状态高亮)
    echo -e "\n$(highlight "info" "■■■ 系统服务自启动 ■■■")"
    (
    echo -e "状态\t服务名称"
    systemctl list-unit-files --type=service --state=enabled 2>/dev/null | \
    awk -v green="$GREEN" -v red="$RED" -v nc="$NC" 'NR>1 && !/^@/ {
        if ($2 == "enabled") {
            status = green"✓"nc
            # 高亮不安全服务
            if ($1 ~ /(telnet|ftp|rsh)/) {service=red$1nc}
            else {service=$1}
        } else {
            status = red"✗"nc
            service=$1 
        }
        printf "%s\t%s\n", status, service 
    }'
    ) | column -t -s $'\t' | head -n 10 
    
    # 用户级自启动项(带高亮)
    echo -e "\n$(highlight "info" "■■■ 用户级自启动项 ■■■")"
    desktop_files=$(find /etc/xdg/autostart /usr/share/autostart ~/.config/autostart -name "*.desktop" 2>/dev/null)
    if [ -n "$desktop_files" ]; then 
        echo "$desktop_files" | xargs -n1 basename 2>/dev/null | \
        awk -v magenta="$MAGENTA" -v nc="$NC" '{print "  " magenta"▪" nc " " $0}'
    else
        highlight "success" "  未检测到用户自启动项"
    fi
    
    # 定时任务(带危险命令高亮)
    echo -e "\n$(highlight "info" "■■■ 定时任务 ■■■")"
    sys_crontab=$(grep -v "^#" /etc/crontab 2>/dev/null)
    user_crontab=$(crontab -l 2>/dev/null | grep -v "^#")
    
    if [ -n "$sys_crontab" ] || [ -n "$user_crontab" ]; then
        [ -n "$sys_crontab" ] && echo -e "$(highlight "warn" "系统定时任务:")" && \
        echo "$sys_crontab" | awk -v red="$RED" -v nc="$NC" '{
            if ($0 ~ /(shutdown|rm\s+-|chmod\s+777)/) {print red$0nc}
            else {print}
        }'
        [ -n "$user_crontab" ] && echo -e "$(highlight "warn" "用户定时任务:")" && \
        echo "$user_crontab" | awk -v red="$RED" -v nc="$NC" '{
            if ($0 ~ /(shutdown|rm\s+-|chmod\s+777)/) {print red$0nc}
            else {print}
        }'
    else 
        highlight "success" "未检测到定时任务"
    fi
}

#密码检查
check_password() {
    print_separator "密码检查"
    
    # 密码过期检查(修复版)
    echo -e "\n${CYAN}密码过期检查${NC}"
    echo -e "------------"
    (
    echo -e "用户名\t\t过期状态"
    getent passwd | awk -F: '$7 !~ /nologin|false/ {print $1}' | while read -r user; do 
        # 修复密码状态检测逻辑 
        if grep -q "^${user}:[^\!*]" /etc/shadow 2>/dev/null; then 
            expiry=$(chage -l "$user" 2>/dev/null | awk -F": " '/Password expires/{print $2}')
            if [ "$expiry" == "never" ]; then 
                echo -e "$user\t\t永不过期"
            elif [ "$expiry" == "password must be changed" ] || [ "$expiry" == "must be changed" ]; then 
                echo -e "$user\t\t${RED}必须修改${NC}"
            elif [ -n "$expiry" ]; then 
                echo -e "$user\t\t$expiry"
            else 
                echo -e "$user\t\t${YELLOW}密码已设置${NC}"
            fi 
        else 
            echo -e "$user\t\t${RED}无密码/已锁定${NC}"
        fi 
    done 
    ) | column -t -s $'\t'
    
    # 密码策略检查(修复版)
    echo -e "\n${CYAN}密码策略检查${NC}"
    echo -e "------------"
    (
    echo -e "策略项\t\t当前值\t建议值\t合规性"
    
    # 获取策略值(带默认值)
    max_days=$(grep "^PASS_MAX_DAYS" /etc/login.defs  2>/dev/null | awk '{print $2}')
    [ -z "$max_days" ] && max_days=99999 
    
    min_days=$(grep "^PASS_MIN_DAYS" /etc/login.defs  2>/dev/null | awk '{print $2}')
    [ -z "$min_days" ] && min_days=0 
    
    min_len=$(grep "^PASS_MIN_LEN" /etc/login.defs  2>/dev/null | awk '{print $2}')
    [ -z "$min_len" ] && min_len=$(grep "^minlen" /etc/security/pwquality.conf  2>/dev/null | awk '{print $3}')
    [ -z "$min_len" ] && min_len=0 
    
    warn_age=$(grep "^PASS_WARN_AGE" /etc/login.defs  2>/dev/null | awk '{print $2}')
    [ -z "$warn_age" ] && warn_age=7 
    
    # 修复整数比较错误 
    is_compliant() {
        local current=$1 
        local recommended=$2 
        if [ "$current" -eq "$recommended" ] 2>/dev/null; then 
            echo -e "${GREEN}符合${NC}"
        elif [ "$current" -lt "$recommended" ] 2>/dev/null; then 
            echo -e "${GREEN}更严格${NC}"
        else 
            echo -e "${RED}不符合${NC}"
        fi 
    }
    
    echo -e "PASS_MAX_DAYS\t$max_days\t90\t$(is_compliant "$max_days" 90)"
    echo -e "PASS_MIN_DAYS\t$min_days\t7\t$(is_compliant "$min_days" 7)"
    echo -e "PASS_MIN_LEN\t$min_len\t12\t$(is_compliant "$min_len" 12)"
    echo -e "PASS_WARN_AGE\t$warn_age\t14\t$(is_compliant "$warn_age" 14)"
    ) | column -t -s $'\t'
    
    # 弱密码用户检查(修复版)
    echo -e "\n${CYAN}弱密码用户检查${NC}"
    echo -e "------------"
 
    # 尝试使用faillock(现代系统)
if [ -x "$(command -v faillock)" ]; then 
    fails=$(faillock 2>/dev/null | awk '
        /^>/ {
            user = substr($1, 2)  # 去掉开头的>
            attempts = $2 
            print "  ⚠ " user " (失败次数: " attempts ")"
        }')
    [ -n "$fails" ] && echo -e "${YELLOW}登录失败用户:${NC}\n$fails" || echo "  无失败记录"
    
# 回退到pam_tally2(旧系统)
elif [ -x "$(command -v pam_tally2)" ]; then
    fails=$(pam_tally2 2>/dev/null | awk '
        NR>1 && !/^$/ {
            print "  ⚠ " $1 " (失败次数: " $2 ")"
        }')
    [ -n "$fails" ] && echo -e "${YELLOW}登录失败用户:${NC}\n$fails" || echo "  无失败记录"
    
# 如果都没有则检查btmp日志 
elif [ -f "/var/log/btmp" ]; then 
    echo -e "${YELLOW}最近登录失败记录:${NC}"
    lastb -a 2>/dev/null | head -n 5 | awk '
        NR>1 && !/^btmp/ {
            print "  ⚠ " $1 " 从 " $3 " 于 " $4 " " $5 " " $6 " " $7
        }'
else 
    echo "  未找到登录失败记录工具"
fi

    # 空密码用户检查(精确版)
    echo -e "\n${CYAN}空密码用户检查${NC}"
    echo -e "------------"
    empty_pass=$(awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow 2>/dev/null)
    if [ -n "$empty_pass" ]; then 
        echo -e "${RED}⚠ 存在空密码/锁定用户:${NC}"
        echo "$empty_pass" | awk '{print "  " $0}'
    else 
        echo -e "${GREEN}✓ 未发现空密码用户${NC}"
    fi 
    
    # 密码哈希算法检查 
    echo -e "\n${CYAN}密码哈希算法${NC}"
    echo -e "------------"
    if grep -q "^ENCRYPT_METHOD SHA512" /etc/login.defs  2>/dev/null; then 
        echo -e "${GREEN}✓ 使用SHA512加密${NC}"
    elif grep -q "^ENCRYPT_METHOD " /etc/login.defs  2>/dev/null; then 
        echo -e "${YELLOW}⚠ 当前使用$(grep "^ENCRYPT_METHOD" /etc/login.defs  | awk '{print $2}')加密${NC}"
    else 
        echo -e "${YELLOW}⚠ 未明确指定加密方法${NC}"
    fi 
}
 
#sudoers检查
check_sudoers() {
    print_separator "Sudoers检查"
    
    # 1. 主sudoers配置检查(增强解析逻辑)
    echo -e "\n${CYAN}=== Sudoers主配置 ===${NC}"
    (
    echo -e "类型\t名称\t权限"
    awk '! /^#|^Defaults|^$/ && !/^@include/ && NF>=3 {
        type = ($1 ~ /^%/) ? "用户组" : "用户"
        name = $1 
        $1 = ""
        gsub(/^[ \t]+/, "", $0)
        print type "\t" name "\t" $0 
    }' /etc/sudoers 2>/dev/null 
    ) | column -t -s $'\t'
 
    # 2. 包含的配置文件检查(递归检查)
    echo -e "\n${CYAN}=== 包含的配置文件 ===${NC}"
    includes=$(grep "^@include" /etc/sudoers 2>/dev/null | awk '{print $2}')
    
    if [ -n "$includes" ]; then 
        (
        echo -e "文件路径\t类型\t名称\t权限"
        while read -r file; do 
            [ -f "$file" ] && awk '! /^#|^Defaults|^$/ && NF>=3 {
                type = ($1 ~ /^%/) ? "用户组" : "用户"
                name = $1 
                $1 = ""
                gsub(/^[ \t]+/, "", $0)
                print FILENAME "\t" type "\t" name "\t" $0 
            }' "$file" 2>/dev/null 
        done <<< "$includes"
        ) | column -t -s $'\t'
    else 
        echo "未找到包含的配置文件"
    fi 
 
    # 3. sudoers.d目录检查(增强错误处理)
    echo -e "\n${CYAN}=== /etc/sudoers.d/配置 ===${NC}"
    if [ -d "/etc/sudoers.d" ]; then 
        (
        echo -e "文件\t类型\t名称\t权限"
        find /etc/sudoers.d -type f -name "*.conf" -exec awk '! /^#|^Defaults|^$/ && NF>=3 {
            type = ($1 ~ /^%/) ? "用户组" : "用户"
            name = $1 
            $1 = ""
            gsub(/^[ \t]+/, "", $0)
            print FILENAME "\t" type "\t" name "\t" $0 
        }' {} + 2>/dev/null 
        ) | column -t -s $'\t' | head -n 5 
    else 
        echo "未找到/etc/sudoers.d目录"
    fi 
 
    # 4. 无需密码的sudo权限(精确匹配)
    echo -e "\n${RED}=== 无需密码的sudo权限(NOPASSWD) ===${NC}"
    nopasswd=$(grep -rEh "NOPASSWD:" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | awk '!seen[$0]++ {
        gsub(/[ \t]+/, " ", $0)
        split($0, parts, "NOPASSWD:")
        printf "%s\t%s\n", parts[1], "NOPASSWD:" parts[2]
    }')
    
    if [ -n "$nopasswd" ]; then 
        echo -e "配置来源\t权限" 
        echo "$nopasswd" | column -t -s $'\t'
    else 
        echo "未配置NOPASSWD权限"
    fi 
 
    # 5. sudo组用户检查(增强兼容性)
    echo -e "\n${YELLOW}=== 通过sudo组获得权限的用户 ===${NC}"
    sudo_users=$(getent group sudo 2>/dev/null | cut -d: -f4 | tr ',' '\n' | sort | uniq)
    
    if [ -n "$sudo_users" ]; then 
        echo "$sudo_users" | awk '{print "  " $0}'
    else 
        echo "  sudo组中没有用户"
    fi 
 
    # 6. 用户详细权限检查(优化性能)
    echo -e "\n${CYAN}=== 用户详细sudo权限 ===${NC}"
    checked_users=0 
    for user in $(getent passwd | cut -d: -f1); do 
        # 跳过root和系统用户 
        [[ "$user" == "root" ]] || [[ "$(getent passwd "$user" | cut -d: -f3)" -lt 1000 ]] && continue 
        
        sudo -U "$user" -l 2>/dev/null | grep -q "may run the following commands" && {
            echo -n "  $user: "
            sudo -U "$user" -l | awk '/may run/,/^$/{if($0 !~ /may run/)print}' | tr '\n' ' '
            echo ""
            ((checked_users++))
            [ $checked_users -ge 3 ] && break  # 限制输出数量 
        }
    done 
    [ $checked_users -eq 0 ] && echo "  未检测到用户特殊sudo权限"
}

#JDK检查
check_jdk() {
    print_separator "JDK检查"
    
    # 1. 检查JAVA_HOME环境变量
    echo -e "\n${CYAN}=== JAVA_HOME环境变量 ===${NC}"
    if [ -n "$JAVA_HOME" ]; then
        echo -e "JAVA_HOME=\"$JAVA_HOME\""
        if [ -d "$JAVA_HOME" ]; then
            echo -e "${GREEN}✓ 路径存在${NC}"
        else
            echo -e "${RED}✗ 路径不存在${NC}"
        fi
    else
        echo -e "JAVA_HOME=\"\""
        echo -e "${YELLOW}⚠ 未设置JAVA_HOME环境变量${NC}"
    fi

    # 2. 检查java命令路径
    echo -e "\n${CYAN}=== Java可执行文件 ===${NC}"
    java_path=$(command -v java 2>/dev/null)
    if [ -n "$java_path" ]; then
        echo -e "java路径: $java_path"
        echo -e "版本信息:"
        java -version 2>&1 | head -n 1 | awk -F '"' '{print $2}'
    else
        echo -e "${RED}✗ 未找到java命令${NC}"
    fi

    # 3. 检查安装的JDK版本
    echo -e "\n${CYAN}=== 已安装的JDK版本 ===${NC}"
    if [ -d "/usr/lib/jvm" ]; then
        echo -e "${GREEN}系统JDK安装目录:/usr/lib/jvm${NC}"
        ls -l /usr/lib/jvm | awk '/jdk|java/ && !/^d/ {print $9}'
    else
        echo -e "${YELLOW}⚠ 未找到标准JDK安装目录${NC}"
    fi

    # 4. 检查备选JDK路径
    echo -e "\n${CYAN}=== 备选JDK路径检查 ===${NC}"
    common_paths=(
        "/usr/java"
        "/opt/java"
        "/Library/Java/JavaVirtualMachines"
        "C:\Program Files\Java"
    )
    
    found=0
    for path in "${common_paths[@]}"; do
        if [ -d "$path" ]; then
            echo -e "${GREEN}找到JDK目录: $path${NC}"
            ls -l "$path" | awk '/jdk|java/ && !/^d/ {print $9}'
            found=1
        fi
    done
    
    [ $found -eq 0 ] && echo -e "${YELLOW}⚠ 未在常见路径找到JDK${NC}"

    # 5. 检查Java进程
    echo -e "\n${CYAN}=== 运行的Java进程 ===${NC}"
    java_processes=$(ps aux | grep java | grep -v grep)
    if [ -n "$java_processes" ]; then
        echo -e "${YELLOW}运行的Java进程:${NC}"
        echo "$java_processes" | awk '{print $1 "\t" $11 "\t" $12}'
    else
        echo -e "${GREEN}✓ 没有运行的Java进程${NC}"
    fi
}

#防火墙检查
check_firewall() {
    print_separator "防火墙检查"

    # 1. 检查iptables状态
    echo -e "\n${CYAN}=== iptables状态 ===${NC}"
    if [ -x "$(command -v iptables)" ]; then
        iptables_status=$(iptables -L 2>/dev/null | grep -q -v "Chain INPUT (policy ACCEPT)" && echo "active" || echo "inactive")
        echo -e "iptables: $iptables_status"
    else
        echo -e "${YELLOW}iptables: 未安装${NC}"
    fi

    # 2. 检查iptables配置文件
    echo -e "\n${CYAN}=== iptables配置文件 ===${NC}"
    if [ -f "/etc/sysconfig/iptables" ]; then
        echo -e "/etc/sysconfig/iptables"
        echo -e "-----------------------"
        cat /etc/sysconfig/iptables | grep -v "^#" | sed '/^$/d'
    else
        echo -e "${YELLOW}未找到/etc/sysconfig/iptables文件${NC}"
    fi

    # 3. 检查firewalld状态
    echo -e "\n${CYAN}=== firewalld状态 ===${NC}"
    if [ -x "$(command -v firewall-cmd)" ]; then
        firewall_status=$(systemctl is-active firewalld 2>/dev/null)
        if [ "$firewall_status" = "active" ]; then
            echo -e "firewalld: ${GREEN}active${NC}"
            echo -e "默认区域: $(firewall-cmd --get-default-zone)"
        else
            echo -e "firewalld: ${YELLOW}inactive${NC}"
        fi
    else
        echo -e "${YELLOW}firewalld: 未安装${NC}"
    fi

    # 4. 检查ufw状态(Ubuntu)
    echo -e "\n${CYAN}=== ufw状态 ===${NC}"
    if [ -x "$(command -v ufw)" ]; then
        ufw_status=$(ufw status | grep "Status:")
        if [[ "$ufw_status" == *"active"* ]]; then
            echo -e "ufw: ${GREEN}active${NC}"
            echo -e "规则:"
            ufw status numbered | tail -n +4
        else
            echo -e "ufw: ${YELLOW}inactive${NC}"
        fi
    else
        echo -e "${YELLOW}ufw: 未安装${NC}"
    fi

    # 5. 检查开放的端口
    echo -e "\n${CYAN}=== 开放端口检查 ===${NC}"
    if [ -x "$(command -v ss)" ]; then
        echo -e "监听端口:"
        ss -tulnp | awk 'NR>1 {print $5 "\t" $1 "\t" $6}'
    elif [ -x "$(command -v netstat)" ]; then
        echo -e "监听端口:"
        netstat -tulnp | awk 'NR>2 {print $4 "\t" $1 "\t" $6}'
    else
        echo -e "${YELLOW}无法检查开放端口(缺少ss/netstat命令)${NC}"
    fi
}

# SSH检查 
check_ssh() {
    print_separator "SSH检查"
    
    # 1. 检查SSH服务状态 
    echo -e "\n${CYAN}=== SSH服务状态 ===${NC}"
    ssh_status=$(systemctl is-active sshd 2>/dev/null || systemctl is-active ssh 2>/dev/null)
    if [ "$ssh_status" = "active" ]; then 
        echo -e "服务状态: ${GREEN}active${NC}"
    else 
        echo -e "服务状态: ${RED}inactive${NC}"
    fi 
 
    # 2. 检查SSH协议版本 
    echo -e "\n${CYAN}=== SSH协议版本 ===${NC}"
    sshd -T 2>/dev/null | grep -E "^protocol" | awk '{print "SSH协议版本: " $2}'
    if grep -q "Protocol 1" /etc/ssh/sshd_config 2>/dev/null; then 
        echo -e "${RED}⚠ 警告: 检测到不安全的SSH协议版本1${NC}"
    fi 
 
    # 3. 检查信任主机 
    echo -e "\n${CYAN}=== 信任主机 ===${NC}"
    if [ -f ~/.ssh/known_hosts ]; then 
        echo -e "已知主机:"
        cat ~/.ssh/known_hosts | awk '{print "  " $1}'
    else 
        echo -e "无信任主机配置"
    fi 
 
    # 4. 检查Root登录权限 
    echo -e "\n${CYAN}=== Root远程登录 ===${NC}"
    root_login=$(sshd -T 2>/dev/null | grep -i "permitrootlogin" | awk '{print $2}')
    if [ "$root_login" = "yes" ]; then 
        echo -e "${RED}PermitRootLogin yes (安全风险!)${NC}"
    else 
        echo -e "${GREEN}PermitRootLogin $root_login${NC}"
    fi 
 
    # 5. 检查密码认证 
    echo -e "\n${CYAN}=== 密码认证 ===${NC}"
    pass_auth=$(sshd -T 2>/dev/null | grep -i "passwordauthentication" | awk '{print $2}')
    if [ "$pass_auth" = "yes" ]; then 
        echo -e "${YELLOW}PasswordAuthentication yes (建议关闭)${NC}"
    else 
        echo -e "${GREEN}PasswordAuthentication $pass_auth${NC}"
    fi 
 
    # 6. 检查SSH配置文件 
    echo -e "\n${CYAN}=== SSH配置文件(/etc/ssh/sshd_config) ===${NC}"
    if [ -f /etc/ssh/sshd_config ]; then 
        echo -e "主要配置项:"
        grep -E "^PermitRootLogin|^PasswordAuthentication|^Protocol|^Port|^UsePAM|^X11Forwarding|^AllowUsers|^AllowGroups|^DenyUsers|^DenyGroups" /etc/ssh/sshd_config 2>/dev/null | \
        while read line; do 
            key=$(echo "$line" | awk '{print $1}')
            value=$(echo "$line" | awk '{print $2}')
            
            case "$key" in 
                "PermitRootLogin")
                    [ "$value" = "yes" ] && echo -e "${RED}$line${NC}" || echo -e "${GREEN}$line${NC}"
                    ;;
                "PasswordAuthentication")
                    [ "$value" = "yes" ] && echo -e "${YELLOW}$line${NC}" || echo -e "${GREEN}$line${NC}"
                    ;;
                "Protocol")
                    [ "$value" = "1" ] && echo -e "${RED}$line${NC}" || echo -e "${GREEN}$line${NC}"
                    ;;
                *)
                    echo -e "$line"
                    ;;
            esac 
        done 
    else 
        echo -e "${RED}SSH配置文件不存在${NC}"
    fi 
 
    # 7. 检查SSH监听端口 
    echo -e "\n${CYAN}=== SSH监听端口 ===${NC}"
    ssh_port=$(sshd -T 2>/dev/null | grep "port" | awk '{print $2}' | head -1)
    echo -e "SSH端口: $ssh_port"
    if [ "$ssh_port" = "22" ]; then 
        echo -e "${YELLOW}⚠ 警告: 使用默认SSH端口(22)${NC}"
    fi 
 
    # 8. 检查SSH最近登录 
    echo -e "\n${CYAN}=== 最近SSH登录 ===${NC}"
    last -n 5 | grep -E "ssh|pts" | awk '{print "  " $0}'
}

# syslog检查 
check_syslog() {
    print_separator "syslog检查"
    
    # 1. 检查syslog服务状态 
    echo -e "\n服务状态:"
    syslog_status=$(systemctl is-active rsyslog 2>/dev/null || systemctl is-active syslog 2>/dev/null)
    if [ "$syslog_status" = "active" ]; then 
        echo -e "${GREEN}active${NC}"
    else 
        echo -e "${RED}$syslog_status${NC}"
        FAIL_FLAG=1 
    fi 
 
    # 2. 检查syslog配置文件 
    echo -e "\n/etc/rsyslog.conf" 
    echo "-----------------"
    if [ -f /etc/rsyslog.conf  ]; then 
        # 过滤出主要的日志配置规则 
        grep -E "^[^#]" /etc/rsyslog.conf  2>/dev/null | \
        awk ' 
            /\.info;|authpriv|mail|cron|\.emerg|uucp|local7/ {
                # 移除行首空格和注释部分 
                gsub(/^[ \t]+/, "")
                sub(/[ \t]+#.*$/, "")
                
                # 高亮重要配置 
                if ($0 ~ /authpriv/) {color="\033[1;33m"}  # 黄色表示认证日志 
                else if ($0 ~ /\.emerg/) {color="\033[1;31m"}  # 红色表示紧急日志 
                else color=""
                
                print color $0 "\033[0m"
            }
        ' | column -t -s $'\t'
    else 
        echo -e "${RED}配置文件不存在${NC}"
        FAIL_FLAG=1 
    fi 
 
    # 3. 检查日志文件是否存在 
    echo -e "\n日志文件检查"
    echo "-----------"
    (
    echo -e "日志文件\t\t状态"
    grep -E "^[^#]" /etc/rsyslog.conf  2>/dev/null | \
    awk '/\// {
        # 提取日志文件路径 
        logfile=$NF 
        gsub(/^-/, "", logfile)  # 处理前面有-的情况 
        
        # 检查文件是否存在 
        if (system("test -f " logfile " 2>/dev/null") == 0) {
            status="\033[32m存在\033[0m"
        } else {
            status="\033[31m缺失\033[0m"
        }
        
        printf "%-20s\t%s\n", logfile, status 
    }'
    ) | column -t 
 
    # 4. 检查日志轮转配置 
    echo -e "\n日志轮转配置(/etc/logrotate.d/syslog)"
    echo "-----------------------------------"
    if [ -f /etc/logrotate.d/syslog ]; then 
        grep -v "^#" /etc/logrotate.d/syslog 2>/dev/null | \
        while read line; do 
            echo -e "  $line"
        done 
    else 
        echo -e "  ${YELLOW}未找到日志轮转配置${NC}"
    fi 
} 

# SNMP检查 
check_snmp() {
    print_separator "SNMP检查"
    
    # 1. 检查SNMP服务状态 
    echo -e "\n服务状态:"
    snmp_status=$(systemctl is-active snmpd 2>/dev/null || echo "unknown")
    if [ "$snmp_status" = "active" ]; then 
        echo -e "${GREEN}active${NC}"
    elif [ "$snmp_status" = "unknown" ]; then 
        echo -e "${YELLOW}unknown${NC}"
    else 
        echo -e "${RED}$snmp_status${NC}"
    fi 
 
    # 2. 检查SNMP配置文件 
    echo -e "\n/etc/snmp/snmpd.conf" 
    echo "---------------------"
    if [ -f /etc/snmp/snmpd.conf  ]; then 
        # 显示关键配置项 
        grep -E "^rocommunity|^rwcommunity|^com2sec|^access" /etc/snmp/snmpd.conf  2>/dev/null | \
        while read line; do 
            # 高亮安全风险配置 
            if echo "$line" | grep -q "public\|private"; then 
                echo -e "${RED}$line (安全风险!)${NC}"
            else 
                echo -e "$line"
            fi 
        done 
    else 
        echo -e "${YELLOW}配置文件不存在${NC}"
    fi 
 
    # 3. 检查SNMP监听端口 
    echo -e "\n监听端口:"
    if netstat -tuln | grep -q ":161"; then 
        echo -e "UDP 161 (SNMP)"
        if [ "$snmp_status" = "active" ]; then 
            echo -e "${GREEN}端口正常监听${NC}"
        else 
            echo -e "${YELLOW}端口监听但服务未运行${NC}"
        fi 
    else 
        echo -e "${YELLOW}未检测到SNMP端口监听${NC}"
    fi 
}
 
# NTP检查 
check_ntp() {
    print_separator "NTP检查"
    
    # 1. 检查NTP/Chrony服务状态 
    echo -e "\n服务状态:"
    if systemctl is-active chronyd >/dev/null 2>&1; then 
        echo -e "${GREEN}active (chronyd)${NC}"
        ntp_service="chronyd"
    elif systemctl is-active ntpd >/dev/null 2>&1; then 
        echo -e "${GREEN}active (ntpd)${NC}"
        ntp_service="ntpd"
    else 
        echo -e "${RED}inactive${NC}"
        ntp_service="none"
        FAIL_FLAG=1 
    fi 
 
    # 2. 检查时间同步状态 
    echo -e "\n时间同步状态:"
    if [ "$ntp_service" = "chronyd" ]; then 
        chronyc tracking 2>/dev/null | grep -E "Reference ID|Stratum|System time"
        chronyc sources 2>/dev/null | head -5 
    elif [ "$ntp_service" = "ntpd" ]; then 
        ntpq -pn 2>/dev/null | head -5 
    else 
        echo -e "${YELLOW}未检测到NTP服务${NC}"
    fi 
 
    # 3. 检查配置文件 
    echo -e "\n配置文件:"
    if [ -f /etc/chrony.conf  ]; then 
        echo -e "/etc/chrony.conf" 
        echo "----------------"
        grep -E "^server|^pool" /etc/chrony.conf  2>/dev/null 
    elif [ -f /etc/ntp.conf  ]; then 
        echo -e "/etc/ntp.conf" 
        echo "-------------"
        grep -E "^server|^pool" /etc/ntp.conf  2>/dev/null 
    else 
        echo -e "${YELLOW}未找到NTP配置文件${NC}"
    fi 
 
    # 4. 检查时间偏移 
    echo -e "\n时间偏移:"
    if command -v chronyc >/dev/null; then 
        offset=$(chronyc tracking 2>/dev/null | awk '/System time/ {print $4}')
        echo -e "chronyd偏移: ${offset:-未知}"
    fi 
    if command -v ntpdate >/dev/null; then 
        ntpdate -q pool.ntp.org  2>/dev/null | tail -1 
    fi 
}

# 软件检查 
check_software() {
    print_separator "软件检查"
    
    # 1. 获取已安装软件列表(RPM系统)
    if command -v rpm >/dev/null 2>&1; then 
        echo -e "\n已安装软件包:"
        rpm -qa --queryformat '%-50{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}  %{INSTALLTIME:date}\n' 2>/dev/null | \
        sort | \
        while read -r line; do 
            # 跳过空行 
            [ -z "$line" ] && continue 
            
            # 提取软件名和架构 
            pkg=$(echo "$line" | awk '{print $1}')
            arch=$(echo "$pkg" | grep -o '\.[^.]*$')
            
            # 高亮特殊软件包 
            if [[ "$pkg" =~ (shc|wget|net-tools) ]]; then 
                echo -e "${YELLOW}$line${NC}"
            elif [[ "$pkg" =~ (firmware|iwl) ]]; then 
                echo -e "${BLUE}$line${NC}"
            else 
                echo -e "$line"
            fi 
        done | head -15  # 限制显示数量 
        
        # 2. 检查关键软件版本 
        echo -e "\n关键软件版本:"
        check_tools=("wget" "curl" "openssl" "python" "java" "docker")
        for tool in "${check_tools[@]}"; do 
            version=$($tool --version 2>&1 | head -1)
            if [ $? -eq 0 ]; then 
                echo -e "${GREEN}$tool: ${version%% *}${NC}"
            else 
                echo -e "${RED}$tool: 未安装${NC}"
            fi 
        done 
        
        # 3. 检查安全更新(修复语法错误)
        if command -v yum >/dev/null 2>&1; then 
            echo -e "\n可用的安全更新:"
            yum_output=$(yum list updates --security 2>/dev/null)
            if [ $? -eq 0 ] && [ -n "$yum_output" ]; then 
                echo "$yum_output" | grep -v "Updated Packages" | \
                awk 'NR>1 && NF>=2 {print $1"\t"$2}' | while read -r line; do 
                    echo -e "${RED}$line${NC}"
                done 
            else 
                echo -e "${GREEN}没有可用的安全更新${NC}"
            fi 
        fi 
        
        # 4. 检查第三方仓库(修复语法错误)
        echo -e "\n第三方仓库:"
        if ls /etc/yum.repos.d/*  >/dev/null 2>&1; then 
            grep -lE "epel|ius|rpmforge|remi" /etc/yum.repos.d/*  2>/dev/null | \
            while read -r repo; do 
                echo -e "${YELLOW}$(basename "$repo")${NC}"
            done 
        else 
            echo -e "未检测到yum仓库文件"
        fi 
    else 
        echo -e "\n${RED}非RPM系统,无法获取软件包列表${NC}"
    fi 
}

# 文件检查 
check_files() {
    print_separator "文件检查"
    
    # 1. 检查最近24小时内被修改过的文件 
    echo -e "\n############################查看所有被修改过的文件返回最近24小时内的############################"
    recent_files=$(find / -type f -mtime -1 2>/dev/null | head -n 10)  # 限制显示10个文件 
    if [ -n "$recent_files" ]; then 
        echo "$recent_files" | while read -r file; do 
            # 获取文件详细信息 
            file_info=$(ls -la "$file" 2>/dev/null)
            modify_time=$(date -r "$file" "+%Y-%m-%d %H:%M:%S" 2>/dev/null)
            
            # 高亮关键目录文件 
            if [[ "$file" =~ /etc/|/root/|/home/ ]]; then 
                echo -e "${YELLOW}$file_info 修改时间: $modify_time${NC}"
            else 
                echo -e "$file_info 修改时间: $modify_time"
            fi 
        done 
    else 
        echo -e "${GREEN}未找到24小时内修改的文件${NC}"
    fi 
 
    # 2. 检查定时任务文件完整性 
    echo -e "\n\n############################检查定时文件的完整性############################"
    crontab_files=("/etc/crontab" "/etc/cron.d/*" "/var/spool/cron/*")
    for crontab_file in ${crontab_files[@]}; do 
        if [ -f "$crontab_file" ] || [ -d "$crontab_file" ]; then 
            echo -e "\n文件: ${BLUE}$crontab_file${NC}"
            echo "----------------------------------------"
            
            # 显示文件内容,过滤注释和空行 
            grep -vE '^#|^$' "$crontab_file" 2>/dev/null | while read -r line; do 
                # 高亮可疑命令 
                if [[ "$line" =~ (chmod\s+777|rm\s+-rf|wget\s+http|curl\s+-sL) ]]; then 
                    echo -e "${RED}$line${NC}"
                else 
                    echo -e "$line"
                fi 
            done 
        fi 
    done 
 
    # 3. 检查系统关键文件完整性 
    echo -e "\n\n############################系统关键文件检查############################"
    critical_files=(
        "/etc/passwd"
        "/etc/shadow"
        "/etc/group"
        "/etc/sudoers"
        "/etc/ssh/sshd_config"
    )
    
    (
    echo -e "文件\t\t\t权限\t所有者\t大小\t修改时间"
    for file in "${critical_files[@]}"; do 
        if [ -f "$file" ]; then 
            file_perms=$(stat -c "%A" "$file")
            file_owner=$(stat -c "%U:%G" "$file")
            file_size=$(stat -c "%s" "$file")
            file_mtime=$(stat -c "%y" "$file" | cut -d'.' -f1)
            
            # 检查异常权限 
            if [[ "$file_perms" =~ "rwx" ]] && [[ "$file" != "/etc/shadow" ]]; then 
                echo -e "${RED}$file\t$file_perms\t$file_owner\t$file_size\t$file_mtime${NC}"
            else 
                echo -e "$file\t$file_perms\t$file_owner\t$file_size\t$file_mtime"
            fi 
        else 
            echo -e "${YELLOW}$file\t文件不存在${NC}"
        fi 
    done 
    ) | column -t -s $'\t'
}

# 系统命令替换检查 
check_command_integrity() {
    print_separator "查看系统命令是否被替换"
    
    # 1. 检查常见系统命令目录 
    common_bin_dirs=("/bin" "/sbin" "/usr/bin" "/usr/sbin" "/usr/local/bin" "/usr/local/sbin")
    
    for bin_dir in "${common_bin_dirs[@]}"; do 
        if [ -d "$bin_dir" ]; then 
            echo -e "\n目录: ${BLUE}$bin_dir${NC}"
            echo "----------------------------------------"
            
            # 获取目录总大小和文件数 
            dir_size=$(du -sh "$bin_dir" 2>/dev/null | awk '{print $1}')
            file_count=$(find "$bin_dir" -type f | wc -l)
            echo -e "总大小: $dir_size\t文件数: $file_count"
            
            # 2. 检查链接文件 
            echo -e "\n链接文件检查:"
            (
            echo -e "权限\t\t链接目标\t\t\t文件名"
            find "$bin_dir" -type l -ls 2>/dev/null | awk '{
                # 提取权限、文件名和链接目标 
                permissions=$3 
                split($13, parts, "->")
                filename=parts[1]
                target=parts[2]
                
                # 检查可疑链接 
                if (target ~ /\.\./ || target ~ /tmp/ || target ~ /dev/) {
                    color="\033[1;31m"
                } else {
                    color=""
                }
                
                printf "%s\t%s\t\t%s%s\033[0m\n", permissions, target, color, filename 
            }'
            ) | column -t -s $'\t' | head -10  # 限制显示数量 
            
            # 3. 检查文件修改时间 
            echo -e "\n最近修改的文件:"
            find "$bin_dir" -type f -printf "%Tb %Td %Tk:%TM %TY\t%p\n" 2>/dev/null | \
            sort -r | head -5 | while read -r line; do 
                file=$(echo "$line" | awk '{print $5}')
                time_info=$(echo "$line" | awk '{$5=""; print $0}')
                
                # 检查最近7天内修改的文件 
                if find "$file" -mtime -7 2>/dev/null | grep -q .; then 
                    echo -e "${YELLOW}$time_info\t$file${NC}"
                else 
                    echo -e "$time_info\t$file"
                fi 
            done 
            
            # 4. 检查文件哈希(可选,需要预先保存基准哈希)
            if [ -f "/var/log/checksum_$(basename "$bin_dir").log" ]; then 
                echo -e "\n文件哈希校验:"
                current_checksum=$(md5sum "$bin_dir"/* 2>/dev/null | sort)
                stored_checksum=$(cat "/var/log/checksum_$(basename "$bin_dir").log")
                
                if diff <(echo "$current_checksum") <(echo "$stored_checksum") >/dev/null; then 
                    echo -e "${GREEN}✓ 文件哈希匹配${NC}"
                else 
                    echo -e "${RED}⚠ 文件哈希不匹配${NC}"
                    diff <(echo "$current_checksum") <(echo "$stored_checksum") | grep "^>" | \
                    awk '{print "  修改的文件: " $3}'
                fi 
            fi 
        fi 
    done 
    
    # 5. 检查关键系统命令 
    echo -e "\n关键系统命令检查:"
    critical_commands=("ls" "ps" "netstat" "ss" "find" "top" "ifconfig" "ip" "passwd" "su" "sudo")
    
    (
    echo -e "命令\t\t路径\t\t\t\t哈希值"
    for cmd in "${critical_commands[@]}"; do 
        cmd_path=$(which "$cmd" 2>/dev/null)
        if [ -n "$cmd_path" ]; then 
            cmd_hash=$(md5sum "$cmd_path" 2>/dev/null | awk '{print $1}')
            
            # 检查命令是否在标准路径 
            if [[ "$cmd_path" =~ ^(/bin|/sbin|/usr/bin|/usr/sbin) ]]; then 
                echo -e "$cmd\t\t$cmd_path\t$cmd_hash"
            else 
                echo -e "${RED}$cmd\t\t$cmd_path\t$cmd_hash (非标准路径)${NC}"
            fi 
        else 
            echo -e "${YELLOW}$cmd\t\t未找到${NC}"
        fi 
    done 
    ) | column -t -s $'\t'
}

# 总结报告(问题导向版)
show_summary() {
    print_separator "巡检问题汇总"
    
    # 初始化问题计数器 
    high_risk=0 
    medium_risk=0 
    low_risk=0 
    
    # 1. 高风险管理问题 
    echo -e "\n${RED}===== 高风险问题 (需立即处理) =====${NC}"
    
    # SSH检查问题 
    if grep -q "PermitRootLogin yes" /etc/ssh/sshd_config 2>/dev/null; then 
        echo -e "  ✗ SSH允许root登录:${RED}建议禁用root远程登录${NC}"
        ((high_risk++))
    fi 
    
    # 密码检查问题 
    if awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow 2>/dev/null | grep -q .; then 
        echo -e "  ✗ 存在空密码账户:${RED}请立即设置密码${NC}"
        ((high_risk++))
    fi 
    
    # 无高风险的默认输出 
    [ $high_risk -eq 0 ] && echo -e "  ${GREEN}✓ 未发现高风险问题${NC}"
 
    # 2. 中风险问题 
    echo -e "\n${YELLOW}===== 中风险问题 (建议处理) =====${NC}"
    
    # 防火墙检查 
    if ! systemctl is-active firewalld >/dev/null && ! systemctl is-active iptables >/dev/null; then 
        echo -e "  ⚠ 防火墙未启用:${YELLOW}建议启用防火墙${NC}"
        ((medium_risk++))
    fi 
    
    # 密码策略检查 
    if grep -q "^PASS_MAX_DAYS" /etc/login.defs  && [ $(grep "^PASS_MAX_DAYS" /etc/login.defs  | awk '{print $2}') -gt 90 ]; then 
        echo -e "  ⚠ 密码有效期过长:${YELLOW}建议设置为90天以下${NC}"
        ((medium_risk++))
    fi 
    
    # 无中风险的默认输出 
    [ $medium_risk -eq 0 ] && echo -e "  ${GREEN}✓ 未发现中风险问题${NC}"
 
    # 3. 低风险问题 
    echo -e "\n${BLUE}===== 低风险问题 (可选处理) =====${NC}"
    
    # 默认SSH端口检查 
    if ss -tuln | grep -q ":22 "; then 
        echo -e "  ⓘ 使用默认SSH端口:${BLUE}建议修改为非常规端口${NC}"
        ((low_risk++))
    fi 
    
    # 无低风险的默认输出 
    [ $low_risk -eq 0 ] && echo -e "  ${GREEN}✓ 未发现低风险问题${NC}"
 
    # 4. 统计信息 
    echo -e "\n${MAGENTA}===== 问题统计 =====${NC}"
    echo -e "  高风险问题: ${RED}$high_risk 个${NC}"
    echo -e "  中风险问题: ${YELLOW}$medium_risk 个${NC}"
    echo -e "  低风险问题: ${BLUE}$low_risk 个${NC}"
    total_problems=$((high_risk + medium_risk + low_risk))
    echo -e "  总计发现问题: $total_problems 个"
 
    # 5. 修复建议 
    if [ $total_problems -gt 0 ]; then 
        echo -e "\n${CYAN}===== 修复建议 =====${NC}"
        [ $high_risk -gt 0 ] && echo -e "  • ${RED}优先处理高风险问题${NC}"
        [ $medium_risk -gt 0 ] && echo -e "  • ${YELLOW}安排处理中风险问题${NC}"
        [ $low_risk -gt 0 ] && echo -e "  • ${BLUE}酌情处理低风险问题${NC}"
        echo -e "  • 查看详细报告: ${REPORT_FILE}"
    else 
        echo -e "\n${GREEN}✓ 系统检查未发现任何问题${NC}"
    fi 
    
    # 6. 报告信息 
    echo -e "\n${GREEN}===== 报告生成信息 =====${NC}"
    echo -e "  生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
    echo -e "  主机名称: $(hostname)"
    echo -e "  报告路径: ${REPORT_FILE}"
}

# 主函数 
main() {
    {
        echo -e "${BLUE}系统巡检脚本:Version $(date +%Y-%m-%d)${NC}"
        check_system_info
        check_cpu 
        check_memory
        check_disk 
        check_raid
        check_network
        check_listening 
        check_processes 
        check_services
        check_users
	check_logins
        check_security
        check_ssh
        check_syslog 
        check_cron
        check_autostart
        check_password
        check_sudoers
        check_jdk
        check_firewall
        check_snmp     
        check_software
        check_ntp 
        check_files 
        check_command_integrity
        show_summary 



        if [ $FAIL_FLAG -eq 0 ]; then 
            echo -e "\n${GREEN}===== 巡检完成,未发现严重问题 =====${NC}"
        else 
            echo -e "\n${RED}===== 巡检完成,发现需要关注的问题 =====${NC}"
        fi 
    } | tee -a $REPORT_FILE
    
    echo -e "\n报告已保存至: ${BLUE}$REPORT_FILE${NC}"
}
 
main

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值