# Windows machine stuff ## Windows SSH server setup - make sure openssh server optional feature is enabled ```powershell powershell.exe "Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Server*'" ``` - configuration, firewall rule, ssh-agent ```powershell # Set the sshd service to be started automatically Get-Service -Name sshd | Set-Service -StartupType Automatic # Now start the sshd service Start-Service sshd # Configure port if needed New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 # Generate SSH keypair ssh-keygen.exe -t ed25519 # Not sure if this ssh-agent stuff is needed but ok # By default the ssh-agent service is disabled. Configure it to start automatically. # Make sure you're running as an Administrator. Get-Service ssh-agent | Set-Service -StartupType Automatic # Start the service Start-Service ssh-agent # This should return a status of Running Get-Service ssh-agent # Now load your key files into ssh-agent ssh-add $env:USERPROFILE\.ssh\id_ed25519 # Main part # Get the public key file generated previously on your client $authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ed25519.pub # Generate the PowerShell to be run remote that will copy the public key file generated previously on your client to the authorized_keys file on your server $remotePowershell = "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'" # Connect to your server and run the PowerShell using the $remotePowerShell variable ssh "$(whoami)@localhost" $remotePowershell ``` - edit `%PROGRAMDATA%/ssh/sshd_config` as administrator ```ssh-config PermitRootLogin no MaxAuthTries 1 PubkeyAuthentication yes PasswordAuthentication no #Match Group administrators # AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys ``` ## WSL ### prevent shutdown - [see here](https://github.com/microsoft/WSL/issues/8854#issuecomment-1490454734) - the service file ```systemd [Unit] Description=Keep Distro Alive [Service] # cleanup if already waiting # get waitfor path by `which waitfor` ExecStartPre=/mnt/c/Windows/system32/waitfor.exe /si MakeDistroAlive ExecStart=/mnt/c/Windows/system32/waitfor.exe MakeDistroAlive [Install] WantedBy=multi-user.target ``` ### networking mode - mirrored - [see here](https://superuser.com/a/1671057) - create/add to `%USERPROFILE%/.wslconfig`: ```ini [wsl2] networkingMode=mirrored ``` ### get Wireguard interface - interface should exist, else it'll be blank ```bash wg_if=$(ip -4 -brief addr show | grep $wg_if_addr | awk '{printf "%s",$1;}') curl -v --interface $wg_if ``` ## 3proxy (native port for windows) - download `.zip` from [github releases (last checked ver - 0.9.4)](https://github.com/3proxy/3proxy/releases) and extract - create a `.cfg` file: ```ini system "echo '3proxy up!'" config "\\3proxy-0.9.4-x64\bin64\3proxy.cfg" monitor "\\3proxy-0.9.4-x64\bin64\3proxy.cfg" log "%USERPROFILE%\.logs\3proxy\%Y%m%d.log" D # the D at the end is important rotate 30 external 10.8.0.2 internal 127.0.0.1 service auth none socks ``` ## The Wireguard split-tunnel problem - i wish to route certain _applications_: not IP address ranges, but programs, over a wireguard tunnel - in particular, i wish to do this for traffic originating from my wireguard peer running on my local Windows machine, and the tunnel in question connects to a cloud VPS running Wireguard - i believe this is called 'application-based split tunneling' - my understanding is that this is something that wireguard's Windows client does not support out of the box - however, if my assumption is correct, i have an alternative approach in mind: - first, whenever the wireguard interface gets created on my machine, it would also create the corresponding routes for the tunnel, and these routes have a low metric value - here, i would set the metric value of the new route(s) to a value higher than the default route that routes most/all the traffic, thereby deprioritizing the tunnel - automate this part to update the metric on interface creation/teardown - this would effectively leave the tunnel active but unused - then, i would create a SOCKS proxy on my local machine, to localhost itself - finally, i would bind any application that would use the wireguard tunnel to this proxy, through the application's settings itself if it provides such functionality, or through third-party applications, such as Proxifier ### Disable automatic route creation - in the [Interface] section of your tunnel config, add `Table = off` - this informs WireGuard not to create a default route automatically - note that this also disables blocking of untunneled traffic (kill-switch functionality), which is what we want in order to achieve split-tunneling - this is a must. direct route manipulation through scripting is not permitted, if the kill-switch functionality is active. it will simply drop traffic (IIRC) ### Enable Wireguard scripts - [scripts are not enabled in Wireguard Windows by default](https://github.com/WireGuard/wireguard-windows/blob/master/docs/adminregistry.md) - go to `Computer\HKEY_LOCAL_MACHINE\SOFTWARE` - right-click `SOFTWARE` in the navigation pane, click `New -> Key`, name it `WireGuard` - create a new `DWORD (32-bit) Value` in the new created key named `DangerousScriptExecution` - set its value to `1` - now you can add `PreUp`, `PostUp`, `PreDown`, `PostDown` scripts #### PostUp script - since we disabled automatic default route(s) addition to table, we have to add the necessary routes - modify routes according to allowedIPs - given case is 0.0.0.0/0 - for other cases, see what routes WireGuard generates on its own normally, and add the missing route(s) from those - other routes get added automatically ```powershell 'postup start' | Out-File -FilePath "${PSScriptRoot}\PostUp.log" # Wireguard tunnel interface details $wgInterface = Get-NetAdapter -InterfaceAlias $env:WIREGUARD_TUNNEL_NAME $wgAddress = (Get-NetIPAddress -InterfaceAlias $env:WIREGUARD_TUNNEL_NAME -AddressFamily IPv4 ).IPAddress # add default 0.0.0.0/0 route with low priority route add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF $wgInterface.ifIndex metric 999 # Set the interface metric for the WireGuard tunnel Set-NetIPInterface -InterfaceIndex $wgInterface.ifIndex -InterfaceMetric 999 # Navigate to the 3proxy directory Set-Location "\\3proxy-0.9.4-x64\bin64\" $cfg_file = "3proxy-wireguard.cfg" # Create 3proxy configuration file 'auth none' | Out-File -FilePath $cfg_file -Encoding ASCII 'internal 127.0.0.1' | Out-File -FilePath $cfg_file -Append -Encoding ASCII "external ${wgAddress}" | Out-File -FilePath $cfg_file -Append -Encoding ASCII # rest of the proxy configuration 'socks' | Out-File -FilePath $cfg_file -Append -Encoding ASCII 'log "%USERPROFILE%\.logs\3proxy\%Y%m%d.log" D' | Out-File -FilePath $cfg_file -Append -Encoding ASCII 'rotate 30' | Out-File -FilePath $cfg_file -Append -Encoding ASCII # Start 3proxy in the background Start-Process -FilePath '.\3proxy.exe' -ArgumentList $cfg_file -NoNewWindow 'postup end' | Out-File -FilePath "${PSScriptRoot}\PostUp.log" -Append ``` #### PreDown script - make sure to specify all routes created in the `PostUp` script ```powershell 'predown start' | Out-File -FilePath "${PSScriptRoot}\PreDown.log" # WireGuard tunnel details $wgInterface = Get-NetAdapter -Name $env:WIREGUARD_TUNNEL_NAME # Delete the default 0.0.0.0/0 route using the interface index route delete 0.0.0.0 mask 0.0.0.0 0.0.0.0 if $wgInterface.ifIndex # Terminate any running instances of 3proxy.exe Set-Location "\\3proxy-0.9.4-x64\bin64\" Stop-Process -Name "3proxy.exe" -Force 'predown end' | Out-File -FilePath "${PSScriptRoot}\PreDown.log" -Append ```