Add selectable Windows PuTTY panel installer with editable server catalog #28

Open
ochenstarik wants to merge 2 commits from codex/windows-panel-installer-20261024 into main
3 changed files with 6 additions and 5 deletions
Showing only changes of commit d4e7e67905 - Show all commits

View file

@ -81,7 +81,7 @@ function Get-PanelRegistryPlan($Record, [string]$KeyPath) {
$entry = ConvertTo-PanelSession $Record $entry = ConvertTo-PanelSession $Record
if ([string]::IsNullOrWhiteSpace($KeyPath) -or $KeyPath -match '[\x00-\x1f]') { throw 'Select your existing private key file.' } if ([string]::IsNullOrWhiteSpace($KeyPath) -or $KeyPath -match '[\x00-\x1f]') { throw 'Select your existing private key file.' }
return [pscustomobject]@{ return [pscustomobject]@{
Strings=@{HostName=$entry.HostName; Protocol='ssh'; UserName=$entry.UserName; PublicKeyFile=$KeyPath; PortForwardings=('L127.0.0.1:' + $entry.LocalPort + '=127.0.0.1:' + $entry.RemotePort)} Strings=@{HostName=$entry.HostName; Protocol='ssh'; UserName=$entry.UserName; PublicKeyFile=$KeyPath; SSHManualHostKeys=$entry.Fingerprint; PortForwardings=('L127.0.0.1:' + $entry.LocalPort + '=127.0.0.1:' + $entry.RemotePort)}
Numbers=@{PortNumber=$entry.PortNumber; LocalPortAcceptAll=0; RemotePortAcceptAll=0; SshNoShell=1; PingInterval=0; PingIntervalSecs=30; TCPKeepalives=1; AgentFwd=0; GssapiFwd=0; ProxyMethod=0; LogType=0} Numbers=@{PortNumber=$entry.PortNumber; LocalPortAcceptAll=0; RemotePortAcceptAll=0; SshNoShell=1; PingInterval=0; PingIntervalSecs=30; TCPKeepalives=1; AgentFwd=0; GssapiFwd=0; ProxyMethod=0; LogType=0}
Arguments=('-load ' + $entry.Name + ' -N -hostkey ' + $entry.Fingerprint) Arguments=('-load ' + $entry.Name + ' -N -hostkey ' + $entry.Fingerprint)
PanelUrl=('http://127.0.0.1:' + $entry.LocalPort + $entry.PanelPath) PanelUrl=('http://127.0.0.1:' + $entry.LocalPort + $entry.PanelPath)

View file

@ -1,4 +1,4 @@
Панели 3x-ui: общий установщик сессий PuTTY для Windows Панели 3x-ui: общий установщик сессий PuTTY для Windows
БЫСТРОЕ НАЧАЛО БЫСТРОЕ НАЧАЛО
1. Распакуйте ZIP целиком в отдельную папку. Не запускайте файл внутри ZIP. 1. Распакуйте ZIP целиком в отдельную папку. Не запускайте файл внутри ZIP.
@ -51,9 +51,9 @@ connections.example.json — только шаблон. Его адрес и о
Для восстановления сессии импортируйте соответствующий *-previous.reg; старый ярлык Для восстановления сессии импортируйте соответствующий *-previous.reg; старый ярлык
скопируйте из той же backup-папки на рабочий стол. Остальные серверы не переустанавливаются. скопируйте из той же backup-папки на рабочий стол. Остальные серверы не переустанавливаются.
Если установка остановится, окно покажет уже установленные записи и папку резервных копий. Если установка остановится, окно покажет уже установленные записи и папку резервных копий.
Ярлык PuTTY передаёт -hostkey с точным отпечатком и открывает forwarding только на127.0.0.1. Проверенный отпечаток сохраняется в сессии PuTTY и передаётся ярлыком через -hostkey.
При ручном запуске сохранённой сессии из самого PuTTY также сверяйте host key; Предыдущий список разрешённых ручных ключей этой сессии заменяется точным отпечатком.
не нажимайте Accept при неожиданной смене ключа. Туннель использует удалённый127.0.0.1. Forwarding слушает только 127.0.0.1. При смене ключа проверьте его в консоли сервера. Туннель использует удалённый127.0.0.1.
Если локальный порт занят, закройте прежнее окно туннеля этой панели либо выберите другой порт. Если локальный порт занят, закройте прежнее окно туннеля этой панели либо выберите другой порт.
Система с корпоративным запретом PowerShell/WinForms может блокировать запуск: Система с корпоративным запретом PowerShell/WinForms может блокировать запуск:
общие ограничения безопасности установщик не отключает. общие ограничения безопасности установщик не отключает.

View file

@ -53,6 +53,7 @@ $plan=Get-PanelRegistryPlan $catalog.Sessions[2] $key
Assert-Panel ($plan.Strings.PublicKeyFile -ceq $key) 'Key path with spaces must remain data.' Assert-Panel ($plan.Strings.PublicKeyFile -ceq $key) 'Key path with spaces must remain data.'
Assert-Panel ($plan.Strings.PortForwardings -ceq 'L127.0.0.1:18055=127.0.0.1:2053') 'Tunnel must bind loopback and target remote loopback.' Assert-Panel ($plan.Strings.PortForwardings -ceq 'L127.0.0.1:18055=127.0.0.1:2053') 'Tunnel must bind loopback and target remote loopback.'
Assert-Panel ($plan.Numbers.LocalPortAcceptAll -eq 0 -and $plan.Numbers.AgentFwd -eq 0 -and $plan.Numbers.ProxyMethod -eq 0) 'Unsafe forwarding/proxy settings.' Assert-Panel ($plan.Numbers.LocalPortAcceptAll -eq 0 -and $plan.Numbers.AgentFwd -eq 0 -and $plan.Numbers.ProxyMethod -eq 0) 'Unsafe forwarding/proxy settings.'
Assert-Panel ($plan.Strings.SSHManualHostKeys -ceq $catalog.Sessions[2].Fingerprint) 'Saved session must replace any previous manual host key allowlist.'
Assert-Panel ($plan.Arguments -ceq ('-load KAgent-DK-panel -N -hostkey SHA256:'+('A'*43))) 'Shortcut must pin the exact host key.' Assert-Panel ($plan.Arguments -ceq ('-load KAgent-DK-panel -N -hostkey SHA256:'+('A'*43))) 'Shortcut must pin the exact host key.'
Assert-Panel ($plan.PanelUrl -ceq 'http://127.0.0.1:18055/private-panel/') 'Browser URL must stay loopback.' Assert-Panel ($plan.PanelUrl -ceq 'http://127.0.0.1:18055/private-panel/') 'Browser URL must stay loopback.'
Expect-Rejection { Get-PanelRegistryPlan $ru '' } 'Missing key path must be rejected.' Expect-Rejection { Get-PanelRegistryPlan $ru '' } 'Missing key path must be rejected.'