Skip to content

Instantly share code, notes, and snippets.

@ryuheechul
Last active March 13, 2024 02:23
Show Gist options
  • Save ryuheechul/494f4e6f08eaca34ef00ab8b238eca2a to your computer and use it in GitHub Desktop.
Save ryuheechul/494f4e6f08eaca34ef00ab8b238eca2a to your computer and use it in GitHub Desktop.
Let that Windows 10/11 be a bit friendlier

An attempt to make Windows 10/11 work for me by customizing/personalizing it

Why gist not dotfiles?

I use dotfiles to personalize *nix type of machines. But I'm new to personalizing Windows 10. So I'm collecting information here first before adding these to the dotfiles. I'm not sure if these will ever move to dotfiles though.

Enable WSL2

https://docs.microsoft.com/en-us/windows/wsl/install-win10

Also reading about ConPTY can help understanding more about how (TUI) wsl and windows host apps work together.

Bootstrap with my dotfiles

cd ~
git clone https://github.com/ryuheechul/dotfiles
dotfiles/bootstrap/foundation/wsl.sh
dotfiles/bootstrap/configuration.sh

Few things to mention about performance

There can be subttle but noticable performace difference between various power mode:

  • power plugged in
  • on battery with Power mode as Recommended
  • on battery with Power mode as Better Performance
  • on battery with Power mode as Best Performance

I compare them using fulltimezsh as opening a new shell is one of the interaction that I care about the fast feedback.

Miss Homebrew? There is Chocolatey

https://chocolatey.org/install

# default code editor
choco install vscode -y
# enable coding/terminal friendly font
choco install firacodenf -y # or below
choco install nerdfont-hack -y

Awesome WSL

Should also check this out, https://github.com/sirredbeard/Awesome-WSL

Terminals

Choose terminals from below if not to settle with Windows Terminal.

https://github.com/sirredbeard/Awesome-WSL#terminals

Customize Windows Terminal

https://www.thomasmaurer.ch/2020/04/my-customized-windows-terminal-settings-json/

  // at "C:\Users\[user-name]\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
  {
    // ...
    "hidden": false,
    "name": "Ubuntu",
+   "fontFace": "FiraCodeNF", // Set terminal friendly font
+   "fontFace": "Hack Nerd Font Mono", // Or this
+   "commandline": "wsl -- bash -c -l 'cd && SHELL=$(which zsh) tmux a'", // replace default `wsl` to start with tmux
    "source": "Windows.Terminal.Wsl"
  },

For Edge Browser

Enable Vimium

https://vimium.github.io/

# swapping `t` and `T` - this is for anywhere not just for Windows
map t Vomnibar.activateTabSelection
map T createTab

# swapping `J` and `K` - this is for in case using vertical tabs in Edge
map J nextTab
map K previousTab

Focus on New Tab Immediately

Thanks to a comment in Reddit, a extention like this, Tab Activate help.

Protect eyes with f.lux

https://justgetflux.com/

Apple Magic Trackpad

https://github.com/imbushuo/mac-precision-touchpad choco install mac-precision-touchpad -y

iCloud

Sign In Troubleshooting

https://www.partitionwizard.com/clone-disk/cant-sign-into-icloud.html

From above link, Reset WinSock worked for me. I also changed DNS to 1.1.1.1 after installing iCloud (not sure if this is related though)

Remote desktop

Configure Wake-On LAN

Actually I'm not sure if this is necessary but preventing sleep on lid closing (below) seems to be.

Turn Off Slow Charger Warning

https://superuser.com/questions/1702345/disable-slow-charger-warning-in-windows/1732917#1732917

might requires rebooting after changing the settings

Preventing sleeping on power

https://support.microsoft.com/en-us/windows/how-to-adjust-power-and-sleep-settings-26f623b5-4fcc-4194-863d-b824e5ea7679

Preventing sleeping on lid closing

Do you want to access your laptop when its lid is closed? In that case, https://uk.pcmag.com/windows-10/121850/how-to-run-your-laptop-with-the-lid-closed.

Lock after inactivity

The step above comes with a (bad security) side effect. Prevent that with setting up automatic locking via instruction at https://docs.microsoft.com/answers/answers/10049/view.html.

Let Vimium to be inactive for Chrome Remote Desktop

if not you will wonder why typing seems to be not working

Add https://remotedesktop.google.com/access/session/* into Excluded URLs and keys in Vimium if you use Chrome Remote Desktop

Slowness when the lid is closed

Apparently lid closing's default behaviour is to limit graphic capabilities a lot and I'm following this instruction to prevent that.

Customize Keyboard

keybinding with AutoHotKey

https://www.autohotkey.com/ choco install autohotkey -y

Might be useful:

my hot keys

Helper to debug

Carnac can display keystrokes.

choco install carnac -y

Keyboard repeat delay

https://thegeekpage.com/change-keyboard-repeat-rate-repeat-delay-windows-10/

Window Manager

https://github.com/fuhsjr00/bug.n is supposed to be similar to i3 on Linux or Amethyst on macOS

Docker

Simply installing via https://hub.docker.com/editions/community/docker-ce-desktop-windows/ should enable Docker for both Windows side and WSL side

also a (good) side effect, it runs wsl on start up

SSH Server (Windows side)

Optional steps

Rename host

Press Window button and type View your PC Name and click Rename PC

Flatten the network

with tailscale if you will

Install & Enable

https://www.hanselman.com/blog/the-easy-way-how-to-ssh-into-bash-and-wsl2-on-windows-10-from-an-external-machine

or with choco install openssh -y

## in Powershell as admin

# for now
Start-Service sshd
Get-Service sshd

# for future (after reboot
Set-Service -Name sshd -StartupType 'Automatic'

# to change the default shell to wsl - https://www.hanselman.com/blog/the-easy-way-how-to-ssh-into-bash-and-wsl2-on-windows-10-from-an-external-machine
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\WINDOWS\System32\bash.exe" -PropertyType String -Force

Even smoother conneciton

Now that default shell is to enter wsl (on Windows side), it feels like I'm connecting to Linux directly. However not quite yet.

Few problems so far:

  • bash start with home folder of Windows not Linux
  • I want to use zsh that is installed via Nix
  • No indication on prompt about SSH

And these can be solved by below.

# ~/.ssh/config - client side

Host [ip-or-domain]
  # let you connect host simply via `ssh@[host]`
  User [username]

  # optional in case doing auth with keys instead of password - more on this later
  IdentityFile ~/.ssh/my-key[.pub]

  # for the command below to be attached
  RequestTTY force

  # $SSH_TTY - just to fake my shell prompt to think it's connected via SSH eventhough in linux perspective it's actually not
  RemoteCommand SSH_TTY=/dev/faketty bash -c -l 'cd ~ && zsh'
Troubleshoot send disconnect: Broken pipe

I noticed that ssh connection keep getting disconnected. And here are what I tried:

And everything failed.

I noticed some weird behaviors though:

  • when getting kicked out was kind of random - sometimes just few seconds sometimes even few minutes
  • connecting from wsl never got kicked out unlike an external device like Macbook or iPad
  • when I tried with local IP address (not the Tailscale one) from my router, it has no response
  • when I try even just a ping with the local IP, timeout
  • and I found this article - https://community.spiceworks.com/topic/440766-client-pc-not-responding-to-ping
  • and one thing came up in my mind - McAfee Antivirus programs that comes with the laptop that I forgot to remove completely

So I removed it and restarted the Windows and ping works and no more ssh being disconnected. So it must have been that app and I guess it makes sense it patrols connections and go around and kill them as it likes. It was a well spent 3 hours of detective work...

Access with password (default)

ssh [username]@[ip-or-domain-name] Also I'm not sure if it's this is same for everyone, but in my case, the user name is the local user name and password is not the local one but the Microsoft account one, which is super confusing but alright.

Advance setup

for example, using public keys https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration

Allowing public keys https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement#deploying-the-public-key

When Repair-AuthorizedKeyPermission is not available, Set-ExecutionPolicy Bypass -Scope Process -Force; Import-Module "C :\Program Files\OpenSSH-Win64\OpenSSHUtils.psd1" -Force

Admin users

If your user is local admin, the above wouldn't work, instead do this, https://www.concurrency.com/blog/may-2019/key-based-authentication-for-openssh-on-windows.

# do this in powershell as admin - https://www.concurrency.com/blog/may-2019/key-based-authentication-for-openssh-on-windows

$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule("Administrators","FullControl","Allow")
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow")
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl

Debug configuration

Server side

dev-sec/ansible-ssh-hardening#188 (comment) or https://unix.stackexchange.com/a/218191

Client side

PowerShell/Win32-OpenSSH#1102 (comment)

SSH (and Mosh) Server (WSL side)

based on https://www.hanselman.com/blog/using-tailscale-on-windows-to-network-more-easily-with-wsl2-and-visual-studio-code

Install packages

# I'm mixing up package managers here for my specific needs, if you just want to stick with `apt-get` for everything, it should be ok too

# install OpenSSH server
sudo apt update
sudo apt install openssh-server

# install tailscale
nix-env -i tailscale
# or follow https://tailscale.com/kb/1039/install-ubuntu-2004/

# install mosh - install linuxbrew first, https://gist.github.com/ryuheechul/bc8a6c32f7a50bde183d1b61dbf71867#true-color-issue
brew install --HEAD mosh

# disable ipv6 for tailscale https://github.com/tailscale/tailscale/issues/562#issuecomment-749121860
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

Run daemons

We need sshd and tailscaled to be running in background. No systemd on WSL2 yet, so I just create and run this script (manually) everytime system start. Now systemd is available!

# shim/init.d.sh

#!/usr/bin/env sh

sudo service ssh start

mkdir -p ~/.var/log
# https://askubuntu.com/a/750423
# https://www.maketecheasier.com/nohup-and-uses/
sudo -b nohup /home/heechul/.nix-profile/bin/tailscaled > ~/.var/log/tailscaled

Add (clients') public keys to ~/.ssh/authorized_keys and it should be good to go.

SSH Client (WSL side)

It should be straigt forward as any other Linux experience but this might be helpful anyway: https://gist.github.com/ryuheechul/bc8a6c32f7a50bde183d1b61dbf71867#ssh

And the topic specifically about the X11 Forwarding can be found at https://gist.github.com/ryuheechul/9515381570a0cea994e62647d92a864f#when-forwardx11-yes-doesnt-work.

Dealing with gotchas

Screen being rotated

Somehow after connecting to Windows laptop with Chrome Remote Desktop, It flips the screen 180 degree. Thanks to https://superuser.com/a/1490095, I discovered Screen Rotate app that helps to flip it back

Keyboard layout

I prefer Korean (or American as English typing experience is same in both Korean and American) layout (where Shift+3 is #). Sometimes You laptop's keyboard layout is different than you expect (for example it's £ instead of #). I install and Korean Microsoft IME and also set it as default preferred language so it stays the same even after reboot.

/etc/hosts gets reset

Because that's apparently a default behaviour but you can actually turn it off as described here, https://docs.microsoft.com/en-us/windows/wsl/wsl-config#network (and the comment in /etc/hosts).

However I noticed that there are some entries added by Docker like below.

# /etc/hosts

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateHosts = false

# ...

192.168.1.209	host.docker.internal
192.168.1.209	gateway.docker.internal
127.0.0.1	kubernetes.docker.internal

# ...

So I wondered how that's possible and searched more and found this comment. And you can see it's added by Docker in /mnt/c/Windows/System32/drivers/etc/hosts

# /mnt/c/Windows/System32/drivers/etc/hosts

# ...
# Added by Docker Desktop
192.168.1.209 host.docker.internal
192.168.1.209 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section

And I decided to write more entries in /mnt/c/Windows/System32/drivers/etc/hosts rather than turning off auto generating behaviour.

Also see microsoft/WSL#5728 (comment)

Edit hosts

Follow instructions here, https://www.liquidweb.com/kb/edit-host-file-windows-10/ and then run wsl --shutdown and reconnect to wsl and /etc/hosts should be regenerated.

Docker

docker-compose

microsoft/WSL#4149 (comment)

sudo for Windows (from WSL)

https://github.com/Chronial/wsl-sudo

Examples

wudo vi
wudo powershell.exe

WSL initiated by SSH

It will close when SSH connection closes. If SSH connection takes longer than expected, maybe it's because this reason.

Usually this happens when you

powershell.exe
wsl --shutdown

to restart for some reason

Print dotnet version

According to these:

Install-Module -Name DotNetVersionLister -Scope CurrentUser #-Force
Get-STDotNetVersion

If fail with security error,

Set-ExecutionPolicy Bypass -Scope Process -Force; Import-Module DotNetVersionLister
Get-STDotNetVersion

Pause Windows Automatic Updates

https://www.cleverfiles.com/howto/disable-update-windows-10.html

$PATH being not loaded via SSH

When connected via SSH, refreshenv won't do, so you might need Restart-Service sshd for your (new) ssh connections to be able to load new $PATH

Etc

Automatic Wallpaper Change

https://www.microsoft.com/en-us/bing/bing-wallpaper

Monitoring

https://github.com/ryuheechul/win-monitoring

Super helpful blog about dev on Windows 10

https://www.hanselman.com/blog/category/win10

Virtual Machines via WSL

https://askubuntu.com/questions/1406888/ubuntu-22-04-gpu-passthrough-qemu

Build An Accelerated KVM Guest Custom Kernel for WSL 2

my note based on https://boxofcables.dev/kvm-optimized-custom-kernel-wsl2-2022/

Automatic Dark Mode Switching

https://github.com/AutoDarkMode/Windows-Auto-Night-Mode#download

@ryuheechul
Copy link
Author

ryuheechul commented Jan 28, 2022

a similar note for macOS

@ryuheechul
Copy link
Author

https://www.makeuseof.com/windows-limit-cpu-usage-program/ might be helpful to reduce the impact with this issue, microsoft/WSL#6982

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment