Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Windows 10-based Linux Developer Setup (Coming from macOS)

How to Install OpenSSH on Windows 10 (any version) with Publickey Authentication working

This brief tutorial assumes you already have an SSH public key you want to use

  1. Install chocolatey via Powershell

    Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(''))
  2. Close Powershell

  3. Open a new Powershell session

  4. Install OpenSSH using Chocolatey

    choco install openssh -params '"/SSHServerFeature /KeyBasedAuthenticationFeature /SSHAgentFeature"'
  5. then enter:

    cd $env:USERPROFILE
    mkdir .ssh
  6. Open up notepad, using CRLF line endings (if you're using an older version of Windows 10, you will likely need to use a text editor like Notepad++, Visual Studio Code or Github's ATOM), paste in your SSH public key, save the file to .ssh\authorized_keys (the name must match for it to be used)

  7. From Windows explorer, remove the .txt extension from .ssh\authorized_keys.txt

  8. Attempt to SSH in to your Windows computer and be amazed at how easy it really is

Setting up your config file

  1. Generate an OpenSSH key pair (the -b flag denotes the bits, in this example 4096 is used which may be excessive):

    ssh-keygen -t rsa -b 4096
  2. You will then receive the following prompt, enter the path and name you would like to use for the key:

    Enter file in which to save the key (C:\Users\myusername/.ssh/id_rsa):
  3. You will then be prompted to enter a passphrase, note the password before entering it in your password manager OR live dangerously and not use a password.

  4. From the command line, type in:

    cd $env:USERPROFILE
    notepad .ssh\config
  5. Update your ssh config as per usual

  6. Remove the .txt extension from .ssh\config by using Windows Explorer

  7. Save the file (CTRL+S)

  8. Run the following to list the users with access

    icacls .ssh/config
  9. Run the following for each user in the list except your own:

    icacls .ssh/config /remove BUILTIN\Administrators
    icacls .ssh/config /remove NT AUTHORITY\SYSTEM
  10. Now you can copy your public key to the machines you want to connect to by copying the contents of your public key into their respective .ssh/authorized_keys file 11.Attempt to connect to one of the hosts you copied the key to-it should work properly

Quality of Life Improvements

Install VSCode first!!!

choco install vscode
choco install openvpn

Yubikey for WSL and Native OpenSSH

Someone wrote a Go-Binary to help with this, you can find it here

Install WireGuard

from here

Associate JSON to VScode

Handy script can be found here

Remapping Keys

Checkout sharpkeys

Spotlight-like Search


Windows Subsystem for Linux 2

#Install WSL
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# Set WSL Version 2 if you have it
#wsl --set-default-version 2

Download Ubuntu

Invoke-WebRequest -Uri -OutFile Ubuntu.appx -UseBasicParsing

How-to Enable

Setting up WSL Environment

Nerd Fonts

There isn't any sort of handy installer, so grab the download(s) for your preferred fonts here

Install your fonts BEFORE you try to configure VSCode to use them!!


Ensure you install PowerShell Core 7 first by running

Tutorial here

Stuff to investigate

Linux keyboard reconfigure to match macOS

sudo apt-get install keyboard-configuration
sudo dpkg-reconfigure keyboard-configuration
export $ZSH_CUSTOM="/home/$(whoami)/.oh-my-zsh/custom"
# Why not use Homebrew for Linux?
# It breaks the rbenv feature in PowerLevel9k
# Install Dependencies
apt-get install -y git clang zsh make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl --no-install-recommends
# Install oh-my-zsh
sh -c "$(curl -fsSL" "" --unattended
# Set the default shell to zsh
chsh -s $(which zsh)
# Install Powerlevel9k
git clone $ZSH_CUSTOM/themes/powerlevel9k
# Install zsh autosuggestions
git clone $ZSH_CUSTOM/plugins/zsh-autosuggestions
git clone $ZSH_CUSTOM/plugins/zsh-syntax-highlighting
exec $SHELL
# Install Env Tools
echo "Installing goenv"
git clone ~/.goenv
echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.zshrc
echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(goenv init -)"' >> ~/.zshrc
echo 'export PATH="$GOROOT/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.zshrc
exec $SHELL
echo "Installing rbenv"
git clone ~/.rbenv
cd ~/.rbenv && src/configure && make -C src
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(rbenv init -)"' >> ~/.zshrc
exec $SHELL
mkdir -p "$(rbenv root)"/plugins
git clone "$(rbenv root)"/plugins/ruby-build
echo "Installing pyenv"
git clone ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.zshrc
exec $SHELL
mkdir ~/{repos,.ssh,.fonts}
unzip -d ~/.fonts
cat > ~/.gemrc <<EOF
# The paths in which to look for gems
# :gempath:
# Force specification of gem server host on push
# disable_default_gem_server:
# A YAML array of remote gem repositories to install gems from
# :sources:
# Self explanatory :-)
benchmark: false
# Verbosity of the gem command. false, true, and :really are the levels
verbose: false
# Enable/disable automatic updating of repository metadata
update_sources: true
# Print backtrace when RubyGems encounters an error
backtrace: true
# <gem_command>: A string containing arguments for the specified gem command
# -N, --no-document - Disable documentation generation
# --[no-]document [TYPES] - Generate documentation for installed gems List the
# documentation types you wish to generate. For example: rdoc,ri
# --[no-]suggestions - Suggest alternates when gems are not found
gem: --no-ri --no-rdoc --no-document --suggestions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment