Due to changing functionality in Windows depending on Microsoft, the steps outlined below may not age well.
Warning: As of Sep 2021, seems like the OpenSSH implementation in Windows stores keys in the Windows Registry instead of RAM... seems dangerous. (update: open since 2019, till today Oct 2024).
Apps > Optional Features > OpenSSH Client
Services > OpenSSH Authentication Agent
ssh-add -t 86400 [PRIVATEKEY]
(add key to agent with 1 day lifetime)ssh-add -D
Problems, of course. SSH agent seems to have to query sshd? Can resolve by adding dummy sshd in admin prompt: sc.exe create sshd binPath=C:\Windows\System32\OpenSSH\ssh.exe
. But ssh-add
still fails to add the key with a timeout, even in admin prompt... Here's another caution for using Window's SSH agent. Mitigation can be as simple as clearing the keys every midnight.
On passphrase-encryption for private key: https://askubuntu.com/questions/346114/how-to-retrieve-passphrase-for-private-key
128-bit AES... So, assuming a strong password and highly parallel decryption (for instance using GPGPU) having 210 threads, each having a very optimistic rate of 230 operations per second, after a day of time, you could have run about 256 operations. With an effective complexity of around 2100, it would take about 3 billion years to break the key...
On known-plaintext attack on AES-128: https://crypto.stackexchange.com/questions/3952/is-it-possible-to-obtain-aes-128-key-from-a-known-ciphertext-plaintext-pair
No for practical definitions of possible, assuming the key was chosen truly randomly, and no side-channel information is available (such as the power-consumption traces of the encrypting device, or the time it took, for many encryptions). The design of AES strives to be such that the best way to find the key from plaintext-ciphertext examples is to try keys among the 2128 possible keys.
Note that brute force attacks are still viable if the passphrase is short.
Clear SSH agent: Clears the keys stored in ssh-agent every midnight. Resolves the problem of Window's port of OpenSSH agent caching the unencrypted private key in Windows Registry and not in RAM.
SSH keys that have too open permissions cannot be used for authenticating a session (this happens when the keyfile is kept on a shared drive, for example). Generally a valid concern, but mostly mitigated with a sufficiently complex passphrase for encrypting the private key. Alternatively, one can just change the permissions for the object directly:
::# Set Key File Variable: Set Key="id_rsa" ::# Remove Inheritance: Icacls %Key% /c /t /Inheritance:d ::# Set Ownership to Owner: :: # Key's within %UserProfile%: Icacls %Key% /c /t /Grant %UserName%:F :: # Key's outside of %UserProfile%: TakeOwn /F %Key% Icacls %Key% /c /t /Grant:r %UserName%:F ::# Remove All Users, except for Owner: Icacls %Key% /c /t /Remove:g "Authenticated Users" BUILTIN\Administrators BUILTIN Everyone System Users ::# Verify: Icacls %Key% ::# Remove Variable: set "Key="
To copy the SSH key to a remote host, use the following command, and verify the remote host fingerprint using the `-o VisualHostKey=yes` flag:
$ cat ~/.ssh/id_rsa.pub | ssh [USER]@[HOST] "mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys" -o VisualHostKey=yes The authenticity of host '[HOST] (fe80::1e69:7aff:fe6c:6927%10)' can't be established. ECDSA key fingerprint is SHA256:V2ETP7Epl+pu+4SGyWpSVahZvQqECmyHnDgpZb5ZM0o. +---[ECDSA 256]---+ | *oo . o=.. | |=oB . . . o.o+ = | |.oEo+. . + .o.B | | . =.o + ...+ . | | + So... | | .o.+ . | | . + + . | | . .. o.. | | o. .oo. | +----[SHA256]-----+ Are you sure you want to continue connecting (yes/no/[fingerprint])?
This took a while to figure out. A couple of resources to start reading from:
# For Powershell > $env:DISPLAY="127.0.0.1:0" # For cmd > set DISPLAY=127.0.0.1:0 # SSH commands # Connecting to untrusted machine > ssh -X # Connecting to trusted machine > ssh -Y
Optional Features: OpenSSH Server
More reliable method to go via CLI: https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=powershell
# Check installation status Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*' # Install the OpenSSH Client Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 # Install the OpenSSH Server Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 # Start the sshd service Start-Service sshd # OPTIONAL but recommended: Set-Service -Name sshd -StartupType 'Automatic' # Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) { Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..." New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 } else { Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists." }
Do a localhost connection test to verify SSH working.
TightVNC is a fantastic option for VNC in Windows, relatively easy to set up too. Even better when layered over a mesh Tailscale network which can provide a direct node-to-node authentication/encryption layer, or using the SSH tunneling option, i.e. ssh -L 5903:USER@HOST:5900 USER@HOST
to tunnel remote VNC port 5900 to local port 5903 (though you need to separately supply the route as well).
Only problem is when there is no active display registered in Windows, which VNC relies on to render display (probably to identify screen resolutions...?). Connecting to a laptop with the lid closed, for example, blacks out the display. This can be bypassed either with a dummy plug, e.g. Headless Ghost, or via another connection protocol, e.g. Teamviewer.
Examples of VNC clients include TightVNC Viewer, and VNC Viewer (supplied by RealVNC).
This article was rather helpful in pointing in the right direction. Started to face issues in getting a connection at all, but turns out it was mainly a syntax issue.
Start by installing WinFsp (FUSE-equivalent that installs a kernel driver as filesystem abstraction layer) and SSHFS-Win (SSHFS port for Windows). The SSHFS-Win-Manager recommended doesn't seem to work well in my case (plus plaintext password store, why?), so avoided that.
In the "Map Network Drive" interface, the syntax (had to find out from SO) follows, noting the /
at the end due to my server being a Linux system:
\\sshfs\USER@HOST/
To unmap a drive, consider using: net use Z: /delete
Network drives mapped locally on-site is not automatically reflected in an SSH session - this is by design since mapped network drives are user-specific, see this comment for more intricacies.
To scp
to/from a Windows remote, apply quotation marks to allow backslashes to be used, and have an overall quotation to escape these characters, e.g.
scp -r justin@192.168.1.100:"\"\"C:\Users\Justin\Desktop\projects\"\"" ~/projects
Note the -r
may be necessary, otherwise a "protocol error: filename does not match request" error may be raised.
A selection of commands to list processes:
# List processes tasklist tasklist /fi "imagename eq notepad.exe" # List process PID with associated TCP ports netstat -ano -p tcp # Kill tasks taskkill /pid {{PID}}
The computer can be powered up from a low power mode via sending of a wake-on-lan magic packet. Several conditions must be met:
Wake on magic packet
should be enabled in properties, and "This device can start the computer" + "Only magic packets can start" enabled under Power Management tabNote that Windows Firewall probably does not need to open port 7 or 9 (common WoL ports)- WoL is a Layer 2 MAC protocol, and it enables the Ethernet card to trigger motherboard chipset to initiate start up, i.e. nothing actually happens at the OS level.
To send the magic packet itself from Linux, consider using the wakeonlan
library.
> wakeonlan MY:MA:CA:DD:RE:SS
Note that both devices must be within the same subnet, since the WoL packet itself is broadcasted. To retrieve MAC address, use ipconfig /all
.
Note also that the HDMI port needs to be connected to signal to the GPU/iGPU that there is a display to output to, so that connection to a display remotely can commence. Either keep the HDMI cable connected to a monitor, or use a dummy HDMI plug, e.g. Headless Ghost.
Windows has a native hypervisor appropriately called "Windows hypervisor".
Virtualization in Windows is an interesting topic. There are five separate virtualization-related features that can be enabled in Optional Features:
Note that for Windows 11, the Windows hypervisor must be used for any virtualization, instead of third-party hypervisors.
Probably need to read up more on native virtualization instructions as well, e.g. Intel VT-x and AMD-V.
Windows can be installed without a license (activation reminders will start randomly appearing after 30 days of non-activation) - for licensing in VM environment, there seems to be some specific enterprise license for it. A quick PSA that using unactivated Windows is not illegal, but activating Windows through unofficial channels is illegal.
To obtain the Windows ISO, there are many many methods:
rufus.ini
.If using Rufus to write to a bootable disk, TPM can also be disabled as well.
See documentation for configuration variables.
Personally haven't got this to work for just any application on a native level yet, intended use was for gaming within sandbox. See configuration below:
<!-- Windows Sandbox configuration file https://docs.microsoft.com/en-us/windows/security/ threat-protection/windows-sandbox/windows-sandbox-configure-using-wsb-file --> <Configuration> <!-- Utilities --> <Networking>Disable</Networking> <AudioInput>Disable</AudioInput> <VideoInput>Disable</VideoInput> <vGPU>Enable</vGPU> <MemoryInMB>8000</MemoryInMB> <!-- Volumes --> <MappedFolders> <MappedFolder> <HostFolder>Z:\</HostFolder> <SandboxFolder>C:\Users\WDAGUtilityAccount\Desktop\Shared</SandboxFolder> <ReadOnly>false</ReadOnly> </MappedFolder> </MappedFolders> <LogonCommand> <Command>explorer.exe C:\Users\WDAGUtilityAccount\Desktop\Shared</Command> </LogonCommand> <!-- Security --> <ProtectedClient>Enable</ProtectedClient> <PrinterRedirection>Disable</PrinterRedirection> <ClipboardRedirection>Disable</ClipboardRedirection> </Configuration>
On Windows Pro platforms, Hyper-V can be used to run virtual machines. Enable Hyper-V in the Optional Features dialog, then create a new VM. Note when prompted to press any key to boot from CD/DVD, do so.
If you're looking to use GPU passthrough (known as Direct Device Access (DDA) in Microsoft lingo), currently needs Server editions of Windows, see this comment. Here's a possible guide for a setup with AMD Threadripper. There used to be a RemoteFX interface by Microsoft, but it got removed due to vulnerabilities.
Another interface called GPU Partitioning (GPU-P) on the other hand is possible, although very much undocumented by Microsoft, and it works even before Nvidia's GPU passthrough enablement announcement. See this article (and a similar Reddit post, reproduced below for longevity:
# Run this in host OS $vm = "windowsvm" Add-VMGpuPartitionAdapter -VMName $vm Set-VMGpuPartitionAdapter -VMName $vm -MinPartitionVRAM 80000000 -MaxPartitionVRAM 100000000 -OptimalPartitionVRAM 100000000 -MinPartitionEncode 80000000 -MaxPartitionEncode 100000000 -OptimalPartitionEncode 100000000 -MinPartitionDecode 80000000 -MaxPartitionDecode 100000000 -OptimalPartitionDecode 100000000 -MinPartitionCompute 80000000 -MaxPartitionCompute 100000000 -OptimalPartitionCompute 100000000 Set-VM -GuestControlledCacheTypes $true -VMName $vm Set-VM -LowMemoryMappedIoSpace 1Gb -VMName $vm Set-VM –HighMemoryMappedIoSpace 32GB –VMName $vm # With the VM running, copy the following files: # - C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_* # --> C:\Windows\System32\HostedDriverStore\FileRepository\ # - C:\Windows\System32\nv* # --> C:\Windows\System32\ # # If using command line, Guest Services must be enabled for guest OS Copy-VMFile "windowsvm" -SourcePath "C:\Windows\System32\nvapi64.dll" -DestinationPath "C:\nvapi64.dll" -CreateFullPath -FileSource Host
Checkpoints need to be disabled, otherwise this dialog pops up:
For audio output, route using VB Audio Cable.
If still failing with Code 43 error, try this one for size: https://github.com/jamesstringerparsec/Easy-GPU-PV Notably uses Parsec for streaming instead, mentioning that Hyper-V and RDP methods will only offer up to 30 FPS, while Parsec offers 4K60FPS. To check current Windows build, go to Settings > System > About.
Add the following to Parsec config to allow resolution changes as well:
host_virtual_monitors = 1 host_privacy_mode = 1
If full GPU passthrough needed, use another hypervisor like ESXi (see ESXi free limitations) or Proxmox (KVM\libvirt) instead, or start with a Linux host (see guides here and here.
A compiled list of programs that may find common usage, updated as of 2022-07-24. Common programs are typically available through Ninite:
Category / Application | Description | Configuration | |
---|---|---|---|
Web browsing | |||
Firefox | Web browser | Install via Ninite. (1) Install relevant add-ons, e.g. Bitwarden integration with timeout lock, (2) Enable HTTPS-only mode, (3) Disable "Ask to save logins/passwords" | |
Tor Browser | Browser for Tor network | Store in network share instead | |
ExpressVPN | Paid VPN service | Login and add device | |
WireGuard VPN | VPN protocol | ||
OpenVPN Connect | VPN client | Install via Chocolatey: openvpn-connect . Add OpenVPN profiles. |
|
Document/Image/Audio editing/playback | |||
Foxit PDF reader | PDF reader | Install via Ninite. | |
GIMP | Raster image editor | Install via Ninite. | |
Inkscape | Vector image editor | Install via Ninite. | |
VLC | User-friendly media player | Install via Ninite. | |
Greenshot | Screenshot tool | Install via Ninite. Remap hotkeys to PrntScrn (Capture region), Shift-PrntScrn (Capture window), Ctrl-PrntScrn (Capture full screen). If remapping is an issue, uncheck the "Print Screen shortcut" option in Settings > Keyboard and restart. Add [Core]\nExcludePlugins=Box Plugin,Confluence Plugin,Dropbox Plugin,Flickr Plugin,Imgur Plugin,Jira Plugin,OCR Plugin,Office Plugin,Photobucket Plugin,Picasa-Web Plugin to %APPDATA%\Greenshot\greenshot-fixed.ini |
|
ffmpeg | Media convertor/player | Install via Chocolatey: ffmpeg |
|
Microsoft Office | Document editor | ||
Searching/Retrieval | |||
Everything | Local file indexing service | Install via Ninite. | |
7-Zip | Archival tool | Install via Ninite. | |
qBittorrent | Bittorrent client | ||
Remote work | |||
VNC Server | RealVNC server | Install via Ninite. Login to RealVNC account with local password authentication. Disable sleep when connected to power supply. | |
VNC Viewer | RealVNC client | Install via Ninite. | |
Teamviewer | Remote server/client | Install via Ninite. Login | |
WinSCP | SFTP/WebDAV client | Install via Ninite. | |
Zoom | Remote meeting tool | Install via Ninite. Login | |
DroidCam | Android webcam connection | ||
Gaming | |||
Steam | PC games | Install via Ninite. Login, disable on startup, map game library to network share | |
User experience | |||
PowerToys | Power tools for Windows | Install via Chocolatey: powertoys . Create custom 6-zone FancyZone (bisect vertically, bisect right zone vertically, bisect all zones horizontally), remove margins, set highlighting to 100px, set "Use non-primary mouse button for zone activation" |
|
AutoHotKey | GUI scripting | ||
carnac | Keystroke display | Install via Chocolatey: carnac |
|
Development | |||
Chocolatey | Windows package manager | ||
git | Version control | Install via Chocolatey: git.install --params "/GitAndUnixToolsOnPath /NoShellIntegration /NoCredentialManager /SChannel /NoOpenSSH /WindowsTerminalProfile /DefaultBranchName:main /Editor:VisualStudioCode" |
|
TortoiseSVN | Version control | Install via Chocolatey: tortoisesvn |
|
Visual Studio Code | Text editor / IDE | Login to sync settings | |
Python 3 | Programming language | Install via pyenv . To view available versions, e.g. pyenv update; pyenv install -l | findstr 3.10 . Add python3 alias to Powershell: Set-Alias -Name python3 -Value python . Remember to disable App Execution Alias. |
|
pyenv | Python version manager | Install via Chocolatey: pyenv-win . Keep listings in line with official Python repository: pyenv update |
|
VcXsrv | X11 server | ||
Gpg4win | GPG manager | ||
Microsoft C++ Build Tools | C++ build tools | Select Desktop build tools for typical usage | |
Others | |||
Asana | Project management | ||
JDK | Java development kit | ||
Atmel Studio | IDE for AVR microcontrollers | ||
Etcher | ISO burner | ||
Rufus | ISO burner with Windows support | ||
DB Browser for SQLite | SQLite browser | ||
Logitech Options | Logitech configuration | ||
Musescore | MIDI notation | ||
MusicBrainz Picard | Audio metadata editor | ||
NodeJS | Javascript server | ||
LTspice | Circuit simulator | ||
KiCAD | Circuit designer | ||
FreeCAD | 3D parametric modelling | ||
VirtualBox | Type-2 hypervisor | ||
VMware Player | Type-2 hypervisor | ||
GNU utilities | Linux tools | Makefile can be alternatively installed via Chocolatey: make . Also consider installing ripgrep in place of grep . |
Initial configuration for Windows:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
$Home\Documents\WindowsPowerShell\Profile.ps1
(exact parent directories might differ)wsl --update
and wsl --install -d Ubuntu-22.04
If strange entries (e.g. "Program") appear in Task Manager, check where the trigger is located Startup Type
, and what location is it pointing to Command line
. Source.
Possible locations:
Registry: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Registry: HKEY_CURRENT_USER\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run Registry: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run Folder: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup Folder: %AppData%\Microsoft\Windows\Start Menu\Programs\Startup
Shame on you, Microsoft Teams.
route -4 print # metric is a cost function route add [SUBNET] mask [MASK] [GATEWAY_IP] metric [REL_METRIC] route delete [SUBNET]
Identify open ports and figuring out which PIDs have accessed them:
netstat -aon | grep LISTENING
then cross-compare with the PID numbers of applications in Task Manager > Details.