继上一篇,上一篇重点介绍了腾讯云Windows Server日志收集工具的“场景”功能,那么场景功能究竟是以什么标准来分级的呢?
经过抽丝剥茧,我发现了该工具存在一个“共性”,那就是主模块下似乎包含了xxxlist或者xxxinfo的所谓“标记位”,并且是大体内容是以”===< xxxxx >===”这种格式存在(截取了其中一段):
##获取进程 function GetProcess () { "processlist ===<" | Out-File -Append ".\$Dirfilename\$Logfilename" "——————————以下为该机的进程列表———————————— " | Out-File -Append ".\$Dirfilename\$Logfilename" get-process -ErrorAction SilentlyContinue | select-object * | Fl | Out-File -Append ".\$Dirfilename\$Logfilename" ">===" | Out-File -Append ".\$Dirfilename\$Logfilename" } ##获取服务 function GetServer () { "servicelist ===<" | Out-File -Append ".\$Dirfilename\$Logfilename" "——————————以下为该机的服务列表———————————— " | Out-File -Append ".\$Dirfilename\$Logfilename" Get-Service -ErrorAction SilentlyContinue | select-object * | FL | Out-File -Append ".\$Dirfilename\$Logfilename" ">===" | Out-File -Append ".\$Dirfilename\$Logfilename" }
经过整理,发现这个规律竟然每个主模块都存在,统计了一下,竟然有多达29个“标志位”(经过简单解析后我把相关标记位具体收集范围做了标注):
osversion 用做系统类型标志 sysinfo 用作标记系统状态列表标志 Driverlist 用作驱动版本类型标志 processlist 用作进程列表类型标志 servicelist 用作服务列表类型标志 Performancelist 用作性能标志 dumpfile 标记是否存在dump文件标志 qcloudservicestatus 标记QCloud服务状态标志 softwarelist 收集子机已安装的软件列表 firewalllist 收集防火墙规则 VPMInfolist 收集虚拟物理内存 logapinfo 收集应用程序日志 logsyinfo 收集系统日志 logseinfo 收集安全类日志 logsetinfo 收集设置、安装类日志 LoginAccountlist 收集当前登录的用户 GetDiskStatus收集当前磁盘状态 portlist 收集当前端口映射情况 uuid_flag uuid信息 ipaddress_flag 内网IP地址信息 plantasklist 收集计划任务列表 GetSpLoglist 收集特定日志信息 FileMD5list 收集特定文件MD5信息 GPOinfo 收集组策略信息 hdiskinfo硬盘硬件信息 hcpuinfo CPU硬件信息 hmeninfo 内存硬件信息 hbiosinfo 主板硬件信息 hraidinfo Raid卡硬件信息
今天我按照3个场景的涉及的标记为进行逐一解析,希望能够借助这个脚本来学习更多关于Windows Server的排错知识。
1、先从最少场景的选项“2”,说起,选项”2”,涉及的场景如下:
GetDVersion
GetGPOResult
GetProduct
GetFireWall
GetProcess
GetServe
GetPRS
GetFileMD5
GetVPMen
GetLoggedOnUserSession
GetPlanList
GetPort
GetDiskStatus
GetDumpFile
GetCloudInit
GetSpLogID
GetHardDiskStatus
GetHardCPUStatus
GetHardMenStatus
GetHardBiosStatus
GetHRaid
(一共涉及21项)
2、别看涉及的项目很多,但是实际上都是读配置操作,比较轻量,所以作者把它们归为“轻量收集”的场景“2”中,我们先来看看以下四个:
- GetDVersion
function GetDVersion () { "Driverlist ===<" | Out-File -Append ".\$Dirfilename\$Logfilename" "——————————以下为该机的驱动版本———————————— " | Out-File -Append ".\$Dirfilename\$Logfilename" Get-WmiObject Win32_PnPSignedDriver -ErrorAction SilentlyContinue | select DeviceName, DriverDate | where { $_.DeviceName -like "*Ethernet*" } | fl | Out-File -Append ".\$Dirfilename\$Logfilename" ">===" | Out-File -Append ".\$Dirfilename\$Logfilename" }
从代码上来看,是通过Get−WmiObject 来收集Win32_PnPSignedDriver这个类下的网卡驱动(从$_.DeviceName -like”*Ethernet*”可以看得出来),引用下官方对Win32_PnPSignedDriver这个类的说明:
The following syntax is simplified from Managed Object Format (MOF) code and includes all of the inherited properties. Properties are listed in alphabetic order, not MOF order.
说人话就是,只要是托管的MOF(https://msdn.microsoft.com/en-us/library/aa823192(v=vs.85).aspx)对象,都会被归集到这个WMI类中。
什么?你不知道啥叫MOF?我简单解释下,MOF其实就相当于Linux的module(KO),有同学说它是驱动,其实不一定全正确,实际上是包含了引导组件+配置文件+状态文件,对应在系统里,可能是ini文件,也可能是dll文件,然而这里工具作者用DeviceName -like”*Ethernet*”这个筛选,基本也就输出了网卡的驱动名称与驱动数据(什么?还听不懂,那就点击MOF那个链接去看看原版解释)。
那这里究竟获取这个网卡驱动版本有什么作用呢?我百思不得其解,因为对于IaaS层面来说,驱动都是直接由虚拟化层提供的,作为虚拟机层面,获取这个驱动其实没有太大意义,因为不像客户端一样,有各类的驱动可以选择,也不存在不标准问题。
直到我在腾讯云官网看到了这个公告:https://cloud.tencent.com/document/product/213/6399
豁然开朗,这里的网卡驱动版本应该是为了方便入门级用户去直接了当的知道自己的网卡驱动版本是多少,看看输出的结果:
嗯,确实也是简单明呢。
那对于普通的Windows Server运维者,这个收集有什么作用呢?
其实各虚拟化平台都有各自的驱动,比如KVM大部分采用的是Virtio驱动,VMware采用自家VMTools,微软采用Hyper-v集成工具(VMGuest.iso),这些的WindowsServer驱动其实都是在原生驱动上构造多一层“MOF”,但是毕竟物理特性与虚拟特性存在很多差异,所以版本迭代难免出现环境不统一问题(笔者以前从事系统集成工作时也踩过这类坑),那么这个收集做为驱动核查,一键获取网卡驱动版本还是极好的能够排除一些断网、网络性能不佳问题(比如把驱动版本号往各类官网KB库一搜基本都能搜出点问题方向)。
- GetGPOResult
function GetGPOResult { "GPOinfo ===<" | Out-File -Append ".\$Dirfilename\$Logfilename" Gpresult /r >> ".\$Dirfilename\$Logfilename" ">===" | Out-File -Append ".\$Dirfilename\$Logfilename" }
GPO有点像Linux中cront+local.rc+selinux+iptables部分功能的集合,在Windows Server体系里是一个举足轻重的角色,然而如果乱玩GPO,或者不理解“计算机配置”、“用户配置”之间的层级关系很容易就会出现系统奇奇怪怪的问题,gpresult是个很经典的命令加/r可以输出计算机中的当前应用的GPO策略。
然而,这个命令对于加入域的域成员机可能有问题,因为存在域权限问题,要知道加入域的域成员机GPO都是统一由域控(DC)统一下发并应用的,不过,按照国内云厂商以及IT环境,估计对于云上搭域这种玩法很少企业能玩得转吧。
说回这个GPO,几乎涵盖了所有WindowsServer系服务的控制,简单举一个利用这个GPO排错的例子
某一次我远程发现无法连接,通过日志排查到,最后发现是GPO里输出了这条:
所以才定位到原来某次误操作把GPO中的远程连接会话数限制了1次,所以当两个人同时进行连接时,另外一个人就无法连接
其实gpresult /r仅仅只能输出概述,更详细的应该使用gpresult /h,不过这个日志工具采用/r同时重定向输出到文本,加上标志位的输出,应该是为了符合某种扫描特征?毕竟基于html需要用到爬虫解析,而文本分析成本更低。
那么gpo策略究竟在Windows Server里应该如何排查呢?个人建议采用gpresult /h xx.html进行采集会得到详细的组策略列表,如果是登录问题,建议关注“远程桌面服务”相关的计算机策略。
- GetProduct
这个模块就非常有意思了,我一直想不明白一个IaaSCVM收集安装了什么软件有什么意义,直到最近我找了一线工程师看工单记录,发现大部分的性能、黑屏问题来源于第三方未认证或者桌面级软件不兼容导致(诸如360桌面版、腾讯电脑管家PC版、百度卫士等),这些桌面级的应用由于在开发时并没有面向企业级的(Server端)做开发,所以在客户触发某些条件后(比如修复xxx注册表)等,通常会因为Server与桌面端之间的细微差异导致服务器异常。
来看下GetProduct如何实现:
##获取已安装的软件 function GetProduct { "softwarelist ===<" | Out-File -Append ".\$Dirfilename\$Logfilename" "——————————$date : 已安装的软件列表如下 ———————————— " | Out-File -Append ".\$Dirfilename\$Logfilename" $InstalledSoftwareList = Get-WmiObject -Class Win32_Product $InstalledSoftwareList | Out-File -Append ".\$Dirfilename\$Logfilename" ">===" | Out-File -Append ".\$Dirfilename\$Logfilename" }
与获取网卡驱动版本一致,同样使用WMI接口进行获取软件安装列表(当然这也是业界较认可的方案),在Windows Server运维过程中,WMI接口的运用非常有用,特别是构建CMDB时,使用WMI接口可以获取到非常多底层信息,虽然很多硬件方面的接口信息跟Linux的lspci还是有一定差距,但是可获取的信息范围要比lspci广得多。Windows Server运维者可以利用这个接口,收集各类信息,这对于软件标准化(基线)非常有帮助,很多性能问题也是因为安装了非兼容软件出现的。
看下输出的结果信息还是比较有用,包括出品公司、版本以及认证ID:
- GetFireWall
防火墙,这个与Linux的Iptables对标有点弱鸡的功能,不过在用得好的情况下还是能够抵挡部分攻击的(比如前段时间出现的SMB漏洞),腾讯云日志收集工具用的是netsh advfirewall,也算是中规中矩,netsh advfirewall收集比较全面:
function GetFireWall { "firewalllist ===<" | Out-File -Append ".\$Dirfilename\$Logfilename" $firewallstate = netsh advfirewall show allprofiles state if ($firewallstate -like "*打开*") { "——————————$date : 防火墙状态 如下(请注意防火墙在关闭的情况下,规则无法生效) ———————————— " | Out-File -Append ".\$Dirfilename\$Logfilename" $afmrule = netsh advfirewall monitor show firewall "——————————$date : 防火墙规则 如下(请注意防火墙在关闭的情况下,规则无法生效) ———————————— " | Out-File -Append ".\$Dirfilename\$Logfilename" $afmruleall = netsh advfirewall firewall show rule all verbose $afmrule | Out-File -Append ".\$Dirfilename\$Logfilename" $afmruleall | Out-File -Append ".\$Dirfilename\$Logfilename" } else { "防火墙未开启,此项无需收集 " | Out-File -Append ".\$Dirfilename\$Logfilename" } ">===" | Out-File -Append ".\$Dirfilename\$Logfilename" }
可以看到是先判断是否有开启防火墙(吐槽下,腾讯云似乎默认创建Windows Server就是关闭了防火墙,不过在安全组的机制下,确实也能够理解),如果未开启就不会进行收集,从而避免了因为状态导致错误。
这里面核心的语句其实是:
netsh advfirewall firewall show rule all verbose
会将所有的防火墙规则列出来,相当于linux的iptables -nvl。
这里使用了这个收集后,防火墙规则情况清晰可见,Windows Server防火墙默认是deny all(与腾讯云安全组规则一致),通过白名单来进行管理放通的端口,所以常见的服务无法连接基本都是防火墙的问题(同时存在出入站方向),比如笔者以前在实践System Center时就经常因为防火墙的问题莫名其妙导致连接失败,Windows 防火墙的设计级别比较高,一般分为三种类型防火墙:域、专用、公用,视网络情况不同而不同应用范围,在域情况下是通过GPO进行控制,所以域成员机可能会显示防火墙被接管,所以域成员机出现问题时,可以直接排查域控(DC)的防火墙规则:
另外,IPSec Rule支持P2P、应用级别的安全规则,我看到工具里并没有涉及收集(这算不算一个BUG?哈哈),可以通过防火墙——高级设置,来检查是否存在端口、应用规则:
今天本来想要写场景2的所有模块,发现实在太多东西可以写了,担心篇幅太长影响阅读感受,所以将拆解后进行逐一模块解读,来为大家揭开腾讯云日志收集工具的这一利器的神秘面纱(好像也没做加密阿喂)。