Lightning Fast and Easy Provisioning of Git with SSH Key Authentication on Windows

Search for a command to run...

No comments yet. Be the first to comment.
For a long time I have been playing with the concept of Enablement Automation Code as a Product. The alternative is roughly “as a quick start template”. In this case, this is not actually a product - but the effort is managed with all the perspective...
Why Least Privilege Security Engineering Is Frequently Skipped or Done Loosely In a previous life, I was on a team that reviewed the IAM policies specified by developers when they created new Cloud applications or required additional permissions for ...

Obscuring sensitive information like AWS account IDs in screenshots and videos is tedious and error-prone. Even with video editing tools that simplify the process, I still have to repeatedly add and remove blurring boxes as the view changes. You know...

AWS CloudShell joins the ranks of hostless shells for operating in your cloud environment. Cloud shells are a huge help to training and enablement scenarios because they remove the pain of fussy configuration of a user-owned endpoint - which can have...

This article is the third and final of a series. Part 1 justified that human-performed DevOps checklists are essentially source code, and according to GitOps principles, belong in Git just like any other code required for successfully managing a soft...

There are always those who feel checklists are an unnecessary waste of time because they think they can always remember the basics of the steps involved to complete a task. Many are also not aware of the huge, cross-discipline benefits that can come ...

Maybe you have a team of Windows developers that are onboarding for your new Git server installation or maybe you’ve decided to drop http password authentication to your existing Git server (due to it’s many problems). Your next steps may well be into a rough and rocky rabbit hole when you were holding out hope for simplicity (you know the kind you’ve fallen into before if you’ve been in tech for more than about 45 minutes).
The guides on the internet for getting Windows setup for SSH authentication for Git are unnecessarily complex.
My inner tool smith really loathes when the very first steps into something new are fraught with rocky rabbit holes - so I took on the challenge of creating an easier way.
The resultant tool is a 20 line PowerShell script that deploys Git, configures SSH and leaves the public key on your clipboard so you can paste it into GitLab or any other Git collaborative webserver. There is also an optional connectivity test.
There are multiple reasons you may want to move your Windows developers to SSH authentication for Git:
You want to get away from git storing local passwords - whether in the git config or in Windows Credentials (with the windows credential helper) because it is pure pain to walk people through how to find and update this password when they change it on the Git server.
You want to avoid both http passwords and the http protocol for git.
The conventional wisdom solution offers many steps that are roughly:
Installing git manually.
Installing the well known Windows SSH client Putty.
Installing Putty’s key generator.
Converting the non-compatible putty generated key into an ssh compatible one.
Precisely placing the SSH key on disk.
Precisely permissioning the SSH key and it’s parent folder (ssh is purposely fussy about this in order to keep the key secure).
Most of this can be avoided by simply using the full SSH client that is embedded inside of the Windows git client install.
Besides the above pure pain, here are the additional things solved for in this code:
Automatically installs Git - but only if necessary (idempotent)
Automatically installs chocolatey to install Git - but only if necessary (idempotent)
Automatically generates an SSH key - but only if necessary (idempotent) (which avoids killing a key that might be in use)
Uses the Git’s built-in SSH client to create SSH keys (avoids the complexity of the above conventional wisdom)
Copies the public key to the clip board and pauses for the user to add it to the Git server (in their profile)
Optionally does a SSH login test if you provide a value for: $SSHEndPointToGitForTesting
This code can be run directly from GitLab with this command:
Invoke-Expression -command "Invoke-WebRequest -uri 'https://gitlab.com/missionimpossiblecode/MissionImpossibleCode/-/raw/master/install-gitwithssh.ps1' -UseBasicParsing -OutFile ./install-gitwithssh.ps1" ; . ./install-gitwithssh.ps1
If you want to download dynamically, but also want the test and instructions to work, then set these environment variables before calling the above:
$env:YourGitServerhttpURL="https://gitlab.com" $env:GitSSHUserAndEndPointForTesting="git@gitlab.com"
#some Git servers might want the windows userid "git", which is specified as $env:username
You can also simply copy the code, hardcode the two variables and distribute it in your organization.
# Set environment variables before calling in order to test
If ((Test-Path env:YourGitServerhttpURL) -and (!(Test-Path variable:YourGitServerhttpURL))) {$YourGitServerhttpURL="$env:YourGitServerhttpURL"} If ((Test-Path env:GitSSHUserAndEndPointForTesting) -and (!(Test-Path variable:GitSSHUserAndEndPointForTesting))) {$GitSSHUserAndEndPointForTesting="$env:GitSSHUserAndEndPointForTesting"}
# $YourGitServerhttpURL="https://gitlab.com"
# $GitSSHUserAndEndPointForTesting="$env:username@gitlab.com" #Optional to trigger testing Use "git@gitlab.com" for GitLab.
If (!(Test-Path 'C:\Program Files\git\usr\bin\ssh-keygen.exe')) { Write-Host 'Installing latest git client using Chocolatey' If (!(Test-Path env:chocolateyinstall)) { Write-Host "Chocolatey is not present, installing on demand." iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex } cinst -y git }
If (!(Test-Path $env:userprofile.ssh\id_rsa.pub)) { Write-Host 'No default ssh key present in $env:userprofile.ssh, generating a new one.' Write-Warning 'Press enter for default file name and twice for password to set it to not have a password' & 'C:\Program Files\git\usr\bin\ssh-keygen.exe' } get-content $env:userprofile.ssh\id_rsa.pub | clip write-host "Your public ssh key is now on your clipboard, ready to be pasted into your git server at $YourGitServerhttpURL"
If (Test-Path variable:GitSSHUserAndEndPointForTesting) { Write-Host 'NOTE: Sometimes it takes a while for your Git server to propagate your key so it is available for authentication after first adding it!' Write-Host 'After you have setup the key, to test the connection, press any key to continue...'; $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
#Use git's open ssh:
Write-Host "...Testing ssh login as ${GitSSHUserAndEndPointForTesting} using key $env:userprofile.ssh\id_rsa on port 22" $env:term = 'xterm256colors' push-location 'c:\program files\git\usr\bin' .\ssh.exe "${GitSSHUserAndEndPointForTesting}" -i $env:userprofile.ssh\id_rsa -p 22 pop-location Write-Host 'After observing the test result above (note it may take time for your new key to propagate at the server), press any key to continue...'; $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); }
The solution is very concise.
The solution is idempotent (only takes steps necessary when things are missing).
The solution solves multiple challenging issues in the simplest possible way.