PSSession через обратный SSH туннель
03 Jul 2017
local_offer
powershell
local_offer
Icinga2
По умолчанию powershell (WS-Management) открывает порты:
TCP/5985 - HTTP
TCP/5986 - HTTPS
Предполагается, что SSH сервер (в моем примере это 222.222.222.222) уже установлен и настроен. Так же предполагается, что PowerShell Remoting тоже уже настроен на удаленной машине.
На удаленном хосте (PC1) за NATом создаем туннель с внешним SSH сервером:
plink.exe -batch -P 2201 -N -C -v -R 59855:localhost:5985 ssh_user@222.222.222.222 -pw passsword
На локальной машине администратора создаем туннель с SSH сервером:
plink.exe -P 2201 -N -C -v -L 59850:localhost:59855 ssh_user@222.222.222.222 -pw passsword
Примечание. Так ка машины скорее всего не в одном домене предварительно выполним команду:
winrm set winrm/config/client @{TrustedHosts="*"}
И запускаем powershell сессию:
Enter-PSSession -ComputerName localhost -port 59850 -Credential PC1\Administrator
Скрипт для Icinga2 - создание туннеля:
```powershell
<#
icinga2scripts
Version 1.0
Description: Скрипт для Icinga 2 - Создание ssh туннеля с удаленным хостом для PSRemoting
Pavel Satin (c) 2017
pslater.ru@gmail.com
#>
#[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3
$portnum = "598" + (Get-Random -minimum 10 -maximum 99).ToString()
$tunnelcmd = "c:\ProgramData\icinga2\Scripts\icinga2\plink.exe"
$tunnelarg = "-batch -P 2201 -N -C -v -R " + $portnum + ":localhost:5985 ssh_user@222.222.222.222 -pw password"
$regSSHkey = "HKCU:\Software\SimonTatham\PuTTY\SshHostKeys"
$regSSHname = "rsa2@2201:222.222.222.222"
$regSSHval = "0x10001,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
if (!(Test-Path $regSSHkey -PathType Any)) {
New-Item -Path $regSSHkey -Force | Out-Null
New-ItemProperty -Path $regSSHkey -Name $regSSHName -Value $regSSHval -PropertyType String -Force | Out-Null
} else {
New-ItemProperty -Path $regSSHkey -Name $regSSHName -Value $regSSHval -PropertyType String -Force | Out-Null
}
$process = (start-process $tunnelcmd -argumentlist $tunnelarg -PassThru)
Start-Sleep -s 5
if ($process.HasExited) {
Write-Host "Failed to start plink. The process is closed with the code: " $process.ExitCode
[System.Environment]::Exit($returnStateCritical)
} else {
#Отправка pushover сообщения
$uri = "https://api.pushover.net/1/messages.json"
$parameters = @{
token = "PUSHOVER_TOKEN"
user = "PUSHOVER_USER"
message = "Создан SSH(PS) туннель на порту: $portnum с узлом: $env:computername"
}
$pushoverreq = $parameters | Invoke-RestMethod -Uri $uri -Method Post
Write-Host "OK - The tunnel is created. Port number: $portnum"
Write-Host "To connect:"
Write-Host "plink.exe -P 2201 -N -C -v -L 59850:localhost:$portnum ssh_user@222.222.222.222 -pw password"
[System.Environment]::Exit($returnStateOK)
}
```
Скрипт для подключения к туннелю со стороны администратора:
```powershell
<#
icinga2scripts
Version 1.0
Description: Скрипт для Icinga 2 - Запуск PSSession через туннель
Pavel Satin (c) 2017
pslater.ru@gmail.com
#>
$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3
#Windows Balloon
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
if ($args[0] -eq $null) {
$objNotifyIcon.Icon = "C:\Scripts\images\icinga.ico"
$objNotifyIcon.BalloonTipIcon = "Error"
$objNotifyIcon.BalloonTipText = "Параметр с именем хоста не передан! Работа скрипта завершена."
$objNotifyIcon.BalloonTipTitle = "Подключение через туннель"
$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(30000)
Start-Sleep -s 10
$objNotifyIcon.Visible = $false
$script:objNotifyIcon.Dispose()
#Remove–Variable –Scope script –Name objNotifyIcon
exit
}
$rdpHost = $args[0]
$plinkPath = "C:\Scripts\bin\"
$user = "icingaapiuser"
$pass= "icingaapipassword"
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)
$apiurl = "http://222.222.222.222:5665/v1/objects/services/" + $rdpHost + "!create-ps-tunnel?attrs=last_check_result"
#$headers = @{}
#$headers["Accept"] = "application/json"
$apireq = Invoke-WebRequest -Credential $credential -Uri $apiurl -Method Get -UseBasicParsing -ContentType "text/plain; charset=Windows-1251"
$outputresult = $apireq | ConvertFrom-Json | Select-Object-Object -expand Results | Select-Object -expand attrs | Select-Object -expand last_check_result
$strOutput = $outputresult.output
$indxPlink = $strOutput.IndexOf("plink")
$portnum = "598" + (Get-Random -minimum 10 -maximum 99).ToString()
$strOutput2 = $strOutput.Substring($indxPlink, $strOutput.Length - $indxPlink)
$cmdArgs = "/C " + $strOutput2.Replace("59850", $portnum)
#Запуск процессов
Start-Process cmd.exe $cmdArgs
$objNotifyIcon.Icon = "C:\Scripts\images\icinga.ico"
$objNotifyIcon.BalloonTipIcon = "Info"
$objNotifyIcon.BalloonTipText = "Устанавливаем подключение к $rdpHost"
$objNotifyIcon.BalloonTipTitle = "Подключение через туннель"
$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(30000)
$objNotifyIcon.Visible = $false
$script:objNotifyIcon.Dispose()
#Remove–Variable –Scope script –Name objNotifyIcon
Enter-PSSession localhost -Credential Administrator -port $portnum
```
Ссылки
- Статья опубликована мной на Хабре: Обратный туннель для доступа по RDP с использованием putty и icinga2
- Enable-PSRemoting
- PowerShell Remoting — настройка и удаленное управление