Windows Server для самых маленьких. Часть 16: Настраиваем SSH на Windows Server

Все части серии «Windows Server для самых маленьких»

WinRM из части 14 — транспорт, который знают только Windows. Администратор, у которого половина серверов на Linux, ноутбук на macOS и привычка жить в терминале, хочет одного ssh на всё. С 2018 года это возможно: Microsoft портировала OpenSSH на Windows, встроила клиент в Windows 10 1809 и Windows Server 2019, а сервер сделала устанавливаемым компонентом, и в Windows Server 2025 он установлен из коробки. Это настоящий OpenSSH — тот же код, те же файлы конфигурации, те же ключи, — с поправками на то, что под ним не Unix. Эта часть о поправках: где лежит конфигурация, кто может войти, как устроены права на ключи администраторов, как сделать PowerShell оболочкой, как входить по Kerberos и как гонять через SSH тот же PowerShell Remoting, что через WinRM.


Установка

Клиент ssh.exe есть в C:\Windows\System32\OpenSSH на любой современной Windows. Сервер — компонент по требованию. Список компонентов требует консоли администратора (без повышенных прав Get-WindowsCapability отвечает «The requested operation requires elevation.»):

PS C:\> Get-WindowsCapability -Online -Name 'OpenSSH*' | Select-Object Name, State

Name                          State
----                          -----
OpenSSH.Client~~~~0.0.1.0 Installed
OpenSSH.Server~~~~0.0.1.0 Installed

PS C:\> Get-Service sshd, ssh-agent | Select-Object Name, Status, StartType

Name       Status StartType
----       ------ ---------
ssh-agent Stopped  Disabled
sshd      Stopped    Manual

На Windows Server 2025 сервер стоит, но не запущен; на 2019 и 2022 его ставит Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0. Включаем:

PS C:\> Set-Service sshd -StartupType Automatic
PS C:\> Start-Service sshd
PS C:\> Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' | Select-Object DisplayName, Enabled, Profile

DisplayName               Enabled Profile
-----------               ------- -------
OpenSSH SSH Server (sshd)    True Private

Правило файрвола для порта 22 компонент создаёт сам, но в Windows Server 2025 оно действует только в профиле Private. Сервер в домене опознаёт свою сеть как доменную (Get-NetConnectionProfile показывает NetworkCategory = DomainAuthenticated), правило к ней не относится, и порт 22 закрыт: sshd слушает, а соединение с рабочей станции не устанавливается. Добавляем доменный профиль:

PS C:\> Set-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -Profile Domain
PS C:\> Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' | Select-Object DisplayName, Enabled, Profile

DisplayName               Enabled Profile
-----------               ------- -------
OpenSSH SSH Server (sshd)    True  Domain

В Windows Server 2019 и 2022 Add-WindowsCapability создаёт то же правило сразу для всех профилей (Any), и его стоит сузить так же. Сам Add-WindowsCapability запускают в консоли сервера: из удалённого сеанса PowerShell он отвечает «Access is denied.». При первом запуске sshd создаёт папку C:\ProgramData\ssh: кладёт туда конфигурацию — копию C:\Windows\System32\OpenSSH\sshd_config_default — и генерирует ключи хоста RSA, ECDSA и Ed25519. Проверка с рабочей станции:

PS C:\> ssh alice.admin@dc1.corp.example.com
The authenticity of host 'dc1.corp.example.com (192.168.1.10)' can't be established.
ED25519 key fingerprint is SHA256:k7Hq3mF9…
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'dc1.corp.example.com' (ED25519) to the list of known hosts.
alice.admin@dc1.corp.example.com's password:
Microsoft Windows [Version 10.0.26100.6584]
(c) Microsoft Corporation. All rights reserved.

corp\alice.admin@DC1 C:\Users\alice.admin>

Вход по паролю, оболочка — cmd.exe. Оба обстоятельства мы сейчас исправим.


Где что лежит

Linux Windows Что
/etc/ssh/sshd_config C:\ProgramData\ssh\sshd_config конфигурация сервера
— C:\Windows\System32\OpenSSH\sshd_config_default конфигурация по умолчанию, из неё создаётся рабочая
/etc/ssh/ssh_host_*_key C:\ProgramData\ssh\ssh_host_*_key ключи хоста
~/.ssh/authorized_keys C:\Users\<user>\.ssh\authorized_keys ключи обычного пользователя
— C:\ProgramData\ssh\administrators_authorized_keys ключи администраторов, общий файл
/etc/ssh/ssh_config, ~/.ssh/config C:\ProgramData\ssh\ssh_config, C:\Users\<user>\.ssh\config конфигурация клиента
/var/log/auth.log журнал событий OpenSSH/Operational или C:\ProgramData\ssh\logs\sshd.log журнал
/usr/lib/openssh/sftp-server sftp-server.exe в C:\Windows\System32\OpenSSH подсистема SFTP

%ProgramData% — обычно C:\ProgramData, скрытая папка. Конфигурация сервера короткая и почти целиком закомментирована: закомментированные строки показывают значения по умолчанию. В Windows Server 2025 действуют четыре директивы:

AuthorizedKeysFile	.ssh/authorized_keys

Subsystem	sftp	sftp-server.exe

AllowGroups administrators "openssh users"

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

AllowGroups пускает только членов двух групп: Administrators и OpenSSH Users. Вторая — встроенная группа BUILTIN\OpenSSH Users (SID S-1-5-32-585), появившаяся в Windows Server 2025 с описанием «Members of this group may connect to this computer using SSH.»; на контроллерах домена она, как и другие встроенные группы, лежит в контейнере CN=Builtin домена. Пользователь домена без прав администратора войти по SSH не может, пока его не добавят в эту группу. В Windows Server 2022 и 2019 строки AllowGroups в конфигурации по умолчанию нет, и войти может любой пользователь.

Блок Match Group administrators — главное отличие от Linux. Для членов локальной группы Administrators ключи читаются не из профиля, а из одного общего файла в ProgramData. Причина: папку своего профиля администратор контролирует сам, а если его учётную запись скомпрометировали без прав администратора (например, через процесс, запущенный от его имени без повышения), запись ключа в ~/.ssh/authorized_keys давала бы вход с полными правами. Файл в ProgramData должен быть доступен только SYSTEM (полный доступ) и Administrators; sshd проверяет права и не берёт ключи из файла, к которому есть доступ у кого-то ещё. На контроллере домена локальной группы Administrators нет, но встроенная доменная группа Administrators занимает её место, и правило действует.

Чтобы администраторы хранили ключи в профилях, как все, этот блок удаляют. Мы оставим его: один файл проще контролировать.

Имена в sshd_config — Windows-имена: доменные пользователи и группы пишутся в виде домен\имя с коротким (NetBIOS) именем домена, имя с пробелами берётся в кавычки, и всё — строчными буквами, так требует документация Microsoft:

AllowGroups administrators "openssh users" "corp\ssh admins"
DenyUsers corp\guest

Проще, однако, не трогать AllowGroups, а добавить нужную группу в OpenSSH Users: на рядовом сервере — Add-LocalGroupMember -Group 'OpenSSH Users' -Member 'CORP\SSH Admins', на контроллерах — Add-ADGroupMember -Identity 'OpenSSH Users' -Members 'SSH Admins'. Изменения в sshd_config применяются после Restart-Service sshd: служба читает файл при запуске.


Ключи

Ключевая пара на рабочей станции и агент, который её хранит:

PS C:\> ssh-keygen -t ed25519 -C 'alice.admin@ws1'
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\alice.admin/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\alice.admin/.ssh/id_ed25519
Your public key has been saved in C:\Users\alice.admin/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:0ODW1wKq21CFjAN+xua1bDduuAjOgooPluX97+GfBfo alice.admin@ws1
...
PS C:\> ssh-add
Error connecting to agent: No such file or directory

ssh-agent в Windows — служба, и по умолчанию она выключена; включать её нужно из консоли администратора:

PS C:\> Set-Service ssh-agent -StartupType Automatic
PS C:\> Start-Service ssh-agent
PS C:\> ssh-add
Identity added: C:\Users\alice.admin/.ssh/id_ed25519 (alice.admin@ws1)

Добавленные в агент ключи хранятся в реестре под учётной записью пользователя, зашифрованными средствами Windows (DPAPI), переживают перезагрузку и доступны только этому пользователю. ssh-copy-id в Windows нет, публичный ключ доставляется на сервер руками. Для администратора — в общий файл, с обязательной правкой прав: файл, созданный в C:\ProgramData\ssh, наследует от папки чтение для Authenticated Users, и sshd такой файл не примет. Первый вход ещё по паролю:

PS C:\> $pub = Get-Content ~\.ssh\id_ed25519.pub
PS C:\> $file = 'C:\ProgramData\ssh\administrators_authorized_keys'
PS C:\> $remote = "powershell Add-Content -Force -Path $file -Value '$pub'; icacls.exe $file /inheritance:r /grant Administrators:F /grant SYSTEM:F"
PS C:\> ssh alice.admin@dc1 $remote
alice.admin@dc1's password:
processed file: C:\ProgramData\ssh\administrators_authorized_keys
Successfully processed 1 files; Failed processing 0 files

PS C:\> ssh alice.admin@dc1 hostname
dc1

Второй вход прошёл без пароля. На Windows с локализованными именами групп вместо Administrators пишут SID: /grant *S-1-5-32-544:F. Если ключ не принимается, в девяти случаях из десяти причина в правах на файл: sshd пишет в журнал о неверных правах (Bad permissions), и команда icacls выше возвращает их к нужным. После того как ключи работают, пароли отключают:

PasswordAuthentication no

Для обычных пользователей, не администраторов, файл — C:\Users\<user>\.ssh\authorized_keys в их профиле; профиль доменного пользователя создаётся при первом входе, в том числе по SSH с паролем.

У входа по ключу есть особенность, которой нет в Linux. Сеанс Windows, открытый по ключу, создаётся без учётных данных пользователя: пароля сервер не видел, билета Kerberos у него нет. Внутри такого сеанса не открываются сетевые ресурсы от имени пользователя — \\dc2\SYSVOL, другой сервер, — это тот же второй прыжок, что в части 14, только без всякого обходного пути. Так же устроен вход по Kerberos без делегирования: dir \\dc2\SYSVOL в таком сеансе отвечает «Network access is denied.». Сеанс, открытый по паролю или по Kerberos с делегированием (о нём ниже), учётные данные имеет.


PowerShell как оболочка

Оболочка по умолчанию задаётся параметром реестра DefaultShell в разделе HKLM:\SOFTWARE\OpenSSH (раздел создаётся вместе с OpenSSH), и это может быть любая программа:

PS C:\> $key = 'HKLM:\SOFTWARE\OpenSSH'
PS C:\> New-ItemProperty -Path $key -Name DefaultShell -Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -PropertyType String -Force | Select-Object DefaultShell

DefaultShell
------------
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Для PowerShell 7 — C:\Program Files\PowerShell\7\pwsh.exe, если он установлен на сервере (в Windows Server его нет из коробки). Команду из ssh host команда sshd передаёт оболочке с ключом: для cmd.exe это /c, для любой другой программы — -c, и в процессах сервера видно "c:\program files\powershell\7\pwsh.exe" -c "команда". И powershell.exe, и pwsh.exe понимают -c как -Command, поэтому для PowerShell больше ничего задавать не нужно. Ключ можно заменить параметром DefaultShellCommandOption в том же разделе, но это нужно только оболочке, которая не понимает -c; значение /c, которое иногда советуют для PowerShell, ничего не меняет: оба PowerShell принимают и его. Перезапуск sshd не нужен: параметры читаются при каждом входе.

PS C:\> ssh alice.admin@dc1
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\alice.admin> Get-Service NTDS, DNS | Select-Object Name, Status

Name  Status
----  ------
DNS  Running
NTDS Running

PS C:\Users\alice.admin> exit
PS C:\> ssh alice.admin@dc1 'Get-ADDomainController | Select-Object HostName, Site'

HostName             Site
--------             ----
dc1.corp.example.com Office

Это полноценный интерактивный PowerShell с историей, автодополнением и цветами: с Windows 10 1809 у консоли есть ConPTY, псевдотерминал, и sshd подключает к нему удалённый терминал, как pty в Unix. Любая консольная программа, включая diskpart и sconfig, работает через SSH как локально. Баннер короче локального: Windows PowerShell печатает две строки без приглашения поставить PowerShell 7, а pwsh.exe — одну строку с версией, PowerShell 7.4.21. Администратор получает сеанс с полными правами, без фильтрации UAC: заголовок окна, который сервер присылает терминалу, начинается с Administrator:.

Команды с кавычками через ssh host '…' передаются оболочке как строка, и экранирование складывается из правил трёх сторон: локального PowerShell, SSH и удалённого PowerShell. Для чего-то сложнее одной команды проще передать скрипт: Get-Content .\script.ps1 | ssh dc1 powershell -Command -.


Kerberos

Пароль или ключ — это аутентификация SSH, у которой нет ничего общего с доменом: ключ администратора на сервере равносилен паролю, и его ротация, отзыв и учёт — ручная работа. В домене есть Kerberos, и OpenSSH умеет им пользоваться через GSSAPI — стандартный программный интерфейс к механизмам безопасности, поверх которого SSH передаёт обмен Kerberos (RFC 4462). Клиент предъявляет серверу билет на host/dc1.corp.example.com, тот самый SPN HOST, который у учётной записи компьютера есть с момента вступления в домен (часть 6). Ни пароля, ни ключа, вход как в любую службу домена. В Windows-версии OpenSSH GSSAPI работает через SSPI, тот же интерфейс, которым пользуются остальные службы Windows. Документация Microsoft называет серверный GSSAPI доступным начиная с Windows Server 2022 и Windows 10 21H1, но компонент, установленный на Windows Server 2019 сегодня, приходит в той же версии OpenSSH_for_Windows_9.5, что и в 2025, и вход по Kerberos в нём работает.

На сервере:

GSSAPIAuthentication yes

На клиенте GSSAPI по умолчанию тоже выключен (ssh -G dc1.corp.example.com показывает gssapiauthentication no); включается в ~\.ssh\config, шаблоны имён в котором чувствительны к регистру:

Host *.corp.example.com
    GSSAPIAuthentication yes
    GSSAPIDelegateCredentials yes

И вход:

PS C:\> ssh -v dc1.corp.example.com hostname 2>&1 | Select-String 'Authenticat|gssapi'

debug1: Authenticating to dc1.corp.example.com:22 as 'corp\\alice.admin'
debug1: Authentications that can continue: publickey,gssapi-with-mic,password,keyboard-interactive
debug1: Next authentication method: gssapi-with-mic
Authenticated to dc1.corp.example.com ([192.168.1.10]:22) using "gssapi-with-mic".

Имя пользователя не указано: встроенный клиент Windows подставляет текущего пользователя в виде corp\alice.admin (в отладочном выводе обратная косая черта удвоена), а билет берёт из кеша сеанса Windows. Linux-серверы домена такое имя не принимают, им нужно ssh -l alice.admin. Без делегирования в сеансе есть только билет, по которому сервер принял вход: klist на dc1 показывает один билет HOST/dc1.corp.example.com с отметкой Cache Flags: 0x8 -> ASC, и в сеть от имени пользователя сервер не ходит. GSSAPIDelegateCredentials yes добавляет делегирование: вместе с билетом на сервер уезжает пересланный TGT, и в сеансе на dc1 есть полноценные учётные данные пользователя:

PS C:\Users\alice.admin> klist | Select-String 'Server: krbtgt|Ticket Flags'

        Server: krbtgt/CORP.EXAMPLE.COM @ CORP.EXAMPLE.COM
        Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent name_canonicalize
PS C:\Users\alice.admin> Get-ChildItem \\dc2\SYSVOL | Select-Object -First 1 Name

Name
----
corp.example.com

Флаг forwarded — это пересланный TGT из части 6, и второй прыжок из части 14 здесь решён без CredSSP: \\dc2\SYSVOL открылся из сеанса на dc1 потому, что у dc1 есть TGT пользователя. Это неограниченное делегирование в чистом виде — удобно и ровно так же опасно, как описано в части 6: TGT пользователя оказывается на сервере, и давать его стоит только серверам, которым доверяют как контроллерам.

Два клиента. На рабочей станции с Git for Windows есть второй ssh — C:\Program Files\Git\usr\bin\ssh.exe. Его вызывает Git для git clone git@…, он отвечает на ssh в Git Bash и попадает в PATH, если при установке Git выбрать вариант с Unix-утилитами. Это OpenSSH из MSYS2, обычно новее встроенного, собранный без SSPI: GSSAPI у него идёт через библиотеку Heimdal Kerberos со своим кешем билетов, о билетах Windows он не знает, и метод gssapi-with-mic молча пропускает — вход откатится на ключ или пароль. Имя по умолчанию он тоже подставляет без домена. Встроенный клиент собран с SSPI и берёт билет прямо из сеанса. Проверка — Get-Command ssh -All | Select-Object Source и ssh -V (у встроенного версия начинается с OpenSSH_for_Windows); лечение — полный путь или порядок в PATH.

С Linux и macOS с билетом Kerberos (kinit alice.admin@CORP.EXAMPLE.COM) вход тот же: ssh -K dc1.corp.example.com (-K включает GSSAPI с делегированием, и встроенный клиент Windows понимает его так же — без строк в ~\.ssh\config); в части 30 мы вернёмся к этому с другой стороны. Доменного пользователя без GSSAPI клиенты называют двумя способами: ssh 'corp\alice.admin'@dc1 или ssh alice.admin@corp.example.com@dc1 — второе выглядит странно, но это UPN перед @ хоста.


PowerShell Remoting поверх SSH

PowerShell 7 умеет то, что в части 14 делалось через WinRM, делать через SSH: Enter-PSSession, Invoke-Command, New-PSSession с параметром -HostName вместо -ComputerName. Транспорт — SSH-подсистема, в которой на сервере запускается pwsh -sshs, и дальше по каналу ездит тот же протокол PSRP. Нужен PowerShell 7 на обеих сторонах; Windows PowerShell 5.1 этого не умеет.

На сервере, в sshd_config:

Subsystem	powershell	C:/progra~1/powershell/7/pwsh.exe -sshs

Путь в формате 8.3 (progra~1 вместо Program Files) — обход ошибки Windows-версии OpenSSH: путь к программе подсистемы с пробелом в ней не работает. Другой обход — символическая ссылка без пробелов в пути, например C:\ProgramData\ssh\pwsh.exe на C:\Program Files\PowerShell\7\pwsh.exe. После Restart-Service sshd:

PS C:\> Enter-PSSession -HostName dc1.corp.example.com
[dc1.corp.example.com]: PS C:\Users\alice.admin\Documents> $PSVersionTable.PSVersion.ToString()
7.6.9
[dc1.corp.example.com]: PS C:\Users\alice.admin\Documents> exit

PS C:\> Invoke-Command -HostName dc1, dc2, dc3 -ScriptBlock { (Get-Service NTDS).Status } -UserName alice.admin

PSComputerName RunspaceId                           Value
-------------- ----------                           -----
dc2            5edd4530-6f8d-445d-a747-e7ead4cf7805 Running
dc1            0b9c63f1-2d4e-4c55-9a51-7e8f3a6d2c10 Running
dc3            c4a1e7d2-93b8-4f06-8e2a-61d5b0f9e3a7 Running

PS C:\> $s = New-PSSession -HostName dc1 -KeyFilePath ~\.ssh\id_ed25519
PS C:\> $s

Id Name      Transport ComputerName ComputerType  State  ConfigurationName Availability
-- ----      --------- ------------ ------------  -----  ----------------- ------------
 1 Runspace1 SSH       dc1          RemoteMachine Opened DefaultShell         Available

PS C:\> Copy-Item .\fix.ps1 -ToSession $s -Destination C:\Temp\

Результаты приходят в порядке готовности, с колонками PSComputerName и RunspaceId, как у WinRM в части 14; сеанс отличается транспортом SSH и конфигурацией DefaultShell — выбирать конечную точку здесь не из чего.

Аутентификация — та, что настроена в SSH: ключ, агент, Kerberos; PowerShell свою не добавляет. Он запускает тот же ssh.exe, поэтому действуют строки из ~\.ssh\config, а отдельные параметры клиента передаются через -Options, например -Options @{ GSSAPIDelegateCredentials = 'yes' }. Если SSH не пустил, PowerShell сначала печатает ответ ssh («Permission denied (publickey,gssapi-with-mic,password,keyboard-interactive).»), а затем свою ошибку: «The SSH client session has ended with error message: The SSH transport process has abruptly terminated causing this remote session to break.». -UserName нужен, когда имя не совпадает с текущим, -KeyFilePath — для конкретного ключа. Ни TrustedHosts, ни HTTPS-слушателя, ни правил WinRM: только порт 22. И это работает с любой платформы: с macOS-ноутбука Invoke-Command -HostName dc1 выполняет PowerShell на контроллере, а неявный remoting из части 15 через такой сеанс даёт модули ActiveDirectory и DnsServer на Linux.

Чего нет у SSH-транспорта по сравнению с WinRM: конфигураций сеансов и всего, что на них держится, — JEA, виртуальных учётных записей, своих прав на конечную точку; отключаемые сеансы тоже остаются возможностью WinRM: Disconnect-PSSession отвечает «The disconnection operation is not supported on the remote computer. To support disconnecting, the remote computer must be running Windows PowerShell 3.0 or a later version of Windows PowerShell and using the WSMan transport.». Второй прыжок решается средствами SSH — делегированием TGT через GSSAPI; без него Get-ChildItem \\dc2\SYSVOL в сеансе отвечает «Access to the path '\dc2\SYSVOL' is denied.». Для администрирования с разных платформ это компромисс, на который идут; для делегирования службе поддержки WinRM с JEA остаётся без замены.


Безопасность

Порт 22 на контроллере домена — это новая дверь к самому важному серверу, и за ней должны быть те же правила, что за RDP:

  • Только ключи или Kerberos: PasswordAuthentication no после того, как ключи заработали.
  • Только нужные группы: в Windows Server 2025 это уже сделано строкой AllowGroups administrators "openssh users"; на 2019 и 2022 её добавляют сами, а членство в OpenSSH Users держат под тем же контролем, что членство в Administrators.
  • Только из сети администраторов: Set-NetFirewallRule -Name OpenSSH-Server-In-TCP -Profile Domain -RemoteAddress 192.168.1.0/24 или адреса рабочих станций уровня 0 из части 15.
  • Файл ключей администраторов — один, с правильными правами, под контролем: каждый ключ в нём — пароль администратора без срока действия.

Журнал. По умолчанию (SyslogFacility AUTH) sshd пишет в журнал событий OpenSSH/Operational, все записи — с кодом 4:

PS C:\> Get-WinEvent -LogName OpenSSH/Operational -MaxEvents 4 | Select-Object TimeCreated, Message

TimeCreated         Message
-----------         -------
15.10.2026 15:40:12 sshd: Accepted gssapi-with-mic for corp\\alice.admin from 192.168.1.100 port 52010 ssh2: CORP\\alice.admin
15.10.2026 15:38:51 sshd: Accepted publickey for corp\\alice.admin from 192.168.1.100 port 52004 ssh2: ED25519 SHA256:0ODW1wKq…
15.10.2026 15:36:03 sshd: Failed password for invalid user root from 203.0.113.77 port 41022 ssh2
15.10.2026 15:36:00 sshd: Invalid user root from 203.0.113.77 port 41022

Те же строки, что в auth.log на Linux, включая попытки входа под root с чужих адресов, если порт виден снаружи; обратная косая черта в доменном имени удвоена, так sshd экранирует её в журнале. После входа по GSSAPI sshd дописывает, чьим билетом он подтверждён (CORP\\alice.admin). Кроме входов, там видны выходы (Received disconnect from … disconnected by user, Disconnected from …), запуски и остановки службы (Server listening on 0.0.0.0 port 22., Received signal …; terminating.). Для записи в файл в sshd_config ставят SyslogFacility LOCAL0 (подробнее — LogLevel VERBOSE), и журнал пойдёт в C:\ProgramData\ssh\logs\sshd.log. В журнале Security вход по SSH — событие 4624, на каждое соединение их два: тип входа 3 (сетевой), процесс входа sshd, имя процесса C:\Windows\System32\OpenSSH\sshd.exe, при Kerberos — пакет Kerberos, повышенный токен (Elevated Token: Yes) у администратора и пустой сетевой адрес (-): адрес клиента есть только в журнале sshd.


Смотрим руками

Действующая конфигурация сервера целиком, со значениями по умолчанию, — sshd -T; запускать её нужно от администратора, потому что sshd читает ключи хоста:

PS C:\> ssh alice.admin@dc1 'sshd -T' | Select-String 'authentication|authorizedkeysfile|subsystem|allowgroups'

hostbasedauthentication no
pubkeyauthentication yes
gssapiauthentication yes
passwordauthentication no
kbdinteractiveauthentication yes
authorizedkeysfile .ssh/authorized_keys
allowgroups administrators
allowgroups openssh users
authenticationmethods any
subsystem sftp sftp-server.exe
subsystem powershell C:/progra~1/powershell/7/pwsh.exe -sshs

authorizedkeysfile .ssh/authorized_keys — для обычных пользователей; для администраторов действует блок Match, и sshd -T -C user=corp\alice.admin,host=ws1,addr=192.168.1.100 покажет уже его: authorizedkeysfile __PROGRAMDATA__/ssh/administrators_authorized_keys. Часть строк sshd -T печатает, хотя в Windows они ничего не делают: документация Microsoft перечисляет недоступные директивы, среди них KbdInteractiveAuthentication, HostbasedAuthentication и StrictModes.

Дерево процессов. Вот что видно на сервере, пока к нему открыт сеанс Remoting поверх SSH:

PS C:\> Get-CimInstance Win32_Process -Filter "Name='sshd.exe' or Name='cmd.exe' or Name='pwsh.exe'" | Select-Object ProcessId, ParentProcessId, Name, @{n='User'; e={(Invoke-CimMethod -InputObject $_ -MethodName GetOwner).User}}, CommandLine

ProcessId ParentProcessId Name     User        CommandLine
--------- --------------- ----     ----        -----------
     2588             688 sshd.exe SYSTEM      C:\WINDOWS\System32\OpenSSH\sshd.exe
     5708            2588 sshd.exe SYSTEM      "C:\WINDOWS\System32\OpenSSH\sshd.exe" -R
     6012            5708 sshd.exe alice.admin "C:\WINDOWS\System32\OpenSSH\sshd.exe" -z
     6104            6012 cmd.exe  alice.admin "c:\windows\system32\cmd.exe" /c "c:/progra~1/powershell/7/pwsh.exe -sshs"
     6120            6104 pwsh.exe alice.admin c:/progra~1/powershell/7/pwsh.exe  -sshs

Это разделение привилегий, как в Unix. Служба sshd под SYSTEM только принимает соединения; на каждое соединение она запускает свою копию (-R), тоже под SYSTEM. До входа та отдаёт разбор протокола непривилегированному процессу sshd.exe -y под виртуальной учётной записью VIRTUAL USERS\sshd_<PID>, у которой нет никаких прав в системе, а после входа на его месте работает sshd.exe -z под вошедшим пользователем. Под ним — оболочка или подсистема, причём строку подсистемы sshd выполняет через оболочку по умолчанию: cmd.exe /c "…pwsh.exe -sshs".

Передача файлов — SFTP и SCP работают, пути в формате Windows с прямыми косыми чертами, а в ответах sftp перед буквой диска стоит /:

PS C:\> scp .\report.csv alice.admin@dc1:C:/Temp/
report.csv                                    100%   18KB   4.1MB/s   00:00
PS C:\> sftp alice.admin@dc1
Connected to dc1.
sftp> ls C:/Windows/NTDS
/C:/Windows/NTDS/edb.chk                /C:/Windows/NTDS/edb.log
/C:/Windows/NTDS/edbres00001.jrs        /C:/Windows/NTDS/edbres00002.jrs
/C:/Windows/NTDS/edbtmp.log             /C:/Windows/NTDS/ntds.dit
/C:/Windows/NTDS/ntds.jfm               /C:/Windows/NTDS/temp.edb

И обмен в пакетах — pktmon filter add -p 22: после обмена версиями (SSH-2.0-OpenSSH_for_Windows_9.5 — так представляется сервер) и KEX всё зашифровано, и единственное, что видно, — длины пакетов и направление. В отличие от WinRM, где по заголовкам HTTP ещё можно было угадать операцию, SSH не показывает ничего, и это та причина, по которой журнал sshd на сервере — единственный источник сведений о том, кто и как вошёл.


Источники


Блок об управлении закончен: модуль, WinRM, рабочая станция и SSH. Следующие четыре части — об эксплуатации: о том, что в домене ломается, как это диагностировать и как чинить без переустановки. Начнём с пяти ролей, которые в части 4 достались первому контроллеру и с тех пор не упоминались.

Дальше — часть 17: роли FSMO. Почему в многохозяйском каталоге есть пять вещей, которыми владеет кто-то один; что делает каждая роль и что перестаёт работать, когда её владелец выключен; как узнать владельцев; Move-ADDirectoryServerOperationMasterRole для переноса и для захвата, и почему после захвата старый владелец не должен вернуться в сеть.

Оставить комментарий могут только зарегистрированные пользователи.

Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.