From ff5b6e4c86cbd6a4d984af5e86659113e2bb7afc Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 23 Nov 2020 10:13:13 +0100 Subject: docs: move to docs subdirectory Signed-off-by: Jason A. Donenfeld --- COPYING | 2 +- README.md | 131 +++++++++++++------------------------------------- adminregistry.md | 40 --------------- attacksurface.md | 47 ------------------ docs/adminregistry.md | 40 +++++++++++++++ docs/attacksurface.md | 47 ++++++++++++++++++ docs/buildrun.md | 98 +++++++++++++++++++++++++++++++++++++ docs/enterprise.md | 86 +++++++++++++++++++++++++++++++++ docs/netquirk.md | 33 +++++++++++++ enterprise.md | 86 --------------------------------- netquirk.md | 33 ------------- 11 files changed, 338 insertions(+), 305 deletions(-) delete mode 100644 adminregistry.md delete mode 100644 attacksurface.md create mode 100644 docs/adminregistry.md create mode 100644 docs/attacksurface.md create mode 100644 docs/buildrun.md create mode 100644 docs/enterprise.md create mode 100644 docs/netquirk.md delete mode 100644 enterprise.md delete mode 100644 netquirk.md diff --git a/COPYING b/COPYING index af9033c1..33db31ae 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 2018-2020 WireGuard LLC +Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/README.md b/README.md index 9bbd57e7..296fd81b 100644 --- a/README.md +++ b/README.md @@ -1,111 +1,46 @@ # [WireGuard](https://www.wireguard.com/) for Windows -***If you've come here looking to simply run WireGuard for Windows, [you may download it here](https://www.wireguard.com/install/).*** +This is a fully-featured WireGuard client for Windows that uses [Wintun](https://www.wintun.net/). It is the only official and recommended way of using WireGuard on Windows. -This is a fully-featured WireGuard client for Windows that uses [Wintun](https://www.wintun.net/). +## Download & Install -### Documentation +If you've come here looking to simply run WireGuard for Windows, [the main download page has links](https://www.wireguard.com/install/). There you will find two things: -In addition to this [`README.md`](README.md), which contains information about building and developing WireGuard for Windows, the following documents are also available: +- [The WireGuard Installer](https://download.wireguard.com/windows-client/wireguard-installer.exe) – This selects the most recent version for your architecture, downloads it, checks signatures and hashes, and installs it. +- [Standalone MSIs](https://download.wireguard.com/windows-client/) – These are for system admins who wish to deploy the MSIs directly. For most end users, the ordinary installer takes care of downloading these automatically. -- [`adminregistry.md`](adminregistry.md) – A list of registry keys settable by the system administrator for changing the behavior of the application. -- [`attacksurface.md`](attacksurface.md) – A discussion of the various components from a security perspective, so that future auditors of this code have a head start in assessing its security design. -- [`enterprise.md`](enterprise.md) – A summary of various features and tips for making the application usable in enterprise settings. -- [`netquirk.md`](netquirk.md) – A description of various networking quirks and "kill-switch" semantics. +## Documentation -### Building +In addition to this [`README.md`](README.md), the following documents are also available: -Windows 10 64-bit or Windows Server 2019, and Git for Windows is required. The build script will take care of downloading, verifying, and extracting the right versions of the various dependencies: +- [`adminregistry.md`](docs/adminregistry.md) – A list of registry keys settable by the system administrator for changing the behavior of the application. +- [`attacksurface.md`](docs/attacksurface.md) – A discussion of the various components from a security perspective, so that future auditors of this code have a head start in assessing its security design. +- [`buildrun.md`](docs/buildrun.md) – Instructions on building, localizing, running, and developing for this repository. +- [`enterprise.md`](docs/enterprise.md) – A summary of various features and tips for making the application usable in enterprise settings. +- [`netquirk.md`](docs/netquirk.md) – A description of various networking quirks and "kill-switch" semantics. -```text -C:\Projects> git clone https://git.zx2c4.com/wireguard-windows -C:\Projects> cd wireguard-windows -C:\Projects\wireguard-windows> build -``` - -### Running +## License -After you've built the application, run `amd64\wireguard.exe` or `x86\wireguard.exe` to install the manager service and show the UI. +This repository is MIT-licensed. ```text -C:\Projects\wireguard-windows> amd64\wireguard.exe +Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. ``` - -Since WireGuard requires the Wintun driver to be installed, and this generally requires a valid Microsoft signature, you may benefit from first installing a release of WireGuard for Windows from the official [wireguard.com](https://www.wireguard.com/install/) builds, which bundles a Microsoft-signed Wintun, and then subsequently run your own wireguard.exe. Alternatively, you can craft your own installer using the `quickinstall.bat` script. - -### Optional: Localizing - -To translate WireGuard UI to your language: - -1. Upgrade `resources.rc` accordingly. Follow the pattern. - -2. Make a new directory in `locales\` containing the language ID: - - ```text - C:\Projects\wireguard-windows> mkdir locales\ - ``` - -3. Configure and run `build` to prepare initial `locales\\messages.gotext.json` file: - - ```text - C:\Projects\wireguard-windows> set GoGenerate=yes - C:\Projects\wireguard-windows> build - C:\Projects\wireguard-windows> copy locales\\out.gotext.json locales\\messages.gotext.json - ``` - -4. Translate `locales\\messages.gotext.json`. See other language message files how to translate messages and how to tackle plural. For this step, the project is currently using [CrowdIn](https://crowdin.com/translate/WireGuard); please make sure your translations make it there in order to be added here. - -5. Run `build` from the step 3 again, and test. - -6. Repeat from step 4. - -### Optional: Creating the Installer - -The installer build script will take care of downloading, verifying, and extracting the right versions of the various dependencies: - -```text -C:\Projects\wireguard-windows> cd installer -C:\Projects\wireguard-windows\installer> build -``` - -### Optional: Signing Binaries - -Add a file called `sign.bat` in the root of this repository with these contents, or similar: - -```text -set SigningCertificate=DF98E075A012ED8C86FBCF14854B8F9555CB3D45 -set TimestampServer=http://timestamp.digicert.com -``` - -After, run the above `build` commands as usual, from a shell that has [`signtool.exe`](https://docs.microsoft.com/en-us/windows/desktop/SecCrypto/signtool) in its `PATH`, such as the Visual Studio 2017 command prompt. - -### Alternative: Building from Linux - -You must first have Mingw and ImageMagick installed. - -```text -$ sudo apt install mingw-w64 imagemagick -$ git clone https://git.zx2c4.com/wireguard-windows -$ cd wireguard-windows -$ make -``` - -You can deploy the 64-bit build to an SSH host specified by the `DEPLOYMENT_HOST` environment variable (default "winvm") to the remote directory specified by the `DEPLOYMENT_PATH` environment variable (default "Desktop") by using the `deploy` target: - -```text -$ make deploy -``` - -### [`wg(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8) Support for Windows - -The command line utility [`wg(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8) works well on Windows. Being a Unix-centric project, it compiles with a Makefile and MingW: - -```text -$ git clone https://git.zx2c4.com/wireguard-tools -$ PLATFORM=windows make -C wireguard-tools/src -$ stat wireguard-tools/src/wg.exe -``` - -It interacts with WireGuard instances run by the main WireGuard for Windows program. - -When building on Windows, the aforementioned `build.bat` script takes care of building this. diff --git a/adminregistry.md b/adminregistry.md deleted file mode 100644 index 513c1c48..00000000 --- a/adminregistry.md +++ /dev/null @@ -1,40 +0,0 @@ -## Registry Keys for Admins - -These are advanced configuration knobs that admins can set to do unusual things -that are not recommended. There is no UI to enable these, and no such thing is -planned. These registry keys may also be removed at some point in the future. -Use at your own risk, and please make sure you know what you're doing. - -#### `HKLM\Software\WireGuard\LimitedOperatorUI` - -When this key is set to `DWORD(1)`, the UI will be launched on desktops of -users belonging to the Network Configuration Operators builtin group -(S-1-5-32-556), with the following limitations for members of that group: - - - Configurations are stripped of all public, private, and pre-shared keys; - - No version update notifications are delivered; - - Adding, removing, editing, importing, or exporting configurations is forbidden; and - - Quitting the manager is forbidden. - -However, basic functionality such as starting and stopping tunnels remains intact. - -#### `HKLM\Software\WireGuard\DangerousScriptExecution` - -When this key is set to `DWORD(1)`, the tunnel service will execute the commands -specified in the `PreUp`, `PostUp`, `PreDown`, and `PostDown` options of a -tunnel configuration. Note that this execution is done as the Local System user, -which runs with the highest permissions on the operating system, and is therefore -a real target of malware. Therefore, you should enable this option only with the -utmost trepidation. Rather than use `%i`, WireGuard for Windows instead sets the -environment variable `WIREGUARD_TUNNEL_NAME` to the name of the tunnel when -executing these scripts. - -#### `HKLM\Software\WireGuard\MultipleSimultaneousTunnels` - -When this key is set to `DWORD(1)`, the UI may start multiple tunnels at the -same time; otherwise, an existing tunnel is stopped when a new one is started. -Note that it is always possible, regardless of this key, to start multiple -tunnels using `wireguard /installtunnelservice`; this controls only the semantics -of tunnel start requests coming from the UI. If all goes well, this key will be -removed and the logic of whether to stop existing tunnels will be based on -overlapping routes, but for now, this key provides a manual override. diff --git a/attacksurface.md b/attacksurface.md deleted file mode 100644 index eb8baade..00000000 --- a/attacksurface.md +++ /dev/null @@ -1,47 +0,0 @@ -### WireGuard for Windows Attack Surface - -_This is an evolving document, describing currently known attack surface, a few mitigations, and several open questions. This is a work in progress. We document our current understanding with the intent of improving both our understanding and our security posture over time._ - -WireGuard for Windows consists of four components: a kernel driver, and three separate interacting userspace parts. - -#### Wintun - -Wintun is a kernel driver. It exposes: - - - A miniport driver to the ndis stack, meaning any process on the system that can access the network stack in a reasonable way can send and receive packets, hitting those related ndis handlers. - - There are also various ndis OID calls, accessible to certain users, which hit further code. - - IOCTLs are added to the NDIS device file, and those IOCTLs are restricted to `SDDL_DEVOBJ_SYS_ALL`. The IOCTL allows userspace to register a pair of rings and event objects, which Wintun then locks the pages of with a double mapping and takes a reference to the event object. It parses the contents of the ring to send and receive layer 3 packets, each of which it minimally parses to determine IP family. - -### Tunnel Service - -The tunnel service is a userspace service running as Local System, responsible for creating UDP sockets, creating Wintun adapters, and speaking the WireGuard protocol between the two. It exposes: - - - A listening pipe in `\\.\pipe\ProtectedPrefix\Administrators\WireGuard\%s`, where `%s` is some basename of an already valid filename. Its DACL is set to `O:SYD:(A;;GA;;;SY)`. If the config file used by the tunnel service is not DPAPI-encrypted and it is owned by a SID other than "Local System" then an additional ACE is added giving that file owner SID access to the named pipe. This pipe gives access to private keys and allows for reconfiguration of the interface, as well as rebinding to different ports (below 1024, even). Clients who connect to the pipe run `GetSecurityInfo` to verify that it is owned by "Local System". - - A global mutex is used for Wintun interface creation, with the same DACL as the pipe, but first CreatePrivateNamespace is called with a "Local System" SID. - - It handles data from its two UDP sockets, accessible to the public Internet. - - It handles data from Wintun, accessible to all users who can do anything with the network stack. - - After some initial setup, it uses `AdjustTokenPrivileges` to remove all privileges, except for `SeLoadDriverPrivilege`, so that it can remove the interface when shutting down. This latter point is rather unfortunate, as `SeLoadDriverPrivilege` can be used for all sorts of interesting escalation. Future work includes forking an additional process or the like so that we can drop this from the main tunnel process. - -### Manager Service - -The manager service is a userspace service running as Local System, responsible for starting and stopping tunnel services, and ensuring a UI program with certain handles is available to Administrators. It exposes: - - - Extensive IPC using unnamed pipes, inherited by the UI process. - - A readable `CreateFileMapping` handle to a binary ringlog shared by all services, inherited by the UI process. - - It listens for service changes in tunnel services according to the string prefix "WireGuardTunnel$". - - It manages DPAPI-encrypted configuration files in `C:\Program Files\WireGuard\Data`, which is created with `O:SYG:SYD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)`, and makes some effort to enforce good configuration filenames. - - The actual DPAPI-encrypted configuration files are created with `O:SYG:SYD:PAI(A;;FA;;;SY)(A;;SD;;;BA)`. - - It uses `WTSEnumerateSessions` and `WTSSESSION_NOTIFICATION` to walk through each available session. It then uses `WTSQueryUserToken`, and then calls `GetTokenInformation(TokenGroups)` on it. If one of the returned group's SIDs matches `IsWellKnownSid(WinBuiltinAdministratorsSid)`, and has attributes of either `SE_GROUP_ENABLED` or `SE_GROUP_USE_FOR_DENY_ONLY` and calling `GetTokenInformation(TokenElevation)` on it or its `TokenLinkedToken` indicates that either is elevated, then it spawns the UI process as that the elevated user token, passing it three unnamed pipe handles for IPC and the log mapping handle, as described above. - - In the event that the administrator has set `HKLM\Software\WireGuard\LimitedOperatorUI` to 1, sessions are started for users that are a member of group S-1-5-32-556, with a more limited IPC interface, in which these non-admin users are denied private keys and tunnel editing rights. (This means users can potentially DoS the IPC server by draining notifications too slowly, or exhausting memory of the manager by spawning too many watcher go routines, or by sending garbage data that Go's `gob` decoder isn't expecting.) - -### UI - -The UI is a process running for each user who is in the Administrators group (per the above), running with the elevated high integrity linked token. It exposes: - - - Since the UI process is executed with an elevated token, it runs at high integrity and should be immune to various shatter attacks, modulo the great variety of clever bypasses in the latest Windows release. - - It uses `AdjustTokenPrivileges` to remove all privileges. - - It renders highlighted config files to a msftedit.dll control, which typically is capable of all sorts of OLE and RTF nastiness that we make some attempt to avoid. - -### Updates - -A server hosts the result of `b2sum -l 256 *.msi > list && signify -S -e -s release.sec -m list && upload ./list.sec`, with the private key stored on an HSM. The MSIs in that list are only the latest ones available, and filenames fit the form `wireguard-${arch}-${version}.msi`. The updater, running as part of the manager service, downloads this list over TLS and verifies the signify Ed25519 signature of it. If it validates, then it finds the first MSI in it for its architecture that has a greater version. It then downloads this MSI from a predefined URL to a randomly generated (256-bits) file name inside `C:\Windows\Temp` with permissions of `O:SYD:PAI(A;;FA;;;SY)(A;;FR;;;BA)`, scheduled to be cleaned up at next boot via `MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT)`, and verifies the BLAKE2b-256 signature. If it validates, then it calls `WinTrustVerify(WINTRUST_ACTION_GENERIC_VERIFY_V2, WTD_REVOKE_WHOLECHAIN)` on the MSI. If it validates, then it executes the installer with `msiexec.exe /qb!- /i`, using the elevated token linked to the IPC UI session that requested the update. Because `msiexec` requires exclusive access to the file, the file handle is closed in between the completion of downloading and the commencement of `msiexec`. Hopefully the permissions of `C:\Windows\Temp` are good enough that an attacker can't replace the MSI from beneath us. diff --git a/docs/adminregistry.md b/docs/adminregistry.md new file mode 100644 index 00000000..513c1c48 --- /dev/null +++ b/docs/adminregistry.md @@ -0,0 +1,40 @@ +## Registry Keys for Admins + +These are advanced configuration knobs that admins can set to do unusual things +that are not recommended. There is no UI to enable these, and no such thing is +planned. These registry keys may also be removed at some point in the future. +Use at your own risk, and please make sure you know what you're doing. + +#### `HKLM\Software\WireGuard\LimitedOperatorUI` + +When this key is set to `DWORD(1)`, the UI will be launched on desktops of +users belonging to the Network Configuration Operators builtin group +(S-1-5-32-556), with the following limitations for members of that group: + + - Configurations are stripped of all public, private, and pre-shared keys; + - No version update notifications are delivered; + - Adding, removing, editing, importing, or exporting configurations is forbidden; and + - Quitting the manager is forbidden. + +However, basic functionality such as starting and stopping tunnels remains intact. + +#### `HKLM\Software\WireGuard\DangerousScriptExecution` + +When this key is set to `DWORD(1)`, the tunnel service will execute the commands +specified in the `PreUp`, `PostUp`, `PreDown`, and `PostDown` options of a +tunnel configuration. Note that this execution is done as the Local System user, +which runs with the highest permissions on the operating system, and is therefore +a real target of malware. Therefore, you should enable this option only with the +utmost trepidation. Rather than use `%i`, WireGuard for Windows instead sets the +environment variable `WIREGUARD_TUNNEL_NAME` to the name of the tunnel when +executing these scripts. + +#### `HKLM\Software\WireGuard\MultipleSimultaneousTunnels` + +When this key is set to `DWORD(1)`, the UI may start multiple tunnels at the +same time; otherwise, an existing tunnel is stopped when a new one is started. +Note that it is always possible, regardless of this key, to start multiple +tunnels using `wireguard /installtunnelservice`; this controls only the semantics +of tunnel start requests coming from the UI. If all goes well, this key will be +removed and the logic of whether to stop existing tunnels will be based on +overlapping routes, but for now, this key provides a manual override. diff --git a/docs/attacksurface.md b/docs/attacksurface.md new file mode 100644 index 00000000..fde9916a --- /dev/null +++ b/docs/attacksurface.md @@ -0,0 +1,47 @@ +# Attack Surface + +_This is an evolving document, describing currently known attack surface, a few mitigations, and several open questions. This is a work in progress. We document our current understanding with the intent of improving both our understanding and our security posture over time._ + +WireGuard for Windows consists of four components: a kernel driver, and three separate interacting userspace parts. + +### Wintun + +Wintun is a kernel driver. It exposes: + + - A miniport driver to the ndis stack, meaning any process on the system that can access the network stack in a reasonable way can send and receive packets, hitting those related ndis handlers. + - There are also various ndis OID calls, accessible to certain users, which hit further code. + - IOCTLs are added to the NDIS device file, and those IOCTLs are restricted to `SDDL_DEVOBJ_SYS_ALL`. The IOCTL allows userspace to register a pair of rings and event objects, which Wintun then locks the pages of with a double mapping and takes a reference to the event object. It parses the contents of the ring to send and receive layer 3 packets, each of which it minimally parses to determine IP family. + +### Tunnel Service + +The tunnel service is a userspace service running as Local System, responsible for creating UDP sockets, creating Wintun adapters, and speaking the WireGuard protocol between the two. It exposes: + + - A listening pipe in `\\.\pipe\ProtectedPrefix\Administrators\WireGuard\%s`, where `%s` is some basename of an already valid filename. Its DACL is set to `O:SYD:(A;;GA;;;SY)`. If the config file used by the tunnel service is not DPAPI-encrypted and it is owned by a SID other than "Local System" then an additional ACE is added giving that file owner SID access to the named pipe. This pipe gives access to private keys and allows for reconfiguration of the interface, as well as rebinding to different ports (below 1024, even). Clients who connect to the pipe run `GetSecurityInfo` to verify that it is owned by "Local System". + - A global mutex is used for Wintun interface creation, with the same DACL as the pipe, but first CreatePrivateNamespace is called with a "Local System" SID. + - It handles data from its two UDP sockets, accessible to the public Internet. + - It handles data from Wintun, accessible to all users who can do anything with the network stack. + - After some initial setup, it uses `AdjustTokenPrivileges` to remove all privileges, except for `SeLoadDriverPrivilege`, so that it can remove the interface when shutting down. This latter point is rather unfortunate, as `SeLoadDriverPrivilege` can be used for all sorts of interesting escalation. Future work includes forking an additional process or the like so that we can drop this from the main tunnel process. + +### Manager Service + +The manager service is a userspace service running as Local System, responsible for starting and stopping tunnel services, and ensuring a UI program with certain handles is available to Administrators. It exposes: + + - Extensive IPC using unnamed pipes, inherited by the UI process. + - A readable `CreateFileMapping` handle to a binary ringlog shared by all services, inherited by the UI process. + - It listens for service changes in tunnel services according to the string prefix "WireGuardTunnel$". + - It manages DPAPI-encrypted configuration files in `C:\Program Files\WireGuard\Data`, which is created with `O:SYG:SYD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)`, and makes some effort to enforce good configuration filenames. + - The actual DPAPI-encrypted configuration files are created with `O:SYG:SYD:PAI(A;;FA;;;SY)(A;;SD;;;BA)`. + - It uses `WTSEnumerateSessions` and `WTSSESSION_NOTIFICATION` to walk through each available session. It then uses `WTSQueryUserToken`, and then calls `GetTokenInformation(TokenGroups)` on it. If one of the returned group's SIDs matches `IsWellKnownSid(WinBuiltinAdministratorsSid)`, and has attributes of either `SE_GROUP_ENABLED` or `SE_GROUP_USE_FOR_DENY_ONLY` and calling `GetTokenInformation(TokenElevation)` on it or its `TokenLinkedToken` indicates that either is elevated, then it spawns the UI process as that the elevated user token, passing it three unnamed pipe handles for IPC and the log mapping handle, as described above. + - In the event that the administrator has set `HKLM\Software\WireGuard\LimitedOperatorUI` to 1, sessions are started for users that are a member of group S-1-5-32-556, with a more limited IPC interface, in which these non-admin users are denied private keys and tunnel editing rights. (This means users can potentially DoS the IPC server by draining notifications too slowly, or exhausting memory of the manager by spawning too many watcher go routines, or by sending garbage data that Go's `gob` decoder isn't expecting.) + +### UI + +The UI is a process running for each user who is in the Administrators group (per the above), running with the elevated high integrity linked token. It exposes: + + - Since the UI process is executed with an elevated token, it runs at high integrity and should be immune to various shatter attacks, modulo the great variety of clever bypasses in the latest Windows release. + - It uses `AdjustTokenPrivileges` to remove all privileges. + - It renders highlighted config files to a msftedit.dll control, which typically is capable of all sorts of OLE and RTF nastiness that we make some attempt to avoid. + +### Updates + +A server hosts the result of `b2sum -l 256 *.msi > list && signify -S -e -s release.sec -m list && upload ./list.sec`, with the private key stored on an HSM. The MSIs in that list are only the latest ones available, and filenames fit the form `wireguard-${arch}-${version}.msi`. The updater, running as part of the manager service, downloads this list over TLS and verifies the signify Ed25519 signature of it. If it validates, then it finds the first MSI in it for its architecture that has a greater version. It then downloads this MSI from a predefined URL to a randomly generated (256-bits) file name inside `C:\Windows\Temp` with permissions of `O:SYD:PAI(A;;FA;;;SY)(A;;FR;;;BA)`, scheduled to be cleaned up at next boot via `MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT)`, and verifies the BLAKE2b-256 signature. If it validates, then it calls `WinTrustVerify(WINTRUST_ACTION_GENERIC_VERIFY_V2, WTD_REVOKE_WHOLECHAIN)` on the MSI. If it validates, then it executes the installer with `msiexec.exe /qb!- /i`, using the elevated token linked to the IPC UI session that requested the update. Because `msiexec` requires exclusive access to the file, the file handle is closed in between the completion of downloading and the commencement of `msiexec`. Hopefully the permissions of `C:\Windows\Temp` are good enough that an attacker can't replace the MSI from beneath us. diff --git a/docs/buildrun.md b/docs/buildrun.md new file mode 100644 index 00000000..265c4d68 --- /dev/null +++ b/docs/buildrun.md @@ -0,0 +1,98 @@ +# Building, Running, and Developing + +### Building + +Windows 10 64-bit or Windows Server 2019, and Git for Windows is required. The build script will take care of downloading, verifying, and extracting the right versions of the various dependencies: + +```text +C:\Projects> git clone https://git.zx2c4.com/wireguard-windows +C:\Projects> cd wireguard-windows +C:\Projects\wireguard-windows> build +``` + +### Running + +After you've built the application, run `amd64\wireguard.exe` or `x86\wireguard.exe` to install the manager service and show the UI. + +```text +C:\Projects\wireguard-windows> amd64\wireguard.exe +``` + +Since WireGuard requires the Wintun driver to be installed, and this generally requires a valid Microsoft signature, you may benefit from first installing a release of WireGuard for Windows from the official [wireguard.com](https://www.wireguard.com/install/) builds, which bundles a Microsoft-signed Wintun, and then subsequently run your own wireguard.exe. Alternatively, you can craft your own installer using the `quickinstall.bat` script. + +### Optional: Localizing + +To translate WireGuard UI to your language: + +1. Upgrade `resources.rc` accordingly. Follow the pattern. + +2. Make a new directory in `locales\` containing the language ID: + + ```text + C:\Projects\wireguard-windows> mkdir locales\ + ``` + +3. Configure and run `build` to prepare initial `locales\\messages.gotext.json` file: + + ```text + C:\Projects\wireguard-windows> set GoGenerate=yes + C:\Projects\wireguard-windows> build + C:\Projects\wireguard-windows> copy locales\\out.gotext.json locales\\messages.gotext.json + ``` + +4. Translate `locales\\messages.gotext.json`. See other language message files how to translate messages and how to tackle plural. For this step, the project is currently using [CrowdIn](https://crowdin.com/translate/WireGuard); please make sure your translations make it there in order to be added here. + +5. Run `build` from the step 3 again, and test. + +6. Repeat from step 4. + +### Optional: Creating the Installer + +The installer build script will take care of downloading, verifying, and extracting the right versions of the various dependencies: + +```text +C:\Projects\wireguard-windows> cd installer +C:\Projects\wireguard-windows\installer> build +``` + +### Optional: Signing Binaries + +Add a file called `sign.bat` in the root of this repository with these contents, or similar: + +```text +set SigningCertificate=DF98E075A012ED8C86FBCF14854B8F9555CB3D45 +set TimestampServer=http://timestamp.digicert.com +``` + +After, run the above `build` commands as usual, from a shell that has [`signtool.exe`](https://docs.microsoft.com/en-us/windows/desktop/SecCrypto/signtool) in its `PATH`, such as the Visual Studio 2017 command prompt. + +### Alternative: Building from Linux + +You must first have Mingw and ImageMagick installed. + +```text +$ sudo apt install mingw-w64 imagemagick +$ git clone https://git.zx2c4.com/wireguard-windows +$ cd wireguard-windows +$ make +``` + +You can deploy the 64-bit build to an SSH host specified by the `DEPLOYMENT_HOST` environment variable (default "winvm") to the remote directory specified by the `DEPLOYMENT_PATH` environment variable (default "Desktop") by using the `deploy` target: + +```text +$ make deploy +``` + +### [`wg(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8) Support for Windows + +The command line utility [`wg(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8) works well on Windows. Being a Unix-centric project, it compiles with a Makefile and MingW: + +```text +$ git clone https://git.zx2c4.com/wireguard-tools +$ PLATFORM=windows make -C wireguard-tools/src +$ stat wireguard-tools/src/wg.exe +``` + +It interacts with WireGuard instances run by the main WireGuard for Windows program. + +When building on Windows, the aforementioned `build.bat` script takes care of building this. diff --git a/docs/enterprise.md b/docs/enterprise.md new file mode 100644 index 00000000..3f75ad14 --- /dev/null +++ b/docs/enterprise.md @@ -0,0 +1,86 @@ +# Enterprise Usage + +WireGuard for Windows has been designed from the ground-up to make full use of standard Windows service, ACL, and CLI capabilities, making WireGuard deployable in enterprise scenarios or as part of Active Directory domains. + +### Installation + +While consumer users are generally directed toward [wireguard-installer.exe](https://download.wireguard.com/windows-client/wireguard-installer.exe), this installer simply takes care of selecting the correct MSI for the architecture, validating signatures, and executing it. Enterprise admins can instead [download MSIs directly](https://download.wireguard.com/windows-client/) and deploy these using [Group Policy Objects](https://docs.microsoft.com/en-us/troubleshoot/windows-server/group-policy/use-group-policy-to-install-software). The installer makes use of standard MSI features and should be easily automatable. The additional MSI property of `DO_NOT_LAUNCH` suppresses launching WireGuard after its installation, should that be required. + +### Tunnel Service versus Manager Service and UI + +The "manager service" is responsible for displaying a UI on select users' desktops (in the system tray), and responding to requests from the UI to do things like add, remove, start, or stop tunnels. The "tunnel service" is a separate Windows service for each tunnel. These two services may be used together, or separately, as described below. + +### Tunnel Service + +A tunnel service may be installed or uninstalled using the commands: + +```text +> wireguard /installtunnelservice C:\path\to\some\myconfname.conf +> wireguard /uninstalltunnelservice myconfname +``` + +This creates a service called `WireGuardTunnel$myconfname`, which can be controlled using standard Windows service management utilites, such as `services.msc` or [`sc`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-query). + +If the configuration filename ends in `.conf`, it is interpreted as a normal [`wg-quick(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8) configuration file. If it ends in `.conf.dpapi`, it is considered to be that same configuration file, but encrypted using [`CryptProtectData(bytes, "myconfname")`](https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata). + +The tunnel service may be queried and modified at runtime using the standard [`wg(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8) command line utility. If the configuration file is a `.conf.dpapi` one, then Local System or Administrator permissions is required to interact with it using `wg(8)`; otherwise users of `wg(8)` must have Local System or Administrator permissions, or permissions the same as the owner of the `.conf` file. Invocation of `wg(8)` follows usual patterns on other platforms. For example: + +```text +> wg show myconfname +interface: myconfname + public key: lfTRXEWxt8mZc8cjSvOWN3tqnTpWw4v2Eg3qF6WTklw= + private key: (hidden) + listening port: 53488 + +peer: JRI8Xc0zKP9kXk8qP84NdUQA04h6DLfFbwJn4g+/PFs= + endpoint: 163.172.161.0:12912 + allowed ips: 0.0.0.0/0 + latest handshake: 3 seconds ago + transfer: 6.55 KiB received, 4.13 KiB sent +``` + +The `PreUp`, `PostUp`, `PreDown`, and `PostDown` configuration options may be specified to run custom commands at various points in the lifetime of a tunnel service, but only if the correct registry key is set. [See `adminregistry.md` for information.](adminregistry.md) + +### Manager Service + +The manager service may be installed or uninstalled using the commands: + +```text +> wireguard /installmanagerservice +> wireguard /uninstallmanagerservice +``` + +This creates a service called `WireGuardManager`, which can be controlled using standard Windows service management utilites, such as `services.msc` or [`sc`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-query). + +When executing `wireguard` with no arguments, the command first attempts to show the UI if the manager service is already running; otherwise it starts the manager service, waits for it to create a UI in the system tray, and then shows the main manager window. Therefore, `wireguard /installmanagerservice` is suitable for silent installation, whereas `wireguard` alone is suitable for interactive startup. + +The manager service monitors `%ProgramFiles%\WireGuard\Data\Configurations\` for the addition of new `.conf` files. Upon seeing one, it encrypts the file to a `.conf.dpapi` file, makes it unreadable to users other than Local System, confers the administrator only the ability to remove it, and then deletes the original unencrypted file. (Configurations can always be _exported_ later using the export feature of the UI.) Using this, configurations can programmatically be added to the secure store of the manager service simply by copying them into that directory. + +The UI is started in the system tray of all builtin Administrators when the manager service is running. A limited UI may also be started in the system tray of all builtin Network Configuration Operators, if the correct registry key is set. [See `adminregistry.md` for information.](adminregistry.md) + +By default, the manager stops existing tunnels when starting new tunnels, so that only one tunnel service is running at a time. This behavior may be disabled if the correct registry key is set. [See `adminregistry.md` for information.](adminregistry.md) + + +### Diagnostic Logs + +The manager and all tunnel services produce diagnostic logs in a shared ringbuffer-based log. This is shown in the UI, and also can be dumped to a file using the command: + +```text +> wireguard /dumplog C:\path\to\diagnostic\log.txt +``` + +### Updates + +Administrators are notified of updates within the UI and can update from within the UI, but updates can also be invoked at the command line using the command: + +```text +> wireguard /update C:\path\to\update\log.txt +``` + +### Wintun Adapters + +The tunnel service creates a Wintun adapter at startup and destroys it at shutdown. It may be desirable, however, to remove all Wintun adapters created in WireGuard's pool and uninstall the driver if no other applications are using Wintun. This can be accomplished using the command: + +```text +> wireguard /removealladapters C:\path\to\removal\log.txt +``` diff --git a/docs/netquirk.md b/docs/netquirk.md new file mode 100644 index 00000000..0a7f1963 --- /dev/null +++ b/docs/netquirk.md @@ -0,0 +1,33 @@ +# Network Configuration Quirks + +As part of setting up a WireGuard tunnel, the tunnel service also sets up various network configuration parameters that are in one way or another related to the original configuration. + +### Routing + +The tunnel service takes all the allowed IPs from each peer, deduplicates them, and adds them to the routes for the WireGuard interface. The service then monitors which interface on the system has a default route (a route with a `/0` CIDR) that is not the WireGuard interface itself, and it uses the [`IP_UNICAST_IF` socket option](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options) to bind WireGuard's UDP packets to that default route interface. If no MTU has been specified in the configuration, it also sets the MTU of the WireGuard interface to be 80 less than the MTU of that default route interface. If no default route interface can be found, then those outgoing packets are blackholed. If WireGuard packets would ordinarily be routed over a non-default route interface, the use of `IP_UNICAST_IF` forces the packets to, in fact, go over the default route interface. This is problematic, but at this moment, Microsoft has not provided a viable workaround. If any allowed IPs are a `/0`, then the interface is given a `0` metric and Windows' [automatic metric logic](https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/automatic-metric-for-ipv4-routes) is disabled. + +### Firewall Considerations for `/0` Allowed IPs + +If an interface has only one peer, and that peer contains an Allowed IP in `/0`, then WireGuard enables a so-called "kill-switch", which adds firewall rules to do the following: + +- Packets from the tunnel service itself are permitted, so that WireGuard packets can flow successfully. +- If the configuration specifies DNS servers, then packets sent to port `53` are only permitted if they are to one of those DNS servers. This is to prevent Windows' [ordinary multihomed DNS resolution behavior](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29), so that DNS queries only go to the DNS server specified, rather than multiple DNS servers. +- Loopback packets are permitted, and packets actually going through the WireGuard tunnel are permitted. +- DHCP for IPv4 and IPv6 and NDP for IPv6 are permitted. +- All other packets are blocked. + +This prevents traffic from leaking outside the tunnel. + +If you'd like to use a default route _without_ having these restrictive kill-switch semantics, one may use the routes `0.0.0.0/1` and `128.0.0.0/0` in place of `0.0.0.0/0`, as well as `::/1` and `8000::/1` in place of `::/0`. This achieves nearly the same thing, but does not activate the above firewalling semantics. And users without the need for a `/0` route at all do not have to worry about this, and instead fall back to ordinary Windows routing and DNS behavior. + +### Considerations for non-`/0` Allowed IPs + +When the above conditions do not apply, routing and DNS information is handed to Windows in the typical way for Windows to manage. This includes its [ordinary multihomed DNS resolution behavior](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29) as well as its ordinary routing table resolution. Users may make use of the normal Windows firewalling and network configuration capabilities to firewall this as needed. + +### Network List Manager + +Windows assigns a unique GUID to each new WireGuard adapter. The application takes pains to make this GUID deterministic, so that firewall policy (such as "public" vs "private" network categorization) can be consistently applied to the tunnel's network. This determinism is based on the configuration of the tunnel. Therefore, if the WireGuard configuration changes, so too will the unique GUID. Technical details are described in [a mailing list post](https://lists.zx2c4.com/pipermail/wireguard/2019-June/004259.html). + +### Adapter Lifetime + +WireGuard's Wintun adapter is created dynamically when a tunnel is started and destroyed when a tunnel is stopped. This means that additional filters, address families, or protocols should be bound to the adapter programmatically, possibly through use of dangerous script execution in thet configuration file or by way of automatic NDIS layer binding. diff --git a/enterprise.md b/enterprise.md deleted file mode 100644 index 3f75ad14..00000000 --- a/enterprise.md +++ /dev/null @@ -1,86 +0,0 @@ -# Enterprise Usage - -WireGuard for Windows has been designed from the ground-up to make full use of standard Windows service, ACL, and CLI capabilities, making WireGuard deployable in enterprise scenarios or as part of Active Directory domains. - -### Installation - -While consumer users are generally directed toward [wireguard-installer.exe](https://download.wireguard.com/windows-client/wireguard-installer.exe), this installer simply takes care of selecting the correct MSI for the architecture, validating signatures, and executing it. Enterprise admins can instead [download MSIs directly](https://download.wireguard.com/windows-client/) and deploy these using [Group Policy Objects](https://docs.microsoft.com/en-us/troubleshoot/windows-server/group-policy/use-group-policy-to-install-software). The installer makes use of standard MSI features and should be easily automatable. The additional MSI property of `DO_NOT_LAUNCH` suppresses launching WireGuard after its installation, should that be required. - -### Tunnel Service versus Manager Service and UI - -The "manager service" is responsible for displaying a UI on select users' desktops (in the system tray), and responding to requests from the UI to do things like add, remove, start, or stop tunnels. The "tunnel service" is a separate Windows service for each tunnel. These two services may be used together, or separately, as described below. - -### Tunnel Service - -A tunnel service may be installed or uninstalled using the commands: - -```text -> wireguard /installtunnelservice C:\path\to\some\myconfname.conf -> wireguard /uninstalltunnelservice myconfname -``` - -This creates a service called `WireGuardTunnel$myconfname`, which can be controlled using standard Windows service management utilites, such as `services.msc` or [`sc`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-query). - -If the configuration filename ends in `.conf`, it is interpreted as a normal [`wg-quick(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8) configuration file. If it ends in `.conf.dpapi`, it is considered to be that same configuration file, but encrypted using [`CryptProtectData(bytes, "myconfname")`](https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata). - -The tunnel service may be queried and modified at runtime using the standard [`wg(8)`](https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8) command line utility. If the configuration file is a `.conf.dpapi` one, then Local System or Administrator permissions is required to interact with it using `wg(8)`; otherwise users of `wg(8)` must have Local System or Administrator permissions, or permissions the same as the owner of the `.conf` file. Invocation of `wg(8)` follows usual patterns on other platforms. For example: - -```text -> wg show myconfname -interface: myconfname - public key: lfTRXEWxt8mZc8cjSvOWN3tqnTpWw4v2Eg3qF6WTklw= - private key: (hidden) - listening port: 53488 - -peer: JRI8Xc0zKP9kXk8qP84NdUQA04h6DLfFbwJn4g+/PFs= - endpoint: 163.172.161.0:12912 - allowed ips: 0.0.0.0/0 - latest handshake: 3 seconds ago - transfer: 6.55 KiB received, 4.13 KiB sent -``` - -The `PreUp`, `PostUp`, `PreDown`, and `PostDown` configuration options may be specified to run custom commands at various points in the lifetime of a tunnel service, but only if the correct registry key is set. [See `adminregistry.md` for information.](adminregistry.md) - -### Manager Service - -The manager service may be installed or uninstalled using the commands: - -```text -> wireguard /installmanagerservice -> wireguard /uninstallmanagerservice -``` - -This creates a service called `WireGuardManager`, which can be controlled using standard Windows service management utilites, such as `services.msc` or [`sc`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-query). - -When executing `wireguard` with no arguments, the command first attempts to show the UI if the manager service is already running; otherwise it starts the manager service, waits for it to create a UI in the system tray, and then shows the main manager window. Therefore, `wireguard /installmanagerservice` is suitable for silent installation, whereas `wireguard` alone is suitable for interactive startup. - -The manager service monitors `%ProgramFiles%\WireGuard\Data\Configurations\` for the addition of new `.conf` files. Upon seeing one, it encrypts the file to a `.conf.dpapi` file, makes it unreadable to users other than Local System, confers the administrator only the ability to remove it, and then deletes the original unencrypted file. (Configurations can always be _exported_ later using the export feature of the UI.) Using this, configurations can programmatically be added to the secure store of the manager service simply by copying them into that directory. - -The UI is started in the system tray of all builtin Administrators when the manager service is running. A limited UI may also be started in the system tray of all builtin Network Configuration Operators, if the correct registry key is set. [See `adminregistry.md` for information.](adminregistry.md) - -By default, the manager stops existing tunnels when starting new tunnels, so that only one tunnel service is running at a time. This behavior may be disabled if the correct registry key is set. [See `adminregistry.md` for information.](adminregistry.md) - - -### Diagnostic Logs - -The manager and all tunnel services produce diagnostic logs in a shared ringbuffer-based log. This is shown in the UI, and also can be dumped to a file using the command: - -```text -> wireguard /dumplog C:\path\to\diagnostic\log.txt -``` - -### Updates - -Administrators are notified of updates within the UI and can update from within the UI, but updates can also be invoked at the command line using the command: - -```text -> wireguard /update C:\path\to\update\log.txt -``` - -### Wintun Adapters - -The tunnel service creates a Wintun adapter at startup and destroys it at shutdown. It may be desirable, however, to remove all Wintun adapters created in WireGuard's pool and uninstall the driver if no other applications are using Wintun. This can be accomplished using the command: - -```text -> wireguard /removealladapters C:\path\to\removal\log.txt -``` diff --git a/netquirk.md b/netquirk.md deleted file mode 100644 index 0a7f1963..00000000 --- a/netquirk.md +++ /dev/null @@ -1,33 +0,0 @@ -# Network Configuration Quirks - -As part of setting up a WireGuard tunnel, the tunnel service also sets up various network configuration parameters that are in one way or another related to the original configuration. - -### Routing - -The tunnel service takes all the allowed IPs from each peer, deduplicates them, and adds them to the routes for the WireGuard interface. The service then monitors which interface on the system has a default route (a route with a `/0` CIDR) that is not the WireGuard interface itself, and it uses the [`IP_UNICAST_IF` socket option](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options) to bind WireGuard's UDP packets to that default route interface. If no MTU has been specified in the configuration, it also sets the MTU of the WireGuard interface to be 80 less than the MTU of that default route interface. If no default route interface can be found, then those outgoing packets are blackholed. If WireGuard packets would ordinarily be routed over a non-default route interface, the use of `IP_UNICAST_IF` forces the packets to, in fact, go over the default route interface. This is problematic, but at this moment, Microsoft has not provided a viable workaround. If any allowed IPs are a `/0`, then the interface is given a `0` metric and Windows' [automatic metric logic](https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/automatic-metric-for-ipv4-routes) is disabled. - -### Firewall Considerations for `/0` Allowed IPs - -If an interface has only one peer, and that peer contains an Allowed IP in `/0`, then WireGuard enables a so-called "kill-switch", which adds firewall rules to do the following: - -- Packets from the tunnel service itself are permitted, so that WireGuard packets can flow successfully. -- If the configuration specifies DNS servers, then packets sent to port `53` are only permitted if they are to one of those DNS servers. This is to prevent Windows' [ordinary multihomed DNS resolution behavior](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29), so that DNS queries only go to the DNS server specified, rather than multiple DNS servers. -- Loopback packets are permitted, and packets actually going through the WireGuard tunnel are permitted. -- DHCP for IPv4 and IPv6 and NDP for IPv6 are permitted. -- All other packets are blocked. - -This prevents traffic from leaking outside the tunnel. - -If you'd like to use a default route _without_ having these restrictive kill-switch semantics, one may use the routes `0.0.0.0/1` and `128.0.0.0/0` in place of `0.0.0.0/0`, as well as `::/1` and `8000::/1` in place of `::/0`. This achieves nearly the same thing, but does not activate the above firewalling semantics. And users without the need for a `/0` route at all do not have to worry about this, and instead fall back to ordinary Windows routing and DNS behavior. - -### Considerations for non-`/0` Allowed IPs - -When the above conditions do not apply, routing and DNS information is handed to Windows in the typical way for Windows to manage. This includes its [ordinary multihomed DNS resolution behavior](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29) as well as its ordinary routing table resolution. Users may make use of the normal Windows firewalling and network configuration capabilities to firewall this as needed. - -### Network List Manager - -Windows assigns a unique GUID to each new WireGuard adapter. The application takes pains to make this GUID deterministic, so that firewall policy (such as "public" vs "private" network categorization) can be consistently applied to the tunnel's network. This determinism is based on the configuration of the tunnel. Therefore, if the WireGuard configuration changes, so too will the unique GUID. Technical details are described in [a mailing list post](https://lists.zx2c4.com/pipermail/wireguard/2019-June/004259.html). - -### Adapter Lifetime - -WireGuard's Wintun adapter is created dynamically when a tunnel is started and destroyed when a tunnel is stopped. This means that additional filters, address families, or protocols should be bound to the adapter programmatically, possibly through use of dangerous script execution in thet configuration file or by way of automatic NDIS layer binding. -- cgit v1.2.3-59-g8ed1b