Wine

简介

Wine 是在x86、x86-64容许类Unix操作系统在X Window System运行Microsoft Windows程序的软件。另外,Wine也提供程序运行库(Winelib)来帮助计算机程序设计师将Windows程序移植到类Unix系统;也有不少软件经过Wine测试后发布,比如Picasa、uTorrent、MediaCoder。

Wine通过提供一个兼容层来将Windows的系统调用转换成与POSIX标准的系统调用。它还提供了Windows系统运行库的替代品和一些系统组件的替代品。为了避免著作权问题,Wine主要使用黑箱测试逆向工程来编写。

Wine最早是“Windows Emulator”,即Windows模拟器的缩写,但Wine现在为“Wine Is Not an Emulator”的递归缩写,即Wine不是模拟器。Wine的正确名称是“Wine”,而不是全大写或全小写。

Wine计划在1993年由Bob Amstadt及Eric Youngdale发起,最初目的是为了让16位Windows 3.1程序可以在Linux上执行,但随着电脑和时代的演进,Wine也一路支持到更新的Windows和64位的计算机体系结构。

由于Windows的DLL为封闭源代码,所以程序员只能由最底层的设计开始,耗费大量的时间来编写和测试,最后达至兼容,这过程是困难且缓慢的。

在1999年期间,当Corel加入这个计划后,Wine很快便能兼容WordPerfect Office,但Corel不久便停止支持这项计划,所以Wine的发展又逐渐趋缓,一直到2006年Google积极参与这个计划后,Wine的发展才又恢复起色,最后终于在2008年发布首个稳定版,其后便以每两周发布一个新版的速度发展着,除此之外,Google每年所举办的夏日代码大赛活动也对Wine有着不少贡献。

Wine虽然是从Linux开始发展,但现在已经支持多种平台,有BSD、Mac OS X与Solaris-x86,在2013年的自由及开源软件开发者欧洲会议上,Wine的项目领导人Alexandre Julliard(英语:Alexandre Julliard)表示目前将积极支持Android平台。

在2008年,Wine已经能够完美运行很多知名程序,例如Lotus Notes及Microsoft Office 2007,Photoshop CS2,但其可靠性及稳定性仍有待改善。如果该程序包含本地的微软Windows系统的库,那样Wine便可很顺利运行该程序。

有些Wine DLLs亦已能完美地取代Windows原来的DLLs,使得有些程序可完美运行。

最晚到2006年,Wine上面已经可以完全基于Wine DLL完美地运行暴雪发行的多款3D游戏了,如魔兽世界、魔兽争霸等。

:以下如果使用zsh,~ 应替换为 $HOME才能正常使用

安装

Here the difference between the packages:

  • winehq-staging: this is the most recent testing wine version.
  • winehq-stable: this is the current stable wine version (probably the one you should install)
  • winehq-devel: this package is used to provide development headers, mostly used by third party software compilation.
  • wine-development: unsure for this one, but probably helps wine developers to debug EXE running with wine with more debug information.

使用 wine 的 tuna mirror 安装最新版本

如果您之前安装过来自其他仓库的 Wine 安装包,请在尝试安装 WineHQ 安装包之前删除它及依赖它的所有安装包(如:wine-mono、wine-gecko、winetricks),否则可能导致依赖冲突。

如果您使用的是 64 位系统,请开启 32 bit 架构支持(如果您之前没有开启的话):

# Verifying you have 64-bit kernel architecture.
$ dpkg --print-architecture
# Verifying you have multi-arch support enabled. 
$ dpkg --print-foreign-architectures
# Enabling multi-arch support.
$ sudo dpkg --add-architecture i386 
$ sudo apt update

下载添加仓库密钥:

$ sudo wget -nc -O /usr/share/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key

并添加 Ubuntu 22.04 仓库:

$ sudo vim /etc/apt/sources.list.d/winehq.list
deb [arch=amd64,i386 signed-by=/usr/share/keyrings/winehq-archive.key] https://mirrors.tuna.tsinghua.edu.cn/wine-builds/ubuntu/ jammy main

安装:

$ sudo apt update
$ sudo apt install --install-recommends winehq-stable

配置

配置Wine的方式通常有:

  • winecfg是Wine的图形界面配置程序。控制台下调用$ winecfg(或指定系统目录:$ WINEPREFIX=~/.系统目录 winecfg)即可启动
  • control.exe是Windows控制面板的Wine实现,通过$ wine control命令启动
  • regedit是Wine的注册表编辑器,比较前两者,该工具能配置更多东西。部分常用键值参见:WineHQ’s article on Useful Registry Keys

初始设置

通过全局菜单,应用程序 - >附件 - >终端 ,输入命令: winecfg 这将在你的家目录中创建一个隐藏文件夹(.wine),其中包含类似于在Windows中的虚拟C:驱动器以及注册表文件。一旦该目录中创建完,wine配置窗口将出现。该窗口将允许您定制wine的各种设置,其中包括Windows版本,DLL替换,显示设置,驱动器映射,以及应用程序的特定设置。单击OK按钮关闭该窗口。

WINEPREFIX

Wine默认将配置文件和安装的Windows程序保存在~/.wine。这样的目录称为一个"Wine prefix"或"Wine bottle"(下文称“系统目录”)。每次运行Windows程序(包括内置程序,如winecfg)时,系统目录会自动创建(如果缺失)或更新。系统目录中存放有文件夹 ~/.wine/drive_c 相当于Windows下C:\C盘(更确切的说应是系统盘)。

通过设置WINEPREFIX环境变量,可以更改Wine系统目录的位置。如果希望让不同的Windows程序使用不同的系统环境或配置,这一变量会非常有用。建议把你安装的不同的Windows程序分给不同的WINEPREFIX,便于打包和隔离。当你要启动这个Windows程序前也记得要设置WINEPREFIX。

例如,如果您使用 $ env WINEPREFIX=~/.win-a wine-A程序.exe参数来运行一个程序。另一个使用 $ env WINEPREFIX=~/.win-b wine-B程序.exe参数,这两个程序将使用独立的C盘和注册表配置。

以下命令会建立一个默认的系统目录,且不启动任何Windows程序:

$ env WINEPREFIX=~/.customprefix wineboot -u

WINEARCH

这个WINEARCH 决定了你模拟的Windows是32位或是64位的x86。对应的值为win32及win64,如果你的Unix系统是64位的它就默认是win64。

发行版所提供的wine一般都有32位及64位两个包,直接对应所模拟的Windows位数,包里面的Unix二进制及运行库也都是对应位数。

对于64位用户,默认创建的系统目录是64位环境的。若想使用纯32位环境,修改WINEARCH 变量win32为即可: $ WINEARCH=win32 winecfg这样就会生成32位Wine环境。若不设置WINEARCH得到的就是64位环境。

通过WINEPREFIX变量,在不同的系统目录分别创建32位和64位环境:

$ WINEARCH=win32 WINEPREFIX=~/win32 winecfg
$ WINEPREFIX=~/win64 winecfg

注意: 系统目录创建过程中,64位版本的wine将视全部目录如同64位系统目录,也将不会在已存在的目录中创建任何32位的。创建32位系统目录,您必须让Wine创建指定的WINEPREFIX目录。

winetricks也接受WINEPREFIX变量,以安装Steam为例:

$ WINEARCH=win32 WINEPREFIX=~/.local/share/wineprefixes/steam winetricks steam

编辑 ~/.bashrc,使得 WINEPREFIX 和 WINEARCH 永久生效

export WINEPREFIX=$HOME/.config/wine/
export WINEARCH=win32

图形驱动

你需要安装32位的显卡驱动。缺少或未能正确配置驱动的一个标志是 Wine 在终端窗口里报告如下内容:

Direct rendering is disabled, most likely your OpenGL drivers have not been installed correctly

注意: 在安装对应的库以后,你可能需要重启 X

声音

Wine程序有可能遇到某些声音问题。首先,确保winecfg中只启用了一种声卡驱动。目前,Wine对Alsa的支持最好。

MIDI 支持

MIDI 是九十年代非常流行的游戏声音系统。如果你尝试运行老一点的游戏,音乐无法开箱即用的情况并不罕见。 Wine 拥有非常优秀的 MIDI 支持。但是首先你需要确保 Wine 会使用正确的 MIDI 输出。详细设置参考 Wine Wiki

中文字体

注意字无法显示和显示为乱码是不同的症状,如果看到乱码,请确保系统语言和运行Wine时的语言环境一致。如果有汉字丢失或显示为方框,请继续字无法显示。

显示为乱码

如果安装的系统LANG不为zh-CN,那么wine运行程序的默认语种也不会是中文,这可能导致一部分乱码。解决这个问题,用如下命令运行程序:

$ env LANG=zh_CN.UTF-8 wine example.exe

字无法显示

将中文字体copy到对应wine的目录下的drive_c/windows/Fonts/

在wine目录下任意位置添加modify_font.reg文件:

REGEDIT4

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink]
"Lucida Sans Unicode"="msyh.ttc"
"Microsoft Sans Serif"="msyh.ttc"
"MS Sans Serif"="msyh.ttc"
"Tahoma"="msyh.ttc"
"Tahoma Bold"="msyh.ttc"
"msyh"="msyh.ttc"
"Arial"="msyh.ttc"
"Arial Black"="msyh.ttc"

msyh.ttc改成自己想改的中文字体。

在wine命令提示符运行:

$ regedit modify_font.reg

启动器和菜单

Wine不会为内置程序(如winecfgwinebrowser)创建桌面启动器和菜单项。但手动安装的Windows程序通常会自动创建启动器和菜单项。在Windows下,安装程序(如setup.exe)通常会在桌面和开始菜单建立快捷方式,而Wine下会创建遵循freedesktop.org规范的.desktop文件(即启动器,相当于快捷方式)。

提示: 如果启动器没有自动创建,或者这些文件丢失了,可以尝试使用winemenubuilder修复。

Gnome3 中清理 Wine 菜单启动项

系统全局的菜单启动器安装在 /usr/share/applications/,清除相应程序的“.desktop”文件即可从整个系统删除该启动器。

如果这样还是无法解决问题,那么很可能 Wine 的启动器存放在用户级别的 ~/.local/share/applications/wine/Programs/ 目录中。删除相应的“.desktop”文件即可清理对应启动项。删除整个 Programs 文件夹将清理所有 Wine 程序的启动项。

安装/运行/卸载 Windows 程序

警告: 千万不要以root身份运行Wine!详情参见本文

使用wine安装应用程序,可以按照以下步骤:

  1. 从某个地址下载Windows应用程序.exe(可执行文件).
  2. 把它放在一个方便的目录(例如,桌面或个人文件夹)
  3. 打开终端,并且切换到.exe文件所在的目录。
  4. 输入命令 wine application-name.exe

这将使用Wine启动.EXE。如果它是一个安装程序,它应该像在windows一样的运行。如果应用程序要求目录来安装应用程序,选择把它放在 C:\Program Files 。

运行Windows程序格式为 WINEPREFIX="wine配置文件存放地" wine [路径]程序.exe 参数 ,如:

$ wine notepad.exe c:/abc.txt
$ wine notepad.exe ~/.wine/drive_c/abc.txt

路径可以是Unix路径,也可以是(在有WINEPREFIX情况下的)Windows路径,wine会自动判断。

对wine来说,你Unix系统里的其他文件(即模拟的C盘之外的文件)的Windows路径都以Z盘开头:

$ wine notepad.exe z:/home/username/.wine/drive_c/abc.txt

内置的msiexec程序可以运行MSI安装包:

$ [wine] msiexec /i path_to_msi

还可以通过在终端运行 winefile 使用 Wine 文件浏览器。

在某些情况下,应用程序需要被从一个特定位置上运行。在这种情况下创建命令启动

$ sh -c "cd /home/USER/.wine/drive_c/Program Files/APPDIR; wine game.exe"

wine uninstaller 这将打开一个类似于Windows的程序“添加/删除程序”控制面板,让您卸载wine安装的应用程序。通过 wine 直接运行卸载程序也应该正常工作。或者,您也可以简单地删除应用程序的文件夹。

技巧

提示: 此外您可能会感兴趣以下文章的开始所提供的链接

  • Wine程序数据库 (Wine Application Database, AppDB) —— 特定Windows程序的Wine兼容情况(运行时的已知问题、用户评分、指南等等),Rating一列由运行结果好到坏为Platinum、Gold、Silver、Bronze、Garbage,无近期结果或近期仍然Silver以下的就放弃吧。
  • WineHQ论坛 —— 要是看完上述网页还有问题,可以到这里咨询

OpenGL 模式

很多游戏(比如魔兽争霸啦)都支持OpenGL模式,在Wine下可能比默认DirectX模式性能更好。一般添加-opengl启动程序即可,但不同程序可能有所不同

$ wine /path/to/3d_game.exe -opengl

请参考AppDB,了解特定程序的相关信息。

Wine 控制台

有些时候,可能需要运行.exe给游戏打补丁,比如给古董游戏添加宽屏支持。这时直接通过Wine运行可能没有用。那么,打开终端,运行一下命令:

$ wineconsole cmd

将进入一个和Windows下cmd一样的命令行环境。在该环境下试试也许就可以了。

winetricks

使用Winetricks快速脚本,能够方便地安装许多Windows组件,包括DirectX、msxml(被Office 2007、IE浏览器依赖)visual运行库还有其他更多的。

使用 Ubuntu 仓库版本

$ sudo apt install winetricks

使用 Github 安装最新版本

$ cd "${HOME}/.local/bin"
$ wget  https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
$ chmod u+x winetricks

可以用winetricks list-all来看看它支持什么,也可以从该脚本中搜索下载链接 load_packagename

Using winetricks

获得 winetricks 后,您只需在控制台输入sh winetricks即可运行它。如果你先chmod +x winetricks ,你也可以使用./winetricks。如果不带参数运行,winetricks 会显示一个带有可用包列表的 GUI。如果您知道要安装的软件包的名称,可以将它们附加到 winetricks 命令,它将立即开始安装过程。例如,

$ sh winetricks corefonts vcrun6 

将安装 corefonts 和 vcrun6 软件包。

所有 Wine 命令一样,winetricks 知道 WINEPREFIX 环境变量。

$ env WINEPREFIX=~/.winetest sh winetricks mfc40 

拥有多个 Wine 版本的用户可以指定 winetricks 应该使用哪个版本

$ env WINE=~/wine-git/wine sh winetricks mfc40 

使用 ~/wine-git 目录中的 Wine 安装 mfc40 包。

Mono & Gecko

Mono 是 .NET Framework 的开源和跨平台实现。Wine 可以使用 Windows 构建的 Mono 来运行 .NET 应用程序。

Wine 实现了自己的 Internet Explorer 版本。该实现基于Mozilla 的 Gecko Layout Engine的自定义版本。

USTC MIRROR 分别下载对应的版本,放入~/.cache/wine就可以了,比如 wine 7.0.1wine-mono-7.0.0-x86.msi

CrossOver

CrossOver是Wine的付费、商业化版本,提供更全面的终端用户支持。它包括脚本、补丁、GUI和可能永远不会被Wine项目接受的第三方软件。这种组合使得那些不太懂技术的人运行Windows程序变得相当容易。

首先在 CrossOver 下载 .bin 安装包,然后要把 .bin 文件设置成可执行的:chmod u+x crossover.bin,接下来运行该文件:./crossover.bin

无限试用

crossover 有15天的试用期,crossover的时间验证信息写在每一个winebottle容器中,相互是完全隔离(不是写在全局配置中)。即使一个容器过期了,依然可以创建新的容器,并重新计算试用期,所以不需要重装软件本身。

即使重装程序,已经过期的容器依旧不能用,不过可以删除该容器,或者删除容器下的.eval文件。

/usr/bin/rm ~/.cxoffice/**/.eval

Tutorials

相对于 wine 而言,CrossOver 更加简洁方便,全程使用 GUI。

在 Select Application 的时候,即使列表中没有列出你需要安装的 Windows 软件,依旧可以尝试使用默认的 Unlisted application,如一些 roguelike、galgame 游戏是可以直接运行的。

如果无法运行:

  • 确保已安装破解补丁。有的破解组安装程序不会自动或者提供选择框来安装,需要手动覆盖。
  • 如果报错缺少dll,这时就在网上查找一下,比如 sskin.dll,如果教程使用的 winetricks,则可以在 winetricks/files/verbs/all.txt 找到具体的依赖名称,如 Visual C++ 6 SP4 libraries,然后可以在 Select Application 输入依赖名来安装,如果下载慢,也可以通过软件显示的下载链接直接下载。
  • 如果什么错也没报,那么就需要参考 Unsupported Troubleshooting 安装依赖或配置 winecfg,确保在安装游戏的时候没有选择升级依赖(比如 DirectX )并且之后安装了必要的依赖项。推荐游戏自带的 CommonRedist 或在 WineHQ - Browse ApplicationsPlayOnLinuxPCGamingWiki 上找依赖,可以但不推荐在虚拟机中运行一下看报错。
  • 如果先是正常运行,之后 wine 报错 page fault 退出,那么可以参考 Gathering debug logs in Crossover Linux 创建 crash log。

凡是依赖解决了,游戏一般是能够运行了,但是运行的好不好,有没有bug就不敢保证了,比如 Skul - The Hero Slayer 是可以直接运行的,但是无法正常显示血量,即使重新安装依赖也是如此。

以下测试的是运行游戏所必须的依赖:

  • Sekiro Shadows Die Twice

    • Microsoft Visual C++ 6.0 (4.2 & 6.0) Redistributable
  • The Elder Scrolls V Skyrim Special Edition

    • DirectX for Modern Games
    • 使用 SkyrimSELauncher.exe 配置,使用 SkyrimSE.exe 启动
  • Life is Strange - Before the Storm

    • 先安装下面两个依赖,如果 FitGirl 报 Getting unarc.dll returned an error code -6,就 try using the set memory limit to 2 gb option;如果是 Miss files,那么就重装。
    • Microsoft Visual C++ 6.0 (4.2 & 6.0) Redistributable
    • DirectX for Modern Games
    • 游戏需要加载一会儿,这个时候屏幕没反应。
  • NieR - Automata

  • Dead Cells

    • 参考 [playonlinux/dead cells](playonlinux/dead cells) 的 SourceCode 安装依赖后能够运行
    • DirectX for Modern Games
    • OpenAL,安装后要在 Wine Configuration > Libraries 中添加 openal32(不加,点击无反应、闪退)(Libraries 中是运行时自动加载进来的库,而需要的 openal32 没有自动加载进来,因此手动添加)
    • Microsoft Visual C++ 6.0 (4.2 & 6.0) Redistributable
  • The Binding of Isaac Rebirth Repentance

  • Valiant Hearts The Great War

    • Copy over the cracked content from the /Crack directory on the image to your game install directory manually.
  • DARK SOULS REMASTERED

    • 更改语言:In the game installation folder find the “steam_emu.ini”, open it and find the line with language, change it to schinese.(在 font 目录可以找到所有语言)
  • Braid

    • DirectX for Modern Games
  • Dying Light Platinum Edition

    • Microsoft Visual C++ 6.0 (4.2 & 6.0) Redistributable
  • Hearth Stone

    • DXVK
  • Undertale

  • Warm Snow

    • DirectX for Modern Games

DXVK

DXVK provides a Vulkan-based translation layer for DXGI, D3D10 and D3D11, which can be used on Linux with Wine.

游戏使用 Vulkan 将获取更好的性能,为使用 Vulkan,需启用 DXVK

打开 System Information,如果在属性下找到了 “vulkan.present”=“yes”,则表示支持 vulkan 并可以安装 DXVK。

  • 使用 CrossOver 安装:

    像安装普通软件那样,在 Select an Application to install 搜索并选择 DXVK (Upstream) 安装——DXVK (Builtin) 可能会导致游戏无法运行。安装后就自动启用了,也可以通过右键一个 Bottle>Settings>DXVK Vulkan backand for D3D11(Custom) 启用。

  • 手动安装:关键在WINEPREFIX环境变量

    $ env LANG=zh_TW.UTF-8 WINEPREFIX=~/.wine-battle.net WINEARCH=win64 ./setup_dxvk.sh install
    

Esync

注:Some Windows applications will not work correctly which ESync enabled. 例如 My Friend Pedro 开了后闪退,应该先保证正确运行,再考虑提升性能。

What is “wine esync” and how should I set it up?

the thing with Far Cry 4, 3 and Primal also Dirt Rally in wine is that it massively loads wineserver and synchronizing all the time, so it is stuck at around 20 fps on ryzen, all those games mentioned. with esync, wineserver is skipped for synchronizing and eventfd is being used, thus increasing performance that much. Games that are CPU bound with wineserver having huge load (wineserver is singlethreaded) benefit the most of this

What is the function of esync? Why most games need it disabled?

The function of esync is to provide lightweight thread synchronization facilities (events/semaphores/mutexes) so that game code that uses them heavily will run faster.

It does this using a linux-specific facility called eventfd, which is built around file descriptors. These are a limited resource normally not needed in large quantities, and therefore traditionally made available to a process only in moderate quantities. This helps prevent runaway processes and malicious code from consuming so many descriptors that none are left for other processes (a denial of service).

Therefore, when a game that uses tens of thousands of thread synchronization objects is run with esync, it will fail unless the system’s per-process file descriptor limit is much higher than the traditional default. Some linux distributions have already adopted a high default, while others still default to a thousand or so. That’s why these games run fine with esync on some distributions but fail on others unless the system’s DefaultLimitNOFILE setting is increased.

Edit: If you’re interested in esync technical issues that are not distribution-specific, check out this comment.

HowToEsync

What is Esync?

Esync removes wineserver overhead for synchronization objects. This increases performance for a lot of games, especially ones that rely heavily on multithreading.

A more detailed explanation can be found here.

How to check Esync compatibility

Systems using Systemd 240 and newer are already compatible with Esync.

If you’re unsure that your system is compatible, run the ulimit -Hn command. If the value printed is equal to or greater than 524288, then your system is Esync-compatible.

How to make your system Esync compatible

If your system is not Esync-compatible (ulimit -Hn, which prints the limit for number of opened files for a process, prints a value lower than 524288, like 4096), you have 2 different methods of solving this problem. Which method is preferable depends on the distribution currently in use. Applying both methods should have no negative side effect.

  1. Modifying Systemd configuration

This method applies to Ubuntu and other systems using systemd. You (with root privileges or sudo) need to edit both /etc/systemd/system.conf and /etc/systemd/user.conf by adding DefaultLimitNOFILE=524288. If DefaultLimitNOFILE= already exists in both system.conf and user.conf, add 524288 after = and make sure to uncomment the line (remove the # in the beginning of the line) to make it functional.

Once the files are edited, restart your computer for the changes to take effect. To verify if the limits were applied, run ulimit -Hn to see 524288 being reported.

If the value printed still says something like 4096, try the ulimits method below.

  1. Modifying ulimits.conf

On Linux distributions not using Systemd or distributions using pam-limits.conf (Arch Linux, Fedora, Solus,… ), you (with root privileges or sudo) need to edit /etc/security/limits.conf.

Change username to your actual username. Once the file is edited, reboot for the changes to take effect, and verify by running ulimit -Hn to see the new limit (524288).

username hard nofile 524288

语言设置

:某些游戏会因为语言设置而无法运行。

修改步骤:打开容器 C:Drive,返回到顶层文件夹(即容器名称),即可找到cxbottle.conf,在文件最后面添加如下内容:

[EnvironmentVariables]
"LANG" = "zh_CN.UTF-8"

也可以像安装软件那样,在搜索框里搜索 “chinese”,然后选择 “Setting bottle’s language to Simplifiled Chinese”

Third-party apps

Bottles

Proton

How To Use Steam Proton To Play Windows Games On Linux?

Enabling the Proton

  1. Fire up the Steam app from the app menu.

  2. In the top-left corner of the app, click on Steam and then click on Settings.

  3. In the sidebar, find and click on Steam Play.

  4. Click Enable Steam Play for supported titles and Enable Steam Play for all other title options.

Can I Install Non-Steam Games Using Proton?

  1. Download the official launcher
  2. “Add non-Steam game…” -> Show all files -> Select the launcher executable -> Done
  3. Setup proton (if not done using global settings)
    • Navigate: Gear icon -> “Settings” -> “Compatibility”
    • Check “Force compatibility layer …”
    • Select Proton 5.13 or newer
  4. Update the target. Gear icon -> “Settings”:
    • Target: explorer.exe
    • Execution directory: /path/to/your/gi/installation/
    • Start options: /desktop=anyname,1920x1080 cmd /c launcher.bat
    • Adjust the screen resolution above, if necessary.

PlayOnLinux

Lutris

可以参考其安装脚本。

实例

HearthStone

如下 wine 7、英文界面、国际服(亚服)直接运行成功:

$ env WINEPREFIX="$HOME/.wine-hearthstone" wineboot --init
$ env WINEPREFIX="$HOME/.wine-hearthstone" winetricks win10
$ env WINEPREFIX="$HOME/.wine-hearthstone" winetricks --force dotnet48
$ env WINEPREFIX="$HOME/.wine-hearthstone" wine Battle.net-Setup.exe

Office 2013 Pro

:在安装前先在 AppDB 中查找要安装的应用,在 Test Results 部分有相关教程,如 Microsoft Office 2013 Test Results

:要提高安装成功率,第一,不同 wine 版本安装结果是不同的,AppDB 有相应的信息;第二,winetricks 如果提供安装镜像的话,一定要用该镜像,winetrics 是一个很大的脚本,打开脚本搜索 office2013pro 即可找到官方镜像下载链接;第三,如果第一次安装失败,可以再尝试安装一次。

I installed office 2013 and I used to get a black window after starting it up. I fixed the black screen by following the solution posted in the [WineHQ-Forum](https://forum.winehq.org/viewtopic.php?f=8&t=28446&p=109296&hilit=office 2013#p109284).

Here’s what I did:

Install Components

$ sudo apt install winbind cabextract

Create Clean 32bit Prefix for Win7

Crete a clean 32 bit prefix and start up winecfg:

$ env WINEPREFIX=~/.wine-office2013pro WINEARCH=win32 winecfg

In the winecfg applications tab select “Windows version: Windows 7” Close wine config and install winetricks

Install Libraries

Then start winetricks for your prefix

$ env WINEPREFIX=~/.wine-office2013pro WINEARCH=win32 winetricks

accept “select the default wineprefix” with OK. Now, select “Install Windows DLL components” and go and install msxml6(这个时候会下载 msxml6,可以手动下载后移动到~/.cache/winetricks中)

To fix the problem in PowerPoint (not enough memory), I added two overrides with winecfg in Library section: “riched20” and “usp10”.

如果是中文软件需安装中文字体。

在这里我直接使用 winetrics 成功安装 office2013pro(wine 6):

$ env WINEPREFIX=~/.wine-office2013pro WINEARCH=win32 winetricks office2013pro

这样下面步骤不需要了。

Fix Black Window

In order to fix the black window that impedes Office 13 to be used, add the HKCU\Software\Wine\Direct3D\MaxVersionGL new DWORD value 30002 (hexa) to the registry.

Here’s how to do this: In Winetricks select Run regedit and wait for the Registry Editor window to open. In the folder tree expand HKEY_CURRENT_USER - Software - Wine and create a new key in the Wine folder. To do so, right click, select new–>key and name it Direct3D. Now create new–>DWORD Value, rename the file to MaxVersionGL and set the value data to 30002 (hexadecimal). Close the Registry Editor window.

Close the winetricks window and run installer:

Install Office 2013

$ env LANG=zh_CN.UTF-8 WINEPREFIX=~/.wine-office2013pro WINEARCH=win32 wine ~/PathTo/Office2013Setup.x86.exe

From here, the install runs and completes 100%.

安装后可以在 ~/.local/share/applications/wine 下找到 微信、QQ 的 .desktop 文件,右键编辑,将 Exec=env 行改为 Exec=env LANG=zh_CN.utf8

Genshin Impact

GI-on-Linux(已验证可玩)or Play another game. Format: link, caveats (Proton/Wine rating)

darling

Darling is a translation layer that lets you run macOS software on Linux

Anbox

Anbox 简介

Anbox 是 “Android in a box” 的缩写。Anbox 是一个基于容器的方法,可以在普通的 GNU/Linux 系统上启动完整的 Android 系统。

Anbox 可以让你在 Linux 系统上运行 Android,而没有虚拟化的迟钝,因为核心的 Android 操作系统已经使用 Linux 命名空间(LXE)放置到容器中了。

Android 容器不能直接访问到任何硬件,所有硬件的访问都是通过在主机上的守护进程进行的。

每个应用程序将在一个单独窗口打开,就像其它本地系统应用程序一样,并且它可以显示在启动器中。

安装使用

Anbox 也可作为 snap 软件包安装,请确保你已经在你的系统上启用了 snap 支持。

为使 Anbox 工作,确保需要的内核模块已经安装在你的系统中。对于基于 Ubuntu 的用户,使用下面的 PPA 来安装它。

$ sudo add-apt-repository ppa:morphis/anbox-support
$ sudo apt update
$ sudo apt install linux-headers-generic anbox-modules-dkms

在你安装 anbox-modules-dkms 软件包后,你必须手动重新加载内核模块,或需要系统重新启动。

$ sudo modprobe ashmem_linux
$ sudo modprobe binder_linux

安装 anbox。

$ sudo apt install anbox

如果你已经在你的系统上安装 snap,其它的步骤可以忽略。

$ sudo snap install --devmode --beta anbox

默认情况下,Anbox 并没有带有 Google Play Store。因此,我们需要手动下载每个应用程序(APK),并使用 Android 调试桥(ADB)安装它。

$ sudo apt install android-tools-adb

既然我们不能使用 Play Store ,你就得从信得过的网站来下载 APK 软件包,像 APKMirror ,然后手动安装它。

首先,你需要启动 ADB 服务。为做到这样,运行下面的命令。

$ adb devices

安装语法格式:

$ adb install Name-Of-Your-Application.apk

QEMU KVM

QEMU 的图形前端

与其他的虚拟化程序如 VirtualBox 和 VMware 不同, QEMU不提供管理虚拟机的GUI(运行虚拟机时出现的窗口除外),也不提供创建具有已保存设置的持久虚拟机的方法。除非您已创建自定义脚本以启动虚拟机,否则必须在每次启动时在命令行上指定运行虚拟机的所有参数。

Libvirt提供了一种管理 QEMU 虚拟机的便捷方式。有关可用的前端,请参阅 libvirt 客户端列表

创建新虚拟系统

创建硬盘镜像

除非直接从 CD-ROM 或网络引导(并且不安装系统到本地),运行 QEMU 时都需要硬盘镜像。硬盘镜像是一个文件,存储虚拟机硬盘上的内容。

一个硬盘镜像可能是 raw镜像, 和客户机器上看到的内容一模一样,并且将始终使用主机上的来宾硬盘驱动器的全部容量。此方法提供的I / O开销最小,但可能会浪费大量空间,因为guest虚拟机上未使用的空间无法在主机上使用。

另外一种方式是qcow2 格式,仅当客户系统实际写入内容的时候,才会分配镜像空间。对客户机器来说,硬盘大小表现为完整大小,即使它可能仅占用主机系统上的非常小的空间。此映像格式还支持QEMU快照功能。但是,使用此格式而不是 raw 可能会影响性能。

QEMU 提供 qemu-img命令创建硬盘镜像.例如创建一个 4 GB raw 格式的镜像:

$ qemu-img create -f raw image_file 4G

您也可以用 -f qcow2 创建一个 qcow2 镜像。

ddfallocate 也可以创建一个 raw 镜像。

警告: 如果硬盘镜像存储在 Btrfs 系统上,则应在创建任何映像之前考虑禁用该目录的写时复制。

调整镜像大小

警告: 调整包含NTFS引导文件系统的镜像将无法启动已安装的操作系统,推荐在操作之前进行备份

执行 qemu-imgresize 选项调整硬盘驱动镜像的大小.它适用于 rawqcow2. 例如, 增加镜像 10 GB 大小, 运行:

$ qemu-img info disk_image
$ qemu-img resize disk_image +10G

在磁盘映像扩容后,必须使用虚拟机内部系统的分区工具对该镜像进行分区并格式化后才能真正开始使用新空间。 在收缩磁盘映像时,必须首先使用虚拟机内部系统的分区工具减少分该分区的大小,然后相应地收缩磁盘映像,否则收缩磁盘映像将导致数据丢失!

PS:用qemu-img调整镜像大小,很简单,问题出在启动系统后,Windows只剩一个一直转圈圈的鼠标与黑屏,一点报错也没有,等了很久(半个小时左右),我直接loadvm加载snapshot,loadvm会回退之前qemu-img resize操作,所以需要再次resize,再次进系统,终于正常了,也看到了多出来的空闲空间。这说明操作是正确的,但是由于各种位置原因导致黑屏,所以重新做一次就好了。这里有一个手把手教程:KVM: How to Expand or Shrink a Virtual Machine Disk Size?

安装操作系统

这是你第一次需要去启动模拟器的步骤,为了在磁盘镜像上安装操作系统,你必须同时将磁盘镜像与安装介质装载到虚拟机上,从安装介质中启动操作系统。

以i386的客户机为例,为了从CD-ROM内的把可用于启动的ISO文件安装到磁盘镜像上,你需要:

$ qemu-system-x86_64 -cdrom iso_image -boot order=d -drive file=disk_image,format=raw

在安装完操作系统后,就可以直接从QEMU镜像内启动了。

注意: 默认情况下仅分配给虚拟机128MB的内存, 分配的内存大小可以通过 -m 调整, 比如 -m 512M-m 2G

提示:

  • 相较于指定 -boot order=x ,一部分用户感觉使用 -boot menu=on 启用boot菜单的体验更舒服些,至少在配置和实验时是这样的。
  • 当使用无界面(headless)模式时, 将会默认在本地5900端口启动一个VNC服务器, 可以用 TigerVNC 连接到客户机的系统上: vncviewer :5900
  • 若你在安装过程中需要替换软盘或CD,可以使用QEMU机器监视器(在虚拟机窗口中按Ctrl + Alt + 2)来删除存储设备并将其连接到虚拟机。使用info block查看块设备,然后使用change命令换出设备。按下Ctrl + Alt + 1返回虚拟机。

运行虚拟化的系统

qemu-system-* 程序 (例如 qemu-system-i386qemu-system-x86_64, 取决于客户机架构)用来运行虚拟化的客户机. 用法是:

$ qemu-system-i386 options disk_image

所有 qemu-system-*的选项是相同的。

默认 QEMU会在窗口中显示虚拟机的视频输出。有一点要记住:当您单击QEMU窗口,鼠标指针被捕获。要放开,按 Ctrl+Alt+g.

警告: QEMU 不应以 root 身份运行。如果必须以root身份在某个脚本中运行QEMU,那么你需要使用 -runas 选项让QEMU放弃root权限

启用 KVM

KVM 必须要您处理器和内核支持, 和必要的 kernel modules加载。更多信息参见 KVM

要在KVM模式中启动QEMU, 追加 -enable-kvm到启动选项. 要检查是否为正在运行的 VM 启用了 KVM,请使用 Ctrl+Alt+Shift+2 进入 QEMU Monitor,然后键入 info kvm。

注意:

  • -machine 选项中的 accel=kvm 参数与-enable-kvm-accel kvm 选项是等价的。
  • CPU模型 host 需要 KVM。
  • 如果你使用GUI工具去启动QEMU,但是性能体验极差,那么最好检查一下是否真的开启了KVM支持,因为QEMU可能选择了备用的模拟模式,即软件级模拟。
  • 需要启用KVM才能正常启动windows7和windows8,否则会出现“蓝屏”.

宿主机和虚拟机数据交互

网络

我们可以利用任何支持文件传输的网络协议实现客户机和宿主机之间的数据交互, 例如 NFS, SMB, NBD, HTTP, FTP, 或 SSH, 当然这么做的前提是你已经配置好二者之间的网络,且在系统上启动了相应的服务程序。

在默认情况下,用户模式的客户机能够通过10.0.2.2这个IP访问到宿主机。任何运行于宿主机上的服务端程序都可以通过这个地址被访问到,比如说我们可以通过这个IP访问到宿主机上的SSH服务器或SMB服务器。因此在这种情况下,客户机能够挂载宿主机通过SMB or NFS暴露出来的目录,也可以访问宿主机上的HTTP服务器等。 通常情况下宿主机无法访问客户机上的服务,不过你也可以通过一些特殊的网络配置达到这个目的 (参阅#Tap 网络)

QEMU 端口转发

QEMU能够将宿主机的端口转发到客户机上以实现一些功能,例如从宿主机上访问客户机的SSH端口。

举个例子,将宿主机上的10022端口与客户机上的22 (SSH) 端口进行绑定, 对应的QEMU命令如下:

$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::10022-:22

确认你客户机上的sshd程序正在运行,然后可以通过如下命令连接到客户机的SSH端口

$ ssh guest-user@localhost -p 10022

你可以用 SSHFS 把客户机的整个文件系统都挂到宿主机上,这样就可以在宿主机上对客户机的文件系统进行读写了。

想进行多端口转发的话, 只需要在-nic参数中指定多个hostfwd, 以VNC端口为例:

$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::10022-:22,hostfwd=tcp::5900-:5900

QEMU 的内置SMB服务器

QEMU的文档中指出它有一个内置的SMB服务器,但实际上,它只是在宿主机上加载一个自动生成的smb.conf配置文件 (位于/tmp/qemu-smb.random_string),然后启动宿主机上的Samba,使得客户机能够通过一个IP地址进行访问 (默认的IP地址是10.0.2.4)。这个方法只适用于用户网络,在你不想在宿主机开启通常的Samba服务 (客户机同样能访问这类Samba服务) 时这个方法还挺好用的。

宿主机上必须安装 Samba。通过如下QEMU命令启用这项特性:

$ sudo apt install samba
$ qemu-system-x86_64 disk_image -net nic -net user,smb=shared_dir_path

shared_dir_path 就是你想要在宿主机和客户机之间共享的目录。

接着,在客户机内,你应该能够通过10.0.2.4访问到名为qemu的共享文件夹。例如在Windows Explorer中前往 \\10.0.2.4\qemu 这个地址。

注意:

  • 如果你像这样多次指定共享选项 -net user,smb=shared_dir_path1 -net user,smb=shared_dir_path2 or -net user,smb=shared_dir_path1,smb=shared_dir_path2 qemu只会共享参数中最后的一个目录。
  • 如果你不能访问共享文件夹且客户机系统为 Windows, 请检查 NetBIOS 协议是否被启用 并确认防火墙没有屏蔽NetBIOS协议的 端口
  • 如果你不能访问共享文件夹且客户机系统为 Windows 10 Enterprise 或 Education 或 Windows Server 2016, 请启用游客访问.
    1. 打开 本地组策略编辑器 (gpedit.msc)。
    2. 在控制台树中,依次选择“计算机配置” > “管理模板” > “网络” > “Lanman 工作站”。
    3. 对于设置,右键单击“启用不安全的来宾登录”,然后选择“编辑”。
    4. 选择“启用”,然后选择“确定”。

共享多个文件夹并在运行时增删文件夹的一个方法是:共享一个空目录,然后在其中创建指向其余共享目录的符号链接。可以用下面的脚本修改SMB服务器的配置,这个脚本还能使宿主机上不允许执行的文件在客户机内拥有执行权限。

#!/bin/bash
eval $(ps h -C smbd -o pid,args | grep /tmp/qemu-smb | gawk '{print "pid="$1";conf="$6}')
echo "[global]
allow insecure wide links = yes
[qemu]
follow symlinks = yes
wide links = yes
acl allow execute always = yes" >> $conf
# in case the change is not detected automatically:
smbcontrol --configfile=$conf $pid reload-config

仅当客户机第一次访问到网络驱动后,才能将该脚本启用,并作用于qemu启动的SMB服务器。共享多文件的另一个方法是在配置文件里加入额外的共享路径,就像下面这样

$ echo "[myshare]
path=another_path
read only=no
guest ok=yes
force user=username" >> $conf

这个共享文件夹可以在客户机内通过\\10.0.2.4\myshare访问。

挂载qcow2镜像内的分区

我们将使用 qemu-nbd 完成这一功能, 同时它也能让我们使用 NBD (network block device) 协议共享该磁盘镜像。

首先,我们需要加载nbd模块:

$ sudo modprobe nbd max_part=16

接着,共享该磁盘并创建设备条目:

$ sudo qemu-nbd -c /dev/nbd0 /path/to/image.qcow2

进行分区发现检测:

$ sudo partprobe /dev/nbd0

fdisk 可以获取 nbd0 内各分区的相关信息 :

$ sudo fdisk -l /dev/nbd0
Disk /dev/nbd0: 25.2 GiB, 27074281472 bytes, 52879456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xa6a4d542

Device      Boot   Start      End  Sectors  Size Id Type
/dev/nbd0p1 *       2048  1026047  1024000  500M  7 HPFS/NTFS/exFAT
/dev/nbd0p2      1026048 52877311 51851264 24.7G  7 HPFS/NTFS/exFAT

接下来可以挂载镜像的任意分区了,比如说我们要挂载分区2:

$ sudo mount /dev/nbd0p2 mountpoint

完成任务后,切记卸载镜像文件,然后根据之前的操作一步步还原,即分区并断开与nbd设备的连接:

$ sudo umount mountpoint
$ sudo qemu-nbd -d /dev/nbd0

网络

采用TAP设备tun 与 tap 设备,都是虚拟网络设备,tun 设备用来实现三层隧道(三层 ip 数据报),tap 设备用来实现二层隧道(二层以太网数据帧)。)和网桥(使用网桥可以将多个接口连接到同一网段内,这一功能等同于交换式集线器。)的虚拟网络的性能应该会比使用用户模式网络或VDE要好,原因在于TAP设备和网桥是在内核中实现的。

此外,虚拟网络的性能可以通过将网络设备直接注册到虚拟机中改善,这比默认情况下模拟e1000 NIC的性能表现要更好,参阅 [安装 virtio 驱动](#安装 virtio 驱动) 获得更多相关信息。

关于链路层地址的限制

若在QEMU启动中指定了 -net nic 参数,QEMU将会为虚拟机注册一块虚拟网卡,其链路层地址为 52:54:00:12:34:56 。然而,当在多台虚拟机之间搭建桥接网络时,每台虚拟机在tap设备的虚拟机端都需要拥有一个独一无二的链路层地址 (MAC),否则网桥会因为收到多个不同源却拥有相同MAC地址的数据包而无法正常工作。即使你为多个tap设备配置了不同的MAC地址也依旧会出现这个问题,因为当数据包通过tap设备时,tap设备并不会改写包内的链路层地址。

因此请确保每个虚拟机拥有自己独一无二的网卡地址, 并且它们都以 52:54: 开头。 可以通过如下命令手动设置虚拟机的MAC地址, 下面的’X’可以替换成任何16进制字符:

$ qemu-system-x86_64 -net nic,macaddr=52:54:XX:XX:XX:XX -net vde disk_image

用户模式

默认情况下,没有任何-netdev参数,QEMU将使用带有内置DHCP服务器的用户模式网络。当您的虚拟机运行其DHCP客户端时,将为其分配IP地址,它们将能够通过QEMU伪装的IP来访问物理主机的网络。

警告: 仅适用于TCP和UDP协议,因此ICMP协议(包括ping)将不起作用。 请勿使用ping测试网络连接。

如果主机已连接Internet,则此默认配置可以使您的虚拟机轻松访问Internet。但是如果您同时启动多个虚拟机,则虚拟机将无法在外部网络上直接看到,虚拟机也将无法相互通信。

QEMU的用户模式网络可以提供更多功能,例如内置TFTP或SMB服务器,将主机端口重定向到虚拟机(例如,允许SSH连接到虚拟机)或将虚拟机连接到VLAN(vlan 全程 virtual lan,能够用来虚拟分配以太网。归属于不同的 VLAN ID 的设备之间需要一个路由才能够通信,这意味这不同的 VLAN ID 将以太网划分成了不同的分组。),以便它们可以彼此通信。 有关更多详细信息,请参见-net user标志上的QEMU文档。

但是,用户模式网络在效用和性能上都有局限性。更高级的网络配置需要使用TAP设备或其他方法。

Tap 网络

Tap devices是一个Linux内核特性,允许您创建作为真实网络接口的虚拟网络接口。发送到tap接口的包将被传递到一个用户空间程序(如QEMU),该程序将自己绑定到该接口。

QEMU可以为虚拟机使用tap网络,因此发送到tap接口的包将被发送到虚拟机,并显示为来自虚拟机中的网络接口(通常是以太网接口)。相反,虚拟机通过其网络接口发送的所有内容都将出现在tap接口上。

Linux桥接驱动程 序支持Tap设备,因此可以将Tap设备彼此桥接在一起,也可以连接其他主机接口,如eth0。如果您希望您的虚拟机能够相互通信,或者希望LAN上的其他机器能够与虚拟机通信,那么这是非常理想的方案。

警告: 如果您将tap设备和一些主机接口桥接在一起,例如eth0,您的虚拟机将直接出现在外部网络上,这将使它们遭受攻击的可能。根据您的虚拟机可以访问的资源,您可能需要采取所有precautions来保护您的虚拟机。如果风险太大,虚拟机没有资源或您设置多个虚拟机,一个更好的解决方案可能是使用host-only networking建立NAT。在这种情况下,您只需要在主机上安装一个防火墙,而不是为每个虚拟机安装多个防火墙。

正如在用户模式网络部分中指出的,tap设备提供比用户模式具有更高的网络性能。如果虚拟机中的操作系统支持virtio网络驱动程序,那么网络性能也会显著提高。假设使用tap0设备,virtio驱动程序在客户端上使用,并且没有使用脚本来帮助启动/停止网络,使用下面的qemu命令:

-net nic,model=virtio -net tap,ifname=tap0,script=no,downscript=no

但是,如果已经使用带有virtio网络驱动程序的Tap设备,则甚至可以通过启用vhost来提高网络性能,例如:

-net nic,model=virtio -net tap,ifname=tap0,script=no,downscript=no,vhost=on

仅主机网络

如果为网桥提供了IP地址,并且使能发往该网桥的流量允许,但没有实际接口(例如eth0)连接到网桥,则虚拟机与虚拟机间,虚拟机与主机间能够相互通信。但是,如果您没有在物理主机上设置IP掩蔽,则他们将无法与外部网络进行通信。 此配置被其他虚拟化软件(例如VirtualBox)称为“仅主机网络模式”。

提示:

  • 如果你想设置IP掩蔽,例如虚拟机的NAT,请查看Internet sharing#Enable NAT页面。

  • 您也许想在网桥接口上运行一个DHCP服务器来服务虚拟网络。例如,使用172.20.0.1/16子网,dnsmasq作为DHCP服务器:

    # ip addr add 172.20.0.1/16 dev br0
    # ip link set br0 up
    # dnsmasq --interface=br0 --bind-interfaces --dhcp-range=172.20.0.2,172.20.255.254
    

内部网络

如果您不为网桥提供IP地址并在iptables添加INPUT规则链,将所有流向网桥中的数据丢弃,则虚拟机将能够彼此通信,但无法与物理主机或外部网络通信。此配置被其他虚拟化软件(例如VirtualBox)称为“内部网络”。您将需要为虚拟机分配静态IP地址,或在其中一个虚拟机上运行DHCP服务器。

在默认情况下,iptables将丢弃桥接网络中的数据包。您可能需要使用这样的iptables规则来允许桥接网络中的数据包:

# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

使用 qemu-bridge-helper 桥接网络

这种方法不需要启动脚本,并且很容易适应多个tap和多个桥。它使用/usr/lib/qemu/qemu-bridge-helper,允许在现有桥上创建tap设备。

提示: 参见 Network bridge 获取创建网桥的信息.

首先,创建一个配置文件,包含QEMU使用的所有网桥的名称:

/etc/qemu/bridge.conf
allow bridge0
allow bridge1
...

现在启动虚拟机:

$ qemu-system-i386 -net nic -net bridge,br=bridge0 [...]

在多个TAP设备的情况下,最基本的用法是要为所有NIC指定VLAN:

$ qemu-system-i386 -net nic -net bridge,br=bridge0 -net nic,vlan=1 -net bridge,vlan=1,br=bridge1 [...]

手工创建网桥

将虚拟机连接到主机接口,如eth0,这可能是最常见的配置。这种配置使虚拟机看起来直接位于外部网络,与物理主机位于同一以太网段。

物理设备和Tap设备之间通过iptables进行网络共享

桥接网络能在有线接口(例如eth0)之间工作,并且很容易设置。但是,如果主机通过无线设备连接到网络,则无法进行桥接。

解决这个问题的一种方法是,给tap设备设置一个静态IP,使linux自动处理它的路由,然后通过iptables规则转发tap接口和连接到网络的设备之间的通信。

通过 VDE2 配置网络

VDE全称为Virtual Distributed Ethernet,作为uml_switch的一个扩展,是一个用于管理虚拟网络的工具包

其基本的思想是创建一个虚拟的开关,就如插座那样,允许虚拟机和物理机通过"插入"连接彼此。下面的配置非常简单,然而,VDE的功能远比展示的更强大,其能够接入虚拟开关,在不同的主机上运行它们并监听开关上的通信。

本方法的优点在于无需sudo特权,普通用户一般没有运行modprobe的权限。

VDE2 网桥

任何连接到vde上的虚拟机都会暴露给外部。举个例子,每台虚拟机都能直接从ADSL路由器那收到DHCP的配置信息。

简化配置参数

如果你经常需要以不同的网络配置选项运行QEMU,就会发现时常得输入大量的-netdev-device选项组合,这些是大量重复性的劳动。可以用-nic选项将二者结合,就如下面这样,底下这些参数:

-netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on -device virtio-net-pci,netdev=network0

可简化为:

-nic tap,script=no,downscript=no,vhost=on,model=virtio-net-pci

要注意的是缺失了网络ID,因此将会以model=创建这些设备。{ic|-nic}}命令的前半部分参数正是-netdev的参数,而后半部分参数(model=之后的部分)则与设备有关,原本设备所提供的参数同样可以在此使用(例如,可以指定smb=)。若要完全禁用网络,可以用-nic none

图形

QEMU 可以使用一下几个图形输出:std, cirrus, vmware, qxl, xenfs 和 vnc。使用 vnc 选项,你可以单独运行客户机,并且通过 VNC 连接。

  • std:使用 -vga std 你可以得到最高 2560 x 1600 像素的分辨率。从 QEMU 2.2 开始是默认选项。

  • qxl:QXL是一个支持2D的并行虚拟化图形驱动。需要在客户机中安装驱动并在启动QEMU时设置-vga qxl选项。你可能也会想使用SPICE优化QXL的图形表现。

    在Linux客户机中,需要加载qxlbochs_drm这两个内核模块,以获得一个比较好的效果。

    QXL设备的默认VGA内存大小为16M,这样的内存大小最高支持QHD (2560x1440)的分辨率,如果想要一个更高的分辨率,请增加vga_memmb

  • virtiovirtio-vga / virtio-gpu 是一个基于virgl的3D并行虚拟化图形驱动。目前依旧处于开发中,仅支持最近的(>= 4.4)的Linux客户机,且需要以gallium-drivers=virgl选项编译mesa (>=11.2)。

    若要在客户机上启用3D加速,那么需要用-vga virtio选项选择此vga,并用-display sdl,gl=on-display gtk,gl=on在显示设备上启用opengl上下文,这两个选项分别适用于sdl输出和gtk输出。如果配置成功了,那么在客户机的kernel log里可以看到:

    # dmesg | grep drm 
    [drm] pci: virtio-vga detected
    [drm] virgl 3d acceleration enabled
    
  • none:这就像一台完全没有VGA卡的PC,无法通过-vnc访问它。另外,这种情况与使用-nographic选项不同,-nographic会让QEMU模拟VGA卡,只是关闭了SDL输出。

VNC

可以用-vnc :X选项将QEMU的VGA输出重定向至VNC会话中。将X替换为输出目标的编号(0代表之后监听在5900,1代表监听在5901…)。

$ qemu-system-x86_64 -vnc :0

警告: 默认的VNC服务器没有使用任何验证手段,用户可以从任何主机上连接到VNC。

基本的口令验证

可以通过使用password选项很容易地设置访问口令。必须在QEMU Monitor中指定口令,仅当用户提供口令时才有可能连接到VNC。

$ qemu-system-x86_64 -vnc :0,password -monitor stdio

在QEMU Monitor中设置口令需使用change vnc password命令,然后指定一个口令。

底下的命令将在启动VNC时直接为其设置口令:

$ printf "change vnc password\n%s\n" MYPASSWORD | qemu-system-x86_64 -vnc :0,password -monitor stdio

注意: 口令被限制在8个字符内,可以用暴力破解的方式猜到口令。因此在公网上推荐使用更细致的保护措施。

音频

-audiodev标识用于设定后端音频驱动及其相关选项。最简单的情况下,你需要选择一个驱动并设置一个id。

-audiodev pa,id=snd0

使用音频设备

Intel HD Audio

模拟Intel HD Audio需要添加控制器和编解码器设备。可以用如下命令列出可用的Intel HDA Audio设备:

$ qemu-system-x86_64 -device help | grep hda

添加音频控制器:

-device ich9-intel-hda

添加音频编解码器并将其映射到宿主机的音频后端id上。

-device hda-output,audiodev=snd0

Intel 82801AA AC97

模拟AC97需要添加声卡设备并将其映射到宿主机的一个音频后端id上。

-device AC97,audiodev=snd0

无音频设备

通过如下命令获取支持模拟的音频驱动列表:

$ qemu-system-x86_64 -soundhw help

比如,要在客户机上模拟hda驱动,需要使用-device intel-hda -device hda-duplex选项启动QEMU。

注意: 客户机的显卡模拟驱动可能也会导致客户机中的音频质量出现问题,需要一个个进行排查。使用qemu-system-x86_64 -h | grep vga列出可用的选项

安装 virtio 驱动

QEMU为用户提供并行虚拟化块设备和网络设备的能力,其是借助virtio驱动实现的,拥有更好的性能表现以及更低的开销。

virtio块设备需要使用-drive指定一个disk image的参数,且需要带上if=virtio参数:

$ qemu-system-x86_64 -boot order=c -drive file=disk_image,if=virtio

网络配置也是类似的:

$ qemu-system-x86_64 -nic user,model=virtio-net-pci

注意: 仅有当客户机有virtio设备对应的驱动时该方法才能起效,Linux是有这方面支持的,不过无法保证这些驱动能够兼容其他操作系统。

以下以windows为例。

块设备驱动

Windows没有自带virtio驱动,因此需要在安装时加载该驱动。镜像文件可以从Fedora 仓库下载。

通过ISO加载只对Windows Vista和Windows Server 2008及其之后的版本有效。这个方法的具体操作是在主磁盘设备和Windows安装盘外挂载一个额外的cdrom设备,将系统镜像与virtio驱动一同加载:

$ qemu-system-x86_64 ... \
-drive file=windows_disk_image,index=0,media=disk,if=virtio \
-drive file=windows.iso,index=2,media=cdrom \
-drive file=virtio.iso,index=3,media=cdrom \
...

在安装过程中,Windows Installer会询问你“Where do you want to install Windows?”,其会返回一个警告表示没有找到任何磁盘设备。接下来跟着如下示例中的步骤进行操作(基于Windows Server 2012 R2 with Update):

  • Select the option Load Drivers.
  • Uncheck the box for Hide drivers that are not compatible with this computer’s hardware.
  • Click the browse button and open the CDROM for the virtio iso, usually named “virtio-win-XX”.
  • Now browse to E:\viostor\[your-os]\amd64, select it, and confirm.

现在应该能看到virtio磁盘出现在列表中了,等待着被选中、格式化并安装。

网络驱动

安装virtio网络驱动程序要容易一些,只需如上所述添加-net参数即可。

$ qemu-system-i386 -m 4G -vga std -drive file=windows_disk_image,if=virtio -net nic,model=virtio-net-pci -cdrom virtio-win-0.1-185.iso

Windows将检测网络适配器并尝试为其找到驱动程序。如果失败,请转到“设备管理器”,找到带有感叹号图标的网络适配器(双击打开),切换到驱动程序并单击“更新驱动程序”,然后选择虚拟CD-ROM。别忘了选中显示要递归搜索目录的复选框。

Balloon 驱动

如果想要追踪客户机内存状态(比如通过virsh的dommemstat命令)或者在运行时改变客户机内存大小(尽管依然无法改变实际的内存大小,不过可以通过inflating balloon驱动限制内存的使用),那么请在客户机上安装balloon驱动吧。

QEMU 监视器

QEMU运行时会提供一个监视器console界面以方便用户同虚拟机进行交互。QEMU监视器提供了许多有趣的功能,例如获取当前虚拟机的信息,热插拔设备,创建快照等。在QEMU监视器console中运行help?命令获得完整的命令列表。

访问QEMU监视器Console

图形化界面

当使用默认的std图形选项时,可以通过按下Ctrl+Alt+2组合键或从QEMU窗口上的View > compatmonitor0访问到QEMU监视器。若要返回到虚拟机的图形界面,那么按下Ctrl+Alt+1或者View > VGA就行。

然而,这种标准的访问方式不够方便,而且并不是在QEMU的所有图形化输出方式中都适用。

Telnet

启动QEMU时带上-monitor telnet:127.0.0.1:*port*,server,nowait参数可以启用telnet。虚拟机启动后可以通过telnet访问到监视器:

$ telnet 127.0.0.1 port

注意: 如果指定 127.0.0.1 作为监听地址,那么只能在运行QEMU的宿主机上连接到该监视器。如果想要远程访问,QEMU需要在0.0.0.0上进行监听:-monitor telnet:0.0.0.0:*port*,server,nowait。还要记住的是,最好对firewall进行配置,该连接是完全不进行认证和加密的,因此需要通过防火墙确保本地网络环境是可信的。

UNIX socket

通过-monitor unix:*socketfile*,server,nowait参数运行QEMU,之后就可以通过socatopenbsd-netcat连接到监视器上。

例如,如果QEMU是通过如下命令启动:

$ qemu-system-x86_64 [...] -monitor unix:/tmp/monitor.sock,server,nowait [...]

就可以像这样连接到监视器上:

$ socat - UNIX-CONNECT:/tmp/monitor.sock

或者通过这种方式:

$ nc -U /tmp/monitor.sock

TCP

可以使用-monitor tcp:127.0.0.1:*port*,server,nowait参数将监视器暴露于TCP端口上,然后用netcat(openbsd-netcatgnu-netcat都可)进行连接:

$ nc 127.0.0.1 port

注意: 为了能够从其它设备上通过TCP socket访问到监视器,而不仅仅从运行QEMU的主机上连接,需要像前面Telnet中描述的那样,在0.0.0.0地址上进行监听。

标准 I/O

如果以-monitor stdio参数运行QEMU,那么其实是可以在运行QEMU的终端下访问到监视器的。

在Monitor conosle下向虚拟机发送按键行为

由于在某些配置下,宿主机可能会拦截一些按键组合另作他用,这导致要在虚拟机中触发一些特定按键组合变得有些困难(一个显然的例子就是Ctrl+Alt+F*组合,该组合用于改变当前的tty)。我们采用在monitor console下发送按键组合的方式解决该问题。只需切换到monitor console下,然后使用sendkey命令,即可将按键转发至虚拟机中,例如:

(qemu) sendkey ctrl-alt-f2

通过 monitor console 创建快照和管理快照

注意: 该特性"只"支持qcow2格式的虚拟机磁盘镜像,对于raw是无效的。

有时候我们很需要将虚拟机的当前状态进行保存,或是将虚拟机重置到之前的快照状态,而且最好是随时能进行这些操作。QEMU monitor console为用户提供了必要的功能,进行快照创建,快照管理,以及快照恢复。

  • Use savevm name 用于创建一个名为name的快照。
  • Use loadvm name 用于将虚拟机状态恢复至快照name
  • Use delvm name 用于删除快照name
  • Use info snapshots 用于查看保存的快照列表,这些快照由一个自增长的ID和标签名(用户创建快照时赋予)进行标识。

以冻结模式运行虚拟机

QEMU支持以冻结态运行虚拟机(需使用-snapshot参数),换句话说,虚拟机关闭时,对于虚拟机的一切修改都会丢弃。当用户对磁盘镜像写入时,这些变动最终写入的位置是/tmp目录下的一个临时文件,QEMU关机时将会把他们丢弃。

不过,即使虚拟机运行于冻结状态下,依旧可以通过monitor console将这些变化写入磁盘镜像(如果你想的话)。使用下面的命令:

(qemu) commit all

另外如果在冻结状态下创建快照,这些快照在QEMU退出时都会被丢弃,除非你显式地commit了他们。

monitor console中的开机和暂停命令

在QEMU monitor console下也可以模拟对物理机的一些操作:

  • system_powerdown 会向虚拟机发送ACPI关机信号,效果就类似物理机上按下电源按钮。
  • system_reset 会重置虚拟机,类似物理机上的重置按钮。该操作可能导致数据丢失或文件系统的损坏,这是因为虚拟机并不是"干净地"重启的。
  • stop 会暂停虚拟机。
  • cont 使暂停的虚拟机恢复运行。

虚拟机截屏

可以在monitor console下运行该命令,获取PPM格式的截屏图片:

(qemu) screendump file.ppm

PCI passthrough via OVMF

笔记本 Optimus MUXless 下的 Intel 和 NVIDIA 虚拟机显卡直通

受到MUXless架构本身的限制,显卡直通有非常大的局限,例如很多游戏无法调用独显、操作麻烦、显示性能仍然较低等。因此,现阶段可以为了折腾而尝试,但不建议用于实用用途。

Optimus MUXed 笔记本上的 NVIDIA 虚拟机显卡直通

技巧

改善虚拟机的性能表现

底下是一些可以改善虚拟机性能表现的技术,例如:

  • 启用#启用 KVM:QEMU的启动命令加上-enable-kvm选项。

  • 通过-cpu host选项让QEMU模拟宿主机上的特定CPU,如果没有该选项QEMU尝试模拟的是一个更为通用的CPU。

  • 特别的,如果客户机是Windows,启用Hyper-V enlightenments可以改善性能:-cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time.

  • 如果宿主机有多个核心,可以用-smp选项为客户机分配更多核心。

  • 检查是否为虚拟机分配的足够的内存。默认情况下,QEMU仅仅为每台虚拟机分配128MiB的内存,可以使用-m选项分配更多的内存。例如,-m 1024代表启动一台内存为1024MiB的虚拟机。

  • 如果客户机操作系统支持相关的驱动,可以使用virtio创建网络设备或块设备。

  • 使用TAP设备代替user-mode网络,参阅#Tap 网络

  • 如果客户机需要进行大量的磁盘写工作,在宿主机文件系统上设置合适的挂载选项可以优化该工作。例如,可以用barrier=0选项挂载一个ext4 file system。在使用这些性能强化选项之前最好阅读相关文档,因为性能上的提升通常伴随着数据完整性下降的代价。

  • 如果有一块原始磁盘镜像,你可能会想要禁用cache:

    $ qemu-system-x86_64 -drive file=disk_image,if=virtio,cache=none
    
  • 使用原生的Linux AIO:

    $ qemu-system-x86_64 -drive file=disk_image,if=virtio,aio=native,cache.direct=on
    
  • 如果正同时运行多台虚拟机,而它们拥有同样的操作系统,可以通过启用内核页归并节省内存。参阅#开启KSM

  • 在一些情况下,可以在运行时从安装了balloon驱动的客户机上回收内存,这需要QEMU启动该客户机时使用-device virtio-balloon选项。

  • 允许使用一个ICH-9 AHCI控制器的仿真层,尽管它并不稳定。AHCI的仿真模拟支持NCQ,因此可以同时处理多个读写请求:

    $ qemu-system-x86_64 -drive id=disk,file=disk_image,if=none -device ich9-ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0
    

参阅 https://www.linux-kvm.org/page/Tuning_KVM 获取更多信息

开机时启动QEMU虚拟机

通过libvirt实现

如果虚拟机是通过libvirt设置的,可以用virsh autostart将其配置为开机自启,或者通过virt-managerGUI中虚拟机的Boot Options,选择"Start virtual machine on host boot up"实现开机自启。

通过systemd service实现

可以用如下的systemd unit和config配置开机时启动QEMU VM。

/etc/systemd/system/qemu@.service
[Unit]
Description=QEMU virtual machine

[Service]
Environment="haltcmd=kill -INT $MAINPID"
EnvironmentFile=/etc/conf.d/qemu.d/%i
ExecStart=/usr/bin/qemu-system-x86_64 -name %i -enable-kvm -m 512 -nographic $args
ExecStop=/bin/bash -c ${haltcmd}
ExecStop=/bin/bash -c 'while nc localhost 7100; do sleep 1; done'

[Install]
WantedBy=multi-user.target

注意: 为了方便地结束任务,该service会等待至console端口被释放(这意味着VM已被关闭)。

接着创建per-VM配置文件,命名为/etc/conf.d/qemu.d/*vm_name*,在其中设置好argshaltcmd变量,配置示例:

/etc/conf.d/qemu.d/one
args="-hda /dev/vg0/vm1 -serial telnet:localhost:7000,server,nowait,nodelay \
 -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0"

haltcmd="echo 'system_powerdown' | nc localhost 7100" # or netcat/ncat
/etc/conf.d/qemu.d/two
args="-hda /srv/kvm/vm2 -serial telnet:localhost:7001,server,nowait,nodelay -vnc :1"

haltcmd="ssh powermanager@vm2 sudo poweroff"

对该变量的描述如下:

  • args - 使用的QEMU命令行参数。
  • haltcmd - 安全关闭虚拟机的命令,在第一个例子中,QEMU monitor是通过-monitor telnet:..选项暴露至telnet,因而关闭虚拟机是通过nc命令在monitor console中发送system_powerdown,完成ACPI关机的工作。在另一个例子里,使用的则是SSH。

若要设置启动时运行哪个虚拟机,enable qemu@*vm_name*.service这个systemd单元

鼠标整合

添加-usb -device usb-tablet选项以避免点击客户机系统的窗口时鼠标被捕获。该选项代表QEMU能够在不捕获鼠标的情况下,向系统报告鼠标的位置,该选项启用时还会覆盖PS/2鼠标模拟功能。 命令示例:

$ qemu-system-x86_64 -hda disk_image -m 512 -usb -device usb-tablet

宿主机的USB设备传递至虚拟机

从客户机访问连接到宿主机USB口的设备是可能的,首先需要识别设备连接的位置,可以用lsusb命令找到设备连接位置,例如:

$ lsusb
...
Bus 003 Device 007: ID 0781:5406 SanDisk Corp. Cruzer Micro U3

上面以显示的数字分别用于标识

  • 003 host_bus
  • 007 host_addr
  • 0781 vendor_id
  • 5406 product_id

基本的思想是在QEMU中-device usb-ehci,id=ehci-device qemu-xhci,id=xhci分别对EHCI (USB 2)或XHCI (USB 3)(在win7无法自动安装 USB3 驱动,因此应用 USB2)控制器进行模拟,然后将物理设备通过-device usb-host,..选项进行添加。

识别出该设备,并将其连接至任一总线以及宿主机上的地址,通用的语法如下:

-device usb-host,bus=controller_id.0,vendorid=0xvendor_id,productid=0xproduct_id

应用于上面例子中使用的设备,它变成:

-device usb-ehci,id=ehci -device usb-host,bus=ehci.0,vendorid=0x0781,productid=0x5406

运行QEMU时会遇到 libusb couldn't open USB device Permission denied 权限错误,可以通过 udev 为设备设定合适的权限。

$ vi /etc/udev/rules.d/50-usbtinyisp.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0781", ATTRS{idProduct}=="5406", GROUP="vane", MODE="0660"

$ ls -al /dve/bus/usb/003/007
crw-rw---- 1 root vane 189, 11 Nov  7 12:37 /dev/bus/usb/003/007

使用SPICE进行USB重定向

使用SPICE时可以将USB设备从客户端重定向至虚拟机中,无需使用QEMU命令。还支持为配置USB重定向插槽数(插槽数将决定可同时重定向的最大设备数)。相比于前面那种使用-usbdevice进行重定向的方法,SPICE方法的优势在于可以在虚拟机启动后USB设备热插拔,移除或添加USB设备时无需停机。这个方法还允许通过网络将客户端的USB设备重定向至服务端。总之,其是在QEMU虚拟机中使用USB设备最灵活的方法。

开启KSM

Kernel Samepage Merging (KSM) 是Linux内核的一个特性,允许应用程序向内核申请同其他申请页归并的进程进行页归并,KSM机制允许客户虚拟机之间进行页共享。当许多客户机运行相似的操作系统时,这个机制可以节省客观的内存。

多屏支持

Linux的QXL驱动支持默认支持四头(虚拟屏幕),可以通过qxl.heads=N这一内核参数进行变更。

复制和粘贴

在宿主机和客户机之间共享剪贴板的方法之一是使用SPICE远程桌面协议,通过SPICE客户端访问客户机,你需要遵照SPICE节中描述的步骤,通过该方式运行的客户机将支持与宿主机进行复制粘贴的操作。

libvirt

Libvirt 是一组软件的汇集,提供了管理虚拟机和其它虚拟化功能(如:存储和网络接口等)的便利途径。这些软件包括:一个长期稳定的 C 语言 API、一个守护进程(libvirtd)和一个命令行工具(virsh)。Libvirt 的主要目标是提供一个单一途径以管理多种不同虚拟化方案以及虚拟化主机,包括:KVM/QEMU,Xen,LXC,OpenVZ 或 VirtualBox hypervisors。

Libvirt 的一些主要功能如下:

  • VM management(虚拟机管理):各种虚拟机生命周期的操作,如:启动、停止、暂停、保存、恢复和迁移等;多种不同类型设备的热插拔操作,包括磁盘、网络接口、内存、CPU等。
  • Remote machine support(支持远程连接):Libvirt 的所有功能都可以在运行着 libvirt 守护进程的机器上执行,包括远程机器。通过最简便且无需额外配置的 SSH 协议,远程连接可支持多种网络连接方式。
  • Storage management(存储管理):任何运行 libvirt 守护进程的主机都可以用于管理多种类型的存储:创建多种类型的文件镜像(qcow2,vmdk,raw,…),挂载 NFS 共享,枚举现有 LVM 卷组,创建新的 LVM 卷组和逻辑卷,对裸磁盘设备分区,挂载 iSCSI 共享,以及更多……
  • Network interface management(网络接口管理):任何运行 libvirt 守护进程的主机都可以用于管理物理的和逻辑的网络接口,枚举现有接口,配置(和创建)接口、桥接、VLAN、端口绑定。
  • Virtual NAT and Route based networking(虚拟 NAT 和基于路由的网络):任何运行 libvirt 守护进程的主机都可以管理和创建虚拟网络。Libvirt 虚拟网络使用防火墙规则实现一个路由器,为虚拟机提供到主机网络的透明访问。

安装

基于守护进程/客户端的架构的 libvirt 只需要安装在需要要实现虚拟化的机器上。注意,服务器和客户端可以是相同的物理机器。

服务端

安装 libvirt 以及至少一个虚拟运行环境(hypervisor):libvirt 的 KVM/QEMU 驱动libvirt 的首选驱动,如果 KVM 功能已启用,则支持全虚拟化和硬件加速的客户机。

$ sudo apt update
$ sudo apt install qemu-kvm libvirt-daemon-system

安装 libvirt-daemon-system 后,需要将用于管理虚拟机的用户添加到libvirt组中。这对于 sudo 组的成员是自动完成的,但对于应该访问系统范围的 libvirt 资源的其他任何人,都需要另外完成。这样做将授予用户访问高级网络选项的权限。

在终端中输入:

$ sudo adduser $USER libvirt

如果选择的用户是当前用户,您需要注销并重新登录才能使新的组成员身份生效。

客户端

客户端是用于管理和访问虚拟机的用户界面。

  • virshvirsh 是用于管理和配置域(虚拟机)的命令行程序。
  • Virtual Machine Manager — 使用libvirt对KVM,Xen,LXC进行管理的图形化工具。

配置

对于系统 级别的管理任务(如:全局配置和镜像 位置),libvirt 要求至少要设置授权和启动守护进程。

注意: 对于用户会话 级别的管理任务,守护进程的安装和设置不是 必须的。授权总是仅限本地,前台程序将启动一个 libvirtd 守护进程的本地实例。

设置授权

libvirt:连接授权:Libvirt 守护进程允许管理员分别为客户端连接的每个网络 socket 选择不同授权机制。这主要是通过 libvirt 守护进程的主配置文件 /etc/libvirt/libvirtd.conf 来实现的。每个 libvirt socket 可以有独立的授权机制配置。目前的可选项有 nonepolkitsasl

由于 libvirt 在安装时将把 polkit 作为依赖一并安装,所以 polkit 通常是 unix_sock_auth 参数的默认值。但基于文件的权限仍然可用。

使用 polkit

注意: 为使 polkit 认证工作正常,应该重启一次系统。

libvirt 守护进程在 polkit 策略配置文件(/usr/share/polkit-1/actions/org.libvirt.unix.policy)中提供了两种策略

  • org.libvirt.unix.manage 面向完全的管理访问(读写模式后台 socket),以及
  • org.libvirt.unix.monitor 面向仅监视察看访问(只读 socket)。

默认的面向读写模式后台 socket 的策略将请求认证为管理员。这点类似于 sudo 认证,但它并不要求客户应用最终以 root 身份运行。默认策略下也仍然允许任何应用连接到只读 socket。

基于文件的权限授权

为了给 libvirt 组用户定义基于文件的权限以管理虚拟机,取消下列行的注释:

$ vim /etc/libvirt/libvirtd.conf
#unix_sock_group = "libvirt"
#unix_sock_ro_perms = "0777"  # set to 0770 to deny non-group libvirt users
#unix_sock_rw_perms = "0770"
#auth_unix_ro = "none"
#auth_unix_rw = "none"

有些资料提到可以通过改变某些特定 libvirt 目录的权限以简化管理。需要记住的是:包更新时,这些变更会丢失。如要修改这些系统目录的权限,需要 root 用户权限。

守护进程

libvirtd.servicevirtlogd.service这两个服务单元都要启动。可以把 libvirtd.service 设置为启用,这时系统将同时启用 virtlogd.servicevirtlockd.socket 两个服务单元,因此后二者不必再设置为启用

测试

测试 libvirt 在系统级工作是否正常:

$ virsh -c qemu:///system

测试 libvirt 在用户会话级工作是否正常:

$ virsh -c qemu:///session

管理

绝大部分的 libvirt 管理可以通过三个工具实现:virt-manager(图形界面)、virshguestfish(它是 libguestfs 的一部分)。

virsh

Visrsh 用于管理客户(虚拟机),在脚本式虚拟化管理环境中工作良好。由于需要通过通讯管道与虚拟运行环境通讯,绝大部分 virsh 命令需要管理员权限。尽管如此,一些典型的管理操作如域的创建、运行等也可以像VirtualBox 那样以普通用户身份执行。

Virsh 允许带命令行选项执行。如果不带则进入其内置的交互式终端:virsh。交互式终端支持 tab 键命令补全。

从命令行执行:

$ virsh [可选项] <命令> [参数]...

在交互式终端里运行:

virsh # <命令> [参数]...

帮助也是可用的:

$ virsh help [option*] or [group-keyword*]
存储池

存储池是指保存的位置。Libvirt 中的定义相当于其他系统中虚拟磁盘虚拟机镜像的概念。存储池应该是一个目录、一个网络文件系统或一个分区(此处包括 LVM)。存储池可以在活动与不活动之间切换,可以为其分配存储空间。

以下示例为添加存储池、目录和 LVM 卷的方法:

$ virsh pool-define-as name type [source-host] [source-path] [source-dev] [source-name] [<target>] [--source-format format]
$ virsh pool-define-as poolname dir - - - - /home/username/.local/libvirt/images
$ virsh pool-define-as poolname fs - -  /dev/vg0/images - mntpoint

上述示例仅仅定义了存储池的信息,下面创建它:

$ virsh pool-build     poolname
$ virsh pool-start     poolname
$ virsh pool-autostart poolname

删除它的命令:

$ virsh pool-undefine  poolname

提示: 对于 LVM 存储池而言:

  • 最佳实践是仅把一个卷组分配给一个存储池。
  • 请为存储池选择一个与 LVM 卷组不同的名字。否则当存储池被删除时,该卷组也将被删除。

用 virt-manager 新建存储池

首先,连接到虚拟运行环境(例如QEMU/KVM的系统/用户会话)。然后,右键点击一个连接(例如QEMU/KVM)选择详情,切换到存储选项卡,点击左下角的**+**,按照向导操作。

存储卷

存储池被创建之后,就可以在存储池中创建存储卷。如果你想新建一个域(虚拟机),那么这一步可以跳过,因为这一步可以在创建域的过程中完成。

用 virsh 新建卷

新建卷,列出卷,变更卷大小,删除卷:

$ virsh vol-create-as      poolname volumename 10GiB --format aw|bochs|raw|qcow|qcow2|vmdk
$ virsh vol-upload  --pool poolname volumename volumepath
$ virsh vol-list           poolname
$ virsh vol-resize  --pool poolname volumename 12GiB
$ virsh vol-delete  --pool poolname volumename
$ virsh vol-dumpxml --pool poolname volumename  # for details.

虚拟机被称作“域”。如果你想在命令行下操作,使用virsh列出,创建,暂停,关闭……域。virt-viewer可以用来查看使用virsh启动的域。域的创建通常以图形化的virt-manager或者命令行下的virt-install完成。 创建新域通常需要安装媒介,例如存储池中的iso文件或是直接从光驱安装。

列出活动的和不活动的域:

# virsh list --all

用 virt-install 新建域

对于很详细的域(虚拟机)配置,可以用 virt-manager 新建域更简单地完成。但是,基础配置同样可以用virt-install完成并且同样运行顺利。至少要配置--name, --memory, 存储(--disk, --filesystem,或--nodisks),和安装方法(通常来说是.iso文件或CD)。查看virt-install(1)得到未列出的选项和更多的详情。

Windows:

$ virt-install \
  --name=windows7           \
  --memory 2048             \
  --cdrom /dev/sr0          \
  --os-variant=win7         \
  --disk /mnt/storage/domains/windows7.qcow2,size=20GiB \
  --network network=vm-net  \
  --graphics spice

导入现有的卷:

$ virt-install  \
  --name demo  \
  --memory 512 \
  --disk /home/user/VMs/mydisk.img \
  --import

用 virt-manager 新建域

首先,连接到虚拟运行环境(例如 QEMU/KVM system 或用户 session,在连接上右击并选择 新建,然后跟随向导完成。

  • 在第四[步中取消选中立即分配全部虚拟磁盘空间会加快创建过程并节省实际虚拟磁盘空间占用;然而,这将导致将来花费额外的磁盘整理时间。
  • 第五步中打开高级选项并确认虚拟化类型设为 kvm(这通常是首选模式)。如果要求附加的硬件配置,选中安装前定制选项。

管理域

启动域:

$ virsh start domain
$ virt-viewer --connect qemu:///session domain

正常关闭域;强制关闭域:

$ virsh shutdown domain
$ virsh destroy  domain

在libvirtd启动时自动启动域:

$ virsh autostart domain
$ virsh autostart domain --disable

在宿主机关闭时自动关闭域:

使用libvirt-guests.serviceSystemd服务,运行中的域可以在宿主机关闭时自动挂起/关闭。同时这个服务还可以让挂起/休眠的域在宿主机启动的时候自动恢复。查看/etc/conf.d/libvirt-guests并设置相关选项。

编辑一个域的XML配置:

$ virsh edit domain

注意: 直接被QEMU启动的虚拟机不被libvirt管理。

网络

这里是有关 libvirt 网络的一个正宗的概述。

默认情况下,当 libvirtd 服务启动后,即创建了一个名为 default 的 NAT 网桥与外部网络联通(仅 IPv4)。对于其他的网络连接需求,可创建下列四种类型的网络以连接到虚拟机:

  • bridge — 这是一个虚拟设备,它通过一个物理接口直接共享数据。使用场景为:宿主机有 静态 网络、不需与其它域连接、要占用全部进出流量,并且域运行于 系统 层级。有关如何在现有默认网桥时增加另一个网桥的方法,请参阅 网桥。网桥创建后,需要将它指定到相应客户机的 .xml 配置文件中。
  • network — 这是一个虚拟网络,它可以与其它虚拟机共用。使用场景为:宿主机有 动态 网络(例如:NetworkManager)或使用无线网络。
  • macvtap — 直接连接到宿主机的一个物理网络接口。
  • user — 本地网络,仅用于用户 会话

绝大多数用户都可以通过 virsh 的各种可选项创建具有各种功能的网络,一般来说比通过 GUI 程序(像 virt-manager 之类)更容易做到。也可以按用 virt-install 新建域 所述实现。

注意: libvirt 通过 dnsmasq 处理 DHCP 和 DNS 请求,以启动每个虚拟网络的不同实例。也会为特定的路由添加 iptables 规则并启用 ip_forward 内核参数。这也意味着宿主机上已运行的dnsmasq并不是libvirt所必须的(并可能干扰到libvirt的dnsmasq实例)。

UEFI 支持

Libvirt 可以通过 qemu 和 OVMF 来支持 UEFI 虚拟机。 安装 ovmf 。 添加下面的内容到 /etc/libvirt/qemu.conf

$ vim /etc/libvirt/qemu.conf
nvram = [
    "/usr/share/ovmf/x64/OVMF_CODE.fd:/usr/share/ovmf/x64/OVMF_VARS.fd"
]

重启 libvirtd

现在你可以创建一个 UEFI 虚拟机了。 你可以通过 virt-manager 来创建。当你进行到向导的最后一步时:

  • 勾选在安装前自定义配置,之后点击完成
  • 概况屏幕, 将固件改为’UEFI x86_64'。
  • 点击开始安装
  • 在启动屏幕,你需要使用linuxefi命令来启动安装程序,并且你需要在系统中运行efibootmgr验证确实运行在UEFI模式下。

virt-manager: Shared folders with Linux Guest

Create a future share folder on your host and set up the permissions (for the purpose of this article I will grand all permissions):

root@host# mkdir /share
root@host# chmod 777 /share

Afterwards shut down the guest if it’s running and attach the new filesystem in virt-manager:

  1. Switch the view to detail hardware view: View > Details
  2. Go to Attach hardware > Filesystem
  3. Fill in the name of the source path (/share in our case) and virtual target path (anything you like, I will go with /sharepoint)
  4. Switch mode to Mapped if you need to have write access from the guest
  5. Confirm and start the VM again

Now you can mount your shared folder from the VM:

root@guest# mkdir /share
root@guest# mount -t 9p -o trans=virtio /sharepoint /share

Or permanently add it to /etc/fstab file:

root@guest# cat /etc/fstab
...
/sharepoint   /share    9p  trans=virtio,version=9p2000.L,rw    0   0

virt-manager: Shared folders with Windows Guest

You can not add a shared folder in virt-manager like it is described in your article because the filesystem passthrough doesn’t work well with a windows guest.

To solve your problem you have several options:

  1. You can share a folder in the local network at your linux host system via SAMBA and access it over the windows filesystem directly.
  2. You can use spice-webdav to share a folder like it is described in this article from Guy Rutenberg. This is not recommend for transferring large files.
  3. If you only want to transfer data one or two times instead of having a permanent shared folder you can pack the data in your host system into a .iso file and add it in virt-manager as a disc to access it in the windows guest system.

virt-manager: Change Default Storage Pool Location

在Create a new virtual machine 的 Setp4 of 5 的时候,选择 Selec or create custom sorage 就行。

QEMU-KVM Win7

环境准备

  1. 安装QEMU:sudo apt install qemu-kvm samba

  2. 下载 Windows virtio driver iso:https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.102/,因为要将磁盘挂接为 virtio 磁盘。

    需使用 virtio-win-0.1.102,我使用 latest 的 virtio-win-0.1.208.iso,Windows安装程序会提示驱动没有包含签名错误No signed device drivers were found. Make sure that the installation media contains the correct drivers, and then click OK

  3. 创建系统盘 qemu-img create -f qcow2 Windows7-VM.img 30G,这将作为Win7的操作系统盘。

  4. 创建启动脚本

    $ vi start_Windows7_VM.sh
    #!/bin/bash
    DISKIMG=$HOME/.vm/Windows7-VM.img
    exec qemu-system-x86_64 --enable-kvm \
        -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \
        -drive file=${DISKIMG},if=virtio \
        -net nic,model=virtio-net-pci -net user,smb=$HOME/Downloads \
        -m 8192 \
        -smp sockets=1,cores=4,threads=2 \
        -monitor stdio \
        -vnc :0 \
        -audiodev pa,id=snd0 -device ich9-intel-hda -device hda-output,audiodev=snd0 \
        -usb -device usb-tablet \
        -rtc base=localtime,clock=host  \
        -name 'Windows7 VM' \
        $@
    
    $ chmod u+x start_Windows7_VM.sh
    
  5. ./start_Windows7_VM.sh -boot d -cdrom $HOME/Downloads/cn_windows_7_ultimate_x64_dvd_x15-66043.iso -drive file=$HOME/Downloads/virtio-win-0.1.102.iso,index=3,media=cdrom

smp,socket,cores,threads几个参数的理解

结合physical server上lscpu命令的输出,对它们的关系梳理了一番

[root@pqsfc018 ~]# lscpu
...
CPU(s):        32
...
Thread(s) per core:  2
Core(s) per socket:  8
Socket(s):       2
...
  • socket就是主板上插cpu的槽的数目,也就是可以插入的物理CPU的个数。
  • core就是我们平时说的“核“,每个物理CPU可以双核,四核等等。
  • thread就是每个core的硬件线程数,即超线程

具体例子,上面这台服务器的CPU配置是2个socket,每个socket是8个core,每个core是超线程(2),这样,整台机器的对外的core就是282=32

SMP,对称多处理器(Symmetric Multi-Processors,简称SMP)是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。在这种技术的支持下,一个服务器系统可以同时运行多个处理器,并共享内存和其他的主机资源。像双至强,也就是我们所说的二路,这是在对称处理器系统中最常见的一种(至强MP可以支持到四路,AMD Opteron可以支持1-8路)。也有少数是16路的。但是一般来讲,SMP结构的机器可扩展性较差,很难做到100个以上多处理器,常规的一般是8个到16个,不过这对于多数的用户来说已经够用了。在高性能服务器和工作站级主板架构中最为常见,像UNIX服务器可支持最多256个CPU的系统,其实qemu从代码设计上也是最大支持256个virtual cpu。

安装 Win 7

  1. 选择 Custom(advanced)

img

  1. 选择 CD Drive (E:) virtio-win

img

  1. 选择 viostor

img

  1. 安装 Win7 Virtio SCSI Driver

img

  1. 安装好以后,就可以看到安装的目标磁盘了

img

  1. 进入常规的 Win7 安装流程

img

安装 Virtio 网络驱动

选择 NetKVM

img

但是安装失败:

img

尝试 device manager 安装:

img

[QEMU 的内置SMB服务器](#QEMU 的内置SMB服务器)

宿主机的USB设备传递至虚拟机

Questions

各种缺dll,好烦。

win7 64位安装wamp缺失vcruntime140.dll和api-ms-win-crt-runtime-l1-1-0.dll 等

安装VC redit.exe程序解决,链接:

Microsoft Visual C++ Install Error 0x80240017

右键 => 兼容性疑难解答

windows7 stop at “starting windows” while intalling on kvm

solved!

Look here:Windows 7 Setup hangs at “Starting Windows” using Proxmox 4.2

and add this to command line:

--video cirrus

QEMU-KVM WinXP SP3

太太太老了,很多软件都不支持了。

windows_xp.sh

#!/bin/bash
DISKIMG=$HOME/.vm/WindowsXP-VM.img
exec qemu-system-x86_64 --enable-kvm \
    -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \
    -drive file=${DISKIMG} \
    -net nic,model=rtl8139 -net user,smb=$HOME/Downloads \
    -m 4096 \
    -cpu Nehalem \
    -rtc base=localtime,clock=host  \
    -usb -device usb-tablet \
    -monitor stdio \
    -vga std \
    $@
Windows XP cannot connect to samba share

You have ‘client min protocol = NT1’ set, there is another similar setting ‘server min protocol’ which from Samba 4.11.0 is set to SMBv2. Your XP is probably only using SMBv1, so it will not be able to see or connect to your Samba server.

So you have to edit the [global] section in the /etc/samba/smb.conf and add the server min protocol = NT1 option here. Then restart the Samba service.

例如:

$ ps h -C smbd -o pid,args
1707 /usr/sbin/smbd --foreground --no-process-group
$ vim /tmp/qemu-smb.SL95F1/smb.conf
[global]
server min protocol = NT1
$ sudo smbcontrol 1707 reload-config

或者编写如下脚本

#!/bin/bash
echo "[global]
server min protocol = NT1" >> /tmp/**/smb.conf
sudo smbcontrol $(ps h -C smbd -o pid) reload-config
Windows XP 上网提示:您的时钟快了/慢了

此时,无论你怎么调整日期和时间,都不能解决上网问题。即使把日期从2020年调整到2015年,此时虽然不在提示 “您的时钟快了”,也有证书期限等异常。

出现这种问题的原因,是因为 Windows XP 确实太老了,Google Chrome、Mozilla Firefox 及其内核的浏览器已经不支持了。

Virtual Machine Manager

键盘不能输入的问题

在 Display 中,设定 keymap,比如 en-us

无网络

在 NIC 中,将 Device model 设置为 rtl8139

QEMU-KVM Gentoo

Configuration

Host

To create a disk image for the virtual machine, run:

$ qemu-img create -f qcow2 Gentoo-VM.img 30G

Download a minimal Gentoo LiveCD from here.

Since QEMU requires a lot of options, it would be a good idea to put them into a shell script, e.g.:

$ vim start_Gentoo_VM.sh
#!/bin/bash
DISKIMG=$HOME/VirtualMachine/Gentoo-VM.img
exec qemu-system-x86_64 -enable-kvm \
        -bios /usr/share/edk2-ovmf/OVMF_CODE.fd \
        -cpu host \
        -drive file=${DISKIMG},if=virtio \
        -netdev user,id=vmnic,hostname=Gentoo-VM,hostfwd=tcp::10022-:22,smb=$HOME/Downloads \
        -device virtio-net,netdev=vmnic \
        -device virtio-rng-pci \
        -m 4G \
        -smp sockets=1,cores=4,threads=2 \
        -monitor stdio \
        -vnc :0 \
        -audiodev pa,id=snd0 -device ich9-intel-hda -device hda-output,audiodev=snd0 \
        
        -rtc base=localtime,clock=host  \
        -name "Gentoo VM" \
        $@

$ chmod u+x start_Gentoo_VM.sh

Change the path to your disk image Gentoo-VM.img in the script. You can add more options when calling the script. To boot the disk image, run:

$ ./start_Gentoo_VM.sh -boot d -cdrom $HOME/Downloads/install-amd64-minimal-20211107T170547Z.iso

Install the guest per the Gentoo Handbook. See the guest section for optimum support. After the installation start the script without the additional options.

Using UEFI with QEMU

UEFI for x86 QEMU/KVM VMs is called OVMF (Open Virtual Machine Firmware). It comes from EDK2 (EFI Development Kit), which is the UEFI reference implementation.

$ sudo apt-get install ovmf 

检查是否安装,命令为:

$ dpkg -L ovmf | grep OVMF.fd 
/usr/share/ovmf/ OVMF.fd
/usr/share/qemu/ OVMF.fd

要在虚拟机中运行操作系统的映像文件,添加 -bios /usr/share/ovmf/OVMF.fd。该代码调用名为 OVMF.fd 的文件,该文件是 Qemu 的 UEFI 固件。

$ qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -cdrom ubuntu-21.04-desktop-amd64.iso

这个名为ovmf的包其实就是名为TianoCore的程序。该名称本身代表开放虚拟机固件)。

“BdsDxe: failed to load Boot0001”

solution: Try hitting F2 to enter the OVMF settings during guest boot and manually pick a new boot drive option.

VirtualBox

执行 .vbs 文件

$ cscript test.vbs

删除备份

删除虚拟机备份,当前状态前一个备份删除得快,两个备份之间的备份删除得慢。

共享文件夹

固定分配的共享文件夹对于定义共享文件夹的虚拟机是永久存在的;

临时分配的共享文件夹在虚拟机运行时添加/删除,虚拟机关闭后消失。

把img系统镜像转为VDI或VMDK格式文件

$ VBoxManage convertdd *.img  *.vdi

在 virtualbox 新建虚拟机时指定 vdi 硬盘文件,就可以安装系统

启动本地磁盘上的其它系统

增加现有虚拟机的磁盘大小

下面是你迟早会遇到的情况。

你在 VirtualBox 中安装了一个或多个操作系统。在创建这些虚拟操作系统的同时,你还在 VirtualBox 中为它们创建了虚拟硬盘。

你指定了虚拟磁盘的最大大小,比如说 15 或 20GB,但现在使用了一段时间后,你发现你的虚拟机已经没有空间了。

虽然在 Ubuntu 和其他操作系统上有释放磁盘空间的方法,但更稳健的处理方式是增加 VirtualBox 中创建的虚拟机的磁盘大小。

是的,你可以在 VirtualBox 中扩大虚拟硬盘,即使在创建之后也可以。虽然这是一个安全且经过测试的过程,但我们强烈建议你在执行这样的操作之前,先创建一个虚拟机的备份。

我将向你展示如何在 VirtualBox 中以图形和命令行(对于 Linux 极客)方式调整磁盘大小。这两种方法都很简单直接。

方法 1:在 VirtualBox 中使用虚拟媒体管理器

VirtualBox 6 增加了一个调整虚拟磁盘大小的图形化选项。你可以在 VirtualBox 主页的文件选项卡中找到它。

进入 “File -> Virtual Media Manager”:

在列表中选择一个虚拟机,然后使用 “Size” 滑块或输入你需要的大小值。完成后点击 “Apply”。

请记住,虽然你增加了虚拟磁盘的大小,但如果你的空间是动态分配的,那么实际的分区大小仍然不变

方法 2:使用 Linux 命令行增加 VirtualBox 磁盘空间

如果你使用 Linux 操作系统作为宿主机,在宿主机中打开终端并输入以下命令来调整 VDI 的大小:

VBoxManage modifymedium "/path_to_vdi_file" --resize <megabytes>

在你按下回车执行命令后,调整大小的过程应该马上结束。

注意事项

VirtualBox 早期版本命令中的 *modifyvdimodifyhd 命令也支持,并在内部映射到 modifymedium 命令。

如果你不确定虚拟机的保存位置,可以在 VirtualBox 主页面点击 “Files -> Preferences” 或使用键盘快捷键 Ctrl+G 找到默认位置。

Seamless Mode

虚拟机通常在一个窗口中运行来宾操作系统及其程序。但是,VirtualBox和VMware都有一些功能,允许您在主机桌面上运行虚拟化程序,从而将它们从监狱中释放出来。…

这意味着您可以在不使用虚拟机窗口和来宾操作系统桌面的情况下使用程序。如果使用多个监视器,甚至可以将虚拟机中的不同窗口放置在不同的监视器上。

工作原理

所有这些特性都同样工作。启动虚拟机,启动您想要使用的程序,然后启用“无缝模式”或“统一模式”。来宾操作系统的桌面和虚拟机窗口将消失,将来宾操作系统的窗口留在桌面上。它们看起来正在运行,好像它们在您的主机操作系统上运行,但虚拟机仍在后台运行。程序仍然是沙盒,因此它们无法访问主机操作系统的文件——它们似乎正在主机操作系统上运行。

无论您使用的是Windows、Linux还是Mac,这些技巧都有效。您可以在Linux桌面上无缝运行Windows程序,也可以在Windows桌面上运行Linux软件。

使用virtualbox的无缝模式

请注意,VirtualBox只允许您在Windows、Linux和Solaris客户机上使用此功能。如果你设法让MacOSX在VirtualBox虚拟机上运行,或者你正在使用像俳句这样的小众操作系统,你将无法使用这个功能。

在使用此功能之前,必须在要使用的来宾虚拟机内安装VirtualBox来宾添加软件包。如果您还没有这样做,请启动虚拟机,单击“设备”菜单,然后选择“安装来宾添加”。系统将提示您安装软件。

要使用此功能,请同时按“主机键”(通常是右Ctrl键,但它显示在虚拟机窗口的右下角)和“L”。也可以单击“视图”菜单,然后选择“切换到无缝模式”。

VirtualBox将隐藏来宾操作系统的桌面背景,使其看起来好像来宾操作系统的程序正在主机操作系统的桌面上运行。但是,正在运行的应用程序不会出现在操作系统的标准任务栏上。

要退出无缝模式,只需按主机键,然后再次按L。您还可以在任务栏上方找到VirtualBox菜单,您可以将鼠标悬停在上面查看。单击查看并再次选择切换到无缝模式以禁用无缝模式。

使用vmware的unity模式

VMware有一个类似的功能,名为Unity mode。它可以在免费的VMware Player、VMware Workstation和VMware的其他付费应用程序上使用。与VirtualBox一样,VMware的Unity模式适用于Windows和Linux客户机。

VBox+WinXP SP3

Windows XP; Guest Additions installation stuck; Virtualbox 6.1.18

Disconnect network. It helps me.

VS VMWare

工具是用来解决问题的,没必要看到开源就意识形态附体

虚拟机网络模式

桥接

桥接网络是指本地物理网卡和虚拟网卡通过VMnet0虚拟交换机进行桥接,物理网卡和虚拟网卡在拓扑图上处于同等地位,那么物理网卡和虚拟网卡就相当于处于同一个网段,虚拟交换机就相当于一台现实网络中的交换机,所以两个网卡的IP地址也要设置为同一网段。

所以当我们要在局域网使用虚拟机,对局域网其他pc提供服务时,例如提供ftp,提供ssh,提供http服务,那么就要选择桥接模式。

例如大学宿舍里有一个路由器,宿舍里四个人连接这个路由器,路由器的wanip就不理会了,这个ip是动态获取的,而lanip默认是192.168.1.1,子网掩码是255.255.255.0。而其他四个人是自动获取ip,假设四个人的ip是:

A:192.168.1.100/255.255.255.0,

B:192.168.1.101/255.255.255.0

C:192.168.1.102/255.255.255.0

D:192.168.1.103/255.255.255.0

那么虚拟机的ip可以设置的ip地址是192.168.1.2-192.168.1.99,192.168.1.104-192.168.1.254 (即网络地址全0和全1的除外,再除去ABCD四个人的ip地址)

那么虚拟机的ip地址可以设置为192.168.1.98/255.255.255.0,设置了这个ip地址,ABCD这四个人就可以通过192.168.1.98访问虚拟机了,如果虚拟机需要上外网,那么还需要配置虚拟机的路由地址,就是192.168.1.1了,这样,虚拟机就可以上外网了,但是,上网我们一般是通过域名去访问外网的,所以我们还需要为虚拟机配置一个dns服务器,我们可以简单点,把dns服务器地址配置为google的dns服务器:8.8.8.8,到此,虚拟机就可以上网了。

NAT

NAT模式中,就是让虚拟机借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。

NAT模式中,虚拟机的网卡和物理网卡的网络,不在同一个网络,虚拟机的网卡,是在vmware提供的一个虚拟网络。

NAT和桥接的比较:

  • NAT模式和桥接模式虚拟机都可以上外网。
  • 由于NAT的网络在vmware提供的一个虚拟网络里,所以局域网其他主机是无法访问虚拟机的,而宿主机可以访问虚拟机,虚拟机可以访问局域网的所有主机,因为真实的局域网相对于NAT的虚拟网络,就是NAT的虚拟网络的外网。
  • 桥接模式下,多个虚拟机之间可以互相访问;NAT模式下,多个虚拟机之间也可以相互访问。

如果你建一个虚拟机,只是给自己用,不需要给局域网其他人用,那么可以选择NAT,毕竟NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,只要虚拟机的网路配置是DHCP,那么你不需要进行任何其他的配置,只需要宿主机器能访问互联网即可,就可以让虚拟机联网了。

例如你想建多个虚拟机集群,作为测试使用,而宿主机可能是一个笔记本,ip不固定。这种应用场景,我们需要采用nat模式了,但是我们要考虑一个问题,虚拟机之间是需要互访的,默认采用dhcp,虚拟机的ip每次重启,ip都是不固定的,所以我们需要手工设置虚拟机的ip地址。

Host-Only

在Host-Only模式下,虚拟网络是一个全封闭的网络,它唯一能够访问的就是主机。其实Host-Only网络和NAT网络很相似,不同的地方就是Host-Only网络没有NAT服务,所以虚拟网络不能连接到Internet。主机和虚拟机之间的通信是通过VMware Network Adepter VMnet1虚拟网卡来实现的。

Host-Only的宗旨就是建立一个与外界隔绝的内部网络,来提高内网的安全性。这个功能或许对普通用户来说没有多大意义,但大型服务商会常常利用这个功能。

VMware

用 VMware 的坑:我用普通账户创建虚拟机,然后它安装 vmware tools 需要 root 权限,用 root 权限开启 VMWare 的话,就没有之前的虚拟机了。所以,最好一开始,就用 root 权限运行 VMWare。

Errors- vmware unable to install all modules vmmon vmnet

In case you get Gcc not found and Kernel modules compiling error upon starting the Vmware, then you have to install them. For that, first, close the Vmware Player window and then run the below two commands:

$ sudo apt install gcc
$ sudo apt-get install build-essential

After that start the Vmware player again and start installing the modules. If you still have the error then follow the further steps.

  • Download the latest vmware-host-modules – VMMON and VMNET

Visit: https://github.com/mkubecek/vmware-host-modules

There as per your Vmware Player station, download the module file. For example– while doing this article the version of Workstation was 16.2.3, hence we download the same module file in zip format.

The file we download using the browser goes to the Downloads directory. Hence, switch to that.

$ cd Downloads
$ sudo apt install unzip
$ unzip vmware-host-modules-w16.2.3-k5.18.zip
$ cd vmware-host-modules-w16.2.3-k5.18
$ tar -cf vmmon.tar vmmon-only
$ tar -cf vmnet.tar vmnet-only
$ sudo cp -v vmmon.tar vmnet.tar /usr/lib/vmware/modules/source/
$ sudo vmware-modconfig --console --install-all

Uninstall or Remove Vmware Linux

$ cd /usr/bin
$ sudo ./vmware-installer -u vmware-player

反虚拟机检测

在开发测试中,不少人会选择使用虚拟机环境来进行,以避免对主机产生影响,特别是一些软件类测试,比如病毒分析等VMWare等。在实际测试中会发现,相当一部分软件或代码也在进行反虚拟机来逃避分析,这种技术可以检测自己是否运行在虚拟机中,如果探测到自己在虚拟机中运行,它就会执行与其本身行为不同的行为,这时候就无法达到我们测试的目的了。因此我们可以考虑通过修改配置来达到让虚拟机内运行的软件无法探测到虚拟机环境的目标。

探测方向

不管是通过 VMware 还是 Oracle VirtualBox 抑或是 Microsoft Hyper-V,只要是虚拟出来的环境,都或多或少会有痕迹存在,目前用来探测的比较多的痕迹有以下几个。

MAC 地址

这是最明显的特征。通常 MAC 地址的前三个字节标识一个提供商。以 00:05:69、00:0c:29 和00:50:56 开始的 MAC 地址与 VMware 相对应;以 00:03:ff 开始的 MAC 地址与 virtualpc 对应;以 08:00:27 开始的 MAC 地址与 VirtualBox 对应。

其他硬件信息

虚拟机环境中,主板序列号、主机型号、系统盘所在磁盘名称等硬件信息,以及这些硬件采用的驱动,通常都会带有 VMware、VirtualBox、VBOX、Virtual Machine 等字眼。

特定的进程信息

为方便使用,比如自动捕获鼠标、分辨率自适应等,我们会安装 VMware Tools 或者 VBoxGuestAdditions 等增强包,这也是虚拟机环境非常明显的一个特征。通过进程快照读取当前进程信息,查找是否存在虚拟机中特有的进程,如 VMware 中的 vmware.exe 和 VirtualBox 中的 VBoxService.exe。

特定的文件夹或文件信息

通过查找磁盘中是否存在特定的文件夹或文件,判断当前是否在虚拟机中。VMware 虚拟机中通常会有路径 C:\Program Files\VMware\VMware Tools\;VirtualBox 虚拟机中通常会有路径 C:\Program Files\Oracle\VirtualBox Guest Additions\。

特定的注册表信息

通过读取主机具有虚拟机特性的注册表位置来判断是否处于虚拟机环境中。针对 VMware 可以判断注册表项 HKEY_CLASSES_ROOT\Applications\VMwareHostOpen.exe;针对 VirtualBox 可以判断注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\VirtualBox Guest Additions。当然,注册表中能被检测出的位置很多,这里只是举个例子。

特定的服务名

通过获取主机当前具有虚拟机特性的服务信息,判断当前主机是否为虚拟机。在 VMware 中通常会存在 VMware 物理磁盘助手服务和VMware Tools服务等;在 VirtualBox 中通常会存在VirtualBox Guest Additions Service服务等。

时间差

由于在虚拟机中,代码的运行速度通常不如真实主机。所以通过运行一段特定的代码来比较这段代码在虚拟机和真实主机之中的相对运行时间,以此来判断是否处于虚拟机之中。

其他

上面说的几种方法都能够检测虚拟机,但检测的方法却不仅限于此,有兴趣的可以再深入研究。

反探测

近年来,随着虚拟化技术的使用不断增加,采用反虚拟机技术的软件数量逐渐下降,编写者已经开始意识到,目标主机是虚拟机,也并不意味着它就没有攻击价值,特别在于目前云计算产业正在如火如荼地发展中。

以 VMware 为例,我们可以通过下面的方法来解决上文探测方向中的大部分痕迹。由于修改信息可能会导致系统激活状态失效,或者修改后配置不生效,故建议在创建虚拟机时就修改好。

修改软件信息

  • VMTools 接口

直接将下面的代码贴到虚拟配置文件 .vmx 中(如果是 EXSi,建议通过 WEB 控制面板来修改配置),屏蔽 VMware 特定信息的探测:

isolation.tools.getPtrLocation.disable = "TRUE"
isolation.tools.setPtrLocation.disable = "TRUE"
isolation.tools.setVersion.disable = "TRUE"
isolation.tools.getVersion.disable = "TRUE"
monitor_control.disable_directexec = "TRUE"
monitor_control.disable_chksimd = "TRUE"
monitor_control.disable_ntreloc = "TRUE"
monitor_control.disable_selfmod = "TRUE"
monitor_control.disable_reloc = "TRUE"
monitor_control.disable_btinout = "TRUE"
monitor_control.disable_btmemspace = "TRUE"
monitor_control.disable_btpriv = "TRUE"
monitor_control.disable_btseg = "TRUE"
monitor_control.restrict_backdoor = "TRUE"

驱动信息

主要是显卡,先安装 VMware Tools 装好驱动,备份出显卡驱动,然后修改驱动中的安装文件 *.inf,将 STRING 一节中的相关字眼修改掉,再还原驱动。

DiskID = "NVIDIA Windows Driver Library Installation"
CompanyName = "NVIDIA"
SVGA = "GeForce GTX 660"

在这一步中,需要安装 VMware Tools 才会有显卡驱动,但是上面修改了配置,将无法安装 VMware Tools,会提示“只应安装在虚拟机内”。由于安装 VMware Tools 将会是一个非常明显的特征,因此不建议安装。且虚拟机驱动其实都是一样的,因此可以从其他虚拟机中导出来直接使用。

修改硬件信息

  • 主板信息

下面的代码表示延用实体机的主板信息:

SMBIOS.reflecthost = "TRUE"
SMBIOS.noOEMStrings = "TRUE"
SMBIOS.addHostVendor = "TRUE"
hw.model.reflectHost = "TRUE"
serialNumber.reflectHost = "TRUE"
board-id.reflectHost = "TRUE"

也可以自己编一个,比如在黑苹果中会用到的:

smbios.reflectHost = "FALSE"
smbios.vendor = "Apple Computer, Inc."
smbios.version = "MBA51.88Z.0055.B08.0610121"
smbios.family ="MacBook Pro"
smbios.model = "MacBookPro1.1"
smbios.date ="10/12/06"
smbios.manufacturer = "Apple Computer, Inc."
smbios.systemversion = "1.0"
  • 磁盘信息

如果在 scsi0 插槽上有 SCSI 虚拟磁盘作为系统驱动器,可以添加:

scsi0:0.productID = "WDC_____WD10EZEX-57WN4D11"
scsi0:0.vendorID = "WDC"

scsi0:0 表示第一个插槽,其他硬件也可以类似指定 ID。

  • 网卡信息

参考实体机 MAC 地址信息,自行编一个:

ethernet0.checkMACAddress = "FALSE"
ethernet0.address = "BC:30:5B:DD:D2:E8"

以上的方法能够解决大部分的虚拟机探测,但是一些使用寄存器值、任务状态段(Task Status Segment, TSS)、I/O 接口等检测方法的软件,仍然骗不过。

参考文章:

1、《反虚拟机技术总结》 2、《过虚拟机检测》 3、《解决VMware Tools提示 “只应安装在虚拟机内"的问题》 4、《VM反虚拟机检测》 5、《那些年病毒用过的损招——反虚拟机技术

相关文章:

1、《VMware Workstation Pro 最新版下载及永久激活 KEY 激活码序列号》 2、《重制:VMware 15 Pro 安装黑苹果 macOS10.13.5 图文教程:流畅、好用!

Questions

piix4_smbus Host SMBus controller not enabled

从内核的说明文档来看,这个 piix4 实际上是 Intel 82371AB 南桥芯片,多功能总线控制器,而在 VMware 里面并没有这个真实的芯片组,但在启动时最会尝试载入这个驱动模块,所以会报错,但对系统没有任何影响。

Others

通过 Qemu 安装 Windows 到硬盘

双系统新思路。今天装windows, 在linux上先用虚拟机,把硬盘直通进去,在raw盘上装好,然后更新grub, 再重启就可以直接接进去了。

这样可以避免装机还要做启动盘,装机过程中的重启也可以避免了。

win的安装过程中驱动都是按照虚拟机的配置安装的,但是win10是自动装驱动的,重启进去后过了一会显卡驱动自动都装好了。

Boot a physical Windows partition with qemu

Booting an native, physical Windows 7 partition can be done by this:

  1. Prepare requisites (Windows 7 installation media, Virtio drivers).
  2. Make your hard drive accessible read-only for your current user.
  3. Boot it using QEMU in snapshot mode.

This does not change anything on the physical drive (in fact it is read-only). If you want to persist the stuff, remove -snapshot from the QEMU invocation or use commit all within the QEMU console.

By the way, this works fine for Windows 10 as well.


Prepare requisites

  1. Prepare an ISO or, if you have a drive at hand, the real installation media for Win7.
  2. Download Virtio drivers, e.g. for example this drivers from Fedora: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso

Take care to use the correct installation media matching the installed Windows architecture (32bit vs 64bit). The following commands assume a 64bit architecture.

Make disk accessible

This assumes your hard drive is /dev/sda and has be executed as root:

chmod g-w /dev/sda
chgrp $USER /dev/sda

This changes will (probably) be lost at next reboot as udev will usually recreate all device files.

Booting with QEMU

  1. This again assumes your hard drive is /dev/sda. Networking is disabled:

    qemu-system-x86_64 -snapshot -m 3G -enable-kvm -usbdevice tablet \
    -drive file=/dev/sda,if=virtio \
    -drive file=<win7-installation-media> \
    -drive file=<virtio-driver-media>,media=cdrom -boot d \
    -net none
    
  2. Now boot from CD/DVD to start Windows 7 recovery, load the Virtio driver and run the following command in the recovery command prompt. Ensure that you replace the drive letters with the proper ones:

    dism /image:g:\ /add-driver /driver:e:\viostor\w7\amd64
    

Drive G: is the drive containing your Windows 7 installation. Drive E: represent the CDROM drive with the Virtio drivers. In order to show some help for this command variant use dism /image:g:\ /?.

The dism command was copied from this Super User answer.

补充

Looking Glass

Looking Glass 讓 Linux 可完美玩 Windows 遊戲 超低延遲不掉格

當用戶安裝了虛擬電腦(VM)實行 Windows,並執行遊戲時,它採用的 KVM frame relay 技術可將 Windows 顯示記憶體,透過 PCI pass-through 直接由 Windows VM 被配置的顯示卡,複製到 Linux 被配置的顯示卡,這樣 Linux 便可在極為低延遲的情況下,接近完美顯示 Windows 遊戲的內容。

簡單來說,就是一部 Linux 電腦裡面裝有虛擬電腦運行的 Windows,Windows 遊戲實行時,在被配置的顯示卡記憶體資料,在主機板 PCI 通道直接複製到 Linux 被配置的顯示卡。即是說 Windows 遊戲原本畫面,可高速反映到 Liunx 的虛擬電腦軟件上。這樣 Linux 用戶就算不 Dual boot 或使用兩個熒幕,在 Linux 上都可得到接近相同的打機體驗。

xrdp

xrdp 使用 RDP(Microsoft 远程桌面协议)为远程计算机提供图形登录。xrdp 接受来自各种 RDP 客户端的连接:FreeRDP、rdesktop、NeutrinoRDP 和 Microsoft 远程桌面客户端(适用于 Windows、macOS、iOS 和 Android)。

正如 Windows 到 Windows 远程桌面一样,xrdp 不仅支持图形远程处理,还支持

  • 双向剪贴板传输(文本、位图、文件)
  • 音频重定向
  • 驱动器重定向(在远程机器上安装本地客户端驱动器)

RDP 传输默认使用 TLS 加密。

QEMU/KVM VS Virtualbox

Linux 系统上的虚拟化解决方案 – KVM 和 VirtualBox

KVM 提供了一些 VirtualBox 没有的功能,反之亦然。IT 世界中没有通用工具,因此使用适合您需求的工具非常重要。基本思想是:如果你想安装二进制 Linux 发行版作为来宾,使用 KVM。它速度更快,并且它的驱动程序包含在官方内核树中。如果您的客户涉及大量编译并且需要一些更高级的功能,并且/或者不是 Linux 系统,那么最好使用 VirtualBox。

技术原因很简单:KVM 更好地与 Linux 集成,它更小更快,虽然你可以在 Linux 以外的其他客户机上使用它,但我们发现体验相当麻烦:BSD 的 I/O 和 Solaris 往往很慢(确切地说,是 OpenIndiana)在引导安装 ISO 后会立即出现恐慌。由于我们使用当前版本的 BSD(并且经常从源代码编译/更新系统)并且还需要 Solaris,我们发现 VirtualBox 是一个更好的选择。Oracle VirtualBox 的另一个优点是它支持挂起,即您可以将机器状态保存在主机的硬盘上并关闭 VirtualBox,当(重新)启动时,系统将从它离开的地方恢复。这就是为什么我们提到源代码编译:如果你有一台嘈杂的机器,你不想一夜之间离开,但你的 Gentoo 虚拟机只是编译一个新的 gcc 版本,暂停机器状态,关闭主机,明天继续。

桌面虚拟化、KVM 还是 Virtualbox?

这两者中的哪一个更适合在 Linux 台式机/笔记本电脑上运行 Windows 10 虚拟机?

  • 带有virt-manager 的QEMU/KVM应该可以与 Virtualbox 媲美。

    Virtualbox 没问题,特别是如果跨主机操作系统使用相同的虚拟化很重要,但 QEMU/KVM 是更好的投资。QEMU/HAXM 也应该可以在 Mac 和 Windows 上运行,尽管它目前还不够成熟。

  • KVM, obviously. You’re probably going to need to learn how to manage it, but it is a much better system and allows abstraction on completely unexposed CPU hardware so you can easily take your image and put it onto another KVM. Windows doesn’t like to have it’s CPUs exchange on it very often.

KVM 与 VirtualBox

  • 表现

    这是要考虑的最重要的领域之一,即管理程序的性能将如何影响您的基础架构。KVM 是 1 类管理程序(这些虚拟机管理程序直接运行在宿主机的硬件上来控制硬件和管理客操作系统),而 VirtualBox 是 2 类管理程序(这些虚拟机管理程序运行在传统的操作系统上,就像其他计算机程序那样运行),这意味着 KVM 应该优于 VirtualBox。

    根据SPECvirt_sc2013 基准测试,VirtualBox 通常比 KVM 需要更多时间来创建和启动服务器,而 KVM 以接近本机的速度运行应用程序,比其他行业管理程序更快。尽管对于典型负载,差异可能微不足道。

  • 管理程序管理

    这两个给定的应用程序都可以通过 GUI 进行管理。Virtualbox 相对来说有更好的 GUI,但 KVM 的当前 GUI 使其管理比以往任何时候都更容易。”

    如果您更喜欢命令行,那么 KVM 中有各种命令行选项。Virtualbox 也提供了一个命令行界面,但它不如 KVM virsh 全面。您不能直接从 bash 启动 Virtualbox VM。

  • 可扩展性

    KVM 继承了 Linux 的性能,如果来宾机器和请求的数量增加,可以扩展以匹配需求负载。KVM 允许对要求最苛刻的应用程序工作负载进行虚拟化,并且是许多企业虚拟化设置的基础,例如数据中心和私有云。

    VirtualBox 可以为每个 VM 提供多达 32 个虚拟 CPU,而不管主机上物理存在多少 CPU 内核。还可以为具有多达 1024 个 CPU 的主机提供支持。

  • 安全

    KVM 提供增强的安全性,因为它结合使用 SELinux 和安全虚拟化 (sVirt)。VirtualBox 可以执行虚拟机的安全实时迁移和磁盘映像加密。它还包括远程桌面协议 (RDP) 身份验证和用于创建进一步身份验证要求以帮助提高安全性的 SDK。您可以在此页面上看到 Virtualbox 的安全功能列表。

  • 成本和定价

    KVM 是一个开源的免费平台,由 Red Hat 等供应商提供有偿支持。虽然 Virtualbox 在限制范围内是免费的。一旦您超过一定的使用水平,您必须获得产品许可。

  • 支持

    对于 KVM,您需要依赖开源社区和您自己的 IT 组织或受支持的供应商(如红帽)的支持。Oracle 正在积极开发 Virtualbox,您可以从他们那里获得任何支持。

Android-x86

android x86 是一个自由而开源的项目,将谷歌制作的安卓系统从 ARM 架构移植到了 x86 架构,可以让用户在他们的桌面电脑上运行安卓系统来享受所有的安卓功能和应用程序及游戏。

首次启动运行该安卓系统,运行:

$ qemu-img create -f qcow2 Android8-VM.img 30G
$ gedit start_Android8_VM.sh
#!/bin/bash
DISKIMG=/media/kurome/Ventoy/QemuKVM/Android8-VM.img
exec qemu-system-x86_64 --enable-kvm \
  -hda ${DISKIMG} \
  -net nic -net user \
  -m 4096 \
  -smp cores=2,threads=4 \
  -monitor stdio \
  -vga std \
  -soundhw es1370 \
  -usb -device usb-tablet \
  -name 'Andriod8 VM' \
  $@
$ chmod u+x start_Android8_VM.sh
$ ./start_Android8_VM.sh -boot d -cdrom ~/Downloads/android-x86_64-9.0-r2.iso

在,安卓系统已经完全安装在你的 android.img 文件中,你应该使用下面的 QEMU 命令来启动它,而不是前面的命令:

$ ./start_Android8_VM.sh

Waydroid

Waydroid是一个基于lxc容器技术,用以启动完整安卓系统的方案。

Genymotion

Android Virtual Devices for all your development & testing needs

LibVF.IO

Commodity GPU Multiplexing Driven By VFIO & YAML.

OSX-KVM

macOS VM in QEMU

$ git clone --depth 2 --recursive https://github.com/kholia/OSX-KVM.git
$ cd OSX-KVM
$ echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs
$ sudo cp kvm.conf /etc/modprobe.d/kvm.conf
$ ./fetch-macOS-v2.py
$ dmg2img -i BaseSystem.dmg BaseSystem.img
$ qemu-img create -f qcow2 mac_hdd_ng.img 128G
$ 
  • 使用 --depth 2,方便 git reset --hard
  • 基本上只需要改 OpenCore-Boot.sh 就行了,比如可以用别人制作好的 iso 镜像,而不用 BaseSystem.dmg(这是个恢复镜像,通过其再下载完整系统)。
  • 不要在设置里改 Resolution,改了之后更差。openSUSE 默认用 vnc,桌面分辨率太高根本显示不全,无法改设置了,vnc 也尝试关闭关不了,烦。
  • Ventura 选择 APFS 安装后报错 an error occurred preparing the update,选择 non-APFS filesystem 则安装成功了。(20221215)

quickemu

Quickly create and run optimised Windows, macOS and Linux desktop virtual machines.