Windows SSH 원격 로그인
Categories:
Windows에서 SSH 원격 액세스를 활성화하려면 일반적으로 Windows의 OpenSSH 기능을 사용해야 합니다. 다음은 자세한 절차 설명입니다:
OpenSSH 확인 및 설치
-
OpenSSH 설치 여부 확인:
- “설정” > “앱” > “앱 및 기능” > “선택 기능 관리"로 이동합니다.
- 설치된 목록에서 “OpenSSH 서버"를 찾습니다. 존재한다면 이미 설치되어 있다는 의미입니다.
-
OpenSSH 설치:
- OpenSSH 서버를 찾을 수 없다면 “선택 기능 관리” 페이지에서 “기능 추가"를 클릭한 후 목록에서 “OpenSSH 서버"를 찾아 “설치"를 클릭합니다.
OpenSSH 서비스 시작 및 설정
-
OpenSSH 서비스 시작:
- 설치完成后, 명령 프롬프트를 관리자 권한으로 실행합니다.
net start sshd명령으로 OpenSSH 서비스를 시작합니다. 시스템 부팅 시 자동으로 시작되도록 하려면sc config sshd start= auto명령을 입력합니다.
-
방화벽 설정:
- Windows 방화벽이 SSH 연결을 허용하는지 확인합니다. “제어판” > “시스템 및 보안” > “Windows Defender 방화벽” > “고급 설정"으로 이동하여 TCP 포트 22 연결을 허용하는 새로운 수신 규칙을 만듭니다.
IP 주소 확인 및 연결 테스트
-
IP 주소 확인:
- SSH 서비스가 활성화된 Windows PC에 다른 머신에서 연결하려면 IP 주소를 알아야 합니다. 명령 프롬프트에서
ipconfig명령을 사용하여 로컬 머신의 IP 주소를 확인할 수 있습니다.
- SSH 서비스가 활성화된 Windows PC에 다른 머신에서 연결하려면 IP 주소를 알아야 합니다. 명령 프롬프트에서
-
연결 테스트:
- 다른 컴퓨터나 모바일 장치에서 SSH 클라이언트(PuTTY, Termius 등)를 사용하여 Windows PC에 연결을 시도합니다. 형식은
ssh username@your_ip_address입니다. 여기서username은 로그인하려는 Windows 계정 이름이며,your_ip_address는 이전에 확인한 IP 주소입니다.
- 다른 컴퓨터나 모바일 장치에서 SSH 클라이언트(PuTTY, Termius 등)를 사용하여 Windows PC에 연결을 시도합니다. 형식은
설정 수정
비밀번호 로그인을 피하는 것이 좋습니다. 이는 절대 금기입니다. 반드시 공개키를 사용하여 로그인해야 하며, 비밀번호 로그인을 비활성화하고 공개키 로그인을 허용하도록 설정을 수정해야 합니다.
이 구성 파일은 수정하기에 적합하지 않으며 특별한 권한이 필요하며 디렉토리와 파일의 권한이 특정 값으로 설정되어 있어야 합니다. 여기서는 스크립트를 사용한 수정을 권장합니다.
# 관리자 권한 확인
$elevated = [bool]([System.Security.Principal.WindowsPrincipal]::new(
[System.Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
if (-not $elevated) {
Write-Error "이 스크립트를 관리자 권한으로 실행하세요"
exit 1
}
# 1. OpenSSH 서버 설치 확인
Write-Host "OpenSSH 서버 설치 상태를 확인 중입니다..."
$capability = Get-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
if ($capability.State -ne 'Installed') {
Write-Host "OpenSSH 서버 설치 중..."
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 | Out-Null
}
# 2. SSH 서비스 시작 및 자동 시작 설정
Write-Host "SSH 서비스를 구성 중입니다..."
$service = Get-Service sshd -ErrorAction SilentlyContinue
if (-not $service) {
Write-Error "OpenSSH 서비스 설치 실패"
exit 1
}
if ($service.Status -ne 'Running') {
Start-Service sshd
}
Set-Service sshd -StartupType Automatic
# 3. 구성 파일 수정
$configPath = "C:\ProgramData\ssh\sshd_config"
if (Test-Path $configPath) {
Write-Host "원본 구성 파일을 백업 중입니다..."
Copy-Item $configPath "$configPath.bak" -Force
} else {
Write-Error "구성 파일을 찾을 수 없습니다: $configPath"
exit 1
}
Write-Host "SSH 구성 수정 중..."
$config = Get-Content -Path $configPath -Raw
# 공개키 인증 활성화 및 비밀번호 로그인 비활성화
$config = $config -replace '^#?PubkeyAuthentication .*$','PubkeyAuthentication yes' `
-replace '^#?PasswordAuthentication .*$','PasswordAuthentication no'
# 필요한 구성 포함 확인
if ($config -notmatch 'PubkeyAuthentication') {
$config += "`nPubkeyAuthentication yes"
}
if ($config -notmatch 'PasswordAuthentication') {
$config += "`nPasswordAuthentication no"
}
# 구성 파일에 다시 쓰기
$config | Set-Content -Path $configPath -Encoding UTF8
authorized_keys 파일 권한 확인
# 일반 사용자
$authKeys = "$env:USERPROFILE\.ssh\authorized_keys"
icacls $authKeys /inheritance:r /grant "$($env:USERNAME):F" /grant "SYSTEM:F"
icacls "$env:USERPROFILE\.ssh" /inheritance:r /grant "$($env:USERNAME):F" /grant "SYSTEM:F"
# 관리자
$adminAuth = "C:\ProgramData\ssh\administrators_authorized_keys"
icacls $adminAuth /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
방화벽 규칙 설정
# SSH 포트 허용
New-NetFirewallRule -DisplayName "OpenSSH Server (sshd)" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
공개키 추가
일반 사용자
# 일반 사용자
$userProfile = $env:USERPROFILE
$sshDir = Join-Path $userProfile ".ssh"
$authorizedKeysPath = Join-Path $sshDir "authorized_keys"
$PublicKeyPath = "D:\public_keys\id_rsa.pub"
# .ssh 디렉토리 생성
if (-not (Test-Path $sshDir)) {
New-Item -ItemType Directory -Path $sshDir | Out-Null
}
# .ssh 디렉토리 권한 설정
$currentUser = "$env:USERDOMAIN\$env:USERNAME"
$acl = Get-Acl $sshDir
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$currentUser, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$acl.AddAccessRule($rule)
Set-Acl $sshDir $acl
# 공개키 추가
if (Test-Path $PublicKeyPath) {
$pubKey = Get-Content -Path $PublicKeyPath -Raw
if ($pubKey) {
# 공개키 끝에 개행 문자가 있는지 확인
if (-not $pubKey.EndsWith("`n")) {
$pubKey += "`n"
}
# 공개키 추가
Add-Content -Path $authorizedKeysPath -Value $pubKey -Encoding UTF8
# 파일 권한 설정
$acl = Get-Acl $authorizedKeysPath
$acl.SetSecurityDescriptorRule(
(New-Object System.Security.AccessControl.FileSystemAccessRule(
$currentUser, "FullControl", "None", "None", "Allow"
))
)
Set-Acl $authorizedKeysPath $acl
}
} else {
Write-Error "공개키 파일이 존재하지 않습니다: $PublicKeyPath"
exit 1
}
# SSH 서비스 재시작
Write-Host "SSH 서비스를 재시작 중입니다..."
Restart-Service sshd
관리자 사용자
# 관리자
$adminSshDir = "C:\ProgramData\ssh"
$adminAuthKeysPath = Join-Path $adminSshDir "administrators_authorized_keys"
$adminPublicKeyPath = "D:\public_keys\id_rsa.pub"
# 관리자 SSH 디렉토리 생성
if (-not (Test-Path $adminSshDir)) {
New-Item -ItemType Directory -Path $adminSshDir | Out-Null
}
# 관리자 SSH 디렉토리 권한 설정
$adminAcl = Get-Acl $adminSshDir
$adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$adminAcl.AddAccessRule($adminRule)
Set-Acl $adminSshDir $adminAcl
# 관리자 공개키 추가
if (Test-Path $adminPublicKeyPath) {
$adminPubKey = Get-Content -Path $adminPublicKeyPath -Raw
if ($adminPubKey) {
# 공개키 끝에 개행 문자가 있는지 확인
if (-not $adminPubKey.EndsWith("`n")) {
$adminPubKey += "`n"
}
# 공개키 추가
Add-Content -Path $adminAuthKeysPath -Value $adminPubKey -Encoding UTF8
# 파일 권한 설정
$adminAcl = Get-Acl $adminAuthKeysPath
$adminAcl.SetSecurityDescriptorRule(
(New-Object System.Security.AccessControl.FileSystemAccessRule(
"Administrators", "FullControl", "None", "None", "Allow"
))
)
Set-Acl $adminAuthKeysPath $adminAcl
}
} else {
Write-Error "관리자 공개키 파일이 존재하지 않습니다: $adminPublicKeyPath"
exit 1
}
# SSH 서비스 재시작
Write-Host "SSH 서비스를 재시작 중입니다..."
Restart-Service sshd