Skip to content

Commit 70d374b

Browse files
committed
FIX: Keyfile usage and non WSL connection check for ssl
1 parent 0cac142 commit 70d374b

File tree

2 files changed

+116
-43
lines changed

2 files changed

+116
-43
lines changed

Connect-SSH.ps1

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,45 @@ if (-not $config) {
1616
# Get servers from config
1717
$servers = @{}
1818
$serverKeyFiles = @{}
19+
$serverUsers = @{}
1920
if ($config.ssh.servers) {
2021
foreach ($key in $config.ssh.servers.PSObject.Properties.Name) {
2122
$servers[$key] = $config.ssh.servers.$key.hostname
2223
if ($config.ssh.servers.$key.keyFile) {
2324
$serverKeyFiles[$key] = $config.ssh.servers.$key.keyFile
2425
}
26+
if ($config.ssh.servers.$key.user) {
27+
$serverUsers[$key] = $config.ssh.servers.$key.user
28+
}
2529
}
2630
}
2731

28-
# Resolve hostname and key file
32+
# Resolve hostname, key file, and user
2933
$keyFile = $null
34+
$configUser = $null
3035
if ($servers.ContainsKey($Target)) {
3136
$Server = $servers[$Target]
3237
if ($serverKeyFiles.ContainsKey($Target)) {
3338
$keyFile = $serverKeyFiles[$Target]
3439
}
40+
if ($serverUsers.ContainsKey($Target)) {
41+
$configUser = $serverUsers[$Target]
42+
}
3543
} else {
3644
$Server = $Target
3745
}
3846

3947
# Try Posh-SSH first if WSL not available
40-
$useWSL = $true
48+
$useWSL = $false
4149
$wsl = Get-Command wsl -ErrorAction SilentlyContinue
42-
if (-not $wsl) {
43-
$useWSL = $false
50+
if ($wsl) {
51+
# Check if WSL has a distribution installed
52+
$wslCheck = wsl echo "ok" 2>&1
53+
if ($wslCheck -eq "ok") {
54+
$useWSL = $true
55+
}
56+
}
57+
if (-not $useWSL) {
4458
# Use Posh-SSH
4559
try {
4660
Import-Module Posh-SSH -ErrorAction Stop
@@ -58,7 +72,12 @@ $credsDir = Join-Path $scriptDir "creds"
5872
# Check for key file authentication
5973
$keyFilePath = $null
6074
if ($keyFile) {
61-
$keyFilePath = Join-Path $credsDir $keyFile
75+
# Support both absolute paths and relative paths (in creds directory)
76+
if ([System.IO.Path]::IsPathRooted($keyFile)) {
77+
$keyFilePath = $keyFile
78+
} else {
79+
$keyFilePath = Join-Path $credsDir $keyFile
80+
}
6281
if (-not (Test-Path $keyFilePath)) {
6382
Write-Host ""
6483
Write-Host "Key file not found: $keyFilePath" -ForegroundColor Yellow
@@ -106,19 +125,23 @@ if (-not $keyFile) {
106125
$password = $cred.GetNetworkCredential().Password
107126
} else {
108127
# For key file auth, we need a username from config or credential file
109-
$credFile = $config.ssh.credentialFile
110-
if ($credFile) {
111-
$credPath = Join-Path $credsDir $credFile
112-
if (Test-Path $credPath) {
113-
$cred = Import-Clixml $credPath
114-
$username = $cred.UserName
128+
if ($configUser) {
129+
$username = $configUser
130+
} else {
131+
$credFile = $config.ssh.credentialFile
132+
if ($credFile) {
133+
$credPath = Join-Path $credsDir $credFile
134+
if (Test-Path $credPath) {
135+
$cred = Import-Clixml $credPath
136+
$username = $cred.UserName
137+
}
115138
}
116139
}
117140

118141
if (-not $username) {
119142
Write-Host ""
120143
Write-Host "Username required for key file authentication." -ForegroundColor Yellow
121-
Write-Host "Create a credential file with just the username:" -ForegroundColor Cyan
144+
Write-Host "Add 'user' to server config or create a credential file:" -ForegroundColor Cyan
122145
Write-Host " `$cred = Get-Credential -UserName 'your-ssh-username'" -ForegroundColor Gray
123146
Write-Host " `$cred | Export-Clixml '.\creds\ssh-credentials.xml'" -ForegroundColor Gray
124147
Write-Host ""
@@ -130,9 +153,11 @@ if (-not $keyFile) {
130153
if ($useWSL) {
131154
if ($keyFile) {
132155
# Convert Windows path to WSL path for key file
133-
$wslKeyPath = wsl wslpath -u "'$keyFilePath'"
156+
$escapedPath = $keyFilePath -replace '\\', '/'
157+
$wslKeyPath = (wsl wslpath -u "'$escapedPath'").Trim()
134158
Write-Host "Connecting to $Server as $username (using key file)..." -ForegroundColor Cyan
135-
wsl bash -c "ssh -o StrictHostKeyChecking=no -i $wslKeyPath $username@$Server"
159+
Write-Host "Key: $wslKeyPath" -ForegroundColor Gray
160+
wsl bash -c "ssh -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i '$wslKeyPath' $username@$Server"
136161
} else {
137162
# Check if sshpass is installed
138163
$hasSshpass = wsl bash -c "command -v sshpass >/dev/null 2>&1 && echo 'yes' || echo 'no'"

Connect-SSHTunnel.ps1

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@ if (-not $config) {
2525
# Get servers from config
2626
$servers = @{}
2727
$serverKeyFiles = @{}
28+
$serverUsers = @{}
2829
if ($config.ssh.servers) {
2930
foreach ($key in $config.ssh.servers.PSObject.Properties.Name) {
3031
$servers[$key] = $config.ssh.servers.$key.hostname
3132
if ($config.ssh.servers.$key.keyFile) {
3233
$serverKeyFiles[$key] = $config.ssh.servers.$key.keyFile
3334
}
35+
if ($config.ssh.servers.$key.user) {
36+
$serverUsers[$key] = $config.ssh.servers.$key.user
37+
}
3438
}
3539
}
3640

@@ -64,13 +68,17 @@ if ($LocalPort -eq 0) {
6468
$LocalPort = $RemotePort
6569
}
6670

67-
# Resolve hostname and key file
71+
# Resolve hostname, key file, and user
6872
$keyFile = $null
73+
$configUser = $null
6974
if ($servers.ContainsKey($Target)) {
7075
$Server = $servers[$Target]
7176
if ($serverKeyFiles.ContainsKey($Target)) {
7277
$keyFile = $serverKeyFiles[$Target]
7378
}
79+
if ($serverUsers.ContainsKey($Target)) {
80+
$configUser = $serverUsers[$Target]
81+
}
7482
} else {
7583
$Server = $Target
7684
}
@@ -81,7 +89,12 @@ $credsDir = Join-Path $scriptDir "creds"
8189
# Check for key file authentication
8290
$keyFilePath = $null
8391
if ($keyFile) {
84-
$keyFilePath = Join-Path $credsDir $keyFile
92+
# Support both absolute paths and relative paths (in creds directory)
93+
if ([System.IO.Path]::IsPathRooted($keyFile)) {
94+
$keyFilePath = $keyFile
95+
} else {
96+
$keyFilePath = Join-Path $credsDir $keyFile
97+
}
8598
if (-not (Test-Path $keyFilePath)) {
8699
Write-Host ""
87100
Write-Host "Key file not found: $keyFilePath" -ForegroundColor Yellow
@@ -129,19 +142,23 @@ if (-not $keyFile) {
129142
$password = $cred.GetNetworkCredential().Password
130143
} else {
131144
# For key file auth, we need a username from config or credential file
132-
$credFile = $config.ssh.credentialFile
133-
if ($credFile) {
134-
$credPath = Join-Path $credsDir $credFile
135-
if (Test-Path $credPath) {
136-
$cred = Import-Clixml $credPath
137-
$username = $cred.UserName
145+
if ($configUser) {
146+
$username = $configUser
147+
} else {
148+
$credFile = $config.ssh.credentialFile
149+
if ($credFile) {
150+
$credPath = Join-Path $credsDir $credFile
151+
if (Test-Path $credPath) {
152+
$cred = Import-Clixml $credPath
153+
$username = $cred.UserName
154+
}
138155
}
139156
}
140157

141158
if (-not $username) {
142159
Write-Host ""
143160
Write-Host "Username required for key file authentication." -ForegroundColor Yellow
144-
Write-Host "Create a credential file with just the username:" -ForegroundColor Cyan
161+
Write-Host "Add 'user' to server config or create a credential file:" -ForegroundColor Cyan
145162
Write-Host " `$cred = Get-Credential -UserName 'your-ssh-username'" -ForegroundColor Gray
146163
Write-Host " `$cred | Export-Clixml '.\creds\ssh-credentials.xml'" -ForegroundColor Gray
147164
Write-Host ""
@@ -157,13 +174,23 @@ Write-Host "Press Ctrl+C to close the tunnel" -ForegroundColor Yellow
157174
Write-Host ""
158175

159176
# Use WSL with sshpass for the tunnel
177+
$useWSL = $false
160178
$wsl = Get-Command wsl -ErrorAction SilentlyContinue
161179
if ($wsl) {
180+
# Check if WSL has a distribution installed
181+
$wslCheck = wsl echo "ok" 2>&1
182+
if ($wslCheck -eq "ok") {
183+
$useWSL = $true
184+
}
185+
}
186+
if ($useWSL) {
162187
if ($keyFile) {
163188
# Convert Windows path to WSL path for key file
164-
$wslKeyPath = wsl wslpath -u "'$keyFilePath'"
189+
$escapedPath = $keyFilePath -replace '\\', '/'
190+
$wslKeyPath = (wsl wslpath -u "'$escapedPath'").Trim()
191+
Write-Host "Key: $wslKeyPath" -ForegroundColor Gray
165192
# Create SSH tunnel using key file through WSL
166-
wsl bash -c "ssh -o StrictHostKeyChecking=no -i $wslKeyPath -N -L ${LocalPort}:${RemoteHost}:${RemotePort} $username@$Server"
193+
wsl bash -c "ssh -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i '$wslKeyPath' -N -L ${LocalPort}:${RemoteHost}:${RemotePort} $username@$Server"
167194
} else {
168195
# Check if sshpass is installed
169196
$hasSshpass = wsl bash -c "command -v sshpass >/dev/null 2>&1 && echo 'yes' || echo 'no'"
@@ -176,27 +203,48 @@ if ($wsl) {
176203
wsl bash -c "SSHPASS='$password' sshpass -e ssh -o StrictHostKeyChecking=no -N -L ${LocalPort}:${RemoteHost}:${RemotePort} $username@$Server"
177204
}
178205
} else {
179-
# Fallback to Posh-SSH
180-
try {
181-
Import-Module Posh-SSH -ErrorAction Stop
206+
# Try native Windows SSH first (available in Windows 10/11)
207+
$nativeSsh = Get-Command ssh.exe -ErrorAction SilentlyContinue
208+
if ($nativeSsh) {
209+
Write-Host "Using native Windows SSH..." -ForegroundColor Gray
210+
$sshArgs = @(
211+
"-o", "StrictHostKeyChecking=no",
212+
"-o", "IdentitiesOnly=yes",
213+
"-N",
214+
"-L", "${LocalPort}:${RemoteHost}:${RemotePort}"
215+
)
182216
if ($keyFile) {
183-
$session = New-SSHSession -ComputerName $Server -KeyFile $keyFilePath -AcceptKey
184-
} else {
185-
$session = New-SSHSession -ComputerName $Server -Credential $cred -AcceptKey
217+
$sshArgs += @("-i", $keyFilePath)
186218
}
219+
$sshArgs += "$username@$Server"
187220

188-
Write-Host "Tunnel established. Keep this window open." -ForegroundColor Green
189-
Write-Host "Press Ctrl+C to close..." -ForegroundColor Yellow
190-
191-
# Keep tunnel open
192-
Start-Sleep -Seconds 999999
193-
194-
} catch {
195-
Write-Host "Tunnel setup failed: $($_.Exception.Message)" -ForegroundColor Red
196-
exit 1
197-
} finally {
198-
if ($session) {
199-
Remove-SSHSession -SessionId $session.SessionId | Out-Null
221+
& ssh.exe @sshArgs
222+
} else {
223+
# Fallback to Posh-SSH
224+
try {
225+
Import-Module Posh-SSH -ErrorAction Stop
226+
if ($keyFile) {
227+
$session = New-SSHSession -ComputerName $Server -KeyFile $keyFilePath -AcceptKey
228+
} else {
229+
$session = New-SSHSession -ComputerName $Server -Credential $cred -AcceptKey
230+
}
231+
232+
# Set up port forwarding
233+
$tunnel = New-SSHLocalPortForward -SSHSession $session -BoundHost "127.0.0.1" -BoundPort $LocalPort -RemoteAddress $RemoteHost -RemotePort $RemotePort
234+
235+
Write-Host "Tunnel established. Keep this window open." -ForegroundColor Green
236+
Write-Host "Press Ctrl+C to close..." -ForegroundColor Yellow
237+
238+
# Keep tunnel open
239+
Start-Sleep -Seconds 999999
240+
241+
} catch {
242+
Write-Host "Tunnel setup failed: $($_.Exception.Message)" -ForegroundColor Red
243+
exit 1
244+
} finally {
245+
if ($session) {
246+
Remove-SSHSession -SessionId $session.SessionId | Out-Null
247+
}
200248
}
201249
}
202250
}

0 commit comments

Comments
 (0)