Windows 10 네이티브 방식으로 SSH 서버 설정하기

남정현
남정현
Nov 7 · 14 min read
Image Credit: https://unsplash.com/photos/JEBeXUHm1c4
Image Credit: https://unsplash.com/photos/JEBeXUHm1c4
Image Credit: https://unsplash.com/photos/JEBeXUHm1c4

지난 번 글에 이어서 Windows 10과 Windows Server 1709부터 기본 제공되는 SSH 서버를 설정하는 방법을 살펴보도록 하겠습니다. 이 방법을 사용하면 Windows Server도 기존의 리눅스 서버와 마찬가지로 SSH로 원격 접속을 할 수 있습니다. 또한 SSH 포트 터널링을 이용하여 방화벽 설정을 수정하지 않고 안전하게 원격 데스크탑을 사용할 수 있는 방법도 살펴보겠습니다.

OpenSSH 서버 설치하고 구성하기

이전 글에서 SSH 클라이언트를 설치했던 것과 동일한 방법으로 OpenSSH 서버를 설치할 수 있습니다.

$OpenSSHServer = Get-WindowsCapability -Online | ? Name -like ‘OpenSSH.Server*’Add-WindowsCapability -Online -Name $OpenSSHServer.Name

OpenSSH 서버 프로그램을 설치한 후에는 NT 서비스를 바로 시작하지 않고 설정을 먼저하는 것이 편리합니다.

비대칭 키 인증 적용하기

비밀 번호 대입을 통한 공격을 방지할 수 있도록 Public Key 인증 방식을 사용하고 비밀 번호 인증 방식을 비활성화하는 것이 좋습니다. 관리자 권한으로 PowerShell을 시작한 후 아래 경로의 파일을 엽니다. (또는 선호하는 다른 텍스트 에디터를 사용해도 됩니다.)

notepad.exe $env:PROGRAMDATA\ssh\sshd_config

그리고 다음의 항목들에 대해, 주석이 적용되어있으면 주석을 해제하고, 다음과 같이 값을 적용하도록 합니다.

  • PubkeyAuthentication yes
  • PasswordAuthentication no
  • PermitEmptyPasswords no

그 다음 SSH 공개 키를 어떤 식으로 관리할 것인지 선호하는 방법을 선택합니다. Windows Server 2019 (또는 1809) 부터는 두 가지 방법이 있는데, 이 중 사용자 홈 디렉터리에 authorized_keys 파일을 만드는 전통적인 방법을 먼저 설명하겠습니다.

$HOME\.ssh\authorized_keys 파일을 사용하는 방법

이 방법을 사용하려면 설정 파일의 하단에 있는 다음의 코드 블록을 주석 처리해야 합니다.

Match Group administrators
AuthorizedKeysFile
__PROGRAMDATA__/ssh/administrators_authorized_keys

그 다음 로그인하려는 사용자 홈 디렉터리로 이동하여 .ssh 디렉터리를 만듭니다.

mkdir "$HOME\.ssh"

새로 만든 디렉터리 안에 authorized_keys 파일 (확장자가 없어야 합니다.)을 만들고 선호하는 텍스트 편집기로 파일을 엽니다.

$authorizedKeyFilePath = “$HOME\.ssh\authorized_keys”New-Item $authorizedKeyFilePathnotepad.exe $authorizedKeyFilePath

여기에 사용 중인 SSH 공개 키 값을 가져와서 기록하고 저장하도록 합니다.

파일을 저장하면 “인증 키 정보를 담은 파일 권한 설정하기” 단락에서 설명하는대로 반드시 파일 권한 설정을 변경해야 합니다. 이 설정이 되어있지 않으면 SSH 연결 시 실패하게 되므로 빠뜨리면 안되는 중요한 작업입니다.

administrators_authorized_keys를 사용하는 방법

이 방식은 Windows Server 2019 (1809)에 포함된 OpenSSH에서 기본으로 사용하는 방식입니다. 각 사용자 별로 SSH 키를 매번 새롭게 등록하지 않고, 한 곳에서 파일을 관리할 수 있습니다.

이 방식을 사용할 경우, 관리자가 아닌 사용자들 (즉 Administrators 그룹에 속하지 않는 사용자들)을 제외하면 모든 공개 키가 $env:PROGRAMDATA\ssh\administrators_authorized_keys 파일에 저장되어야 하며, 관리자 그룹에 속한 사용자가 접속을 시도하면, 이 설정을 홈 디렉터리의 설정 대신 사용하므로 여기에 키가 없으면 접속에 실패합니다.

administrators_authorized_keys 파일은 기본적으로 존재하지 않으므로 새로 만들어야 합니다.

$authorizedKeyFilePath = “$env:ProgramData\ssh\administrators_authorized_keys”New-Item $authorizedKeyFilePathnotepad.exe $authorizedKeyFilePath

여기에 사용 중인 SSH 공개 키 값을 가져와서 기록하고 저장하도록 합니다.

파일을 저장하면 “인증 키 정보를 담은 파일 권한 설정하기” 단락에서 설명하는대로 반드시 파일 권한 설정을 변경해야 합니다. 이 설정이 되어있지 않으면 SSH 연결 시 실패하게 되므로 빠뜨리면 안되는 중요한 작업입니다.

인증 키 정보를 담은 파일 권한 설정하기

Windows용 OpenSSH 서버 설정에서 가장 많은 어려움을 겪게 되는 부분이 바로 이 부분입니다. 혹은 잘 되던 SSH 접속이 어느날 갑자기 안되더라 하는 것도 이 부분과 관련이 있을 수 있습니다.

앞 단계에서 선택한 방법에 따라 authorized_keys 파일 또는 administrators_authorized_keys 파일의 경로를 확인하여 icacls.exe 유틸리티와 Get-Acl, Set-Acl 명령을 사용하여 시스템 계정만이 접근할 수 있게 권한을 변경해야 합니다.

$authorizedKeyFilePath = "..."icacls.exe $authorizedKeyFilePath /remove “NT AUTHORITY\Authenticated Users”icacls.exe $authorizedKeyFilePath /inheritance:rGet-Acl “$env:ProgramData\ssh\ssh_host_dsa_key” | Set-Acl $authorizedKeyFilePath

SSH 기본 셸 변경하기

기본적으로 호환성을 고려하여 Windows 운영 체제는 예전부터 지금까지 DOS 명령어를 인식하는 인터프리터를 기본으로 하는 셸을 제공해왔습니다. 하지만 이제 DOS 명령어를 사용하여 작업하는 것보다 더 많고 다양한 기능을 제공하는 PowerShell이 좋은 대안이 되어가고 있습니다.

만약 필요하다면 DOS 인터프리터 대신 PowerShell을 SSH의 기본 셸로 처음부터 사용하도록 지정할 수도 있습니다. 단, 여기서 설정하는 것은 SSH 세션에만 한정됩니다.

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "$env:WINDIR\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

SSH 서비스 시작하기

이제 SSH 서버를 시작할 준비가 되었습니다. SSH 서버는 기본적으로 수동 실행 상태로 설정되어있으므로, 시작 모드를 자동으로 변경하고 서비스를 시작하도록 합니다.

$SSHDaemonSvc = Get-Service -Name ‘sshd’Set-Service -Name $SSHDaemonSvc.Name -StartupType AutomaticStart-Service -Name $SSHDaemonSvc.Name

다음과 같이 접속이 가능함을 확인하면 잘 된 것입니다.

Windows Server에 SSH로 접속한 모습

이렇게해서 Windows도 기본 제공되는 소프트웨어만으로 리눅스 처럼 비밀 번호를 사용하지 않고 접속하는 것이 가능해졌습니다.

원격 데스크탑의 보안을 강화하는 방법

Windows는 리눅스와는 달리 시스템에서 여전히 많은 부분들이 커맨드 라인 기반이 아닌 그래픽 인터페이스 기반으로 실행됩니다. 그래서 위와 같이 터미널로 접속하여 뭔가를 하려고 하면 예상했던 것과는 달리 할 수 있는 일이 많지 않을 수 있습니다.

하지만 원격 데스크탑은 익히 알려진대로 많은 해커들과 스크립트 키디들의 좋은 먹잇감이기도 합니다. 편의성과 보안 중 하나를 선택해야 하는 딜레마에 빠지기 쉬운 부분인 것입니다.

다행히 SSH는 터널링이라는 컨셉을 제공하여, 다른 네트워크 연결을 안전하게 중계하는 기능을 지원합니다. 원격 데스크탑 연결도 이 방법을 통하여 보호하는 것이 가능하므로 안심하고 사용할 수 있습니다.

우선 TCP 3389 포트와 UDP 3389 포트를 차단하는 것부터 시작합니다. SSH 터널링 방식으로만 원격 데스크탑을 사용할 것이므로 이렇게 해도 됩니다.

Set-NetFirewallRule -DisplayName “Remote Desktop - User Mode (UDP-In)” -Action BlockSet-NetFirewallRule -DisplayName “Remote Desktop - User Mode (TCP-In)” -Action Block

그 다음, 원격 데스크탑 서버가 연결을 받아들일 수 있도록 레지스트리 플래그 값을 변경해야 합니다.

Set-ItemProperty -Path ‘HKLM:\System\CurrentControlSet\Control\Terminal Server’ -Name “fDenyTSConnections” -Value 0

그리고 지금 설명할 부분이 정말 멋진 부분입니다. 앞서 보았듯 OpenSSH로 접속하는 시점에는 비밀 번호를 묻지 않으므로, 사용할 때 마다 임의로 생성한 강력한 비밀 번호를 설정하는 것이 가능합니다. 이 작업을 할 수 있는 간단한 스크립트를 시스템 디렉터리에 만들어두면 매우 유용합니다.

여러분이 원하는 종류의 스크립트를 다음 중에 선택하여 ChangePassword.ps1 이라는 파일을 만들도록 합니다. 파일은 편의 상 시스템 디렉터리에 보관하도록 하겠습니다.

$change_pwd_script_path = “$env:WINDIR\ChangePassword.ps1”
Clear-Content $change_pwd_script_path -ErrorAction SilentlyContinue
notepad.exe $change_pwd_script_path

원하는 비밀 번호를 설정하기

다음과 같이 ChangePassword.ps1 파일의 내용을 만듭니다.

$Password = Read-Host -Prompt "Provide your new account password" -AsSecureStringSet-LocalUser -Name "$env:UserName" -Password $PasswordClear-Variable "Password"Write-Host "Detailed settings such as remote desktop settings, WinRM connection settings, and Windows Update can be controlled using the sconfig command."

이 스크립트를 사용하면 비밀 번호를 사용자가 직접 입력하여 지정할 수 있습니다. 다만 별도 정책 변경을 하지 않으면, Windows Server의 강화된 기본 비밀 번호 규칙을 통과하는 비밀 번호만 사용할 수 있으며, 다음의 조건을 모두 만족해야 하는 비밀 번호를 지정해야 합니다.

  • 영어 대문자 (A부터 Z까지)
  • 영어 소문자 (a부터 z까지)
  • 아라비아 숫자 (0부터 9까지)
  • 특수 기호 (예: !, $, #, %)

매번 새로운 비밀 번호를 설정하기

다음과 같이 ChangePassword.ps1 파일의 내용을 만듭니다.

Add-Type -AssemblyName System.Web$Password = [System.Web.Security.Membership]::GeneratePassword(30,10)Set-LocalUser -Name "$env:UserName" -Password ($Password | ConvertTo-SecureString -AsPlainText -Force)Write-Host "Your New Password is:`r`n`r`n$Password"Write-Host "Detailed settings such as remote desktop settings, WinRM connection settings, and Windows Update can be controlled using the sconfig command."Clear-Variable "Password"

이 방식을 이용하면 매번 강력한 비밀 번호를 새로 설정할 수 있습니다. 혹시 비밀 번호를 잊더라도 2차 인증 수단으로 여전히 공개 키 인증을 사용할 수 있으므로 안심할 수 있습니다.

이제 위의 스크립트를 실행하기 위해 다음과 같이 명령어를 입력합니다. 그 다음에는 스크립트에서 가이드하는대로 비밀 번호를 설정하고 원격 데스크탑 접속이 잘 되는지 확인하면 됩니다.

ChangePassword

실제로 원격 데스크탑 로그인해보기

원격 데스크탑에 로그인하기 위해서는 다음과 같이 SSH를 실행하면 됩니다.

ssh -L 3389:localhost:3389 <user_id>@<host_address>

앞 부분의 3389는 서버 측의 포트 번호, 뒷 부분의 주소는 로컬에서 사용할 포트 번호입니다. 만약 서버에서 원격 데스크탑의 포트 번호를 다른 번호로 레지스트리에서 변경했던 적이 있다면 3389 대신 변경한 포트 번호를 대신 기재하면 됩니다.

macOS의 Remote Desktop 10으로 SSH 터널링을 이용하여 원격 데스크탑에 접속한 모습

<host_address> 부분만을 사용하여 기존처럼 원격 데스크탑 연결을 시도하면 앞에서 설정한 것처럼 방화벽이 연결을 차단하기 때문에, SSH 비밀 키와 일치하는 공개 키를 해당 서버에 등록한 사용자가 아니면 아무도 원격 데스크탑에 직접 접속할 수 없는 상태가 됩니다.

안전한 파일 송수신 기능 사용하기

당연한 이야기이지만, SSH를 기반으로 하는 SFTP를 사용하는 것도 가능합니다. 이 기능을 이용하여 원격 데스크탑의 폴더 공유 기능을 대신하여 더 안전하게 대용량 파일 전송도 안전하게 처리할 수 있습니다.

FileZilla의 SFTP 기능을 이용하여 Windows Server에 접속한 모습

FileZilla와 같이 SFTP 기능을 지원하는 클라이언트라면 모두 호환되며, 기존 FTP처럼 복잡한 방화벽 개방 정책을 적용할 필요도 없으므로 관리 상으로도 이점이 뛰어납니다.

마무리

이로써 Windows 10 1709 이후로 새롭게 추가된 SSH 기능을 모두 살펴보았습니다. 두 편의 글 모두 Windows 10과 Windows Server 2019에서 사용 가능한 내용들이므로, 잠시 시간을 내어 설정해두시면 한층 더 강력한 보안을 구현하실 수 있으니 꼭 살펴보시기를 권해드립니다.

Credits

이 글을 작성할 때 아래 글들의 도움을 받았습니다.

남정현의 블로그

DevOps related blogs

남정현

Written by

남정현

Azure와 .NET 기술을 즐겨 사용하는 개발자입니다. 한국 Azure 사용자 페이스북 그룹에서 활동합니다.

남정현의 블로그

DevOps related blogs

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade