Windows OpenSSH 키 인증, 비밀번호 없이 운영할 때 놓치기 쉬운 설정

Windows PC와 노트북을 이더넷으로 연결하고 SSH 키 인증을 구성하는 장면을 표현한 현실적인 사진풍 이미지 1

AI를 활용하여 생성한 이미지입니다.

Windows PC를 원격으로 관리할 일이 늘면 비밀번호 로그인만으로는 금방 불편해져요. 여러 장비에서 같은 계정을 쓰기 쉽고, 자동화 작업에 비밀번호를 넣는 순간 관리해야 할 비밀값도 늘어납니다. Windows에 기본으로 들어오는 OpenSSH Server는 키 쌍을 이용한 로그인을 지원하므로, 비밀번호 입력을 줄이면서 접속 주체를 분리할 수 있어요.[1]

다만 Linux에서 하던 방식 그대로 공개 키를 복사하면 Windows에서는 막히는 경우가 있습니다. 특히 Administrators 그룹 계정은 일반 사용자와 공개 키 파일 위치가 다르고, sshd_config를 바꾼 뒤 서비스가 재시작되지 않으면 원인을 찾기 어렵죠. 이 글은 OpenSSH가 설치되어 있고 관리자 PowerShell을 열 수 있다는 전제에서, 키 생성부터 검증과 원상복구까지 한 흐름으로 정리했어요.

먼저 구조를 나눠야 하는 이유

SSH 로그인에는 세 가지가 따로 있어요. 클라이언트가 보유한 개인 키, 서버에 등록하는 공개 키, 그리고 서버가 어떤 파일과 정책을 읽을지 결정하는 sshd_config입니다. 개인 키는 클라이언트 밖으로 복사하지 않고, 공개 키만 Windows 계정에 등록해야 해요.[2] Windows의 OpenSSH 서버 설정 파일 기본 경로는 %programdata%\ssh\sshd_config입니다.[2]

Microsoft의 현재 안내는 Windows 10 빌드 1809 이상, Windows 11, Windows Server 2019 이상에서 기본 OpenSSH 기능을 사용하는 흐름을 전제로 합니다.[1] 기본 제공 기능은 Windows Update로 서비스되는 경로라서, 별도 포크를 설치하기 전에 선택적 기능과 서비스 상태부터 확인하는 편이 안전해요.[1]

설치와 서비스 상태 확인

관리자 PowerShell에서 아래 명령으로 기능과 서비스를 확인해요. 이미 설치된 장비라면 설치 명령을 다시 실행할 필요는 없습니다.

Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Get-Service sshd -ErrorAction SilentlyContinue
Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue

OpenSSH.Server~~~~0.0.1.0의 상태가 Installed가 아니면 다음처럼 설치할 수 있어요.

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic

원격 접속을 외부 인터넷에 바로 노출하는 단계는 여기서 멈추는 게 좋아요. 먼저 같은 내부망에서 서버 이름이나 IP로 접속이 되는지 확인하고, 라우터 포트 포워딩과 방화벽 범위는 별도 보안 검토를 거쳐야 합니다.

키를 만들고 공개 키만 배포하기

접속할 클라이언트에서 사용자용 Ed25519 키를 만들어요. 이미 같은 목적의 키가 있으면 덮어쓰지 말고 파일명을 다르게 지정하세요.

ssh-keygen -t ed25519 -C "windows-admin" -f ~/.ssh/windows_admin_ed25519
ssh-keygen -lf ~/.ssh/windows_admin_ed25519.pub

두 번째 명령은 공개 키 지문을 보여줘요. 나중에 서버에 들어간 키가 내가 만든 키인지 비교할 때 씁니다. 개인 키 파일인 windows_admin_ed25519는 서버나 채팅, 백업 공유 폴더에 올리면 안 돼요. 공개 키인 .pub 파일만 서버로 전달합니다.

일반 사용자 계정이라면 Windows 서버의 사용자 프로필 아래 .ssh\authorized_keys에 공개 키 한 줄을 넣는 방식이 기본입니다. PowerShell에서는 다음처럼 폴더를 만든 뒤 공개 키 내용을 추가할 수 있어요.

$sshDir = Join-Path $env:USERPROFILE '.ssh'
New-Item -ItemType Directory -Force $sshDir | Out-Null
notepad (Join-Path $sshDir 'authorized_keys')

파일에는 공개 키 한 줄만 넣고, 줄바꿈이 깨지지 않았는지 확인하세요. 계정 이름이 다르면 $env:USERPROFILE이 가리키는 위치도 달라지므로, 원격으로 사용할 계정으로 로그인한 뒤 실행하는 게 좋습니다.

Administrators 계정은 파일 위치가 다르다

Windows OpenSSH는 Administrators 그룹에 속한 계정에 대해 기본 관리자 키 파일을 별도로 사용합니다.[2] Microsoft 문서의 키 관리 안내처럼 이 경우 공개 키를 C:\ProgramData\ssh\administrators_authorized_keys에 넣고, 파일 권한도 관리자 계정만 읽을 수 있도록 맞춰야 해요.[2]

$keyPath = 'C:\ProgramData\ssh\administrators_authorized_keys'
New-Item -ItemType File -Force $keyPath | Out-Null
Add-Content -Path $keyPath -Value (Get-Content "$env:USERPROFILE\.ssh\windows_admin_ed25519.pub")
icacls.exe $keyPath /inheritance:r
icacls.exe $keyPath /grant 'Administrators:F' /grant 'SYSTEM:F'

여기서 공개 키를 일반 사용자 경로와 관리자 경로에 모두 복사하면 동작은 할 수 있지만, 어느 계정으로 허용했는지 추적하기 어려워집니다. 관리자 계정은 관리자 경로 하나만 사용하고, 일반 계정은 자신의 authorized_keys만 사용하도록 분리하는 편이 낫습니다.

sshd_config를 바꾸기 전에 검증하는 순서

처음부터 비밀번호 인증을 끄지 말고, 새 키 로그인이 성공한 뒤에 정책을 줄이세요. 설정 파일을 백업하고 관리자 PowerShell에서 현재 유효한 구성을 검사합니다.

Copy-Item $env:ProgramData\ssh\sshd_config $env:ProgramData\ssh\sshd_config.before-key-auth
sshd.exe -t -f $env:ProgramData\ssh\sshd_config

검사 결과가 조용히 끝나면 문법 오류가 없다는 뜻이에요. 이제 설정 파일에서 다음처럼 허용 사용자를 제한할 수 있습니다. Windows 문서에서는 AllowUsers, AllowGroups, DenyUsers, DenyGroups를 Windows 계정과 함께 사용할 수 있다고 설명하며, 계정 이름은 소문자로 지정해야 한다고 안내합니다.[3]

PubkeyAuthentication yes
PasswordAuthentication yes
AllowUsers localuser

새 키로 별도 터미널에서 접속을 확인한 뒤에야 비밀번호 인증을 끄는 것을 고려하세요.

PubkeyAuthentication yes
PasswordAuthentication no
AllowUsers localuser

도메인 계정, 서비스 계정, 백업 작업이 함께 물려 있다면 PasswordAuthentication no를 일괄 적용하지 마세요. 한 계정의 키가 빠졌을 때 콘솔 접근이나 복구 계정까지 사라질 수 있습니다.

재시작보다 먼저 새 세션을 열기

설정을 저장한 뒤 기존 SSH 세션을 끊지 말고 새 터미널에서 접속을 시험해요.

Restart-Service sshd
ssh -i ~/.ssh/windows_admin_ed25519 [email protected]
ssh -vvv -i ~/.ssh/windows_admin_ed25519 [email protected]

-vvv 로그에서 공개 키를 제시했는데 거절되는지, 서버까지 연결되지 않는지, 계정 경로가 틀렸는지를 나눠 볼 수 있어요. 키는 맞는데 접속이 거절되면 공개 키 파일의 위치와 ACL을 먼저 보고, 연결 자체가 되지 않으면 방화벽·포트·서비스 상태를 따로 점검하세요. 서로 다른 문제를 한꺼번에 고치려고 하면 원인이 흐려집니다.

실패 원인별 점검표

증상 먼저 볼 곳 되돌리는 방법
Connection refused Get-Service sshd, 포트 22 방화벽 서비스를 시작하고 방화벽 규칙을 내부망 범위로 복원
Permission denied (publickey) 공개 키 위치, 줄바꿈, ACL, 사용자 이름 키 파일을 다시 배치하고 관리자 경로와 일반 사용자 경로를 구분
설정 저장 뒤 서비스 중지 sshd.exe -t 결과 백업한 sshd_config.before-key-auth를 복원한 뒤 재시작
키 접속은 되지만 제한이 적용되지 않음 AllowUsers 계정 표기와 실제 로그인 이름 계정 이름을 소문자로 맞추고 한 사용자씩 재검증

운영 전에 할 일

  • 새 키 세션을 하나 더 열어 기존 세션을 대체할 수 있는지 확인하세요.
  • 개인 키에 암호문을 설정하고 클라이언트의 SSH 에이전트 사용 범위를 정하세요.
  • 관리자 계정과 일반 계정의 공개 키 파일을 각각 기록하세요.
  • sshd_config를 바꿀 때마다 백업 파일과 변경 이유를 남기세요.
  • 외부 공개가 필요하면 VPN이나 접근 제어를 먼저 검토하고 포트만 열지 마세요.

자주 묻는 것

비밀번호 인증을 바로 꺼도 되나요?

새 키로 로그인한 별도 세션을 확인하기 전에는 끄지 않는 편이 안전해요. 키 파일 권한이나 관리자 계정 경로가 틀리면 현재 세션을 닫는 순간 잠길 수 있습니다.

Windows에서 Linux처럼 AuthorizedKeysCommand를 쓸 수 있나요?

Microsoft 안내에 따르면 Windows OpenSSH는 AuthorizedKeysCommand와 AuthorizedKeysCommandUser를 지원하지 않아요. Active Directory에서 키를 동적으로 가져오는 설계를 그대로 옮기기보다, 지원되는 사용자·그룹 제한과 중앙 관리 방식을 따로 검토해야 합니다.[2]

키 인증을 해도 SSH가 안전해지나요?

키 인증은 비밀번호 재사용과 자동화 비밀값 노출을 줄이는 방법이지, 네트워크 노출을 없애는 기능은 아니에요. 계정 범위, 방화벽, 업데이트, 로그 점검을 함께 운영해야 합니다.

Sources:

함께 읽을 글