[Windows]做一回自己电脑的明白人

Windows 7 已经停止更新,全球无数的 Windows 7 用户其实并不会随着微软的脚步而更新自己的硬件。Windows 10 对硬件的要求其实是很高的。 一般的 8G 内存的机器才能勉强胜任原来 Windows 7 4G 内存的机器,Win10 对 CPU 的要求更是让很多 Win7 用户抓狂。

怎样让自己的 Win7 跑得更快更安全?怎样确保之前卸载的软件,已经卸载干净?除了常规的三板斧,我们也需要明白 Windows 后面启动起来的资源。腾讯的电脑管家可以检测一部分不需要启动的服务以及任务,但是对于许多内核级的驱动,电脑管家无能为力。 Sysinternal 里有一个叫做 autorun 的工具,对于检查系统启动缓慢,可能的病毒加载是一个神器。当然使用这个工具,需要专业人员。非专业人员就算下载启动了这个工具,估计也是一头雾水。

下面的截屏,假定你已经下载并启动了 autorun,那么切换菜单里的 User ,分别检查 Logon Tab 里的内容,就可以看到每个用户(包括系统用户)可能启动的一些程序,其实你会非常震撼,原来你的系统启动了那么多乱七八糟的程序,你可以右键 Delete,或者直接按 Ctr-D 逐个删除。另外一个需要检查的地方是 “Drivers” tab,那里也是藏污纳垢之地,有些垃圾软件就是利用那个地方隐藏在系统的后面做一些龌龊的事情,例如 360,2345 之类的。当然,这些东西,你也不能乱删,最好先禁用,然后重启,如果重启正常,那就可以删除。 如果重启不正常,可以用 F8 , 恢复到上次启动正常,就可以继续启动,否则,需要用 Win PE 之类的工具修复。甚至重新安装 Windows 。

Windows 客户端从 DHCP 服务器上自动取 DNS 域名搜索后缀

先给答案:不可能
标题里说的事情,在 DHCP 服务器上叫做 Option 119 DOmain Suffix Search

Linux 上的 DNS 服务器 dnsmasq ,有一个 dnsmasq –help dhcp 命令,能输出所有的选项:

具体来说就是在 dnsmasq 配置上添加如下:总体上三行是等效的,加了 force 是强制 push.

然后在查看到这篇文章:
https://serverfault.com/questions/37417/which-dhcp-client-os-support-dhcp-option-119-domain-suffix-search
里面提到的的微软的链接里,提到微软其实是不支持的。

用 LLMNR协议实现 Windows 和 Linux 的统一访问

LLMNR 全称是 Link-local Multicast Name Resolution,微软 MSDN 上2010年的一篇文章有比较详细的解释。对于一个纯粹的 Windows 机器网络而言,IPv4 可以完全通过 NetBIOS over TCP/IP(NetBT) 实现,换言之, NetBT 是不支持 IPv6 的。

LLMNR有一个典型的应用是,在一个 802.11 无线临时网络里,在没有 DHCP 服务的情况下,相互之间能通过主机名访问。

LLMNR 采用和 RFC1035 规定的类似的DNS 消息通过 UDP 5355 端口通信。
RFC4795 规定了通过 TCP 5355 端口发送消息,但是 Windows(Vista) 不支持。

对于 IPv6 , LLMNR 通过 FF02::1:3 的多播地址,IPv4 是 224.0.0.252的多播地址。DNS解析启动时,主机会向网络广播自己的地址,如果没有冲突,就宣告自己为合法的主机名,如果有冲突,就会等15分钟继续广播查询。

非常幸运的是, Linux 的 systemd-resolved 也支持 LLMNR,但是不幸的是 CentOS7 还使用比较旧版本的 systemd (219),只有229版本以后才支持全功能。

具体而言就是配置文件 /etc/systemd/resolved.conf 只支持
DNS 和 LLMNR 以及 FallbackDNS 三个选项
这个可以通过运行 man resolved.conf 看到。而同样的,在 Ubuntu 1904 上,我们可以看到更多的配置选项, man 去看手册也有更多配置选项的介绍。

在 Ubuntu 上的配置是这样的:

我们内部有两台做加密 DNS 查询的安装有 dnsmasq + DNScrypt-Proxy 的虚拟机,Domains 是解析搜索的顺序,LLMNR 就是这里的主角,打开这个开关, systemd-resolved 服务就会启用 TCP/UDP 5355 端口。MulticastDNS 是多播,会和 avahi-daemon 冲突,由于我们计划使用 LLMNR,所以,多播包括 avahi-daemon 其实都是可以关闭的。

这样子,无论在 CentOS 7 上还是 Ubuntu 上,我们只要用 yum/apt install systemd-resolved 软件包后,根据自己需要修改好配置文件: /etc/systemd/resolved.conf ,然后 systemctl –now enable systemd-resolved 就可以实现 Linux 和 Windows 的无缝访问了。只要知道主机名就可以,无须理会 IP 地址,无须设置 DNS 服务器, avahi-daemon 的多播 DNS 也可以关闭(部分网关设备会开启 avahi-daemon 实现通过名字访问,苹果的机器也需要,所以可以根据情况决定是否关闭 Linux 上的 avahi-daemon)。

当然,事情绝对不会那么顺利,在 Ubuntu 上都能正常解析的主机名,在 CentOS 上都不能相互访问,原来是 /etc/nsswitch.conf 文件作怪。 Ubuntu 上的 这个文件, hosts 那一行非常简单:
hosts: files dns

但是在 CentOS 7 上,在安装有 avahi-daemon 后,这一行是:
hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname
在我们删除软件包 avahi-daemon 后,依然无解。正确的写法是:
hosts: files resolve [!UNAVAIL=return] dns

也就是说,CentOS 这里最大的坑就是 resolve 这个关键字! 没有这个关键字,系统是不会去走 LLMNR 解析的!!!

还有一个待解的问题,当操作系统是通过 dnsmasq DHCP 的 Linux ,通过 Windows 机器 ping 这些名字,都可以正常返回 IPv4 的地址,但是对于静态分配地址的机器,都只是返回 IPv6 的地址。

把一台联想 天逸 FM41M 的陈旧笔记本用 Ubuntu 1904 RDP 上 Win 10

有一台陈旧的联想 天逸笔记本电脑,只有 1G 内存,是 奔腾 Pro 的 CPU,开始是因为硬盘的问题,无法安装操作系统,更换硬盘后,虽然安装过程有点慢,但是还是顺利的安装上了 Ubuntu 1904,并启用了 GNOME 3的 Desktop。

接下来我们只要 apt install freerdp2-x11,就可以用 xfreerdp host_name 命令或者桌面点击就能远程进入任何已经开启 RDP 服务的 Windows 机器了。 如果在命令行下,可以先用 export DISPLAY=:0 输出 DISPLAY 环境变量。

老机器就能熠熠生辉了!

— 本文在 Linux 下的 Firefox 浏览器下输入

通过 Live CD/USB 做 Windows 10 的 P2V 到 KVM 上

上次说到把一块之前的 SATA 物理盘,通过 USB 物理挂接到 KVM Host 上实现 P2V,但是如果是一台远程的服务器,或者笔记本电脑,反正硬盘不能拆卸的情形下,我们怎样把硬盘里的操作系统克隆成虚拟机呢?

环境:一台 笔记本电脑上的 Windows 10 专业版,一台同一个局域网内的 Linux 机器(可以运行 nc 命令监听,有足够的磁盘空间)
工具:一个 8GB或者 16GB 的 U盘,刻录了任何 Linux 操作系统能启动安装就可以。

步骤:
笔记本电脑,从 U盘启动,进入 Linux 安装界面,不是真实的安装, 只要到检测到网卡,网络能工作就可以,然后按 Ctr-Alt-F3 或者 F4~F6,看自己喜欢。反正就是进入命令行界面。
确认能 ping 通 KVM 主机
# ping 192.168.7.100
没有 fdisk 命令,用 blkid 看下系统内的磁盘,然后 dmesg|grep sdX X 是看到的磁盘的字母 a 或者 b 或者 c 等,确定要克隆的设备名称,假定为 /dev/sda

在命令行下 运行
# nc if=/dev/sda |nc 192.168.7.100 6500
也就是把数据写往 192.168.7.100 的 6500 端口
这里的 nc 命令其实是 busybox 命令的昵称

然后在 KVM Host 上启动 nc 的 Listen:
# nc -l -p 6500 > win10_sda.raw
经过漫长的网络读写后,笔记本电脑上的 nc 会自动结束,标记 recrods in/out 的数据。
在 KVM Host 上,我们用 qemu-img info 查看写好的文件:

这个时候无需做任何的其他操作,我们只要把这个 raw Image 挂接为 ide 方式,就能直接启动了!

新问题来了,原始磁盘实际上我事先做了空间整理, 250GB 的 SSD,实际大概只使用了 90多GB,而且有一个分区都被我删除了。 但是导出来的 raw 文件还是 250GB,怎么办呢?

我们用 losetup -vf win10.raw 把 raw 文件做回环挂接, fdisk -l /dev/loop1 就可以看到原始的磁盘的分区信息了。 我们只要第一个分区的数据,所以用 dd 重新把 raw 文件写到一个新的 raw 文件:
dd if=win10.raw of=win10_shrinked.raw bs=512 count=xxxx
就可以得到一个实际原来分区的新的映像文件。

这样我们只要 virsh edit 用新的文件名替换原先的 raw 文件名,就能成功的启动 Win 10 了。
当然, 我们同时可以挂接 virtio-win 的 iso 映像,然后进入 Win 10 虚拟机更新 PCI/网卡/视频驱动。
但是 Win10 的视频驱动有问题, 不能识别, 需要 qxldod 驱动。
另外,原先的 License 都丢失了, 需要重新激活 Win 10. 🙁

我们可以通过 Windows 上安装的 virt-viewer 连接到 Spice 上,
输入 spice 连接为: 远程 KVM 主机 + 端口号(一般为 5900)
取决于你 虚拟机的 spice 设置,需要修改 listen 的地址 127.0.0.1 修改为 0.0.0.0,然后端口如果是默认的话,会自动启动新的端口,也就是说如果有10个虚拟机在跑,第一个是 5900,那么新开启的虚拟机 spice 端口就是 5901 了。
当然如果虚拟机 IP 地址已经拿到, 通过 RDP 到虚拟机的 IP 当然更方便。



wsl 就是个笑话

能进微软的人,大多是头脑聪明的。微软从来就是对 Linux 保持攻击的,最早的所谓 FUD 战术( Fear, uncertainty, and doubt ),就是针对 Linux 进行的。

今天想在 wsl 里面再测试一下 dnscrypt-proxy 的安装,没意识到服务安装以后,是不能通过 systemctl 启动的。微软连这些基本的东西都没有做好,怎么能让 wsl 继续跑下去?

Windows 10 专业版也可以开启 Hyper-V 功能,与其那样的话,还不如走 Hyper-V 创建虚拟机来得爽,不过 Hyper-V 和 Oracle VirtualBox 的优势又在哪里呢?

微软 Windows 10 以后就真没什么好玩的了? Linux 一统天下,连 Windows Mobile 也放弃了和 Android 的角逐。
Windows 10 IoT 版本又如何?微软带着沉甸甸的包袱,依赖着 Office 这架印钞机,撬动 Azure 云计算平台的轮子,总算在云计算上快步跑起来。

微软的下一个操作系统或许就是有 Linux 内核,Windows 外壳的平台。
我想多了。
但是 wsl 基本上是啥都不能干,微软为什么要花费人力物力浪费在上面?

强行删除 电脑管家的卸载程序里看到的旧软件名称

除了 腾讯电脑管家以外另外 安装两个工具 Windows Installer CleanUp Utility 和 CCleaner 。 有些旧的软件一种方法就是直接暴力删除目录,但是不见得管用。
前者是微软官方工具,可以直接删除一些不能卸载的软件,后者做注册表的清理比较好。 一般通过前者清理/删除后,通过控制面板卸载软件就不会看到旧的软件了, CCleaner 自带的也看不到了,CCleaner 也有删除功能,但是不一定都有效。但是有些软件很“顽固”,在电脑管家的卸载项里,一直存在,不能卸载。终极方案是进入注册表删除:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

解决以后,把后面安装的两个工具也卸载掉就完美了!

把2012年的一块 Windows 7 企业版 SATA 硬盘挂接到 KVM 下面

柳三变曾有词曰:“十年一觉扬州梦”,从中秋开始玩 KVM 兴起,老的 Desktop 容量太小,买大硬盘换上,抽屉里发现了几块之前的硬盘,用绿联的 SATA 转接 USB 的电缆,直接把盘连接到 KVM 主机上,变成一个移动硬盘。

# qemu-img convert /dev/sdb -O qcow2 /opt/vm/old_win7.qcow2
就可以把整盘(注意:必须是整盘 sdb 后面没有分区数字)转换成虚拟机的盘了。 也就是说一条命令就搞定了所谓的 p2v
其实还有另外的命令, 例如: virt-p2v-make-disk 可能更简单。

当然 Windows 直接做好的 qcow2 文件是不能启动的, 我们要借助 WinPE 工具,做引导区的恢复,这里就直接借用了老毛桃自带的工具,在创建虚拟机后,把老毛桃挂接为启动盘,启动老毛桃的 PE 环境,运行里面的 Win 修改工具,选择 原 Windows 的启动盘盘符,然后这个工具会做好 bcdedit ,等于修复了引导区。就可以从老的 Windows 启动了。

在启动之前,我们可以把老毛桃去掉,挂接 virtio-win 的 iso ,以及任意一个qcow2 磁盘,设置为 virtio ,把网卡驱动也设置为 virtio,启动虚拟机以后,把网卡,SCICI 硬盘的驱动都更新一下,整体的系统就可用了。 当然,Windows 的 License 只有三天有效期,这个以后分解。

原始的操作系统没有打开 Remote Desktop, 除了要打开服务,打开防火墙以外,还要运行 gpedit 修改 Policy ,配置“计算机配置\管理模板\Windows 组件\远程桌面服务\远程桌面会话主机\连接\允许用户使用远程桌面服务进行远程连接” 为已启用,就能实现远程 RDP 了。 以下的截图都是 远程 RDP 来的。

========= 欣赏 2012 年的 Desktop 的样子 =========


还有多么熟悉的 MSN 启动界面:

还有那些安装过的软件:

逝者如斯乎!

安装 Windows 7 到 KVM 主机上

通过 virt-manager GUI 创建一个 20GB 的 qcow2 格式的 Win7 OS Disk , 另外创建一个 20GB 的 qcow2 格式 (cache=none)的 Data Disk,后面可以格式化为 D 盘,系统里面当然是 NTFS 文件系统。
把 某 WinPE 的 8GB U盘,挂上,设置引导顺序为 U 盘先, 启动 机器,就和正常物理机一样 Ghost Win 7 ,然后安装 电脑管家,漏洞检测,安全更新,设置 Admin 密码,创建自己的用户账号,设置为管理员。

开启 Remote Desktop 服务(有三个相关的),确认一下 Windows 防火墙允许 Remote Desktop 的入站规则

RDP 默认不提供重启机器的功能, 需要手工敲 shutdown /r /t 0 可以重启机器。
按照以上设置, 直接做 Live Migration 也是杠杠的,大概会丢 40 个包,如果是 Linux 的机器, 只会丢 10-15个包。

本来以为 Win7 Guest 是要安装 libvirt 的guest 驱动的, 网络上确实有驱动,但是这个小的 iso 挂接到 windows 虚拟机里面,打开来是 windows 2008/R2 的驱动,也不知道怎么安装,反正挂接的 qcow2 磁盘映像只能用 IDE 接口,其他 SATA, SCSI,VirtIO 都不能用。

至于显示驱动,也没有看到特别的,好像一台 Dell 20 寸, 全屏支持到 1600×1200 也算可以了。

主板详情
芯片组 英特尔 440FX – 82441FX PMC [Natoma]


显卡详情
显卡名称 标准 VGA 图形适配器
显卡厂商 Red Hat, Inc.
驱动版本 6.1.7600.16385

CPU详情
CPU厂商 GenuineIntel
CPU (英特尔)Intel Xeon E312xx (Sandy Bridge, IBRS update)
CPU核心数 2
CPU默认频率 2492 MHz
CPU当前频率 2492 MHz
CPU序列号 xxxxxxxxxxxx
数据宽度 64bit
指令集 MMX,SSE,SSE2,SSE3,SSSE3,SSE4.1,SSE4.2,EM64T
扩展版本 Ext.Family 0 Ext.Model 2

扩充 C: 盘:

# virsh blockresize vm-win7-01 /opt/nfspool/vm-win7-01.qcow2 30G
启动 Windows 虚拟机,运行磁盘管理 diskmgmt.msc 选择扩展卷,就可以了!

作为开发人员, 必安装的 Cygwin(apt-cyg), , 微信开发者工具 ,其他PHP/Nginx/Python 都可以通过 apt-cyg 安装。
一个标准 Windows 操作系统模版需要安装的基本软件,除了 Chrome, WeChat 以外,还有以下截屏里的软件:
7zip, Xmind, Foxit, Git, VSC, TIM, Notepad++, 另外 Free Download Manager 也是必装, 另外 还可以安装 SysinternalsSuite (里面有个 psgetsid 是可以读取机器的 SID的) 可以解压到 c:\tools 下,把 C:\tools 添加到路径, 运行 c:\tools\procexp64.exe 在 Options 菜单下,选择 “Replace Task Manager”
当然还要安装好办公室内的默认打印机
Bonjour Browser 是查看局域网内 Bonjour 服务的工具,也可以下载安装一下。

Windows Guest 会遇到重启后时钟默认使用 UTC ,要通过 virsh edit 设置
<clock offset=’localtime’>
clock的offset属性有”utc”,”localtime”,”timezone”,”variable”四个可选项。
如果guest OS是Linux系统,应该选用”utc”,guest OS在启动时便会向host同步一次utc时间,然后根据/etc/localtime中设置的时区,来计算系统时间。如果guest OS是windows系统,则应该选用”localtime”,guest OS在启动时向host同步一次系统时间。


另外如果时钟不同步,解决的办法是 boot.ini 添加 /use pmtimer 选项, 但是 Windows 7 没有 boot.ini 文件。参考红帽子的文章

在 Windows 7 虚拟机里执行:(*BCD= Boot Configuration Data )
$ bcdedit /set {default} USEPLATFORMCLOCK on
The operation completed successfully.
把系统时间同步成北京时间后,重启即可。

另外, 在 KVM Host 上执行
# virsh dumpxml win7_vm_domain_name |grep timer
留意 track=’guest’ 选项

<timer name='rtc' tickpolicy='catchup' track='guest'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>

Win7 安装 Guest 驱动 virtio-win , Ubntu 上没有搜索到相关的直接的驱动下载,但是 RHEL Fedora 都有提到。 Fedora 那个页面上直接下载 300M 左右的 iso 也可以。我们把 iso 放到 Ubuntu 上的 nfspool 文件夹里。 让已经安装好操作系统的 Win7 VM 在命令行里挂接 iso 文件, 有点小困难。 最后还是 virsh edit vm-win7 来添加驱动的。 基本上就是添加一个光驱类型如下:

然后修改 其他非操作系统启动盘的 dev=”hdb” 修改为 “vdb”,bus=”ide” 修改为 bus=”virtio”, 注意, 这个只是修改非系统的硬盘(假定你有这样的盘,如果没有的话,可以添加一个小的例如只有 1GB 的盘,只是为了后面让操作系统识别 virtio 的磁盘),然后把网卡的驱动也从 e1000 修改为 virtio。
Win7 Guest 启动后,就能找到新的 PCI/网卡 ,原先的D盘不能识别,更新驱动,找到 挂接在 CDROM 上的驱动,例如(E:\),全盘含子目录搜索驱动,更新完驱动后,就可以看到原先的第二硬盘也识别了。 查看网卡, 可以看到网卡支持速度变成了 “100Gbps”,简直飞起,驱动变成了 Red Hat VirtIO。接下来当然是关机,继续修改 XML , 把第一块操作系统硬盘的驱动也从 ide 修改为 virtio,操作系统就可以正常启动了。 根据说明,这个 Win7 虚机简直获得了物理机的性能。

关于 Machine Security ID (SID) , 微软官方博客有一篇不错的解释

对于 Windows 7, 我们要使用 The Windows® Automated Installation Kit (AIK) for Windows® 7 来用 sysprep 准备 Win7 的模板,否则直接克隆的 Win7 虚拟机会有一样的 SID,有很大的安全隐患。
这部分的文档,微软已经有描述,实际上十分简单。我们有了第一个通过 U盘或者光盘安装好的 Windows 7 并打好补丁,安装好了各种需要的应用和用户,直接运行文档里的 Step 2 的第4点, c:\windows\system32\sysprep\sysprep.exe /oobe /generalize /shutdown ,大概 5-10分钟之后,模板虚拟机自动关机,我们就得到了一个需要初始化的模板机器可以克隆了。如果没有设置 Answer File, 我们只要拿着这个 sysprep 之后的 qcow2 虚拟机文件,Host 上运行 virsh vol-clone,然后 virsh define 一个虚拟机用这个克隆以后的虚拟机映像,启动新的虚拟机,启动以后,只要回答几个简单的问题,就得到了一个有新的 SID 的 Windows 7 虚拟机。

在我写完这篇文档的时候,发现6年多前有人就回答了这些问题。 🙁

所以 KVM 自带的 virt-sysprep 工具,只能也只会去 配置非 Windows 的系统,也可以理解了。 因为只有 Windows 的系统,自带了 sysprep 工具,只要一个安装好的 OS,运行一次 sysprep 就成为一个模板(原先的网络配置都会去掉),以后就一直 clone 这个模板即可,克隆出来的机器,经过简单设置后,具有新的 SID。
而 对 Linux 而言,任何虚拟机映像都可以成为模板,而且可以随时 clone,只要运行一下 virt-sysprep 即可。

在 Linux 上跑 Windows 7 的梦想终于实现了, 原先一机多屏,仍旧可以通过 RDP 实现,在 Windows 上 RDP 去远程的 Windows 机器, 用 mstsc /multimon 命令, 在 Linux 上有一个 freerdp 的工具, xfreerdp /multimon 也一样可以实现,一机多屏,当全屏幕多屏运行 Windows 时,别人不会知道你的Windows 原来是运行在 Linux 上。除非你按 Ctrl-Alt-Enter 退出全屏。