Simplifying SSH Key Management setup with PowerShell
Simplifying SSH Key Management setup with PowerShell
Introduction
Managing SSH keys effectively is crucial for maintaining secure and efficient access to remote systems. This blog post introduces a PowerShell script designed to configure an SSH-Agent on Windows 11 with keys. I use this method when I first build a new Windows 11. Using SSH-Agent allows me to use forwarding agent requests and allows for using Yubikey certificates acorss an RDP session. The management of SSH keys by automating the key addition, configuration, and cleanup processes.
Overview of the Script
This PowerShell script simplifies SSH key management by:
- Ensuring the
ssh-agent
service is running and set to start automatically. - Copying private key files (
.key
) from a specified source folder to the.ssh
directory. - Adding the private keys to
ssh-agent
. - Updating the SSH config file with predefined host configurations.
- Cleaning up by removing the private key files after adding them to
ssh-agent
.
How the Script Works
Step 1: Checking Administrative Privileges
The script starts by verifying if it is run with administrative privileges, as managing the ssh-agent
service requires elevated rights.
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Error "This script must be run as an administrator."
exit 1
}
Step 2: Managing the ssh-agent Service
The script ensures that the ssh-agent
service is active and configured to start automatically.
Get-Service ssh-agent | Set-Service -StartupType Automatic -PassThru | Start-Service
Step 3: Copying and Adding Keys
Private keys are copied from the specified source folder to the .ssh
directory. After copying, each key is added to the ssh-agent
.
Get-ChildItem -Path $sourceFolder -Recurse -Filter "*.key" | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $destinationFile -Force
ssh-add $destinationFile
}
Step 4: Cleaning Up Key Files
Once the keys are added to ssh-agent
, they are removed from the .ssh
directory to enhance security.
Get-ChildItem -Path $destinationFolder -Filter "*.key" | ForEach-Object {
Remove-Item -Path $_.FullName -Force
}
Step 5: Updating SSH Configurations
The script appends predefined host configurations to the SSH config file, ensuring consistent and secure connection settings.
Add-Content -Path $sshConfigFile -Value $newHostConfig
Customization and Usage
You can customize the source folder path and the SSH host configurations as needed. To run the script, use the following command:
.\ManageSSH.ps1 -sourceFolder "Path\To\Your\Keys"
Complete Script
<#
.SYNOPSIS
Manages SSH keys by ensuring the ssh-agent is running, copying keys, adding them to the agent,
updating the SSH config file, and removing the copied key files after adding them to ssh-agent.
.DESCRIPTION
This script performs the following tasks:
- Ensures the ssh-agent service is running and set to start automatically.
- Recursively copies private key files (.key) from a specified source folder to the .ssh directory.
- Adds the private keys to the ssh-agent.
- Updates the SSH config file with specified host configurations.
- Removes all private key files from the .ssh directory after they are added to ssh-agent.
.PARAMETER sourceFolder
The path to the folder containing the private key files to be processed.
.EXAMPLE
.\ManageSSH.ps1 -sourceFolder "G:\Keys"
This command recursively copies all .key files from "G:\Keys" to the .ssh directory,
adds them to the ssh-agent, updates the SSH config, and removes the copied keys.
.NOTES
Author: Craig
Date: 2024-11-03
Version: 1.3
#>
param (
[string]$sourceFolder
)
# Check for administrative privileges
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Error "This script must be run as an administrator."
exit 1
}
Write-Output "Starting SSH key management process..."
# Ensure ssh-agent service is set to start automatically and is running
Write-Output "Ensuring ssh-agent service is running..."
Get-Service ssh-agent | Set-Service -StartupType Automatic -PassThru | Start-Service
Write-Output "ssh-agent service is running."
# Define the destination folder as the .ssh directory in the user's profile
$destinationFolder = "$($env:USERPROFILE)\.ssh"
# Create the .ssh folder if it doesn't exist
if (!(Test-Path -Path $destinationFolder)) {
Write-Output "Creating .ssh directory at $destinationFolder..."
New-Item -ItemType Directory -Path $destinationFolder | Out-Null
Write-Output ".ssh directory created."
} else {
Write-Output ".ssh directory already exists at $destinationFolder."
}
# Process .key files: copy to .ssh, add to ssh-agent
Write-Output "Processing private keys from $sourceFolder..."
Get-ChildItem -Path $sourceFolder -Recurse -Filter "*.key" | ForEach-Object {
$sourceFile = $_.FullName
$destinationFile = Join-Path -Path $destinationFolder -ChildPath $_.Name
# Log the file being processed
Write-Output "Processing file: $sourceFile"
# Copy the key file to the .ssh directory
Copy-Item -Path $sourceFile -Destination $destinationFile -Force
Write-Output "Copied: $sourceFile to $destinationFile"
# Add the key to the ssh-agent
ssh-add $destinationFile
Write-Output "Added key to ssh-agent: $destinationFile"
}
Write-Output "All private keys added to ssh-agent."
# Remove all .key files from the .ssh directory
Write-Output "Cleaning up .ssh directory by removing all .key files..."
Get-ChildItem -Path $destinationFolder -Filter "*.key" | ForEach-Object {
Write-Output "Removing key file: $($_.FullName)"
Remove-Item -Path $_.FullName -Force
Write-Output "Removed key file: $($_.FullName)"
}
# Define the path to the SSH config file
$sshConfigFile = Join-Path -Path $destinationFolder -ChildPath "config"
# Check if config file exists, create if it doesn't
if (!(Test-Path -Path $sshConfigFile)) {
Write-Output "Creating SSH config file at $sshConfigFile..."
New-Item -ItemType File -Path $sshConfigFile | Out-Null
Write-Output "SSH config file created."
} else {
Write-Output "SSH config file already exists at $sshConfigFile."
}
# Define the new host configuration as a string
$newHostConfig = @"
# Default settings for all hosts
Host *
ForwardAgent yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 60
ServerAliveCountMax 3
# Specific host configuration
Host host-01
HostName host-01
User craig
port 22
"@
# Append the new host configuration to the SSH config file
Write-Output "Appending new host configurations to SSH config file..."
Add-Content -Path $sshConfigFile -Value $newHostConfig
Write-Output "New host configurations added to SSH config."
Write-Output "SSH key management process completed."
Conclusion
This PowerShell script automates the setup task of managing SSH keys, making it easier to maintain secure and organized SSH configurations. By integrating this script into your workflow, you can ensure that your SSH key configuration is efficient and secure.