浅谈wsl
本文简单介绍了WSL的工作原理。
介绍
Windows Subsystem for Linux(WSL)是一个用于在本地运行linux二进制可执行文件(ELF格式)的兼容层。
在软件工程领域,兼容层是一个允许面向旧或异质系统的二进制文件运行在特定主机系统上的接口。这意味着将面向异质系统的系统调用转换为面向主机系统。有些库会面向异质系统,这通常是为主机系统提供运行异质二进制文件的能力。而硬件兼容层工具允许硬件仿真。
与虚拟机相比,wsl没有虚拟硬件的过程,而是直接在windows上虚拟一个linux内核,模拟linux系统调用,以运行linux执行文件。
可以简单的将它理解为可以运行linux可执行文件的、类似于powershell的shell,具有互操作性(在linux中执行windows命令,在windows中执行linux命令)。
虚拟机技术的原理
Hypervisor
Hypervisor(虚拟机管理器)是一种运行在物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享一套基础物理硬件,因此也可以看作是虚拟环境中的“元”操作系统,它可以协调访问服务器上的所有物理设备和虚拟机,也叫虚拟机监视器(Virtual Machine Monitor)。
WSL原理
wsl组件
wsl实现的组件涉及到了用户和内核模式。在Windows NT内核模式中,LXCore,LXSS这两个驱动提供了linux内核调用的实现,即将linux调用转化为对应的windows NT内核调用;还提供了两种文件系统:VolFs(挂载在/目录上,支持linux文件系统所有特性)和DriverFs(挂载在/mnt/c,/mnt/d等等windows分区,主要为了支持系统间的互操作性);驱动还会模拟内核的行为,对linux进程进行调度。
在用户模式下,windows提供了一种特殊的进程类型:Pico进程,来支持linux进程的运行。windows会 “放松” 对该类型进程的控制,主要交由linux虚拟内核调用和管理,即隔离性(因此需要系统的支持,低版本的系统不能使用wls的功能)。pico会将ELF二进制可执行文件装入到自己的地址空间,然后执行在linux虚拟内核提供的兼容层上。一个pico对应一个linux进程,并且pico进程也是windows的一种特殊进程,因此你可以在任务管理器上看到linux进程。
无论exe还是elf格式的二进制文件,原理上都可以在同架构的cpu上执行,只是结构不同操作系统不能解析罢了。而Pico能够解析ELF格式的二进制文件,只需要linux虚拟内核能够提供正确的系统调用,就能够运行大部分linux命令。
LXSS管理服务主要用于协调windows和linux进程之间的关系,和给于Bash.exe(并不是shell,只是我们访问wsl的入口)调用linux命令的接口。所有的运行的linux进程都会被加入到叫Linux实例(应该有LXSS记录的)中,只有第一次请求访问linux进程时才会创建Linux实例,才会创建init进程;当window关机时,会自动关闭linux实例,即关闭linux所有进程。
也就是wsl不会随windows系统自启而自启,同时没有使用发行版的init进程,导致wsl中没有服务的存在。
COM简介
Microsoft 组件对象模型 (COM) 定义了一个二进制互操作性标准,用于创建在运行时交互的可重用软件库。 无需将它们编译到应用程序中即可使用 COM 库。 COM 是许多 Microsoft 产品和技术的基础,例如Windows 媒体播放器和Windows服务器。
Pico Process
As part of Project Drawbridge, the Windows kernel introduced the concept of Pico processes and Pico drivers. Pico processes are OS processes without the trappings of OS services associated with subystems like a Win32 Process Environment Block (PEB). Furthermore, for a Pico process, system calls and user mode exceptions are dispatched to a paired driver.
Pico processes and drivers provide the foundation for the Windows Subsystem for Linux, which runs native unmodified Linux binaries by loading executable ELF binaries into a Pico process’s address space and executes them atop a Linux-compatible layer of syscalls.
System Call
WSL executes unmodified Linux ELF64 binaries by virtualizing a Linux kernel interface on top of the Windows NT kernel.
On native Linux, when a syscall is made from a user mode executable it is handled by the Linux kernel. On WSL, when a syscall is made from the same executable the Windows NT kernel forwards the request to lxcore.sys. Where possible, lxcore.sys translates the Linux syscall to the equivalent Windows NT call which in turn does the heavy lifting. Where there is no reasonable mapping the Windows kernel mode driver must service the request directly.
File System
File system support in WSL was designed to meet two goals.
- Provide an environment that supports the full fidelity of Linux file systems
- Allow interoperability with drives and files in Windows
The Windows Subsystem for Linux provides virtual file system support similar to the real Linux kernel. Two file systems are used to provide access to files on the users system: VolFs and DriveFs.
VolFs
VolFs is a file system that provides full support for Linux file system features, including:
- Linux permissions that can be modified through operations such as chmod and chroot
- Symbolic links to other files
- File names with characters that are not normally legal in Windows file names
- Case sensitivity
Directories containing the Linux system, application files (/etc, /bin, /usr, etc.), and users Linux home folder, all use VolFs.
Interoperability between Windows applications and files in VolFs is not supported
wsl运行过程
一个正常完整的Linux系统的启动过程为:引导程序载入内核,内核初始化后载入init进程。init开启各项服务。
wsl并不是一个真正的系统,它是一个可以执行Linux ELF的程序。wsl的内核是虚拟内核,具有一定的隔离性。
wsl的工作流程为:windows自启结束并加载了LxCore/LXSS两个驱动后,准备工作结束。当用户执行bash.exe时,创建linux实例,执行init服务进程。然后创建bash shell和另一个init进程,在本次会话结束时(关闭Bash.exe窗口)这两个进程结束。之后再通过Bash.exe连接wsl,都只会创建bash和右边的init进程。
文件系统
上述讲到了,wsl只有两种windows设计的文件系统:VolFs和DriverFs。其中VolFs文件系统主要是为了支持linux文件系统的全部特性,如linux的文件权限、符号链接、不同于windows的文件名、文件名大小写敏感等等。
而DriveFs主要是为了挂载windows的分区,并且实现互操作性而存在。实际上就是NTFS文件系统的包装,能够让NTFS在linux中使用,即使也提供了大部分linux文件系统特性,但是限制很多,如:
- 文件目录权限全为777,实际上就算是root用户,在windows分区中也只有打开Base.exe命令拥有者的权限。说明普通用户使用root权限也不能修改c盘中大部分文件。
- 最好不要在windows下创建文件名只有大小写不同的文件,尽管NTFS支持了。
- 支持linux符号链接,为windows可执行文件创建符号链接时,注意添加后缀.exe。不要与windows的快捷方式混淆,它们目的一致,但结构不一致,不能在linux中使用。
缺陷
- 并非所有系统调用都被实现。
- WSL不能使用所有的硬件资源。例如,在wsl下不能访问GPU,重复性的计算只能通过CPU完成。
- 磁盘IO比原生Linux效率低。后果是,wsl下的编译会很慢。
设计
wsl1
WSL 1的设计没有硬件模拟/虚拟化(与coLinux等其他项目不同),WSL直接使用主机文件系统(通过VolFS和DrvFS)和硬件的某些部分,例如网络(Web服务器,用于例如,可以通过主机上配置的相同接口和IP地址进行访问,并且对使用需要管理权限的端口或已经被其他应用程序占用的端口共享相同的限制),这保证了互操作性。
即使从shell运行sudo,某些位置(例如系统文件夹)和配置的访问/修改也受到限制。必须启动具有提升权限的实例才能获得“真正的sudo”并允许此类访问。
wsl2
Hyper-V
Microsoft的本地虚拟机管理系统。
基于Hyper-V的更高层次的虚拟化。
VPN
VPN是通过使用专用线路或在现有网络上使用隧道协议创建一个虚拟的点对点连接而形成的。可从公共 Internet 获得的 VPN可以提供广域网 (WAN) 的一些好处。 从用户的角度来看,可以远程访问专用网络中可用的资源。
正常网络通信时,所有网络请求都是通过我们的物理网卡直接发送出去。而VPN是客户端使用相应的VPN协议先与VPN服务器进行通信,成功连接后就在操作系统内建立一个虚拟网卡,一般来说默认PC上所有网络通信都从这虚拟网卡上进出,经过VPN服务器中转之后再到达目的地。
VPN有多种协议:OPENVPN、PPTP、L2TP/IPSec、SSLVPN、IKEv2 VPN,Cisco VPN等。其中的PPTP和L2TP是明文传输协议。只负责传输,不负责加密。分别利用了MPPE和IPSec进行加密。
背景 | PPTP 是一个基于 PPP 的很基本的协议。PPTP 是微软 Windows 平台第一个支持的 VPN 协议。PPTP 标准并没有实际描述加密和授权特性,并且依赖于 PPP 协议的隧道来实现安全功能。 | L2TP 是一个在 IETF RFC 3193 中被正式标准化的高级协议。推荐在需要安全加密的地方用来替代 PPTP。 | OpenVPN 是一个高级的开源 VPN 解决方案,由 “OpenVPN technologies” 支持,并且已经成为开源网络领域里的事实标准。OpenVPN 使用成熟的 SSL/TLS 加密协议。 |
数据加密 | PPP 负载是使用微软点对点协议(Microsoft’s Point-to-Point Encryption protocol,MPPE)加密。MPPE 实现了 RSA RC4 加密算法,并使用最长 128 位密钥。 | L2TP 负载使用标准的 IPSec 协议加密。在 RFC 4835 中指定了使用 3DES 或 AES 加密算法作为保密方式。 | OpenVPN 使用 OpenSSL 库来提供加密。OpenSSL 支持好几种不同的加密算法,如:3DES,AES,RC5 等。 |
安装/配置 | Windows 所有版本和大多数其他操作系统包括移动平台都内建了对 PPTP 的支持。PPTP 只需要一个用户名和密码,以及一个服务器地址,所以安装和配置相当简单。 | 从 2000/XP 起的所有 Windows 平台和 Mac OS X 10.3+ 都内建了 L2TP/IPSec 的支持。大多数现代的移动平台比如 iPhone 和 Android 也有内建的客户端。 | OpenVPN 不包含在任何操作系统中,需要安装客户端软件,但安装也是相当简单,基本上 5 分钟可以完成。 |
速度 | 由于使用 128 位密钥,加密开销相比 OpenVPN 使用 256位密钥要小,所以速度感觉稍快一点,但这个差异微不足道。 | L2TP/IPSec 将数据封装两次,所以相比其他竞争者效率稍低,速度也慢一些。 | 当使用默认的 UDP 模式,OpenVPN 的表现是最佳的。 |
端口 | PPTP 使用 TCP 1723 端口和 GRE(协议 47)。通过限制 GRE 协议,PPTP 可以轻易地被封锁。 | L2TP/IPSec 使用 UDP 500 端口用来初始化密钥交换,使用协议 50 用来传输 IPSec 加密的数据( ESP ),使用 UDP 1701 端口用来初始化 L2TP 的配置,还使用 UDP 4500 端口来穿过 NAT。L2TP/IPSec 相比 OpenVPN 容易封锁,因为它依赖于固定的协议和端口。 | OpenVPN 可以很容易的配置为使用任何端口运行,也可以使用 UDP 或 TCP 协议。为了顺利穿越限制性的防火墙,可以将 OpenVPN 配置成使用 TCP 443 端口,因为这样就无法和标准的 HTTPS 无法区分,从而极难被封锁。 |
稳定性/兼容性 | PPTP 不如 OpenVPN 可靠,也不能像 OpenVPN 那样在不稳定网络中快速恢复。另外还有部分同 GRE 协议和一些路由器的兼容性问题。 | L2TP/IPSec 比 OpenVPN 更复杂,为了使在 NAT 路由器下的设备可靠地使用,配置可以会更加困难。但是,只要服务器和客户端都支持 NAT 穿越,那么就没什么问题了。 | 无论是无线网络、蜂窝网络,还是丢包和拥塞经常发生的不可靠网络,OpenVPN 都非常稳定、快速。对于那些相当不可以的连接,OpenVPN 有一个 TCP 模式可以使用,但是要牺牲一点速度,因为将 TCP 封装在 TCP 时效率不高。 |
安全弱点 | 微软实现的 PPTP 有一个严重的安全问题(serious security vulnerabilities)。对于词典攻击来说 MSCHAP-v2 是很脆弱的,并且 RC4 算法也会遭到“位翻转攻击( bit-flipping attack )”。如果保密是重要的,微软也强烈建议升级到 IPSec。 | IPSec 没有明显的漏洞,当和安全加密算法如 AES 一起使用时,被认为是很安全的。 | OpenVPN 也没有明显漏洞,当和安全加密算法如 AES 一起使用时,也被认为是相当安全的。 |
客户端的兼容性 | Windows、Mac OS X、Linux、Apple iOS、Android、DD-WRT | Windows、Mac OS X、Linux、Apple iOS、Android | Windows、Mac OS X、Linux |
结论 | 由于主要的安全漏洞,除了兼容性以外没有好的理由选择使用 PPTP。如果你的设备既不支持 L2TP/IPSec 又不支持 OpenVPN,那么 PPTP 是一个合理的选择。如果关心快速安装和简易配置,那么 L2TP/IPSec 值得考虑。 | L2TP/IPSec 是优秀的,但相比 OpenVPN 的高效和杰出的稳定性要落后一点。如果你使用运行 iOS 或 Android 的移动设备,那么这就是最佳的选择,因为 OpenVPN 目前还不支持这些平台。另外,如果需要快速安装,L2TP/IPSec 也是一个较佳的选择。 | 对于所有的 Windows, Mac OS X 以及 Linux 桌面用户来说,OpenVPN 是最好的选择。OpenVPN 速度快,并且安全可信。但劣势是缺乏对移动设备的支持,另外还需要安装第三方客户端。 |
代理服务器
代理(英语:Proxy)也称网络代理,是一种特殊的网络服务,允许一个终端(一般为客户端)通过这个服务与另一个终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,在一定程度上能够阻止网络攻击。
SSH
安全外壳协议(Secure Shell Protocol,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境[1]。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接[2]。SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。SSH使用频率最高的场合是类Unix系统,但是Windows操作系统也能有限度地使用SSH。