RDP ์„ธ์…˜ ๊ด€๋ฆฌ ์œ„์ž„

RDP ์„ธ์…˜ ๊ด€๋ฆฌ ์œ„์ž„
๋‚ด๊ฐ€ ๊ทผ๋ฌดํ•˜๋Š” ์กฐ์ง์—์„œ๋Š” ์›์น™์ ์œผ๋กœ ์›๊ฒฉ๊ทผ๋ฌด๋ฅผ ๊ธˆ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜€๋‹ค. ์ง€๋‚œ ์ฃผ๊นŒ์ง€. ์ด์ œ ์†”๋ฃจ์…˜์„ ๊ธด๊ธ‰ํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋น„์ฆˆ๋‹ˆ์Šค์—์„œ ์ƒˆ๋กœ์šด ์ž‘์—… ํ˜•์‹์œผ๋กœ์˜ ํ”„๋กœ์„ธ์Šค ์ ์‘, ํ•€ ์ฝ”๋“œ ๋ฐ ํ† ํฐ์ด ํฌํ•จ๋œ PKI, VPN, ์ž์„ธํ•œ ๋กœ๊น… ๋“ฑ.
๋ฌด์—‡๋ณด๋‹ค๋„ ํ„ฐ๋ฏธ๋„ ์„œ๋น„์Šค๋ผ๋Š” ์›๊ฒฉ ๋ฐ์Šคํฌํ†ฑ ์ธํ”„๋ผ ์„ค์ •์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์„ผํ„ฐ์— ์—ฌ๋Ÿฌ RDS ๋ฐฐํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉํ‘œ ์ค‘ ํ•˜๋‚˜๋Š” ๊ด€๋ จ IT ๋ถ€์„œ์˜ ๋™๋ฃŒ๊ฐ€ ๋Œ€ํ™”ํ˜•์œผ๋กœ ์‚ฌ์šฉ์ž ์„ธ์…˜์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์•„์‹œ๋‹ค์‹œํ”ผ ์ด๋ฅผ ์œ„ํ•œ ์ผ๋ฐ˜ RDS ์„€๋„์šฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์žˆ์œผ๋ฉฐ ์ด๋ฅผ ์œ„์ž„ํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ RDS ์„œ๋ฒ„์— ๋Œ€ํ•œ ๋กœ์ปฌ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋™๋ฃŒ๋“ค์„ ์กด๊ฒฝํ•˜๊ณ  ๊ณ ๋งˆ์šด ๋งˆ์Œ์„ ๊ฐ–๊ณ  ์žˆ์ง€๋งŒ, ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ๋ฐฐ๋ถ„์—๋Š” ์š•์‹ฌ์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ๐Ÿ™‚ ์ €์—๊ฒŒ ๋™์˜ํ•˜์‹œ๋Š” ๋ถ„๋“ค์€ ๊ณ ์–‘์ด ๋ฐ‘์œผ๋กœ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๊ธ€์Ž„, ์ง€๊ธˆ์€ ๋น„์ฆˆ๋‹ˆ์Šค์— ๋Œ€ํ•œ ์ž‘์—…์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.

1 ๋‹จ๊ณ„

Active Directory์—์„œ ๋ณด์•ˆ ๊ทธ๋ฃน ์ƒ์„ฑ RDP_์šด์˜์ž ๊ถŒํ•œ์„ ์œ„์ž„ํ•˜๋ ค๋Š” ์‚ฌ์šฉ์ž์˜ ๊ณ„์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

$Users = @(
    "UserLogin1",
    "UserLogin2",
    "UserLogin3"
)
$Group = "RDP_Operators"
New-ADGroup -Name $Group -GroupCategory Security -GroupScope DomainLocal
Add-ADGroupMember -Identity $Group -Members $Users

AD ์‚ฌ์ดํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ด๋™ํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๋„๋ฉ”์ธ ์ปจํŠธ๋กค๋Ÿฌ์— ๋ณต์ œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ณดํ†ต 15๋ถ„ ์ด์ƒ ๊ฑธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2 ๋‹จ๊ณ„

๊ฐ RDSH ์„œ๋ฒ„์—์„œ ํ„ฐ๋ฏธ๋„ ์„ธ์…˜์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๊ทธ๋ฃน์— ๋ถ€์—ฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์„ธํŠธ-RDSPermissions.ps1

$Group = "RDP_Operators"
$Servers = @(
    "RDSHost01",
    "RDSHost02",
    "RDSHost03"
)
ForEach ($Server in $Servers) {
    #ะ”ะตะปะตะณะธั€ัƒะตะผ ะฟั€ะฐะฒะพ ะฝะฐ ั‚ะตะฝะตะฒั‹ะต ัะตััะธะธ
    $WMIHandles = Get-WmiObject `
        -Class "Win32_TSPermissionsSetting" `
        -Namespace "rootCIMV2terminalservices" `
        -ComputerName $Server `
        -Authentication PacketPrivacy `
        -Impersonation Impersonate
    ForEach($WMIHandle in $WMIHandles)
    {
        If ($WMIHandle.TerminalName -eq "RDP-Tcp")
        {
        $retVal = $WMIHandle.AddAccount($Group, 2)
        $opstatus = "ัƒัะฟะตัˆะฝะพ"
        If ($retVal.ReturnValue -ne 0) {
            $opstatus = "ะพัˆะธะฑะบะฐ"
        }
        Write-Host ("ะ”ะตะปะตะณะธั€ะพะฒะฐะฝะธะต ะฟั€ะฐะฒ ะฝะฐ ั‚ะตะฝะตะฒะพะต ะฟะพะดะบะปัŽั‡ะตะฝะธะต ะณั€ัƒะฟะฟะต " +
            $Group + " ะฝะฐ ัะตั€ะฒะตั€ะต " + $Server + ": " + $opstatus + "`r`n")
        }
    }
}

3 ๋‹จ๊ณ„

๋กœ์ปฌ ๊ทธ๋ฃน์— ๊ทธ๋ฃน ์ถ”๊ฐ€ ์›๊ฒฉ ๋ฐ์Šคํฌํ†ฑ ์‚ฌ์šฉ์ž ๊ฐ RDSH ์„œ๋ฒ„์—์„œ. ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜ ๋ชจ์Œ์œผ๋กœ ๊ฒฐํ•ฉ๋œ ๊ฒฝ์šฐ ๋ชจ์Œ ์ˆ˜์ค€์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

$Group = "RDP_Operators"
$CollectionName = "MyRDSCollection"
[String[]]$CurrentCollectionGroups = @(Get-RDSessionCollectionConfiguration -CollectionName $CollectionName -UserGroup).UserGroup
Set-RDSessionCollectionConfiguration -CollectionName $CollectionName -UserGroup ($CurrentCollectionGroups + $Group)

๋‹จ์ผ ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋ฃน ์ •์ฑ…, ์„œ๋ฒ„์— ์ ์šฉ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ๊ธฐ๋‹ค๋ฆฌ๊ธฐ ๋„ˆ๋ฌด ๊ฒŒ์œผ๋ฅธ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ์ข‹์€ ์˜ค๋ž˜๋œ gpupdate๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค‘์•™์—์„œ.

4 ๋‹จ๊ณ„

"๊ด€๋ฆฌ์ž"์— ๋Œ€ํ•ด ๋‹ค์Œ PS ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ค€๋น„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

RDSManagement.ps1

$Servers = @(
    "RDSHost01",
    "RDSHost02",
    "RDSHost03"
)

function Invoke-RDPSessionLogoff {
    Param(
        [parameter(Mandatory=$True, Position=0)][String]$ComputerName,
        [parameter(Mandatory=$true, Position=1)][String]$SessionID
    )
    $ErrorActionPreference = "Stop"
    logoff $SessionID /server:$ComputerName /v 2>&1
}

function Invoke-RDPShadowSession {
    Param(
        [parameter(Mandatory=$True, Position=0)][String]$ComputerName,
        [parameter(Mandatory=$true, Position=1)][String]$SessionID
    )
    $ErrorActionPreference = "Stop"
    mstsc /shadow:$SessionID /v:$ComputerName /control 2>&1
}

Function Get-LoggedOnUser {
    Param(
        [parameter(Mandatory=$True, Position=0)][String]$ComputerName="localhost"
    )
    $ErrorActionPreference = "Stop"
    Test-Connection $ComputerName -Count 1 | Out-Null
    quser /server:$ComputerName 2>&1 | Select-Object -Skip 1 | ForEach-Object {
        $CurrentLine = $_.Trim() -Replace "s+"," " -Split "s"
        $HashProps = @{
            UserName = $CurrentLine[0]
            ComputerName = $ComputerName
        }
        If ($CurrentLine[2] -eq "Disc") {
            $HashProps.SessionName = $null
            $HashProps.Id = $CurrentLine[1]
            $HashProps.State = $CurrentLine[2]
            $HashProps.IdleTime = $CurrentLine[3]
            $HashProps.LogonTime = $CurrentLine[4..6] -join " "
            $HashProps.LogonTime = $CurrentLine[4..($CurrentLine.GetUpperBound(0))] -join " "
        }
        else {
            $HashProps.SessionName = $CurrentLine[1]
            $HashProps.Id = $CurrentLine[2]
            $HashProps.State = $CurrentLine[3]
            $HashProps.IdleTime = $CurrentLine[4]
            $HashProps.LogonTime = $CurrentLine[5..($CurrentLine.GetUpperBound(0))] -join " "
        }
        New-Object -TypeName PSCustomObject -Property $HashProps |
        Select-Object -Property UserName, ComputerName, SessionName, Id, State, IdleTime, LogonTime
    }
}

$UserLogin = Read-Host -Prompt "ะ’ะฒะตะดะธั‚ะต ะปะพะณะธะฝ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปั"
Write-Host "ะŸะพะธัะบ RDP-ัะตััะธะน ะฟะพะปัŒะทะพะฒะฐั‚ะตะปั ะฝะฐ ัะตั€ะฒะตั€ะฐั…..."
$SessionList = @()
ForEach ($Server in $Servers) {
    $TargetSession = $null
    Write-Host "  ะžะฟั€ะพั ัะตั€ะฒะตั€ะฐ $Server"
    Try {
        $TargetSession = Get-LoggedOnUser -ComputerName $Server | Where-Object {$_.UserName -eq $UserLogin}
    }
    Catch {
        Write-Host "ะžัˆะธะฑะบะฐ: " $Error[0].Exception.Message -ForegroundColor Red
        Continue
    }
    If ($TargetSession) {
        Write-Host "    ะะฐะนะดะตะฝะฐ ัะตััะธั ั ID $($TargetSession.ID) ะฝะฐ ัะตั€ะฒะตั€ะต $Server" -ForegroundColor Yellow
        Write-Host "    ะงั‚ะพ ะฑัƒะดะตะผ ะดะตะปะฐั‚ัŒ?"
        Write-Host "      1 - ะฟะพะดะบะปัŽั‡ะธั‚ัŒัั ะบ ัะตััะธะธ"
        Write-Host "      2 - ะทะฐะฒะตั€ัˆะธั‚ัŒ ัะตััะธัŽ"
        Write-Host "      0 - ะฝะธั‡ะตะณะพ"
        $Action = Read-Host -Prompt "ะ’ะฒะตะดะธั‚ะต ะดะตะนัั‚ะฒะธะต"
        If ($Action -eq "1") {
            Invoke-RDPShadowSession -ComputerName $Server -SessionID $TargetSession.ID
        }
        ElseIf ($Action -eq "2") {
            Invoke-RDPSessionLogoff -ComputerName $Server -SessionID $TargetSession.ID
        }
        Break
    }
    Else {
        Write-Host "    ัะตััะธะน ะฝะต ะฝะฐะนะดะตะฝะพ"
    }
}

PS ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก PS ์Šคํฌ๋ฆฝํŠธ์™€ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ cmd ํŒŒ์ผ ํ˜•์‹์œผ๋กœ ์…ธ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

RDSManagement.cmd

@ECHO OFF
powershell -NoLogo -ExecutionPolicy Bypass -File "%~d0%~p0%~n0.ps1" %*

๋‘ ํŒŒ์ผ์„ "๊ด€๋ฆฌ์ž"๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํด๋”์— ๋„ฃ๊ณ  ๋‹ค์‹œ ๋กœ๊ทธ์ธํ•˜๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ cmd ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜์—ฌ RDS Shadow ๋ชจ๋“œ์—์„œ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์— ์—ฐ๊ฒฐํ•˜๊ณ  ๊ฐ•์ œ๋กœ ๋กœ๊ทธ์•„์›ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์‚ฌ์šฉ์ž๊ฐ€ ์Šค์Šค๋กœ "๋ฉˆ์ถ˜" ์„ธ์…˜์„ ์ข…๋ฃŒํ•  ์ˆ˜ ์—†์„ ๋•Œ ์œ ์šฉํ•จ).

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ž…๋‹ˆ๋‹ค.

"๋งค๋‹ˆ์ €"์—๊ฒŒRDP ์„ธ์…˜ ๊ด€๋ฆฌ ์œ„์ž„

์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ดRDP ์„ธ์…˜ ๊ด€๋ฆฌ ์œ„์ž„

๋ช‡ ๊ฐ€์ง€ ๋งˆ์ง€๋ง‰ ๋ฐœ์–ธ

๋‰˜์•™์Šค 1. ์ œ์–ด๊ถŒ์„ ์–ป์œผ๋ ค๋Š” ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์ด ์„œ๋ฒ„์—์„œ Set-RDSPermissions.ps1 ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์‹œ์ž‘๋œ ๊ฒฝ์šฐ "๊ด€๋ฆฌ์ž"๋Š” ์•ก์„ธ์Šค ์˜ค๋ฅ˜๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•ด๊ฒฐ์ฑ…์€ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ๋˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ ๋กœ๊ทธ์ธํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค.

๋‰˜์•™์Šค 2. ๋ฉฐ์น  ๋™์•ˆ RDP Shadow๋กœ ์ž‘์—…ํ•œ ํ›„ ๊ทธ๋“ค์€ ํฅ๋ฏธ๋กœ์šด ๋ฒ„๊ทธ ๋˜๋Š” ๊ธฐ๋Šฅ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋‹ค์‹œ ๋กœ๊ทธ์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ˜ผ์ž๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์‹œ๊ฐ„, ะดะฒะฐ, ์„ธ.

๊ทธ๊ฒŒ ๋‹ค์•ผ. ๋‚˜๋Š” ๋‹น์‹ ๊ณผ ๋‹น์‹ ์˜ ์„œ๋ฒ„์— ๊ฑด๊ฐ•์„ ๊ธฐ์›ํ•ฉ๋‹ˆ๋‹ค. ์–ธ์ œ๋‚˜์ฒ˜๋Ÿผ ์˜๊ฒฌ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ํ”ผ๋“œ๋ฐฑ์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ์•„๋ž˜์˜ ๊ฐ„๋‹จํ•œ ์„ค๋ฌธ ์กฐ์‚ฌ์— ์ฐธ์—ฌํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์†Œ์Šค

๋“ฑ๋ก๋œ ์‚ฌ์šฉ์ž๋งŒ ์„ค๋ฌธ ์กฐ์‚ฌ์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์ œ๋ฐœ

๋‹น์‹ ์€ ๋ฌด์—‡์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

  • 8,1%AMMYY ๊ด€๋ฆฌ์ž5

  • 17,7%์• ๋‹ˆ๋ฐ์Šคํฌ11

  • 9,7%๋ฐ์ž„์›จ์–ด6

  • 24,2%๋ผ๋ฏผ15

  • 14,5%RDS ์„€๋„์šฐ9

  • 1,6%๋น ๋ฅธ ์ง€์› / Windows ์›๊ฒฉ ์ง€์›1

  • 38,7%ํŒ€๋ทฐ์–ด24

  • 32,3%VNC20

  • 32,3%๊ธฐํƒ€20

  • 3,2%๋ผ์ดํŠธ๋งค๋‹ˆ์ €2

62๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ํˆฌํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. 22๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๊ถŒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€