Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Check if the script is running with administrative privileges
- if (-not (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- Write-Host "This script requires administrative privileges..."
- Read-Host "Press Enter to end"
- exit
- }
- # Function to display instructions
- function Show-Instructions {
- Clear-Host
- Write-Host "==== OpenSSH Server Configuration Instructions ===="
- Write-Host ""
- Write-Host "This script configures the OpenSSH server on this Windows machine."
- Write-Host "After installing and configuring the server settings, you need to"
- Write-Host "generate and deploy SSH keys for secure access."
- Write-Host ""
- Write-Host "1. First, complete all necessary server configurations through this script."
- Write-Host " - Install or reinstall the OpenSSH Server."
- Write-Host " - Configure SSHD settings, the firewall rule, and SSH agent as needed."
- Write-Host ""
- Write-Host "2. After configuring the server, run the 'SSH_Key_Deployment_and_Connection.ps1'"
- Write-Host " script on your local machine to generate SSH keys and deploy them to this server."
- Write-Host ""
- Write-Host "3. Finally, use the key-based SSH connection to access this server securely."
- Write-Host ""
- Write-Host "Press Enter to return to the main menu..."
- Read-Host
- }
- # Function to install OpenSSH Server
- function Install-OpenSSHServer {
- <#
- .SYNOPSIS
- Installs the OpenSSH Server capability.
- .DESCRIPTION
- Installs the OpenSSH Server capability if it's available.
- .EXAMPLE
- Install-OpenSSHServer
- #>
- Install-OrReinstallOpenSSHServer -InstallOnly
- }
- # Function to reinstall OpenSSH Server
- function Reinstall-OpenSSHServer {
- <#
- .SYNOPSIS
- Reinstalls the OpenSSH Server capability.
- .DESCRIPTION
- Removes and reinstalls the OpenSSH Server capability if it's available.
- .EXAMPLE
- Reinstall-OpenSSHServer
- #>
- Install-OrReinstallOpenSSHServer -Reinstall
- }
- # Helper function to install or reinstall OpenSSH Server
- function Install-OrReinstallOpenSSHServer {
- param (
- [switch]$InstallOnly,
- [switch]$Reinstall
- )
- # Locate the OpenSSH Server capability
- $opensshCapability = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*'
- if ($opensshCapability) {
- try {
- if ($Reinstall -and $opensshCapability.State -eq 'Installed') {
- # Remove OpenSSH Server capability
- Write-Output "Removing OpenSSH Server..."
- Remove-WindowsCapability -Online -Name $opensshCapability.Name -ErrorAction Stop
- Write-Output "OpenSSH Server removed successfully."
- }
- # Attempt to install OpenSSH Server capability
- Write-Output "Installing OpenSSH Server..."
- Add-WindowsCapability -Online -Name $opensshCapability.Name -ErrorAction Stop
- Write-Output "OpenSSH Server installed successfully."
- }
- catch {
- Write-Error "Failed to $(if ($Reinstall) {"reinstall"} else {"install"}) OpenSSH Server: $($_.Exception.Message)"
- }
- }
- else {
- Write-Error "OpenSSH Server capability not found."
- }
- }
- # Function to start and set OpenSSH service
- function Set-OpenSSHService {
- [string]$serviceName = 'sshd'
- if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) {
- try {
- Start-Service $serviceName
- Set-Service -Name $serviceName -StartupType 'Automatic'
- Write-Output "OpenSSH service started and set to start automatically."
- }
- catch {
- Write-Error "Failed to configure OpenSSH service: $($_.Exception.Message)"
- }
- } else {
- Write-Error "Service '$serviceName' does not exist."
- }
- }
- # Function to configure sshd_config file settings
- function Configure-SSHDConfig {
- param (
- [string]$Port
- )
- $configPath = "C:\ProgramData\ssh\sshd_config"
- $defaultConfigPath = "C:\Windows\System32\OpenSSH\sshd_config_default"
- # Check if the sshd_config file exists
- if (-not (Test-Path -Path $configPath)) {
- # If it doesn't exist, copy the default config file
- try {
- Copy-Item -Path $defaultConfigPath -Destination $configPath -Force
- Write-Output "Copied default sshd_config file to $configPath"
- }
- catch {
- Write-Error "Failed to copy default sshd_config file: $($_.Exception.Message)"
- return
- }
- }
- # Function to modify or add settings in sshd_config file
- function Set-ConfigLine {
- param (
- [string]$FilePath,
- [string]$Setting,
- [string]$Value
- )
- # Read the file content as a single string
- $content = Get-Content -Path $FilePath -Raw
- # Special handling for 'Port' to ensure it's placed before any 'Match' block
- if ($Setting -eq 'Port') {
- $pattern = "^\s*#?\s*Port\s+.*" # Match lines with or without comment
- # Check if the 'Port' line exists, either commented or uncommented
- if ($content -match $pattern) {
- # Replace the line with the uncommented port setting
- $content = $content -replace "^\s*#?\s*Port\s+.*", "Port $Value"
- } else {
- # If the setting doesn't exist, add it before any Match block
- $matchIndex = $content.IndexOf("Match ")
- if ($matchIndex -ne -1) {
- # Insert before the 'Match' block
- $content = $content.Insert($matchIndex, "`r`nPort $Value`r`n")
- }
- else {
- # If no 'Match' block, append to the end
- $content += "`r`nPort $Value"
- }
- }
- }
- else {
- # Generic pattern for other settings
- $pattern = "^\s*#?\s*$Setting\s+.*"
- if ($content -match $pattern) {
- # Replace the matched line with the uncommented version of the setting
- $content = $content -replace "^\s*#?\s*$Setting\s+.*", "$Setting $Value"
- }
- else {
- # If the setting isn't found, add it before any Match block or at the end
- $matchIndex = $content.IndexOf("Match ")
- if ($matchIndex -ne -1) {
- $content = $content.Insert($matchIndex, "$Setting $Value`r`n")
- }
- else {
- $content += "`r`n$Setting $Value"
- }
- }
- }
- # Write the updated content back to the file, trimming extra newlines
- Set-Content -Path $FilePath -Value ($content.TrimEnd() + "`r`n")
- }
- # Configure each setting, replacing any matching commented-out or uncommented lines
- Set-ConfigLine -FilePath $configPath -Setting 'Port' -Value $Port
- Set-ConfigLine -FilePath $configPath -Setting 'PasswordAuthentication' -Value 'no'
- Set-ConfigLine -FilePath $configPath -Setting 'PermitRootLogin' -Value 'no'
- Set-ConfigLine -FilePath $configPath -Setting 'MaxAuthTries' -Value '3'
- Set-ConfigLine -FilePath $configPath -Setting 'LoginGraceTime' -Value '20'
- Set-ConfigLine -FilePath $configPath -Setting 'PubkeyAuthentication' -Value 'yes'
- Set-ConfigLine -FilePath $configPath -Setting 'KbdInteractiveAuthentication' -Value 'no'
- # Restart SSH service after configuration
- function Restart-SSHService {
- try {
- Restart-Service sshd
- Write-Output "SSH service restarted successfully after configuration changes."
- }
- catch {
- Write-Error "Failed to restart SSH service: $($_.Exception.Message)"
- }
- }
- Restart-SSHService
- }
- # Function to create firewall rule with optional port and force creation
- function New-OpenSSHFirewallRule {
- param(
- [int]$Port,
- [switch]$Force
- )
- $ruleName = "OpenSSH-Server-Custom-Port"
- $existingRule = Get-NetFirewallRule -Name $ruleName -ErrorAction SilentlyContinue
- if ($existingRule) {
- if ($Force) {
- # Remove existing rule if -Force is specified
- Remove-NetFirewallRule -Name $ruleName
- Write-Output "Existing firewall rule '$ruleName' was removed due to -Force."
- } else {
- # Notify if rule already exists and -Force is not specified
- Write-Output "Firewall rule '$ruleName' already exists. Use -Force to overwrite it."
- return
- }
- }
- # Attempt to create the new firewall rule
- try {
- New-NetFirewallRule -Name $ruleName -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort $Port
- Write-Output "Firewall rule '$ruleName' created successfully on port $Port."
- }
- catch {
- Write-Error "Failed to create firewall rule: $($_.Exception.Message)"
- }
- }
- # Function to start and configure ssh-agent
- function Start-SSHAgent {
- $sshAgentService = Get-Service ssh-agent -ErrorAction SilentlyContinue
- if ($sshAgentService) {
- if ($sshAgentService.Status -eq "Running") {
- Write-Output "SSH Agent is already running."
- }
- else {
- try {
- Start-Service ssh-agent
- Set-Service -Name ssh-agent -StartupType 'Automatic'
- Write-Output "SSH Agent started and set to start automatically."
- }
- catch {
- Write-Error "Failed to start SSH Agent: $($_.Exception.Message)"
- }
- }
- } else {
- Write-Error "SSH Agent service does not exist."
- }
- }
- # Function to verify SSH setup, including service status check and local connection tests
- function Verify-SSHSetup {
- # Path to SSHD configuration
- $sshdConfigPath = "C:\ProgramData\ssh\sshd_config"
- # Display SSHD config port setting
- Write-Host "sshd_config port setting:"
- try {
- $portSetting = (Get-Content -Path $sshdConfigPath | Select-String -Pattern '^Port').Line
- Write-Output "Configured SSH Port: $portSetting"
- }
- catch {
- Write-Error "Could not retrieve Port setting from sshd_config: $($_.Exception.Message)"
- }
- # Display SSH firewall rule ports
- Write-Host "SSH server firewall rule port(s):"
- try {
- $firewallPorts = Get-NetFirewallRule -DisplayName 'OpenSSH Server (sshd)' | Get-NetFirewallPortFilter | ForEach-Object { $_.LocalPort }
- Write-Output "Firewall Rule Ports: $firewallPorts"
- }
- catch {
- Write-Error "Could not retrieve firewall rule ports: $($_.Exception.Message)"
- }
- # Check if sshd service is running
- Write-Host "Checking SSH service status..."
- $sshdService = Get-Service -Name 'sshd' -ErrorAction SilentlyContinue
- if ($sshdService -and $sshdService.Status -eq 'Running') {
- Write-Output "SSH service is running. Proceeding with connection tests..."
- # Connection test using password authentication
- Write-Host "Testing SSH connection with password authentication..."
- try {
- $passwordAuthResult = & ssh -o PreferredAuthentications=password -o ConnectTimeout=3 -p 1337 localhost "echo 'Password authentication successful'" 2>&1
- if ($passwordAuthResult -match "Password authentication successful") {
- Write-Host "Password authentication was successful."
- } else {
- Write-Warning "Password authentication failed or is disabled."
- }
- } catch {
- Write-Error "An error occurred during password authentication test: $($_.Exception.Message)"
- }
- # Connection test using key authentication
- Write-Host "Testing SSH connection with key authentication..."
- try {
- $keyAuthResult = & ssh -o PreferredAuthentications=publickey -o ConnectTimeout=3 -p 1337 localhost "echo 'Key authentication successful'" 2>&1
- if ($keyAuthResult -match "Key authentication successful") {
- Write-Host "Key authentication was successful."
- } else {
- Write-Warning "Key authentication failed or is disabled."
- }
- } catch {
- Write-Error "An error occurred during key authentication test: $($_.Exception.Message)"
- }
- }
- elseif ($sshdService) {
- Write-Host "SSH service is installed but currently stopped. Skipping connection tests."
- }
- else {
- Write-Error "SSH service ('sshd') is not installed or cannot be found."
- }
- Write-Host "`nSSH setup verification complete."
- }
- # Function to set up key-based authentication
- function Setup-KeyAuthentication {
- $sshDir = "$env:USERPROFILE\.ssh"
- $authKeysFile = "$sshDir\authorized_keys"
- # Ensure .ssh directory exists
- if (-not (Test-Path -Path $sshDir)) {
- New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
- Write-Output ".ssh directory created at $sshDir"
- }
- # Create authorized_keys file with public key if it doesn't exist
- if (-not (Test-Path -Path $authKeysFile)) {
- # Generate keys if they don't exist
- if (-not (Test-Path -Path "$sshDir\id_ed25519.pub")) {
- ssh-keygen -t ed25519 -f "$sshDir\id_ed25519" -N "" | Out-Null
- Write-Output "SSH key pair generated."
- }
- # Copy public key to authorized_keys
- $publicKey = Get-Content -Path "$sshDir\id_ed25519.pub" -Raw
- Set-Content -Path $authKeysFile -Value $publicKey
- Write-Output "Public key added to authorized_keys."
- }
- else {
- Write-Output "authorized_keys file already exists."
- }
- # Set appropriate permissions on authorized_keys
- icacls $authKeysFile /inheritance:r /grant "$env:USERNAME:F" /grant "SYSTEM:F" | Out-Null
- Write-Output "Permissions set on authorized_keys."
- # Restart SSH service to apply changes
- Restart-Service sshd
- Write-Output "SSH service restarted to apply key-based authentication changes."
- }
- # Function to set up key-based authentication for administrator access
- function Setup-AdminKeyAuthentication {
- $sshDir = "C:\ProgramData\ssh"
- $authKeysFile = "$sshDir\administrators_authorized_keys"
- # Ensure ssh directory exists
- if (-not (Test-Path -Path $sshDir)) {
- New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
- Write-Output "SSH directory created at $sshDir"
- }
- # Define paths for the admin key files
- $adminKeyPath = "$env:USERPROFILE\.ssh\admin_id_ed25519"
- $adminPublicKeyPath = "$adminKeyPath.pub"
- # Generate admin key pair if public key doesn't exist
- if (-not (Test-Path -Path $adminPublicKeyPath)) {
- Start-Process ssh-keygen -ArgumentList "-t", "ed25519", "-f", "$adminKeyPath" -NoNewWindow -Wait
- if (Test-Path -Path $adminPublicKeyPath) {
- Write-Output "Admin SSH key pair generated."
- }
- else {
- Write-Output "Error: Failed to generate admin SSH key pair."
- return # Exit if key generation failed
- }
- }
- else {
- Write-Output "Admin SSH key pair already exists."
- }
- # Copy public key to administrators_authorized_keys
- $publicKey = Get-Content -Path $adminPublicKeyPath -Raw
- Set-Content -Path $authKeysFile -Value $publicKey
- Write-Output "Admin public key added to administrators_authorized_keys."
- # Set appropriate permissions on administrators_authorized_keys
- icacls $authKeysFile /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" | Out-Null
- Write-Output "Permissions set on administrators_authorized_keys."
- # Restart SSH service to apply changes
- Restart-Service sshd
- Write-Output "SSH service restarted to apply administrator key-based authentication changes."
- }
- # Display menu
- function Show-Menu {
- Clear-Host
- Write-Host "1. Display Instructions"
- Write-Host "2. Install OpenSSH Server"
- Write-Host "3. Reinstall OpenSSH Server"
- Write-Host "4. Configure OpenSSH Service"
- Write-Host "5. Configure SSHD Settings"
- Write-Host "6. Add Firewall Rule"
- Write-Host "7. Start SSH Agent"
- Write-Host "8. Verify SSH Setup"
- Write-Host "9. Setup Key-Based Authentication for User"
- Write-Host "10. Setup Key-Based Authentication for Administrator"
- Write-Host "11. Exit"
- }
- # Update the main loop to include the new admin key authentication function
- do {
- Show-Menu
- $choice = Read-Host "Select an option [1-11]"
- switch ($choice) {
- "1" { Show-Instructions }
- "2" { Install-OpenSSHServer }
- "3" { Reinstall-OpenSSHServer }
- "4" { Set-OpenSSHService }
- "5" {
- $Port = Read-Host "Enter the SSH Port (default is 1337)"
- if (-not $Port) { $Port = "1337" }
- Configure-SSHDConfig -Port $Port
- }
- "6" {
- $Port = Read-Host "Enter the SSH Port for Firewall Rule (default is 1337)"
- if (-not $Port) { $Port = "1337" }
- New-OpenSSHFirewallRule -Port $Port
- }
- "7" { Start-SSHAgent }
- "8" { Verify-SSHSetup }
- "9" { Setup-KeyAuthentication }
- "10" { Setup-AdminKeyAuthentication }
- "11" { Write-Host "Exiting..."; break }
- default { Write-Host "Invalid selection. Please choose a valid option." }
- }
- Read-Host "Press Enter to continue..."
- } while ($choice -ne "11")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement