다음을 통해 공유


보안 문제 해결

 

적용 대상: Windows Azure 팩

이 항목에서는 Windows Server용 Windows Azure 팩의 보안 및 인증과 관련된 문제 해결에 대해 설명합니다. 이 항목의 자격 증명 검사 목록을 검토하여 많은 문제를 해결할 수 있습니다. 다음 문제에 대한 권장 사항이 제공됩니다.

  • AD FS를 통합한 후 AD를 사용하도록 관리 포털을 다시 설정합니다.

  • AD FS를 통합한 후에는 테넌트 포털에 액세스할 수 없습니다.

  • Get-MgmtSvcToken cmdlet을 사용하여 토큰 가져오기

  • 프로그래밍 방식으로 테넌트 인증서 사용

  • 자체 서명된 인증서를 신뢰할 수 있는 인증서로 바꾸기

  • 인증서 경고 해결

  • 여러 계정에서 관리 포털에 로그인

  • SSL/TLS 설정 검토

자격 증명 검사 목록

다음 검사 목록은 Windows Azure 팩 및 사용하는 제품 및 공급자에 대한 인증서, 사용자 이름 및 암호를 구성하는 모범 사례를 제공합니다.

  • 관리자용 관리 포털 또는 관리 API와 같은 인터넷 연결이 아닌 구성 요소를 테스트하거나 테스트하는 경우 Microsoft 인증 기관을 사용하여 자체 서명된 인증서를 만들 수 있습니다.

  • 테넌트용 관리 포털 및 테넌트 공용 API와 같은 인터넷 연결 구성 요소의 경우 신뢰할 수 있는 공용 인증 기관을 사용합니다.

  • 도메인 사용자 자격 증명 계정을 사용하도록 Service Provider Foundation을 실행하는 서버에서 IIS(인터넷 정보 서비스)의 서비스 공급자 파운데이션에 대한 애플리케이션 풀 ID를 구성합니다. Network Services를 사용하지 않는 것이 좋습니다.

  • System Center 2012 R2 Virtual Machine Manager 및 Service Provider Foundation을 실행하는 서버에서 애플리케이션 풀 ID를 구성하여 서비스 권한으로 로그온 된 동일한 도메인 계정을 사용합니다.

  • IIS에서 기본 인증을 사용하도록 Service Provider Foundation을 구성합니다.

  • Service Provider Foundation을 실행하는 서버에서 VMM, 관리, 공급자 및 사용 그룹의 구성원이 되도록 관리 권한이 있는 로컬 사용자 계정을 구성합니다. 이 로컬 사용자 계정을 사용하여 Windows Server용 Windows Azure 팩에 Service Provider Foundation 엔드포인트를 등록합니다.

자세한 내용은 블로그 게시물 Windows Azure 팩 문제 해결, Service Provider Foundation & Virtual Machine Manager를 참조하세요. Service Provider Foundation 웹 서비스에 대한 개요는 Service Provider Foundation에서 웹 서비스 및 Connections 관리를 참조하세요. Windows Azure 팩 인증 개요도 참조하세요.

AD FS를 통합한 후에는 테넌트 포털에 액세스할 수 없습니다.

관련 사항: Windows Azure Pack에 대한 Active Directory Federation Services 구성

문제점

AD FS(Active Directory Federation Services)를 구성한 후에는 테넌트 로그온 화면이 표시되지 않거나 테넌트용 관리 포털에 액세스할 수 없습니다.

권장

Windows Azure Pack이 설치된 도메인에 AD FS를 통합하면 로그인 페이지가 포털로 직접 이동하지 않습니다. 이는 예상되는 브라우저 동작입니다.

테넌트의 관리 포털에 액세스할 수 없는 경우 서버 관리자 사용하여 ADSI 편집을 실행하고 AD SF 서버에 SPN(서비스 사용자 이름)이 나열되어 있는지 확인합니다. SPN은 http/myADFSServer 형식이어야 합니다.

맨 위로 이동

AD FS를 통합한 후 AD를 사용하도록 관리 포털을 다시 설정합니다.

관련 사항: Windows Azure Pack에 대한 Active Directory Federation Services 구성

문제점

AD FS(Active Directory Federation Services)를 통합한 후 관리 포털에 AD(Active Directory) 사용으로 돌아가려고 합니다.

권장

AD FS와 마찬가지로 관리자용 관리 포털과 Windows 인증 사이트 간에 트러스트를 다시 설정해야 합니다. Windows 인증 사이트는 포트 30072입니다. Windows PowerShell cmdlet Set-MgmtSvcRelyingPartySettignsSet-MgmtSvcIdentityProviderSettings를 사용할 수 있습니다.

Get-MgmtSvcToken cmdlet을 사용하여 토큰 가져오기

관련 사항: windows Server Automation용 Windows Azure 팩과 Windows PowerShell

문제점

Get-MgmtSvcToken 토큰을 예상대로 반환하지 않습니다.

권장

이 문제는 Get-MgmtSvcToken cmdlet이 AD FS(Active Directory Federation Services)를 올바르게 사용하지 않는 문제일 수 있습니다. 다음 스크립트는 Get-AdfsToken 함수를 해결 방법으로 정의합니다.

function Get-AdfsToken([string]$adfsAddress, [PSCredential]$credential)
{
    $clientRealm = 'http://azureservices/AdminSite'
    $allowSelfSignCertificates = $true

    Add-Type -AssemblyName 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
    Add-Type -AssemblyName 'System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

    $identityProviderEndpoint = New-Object -TypeName System.ServiceModel.EndpointAddress -ArgumentList ($adfsAddress + '/adfs/services/trust/13/usernamemixed')
    $identityProviderBinding = New-Object -TypeName System.ServiceModel.WS2007HttpBinding -ArgumentList ([System.ServiceModel.SecurityMode]::TransportWithMessageCredential)
    $identityProviderBinding.Security.Message.EstablishSecurityContext = $false
    $identityProviderBinding.Security.Message.ClientCredentialType = 'UserName'
    $identityProviderBinding.Security.Transport.ClientCredentialType = 'None'

    $trustChannelFactory = New-Object -TypeName System.ServiceModel.Security.WSTrustChannelFactory -ArgumentList $identityProviderBinding, $identityProviderEndpoint
    $trustChannelFactory.TrustVersion = [System.ServiceModel.Security.TrustVersion]::WSTrust13

    if ($allowSelfSignCertificates)
    {
        $certificateAuthentication = New-Object -TypeName System.ServiceModel.Security.X509ServiceCertificateAuthentication
        $certificateAuthentication.CertificateValidationMode = 'None'
        $trustChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = $certificateAuthentication
    }

    $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($credential.Password)
    $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
    [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($ptr)

    $trustChannelFactory.Credentials.SupportInteractive = $false
    $trustChannelFactory.Credentials.UserName.UserName = $credential.UserName
    $trustChannelFactory.Credentials.UserName.Password = $password #$credential.Password

    $rst = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.RequestSecurityToken -ArgumentList ([System.IdentityModel.Protocols.WSTrust.RequestTypes]::Issue)
    $rst.AppliesTo = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.EndpointReference -ArgumentList $clientRealm
    $rst.TokenType = 'urn:ietf:params:oauth:token-type:jwt'
    $rst.KeyType = [System.IdentityModel.Protocols.WSTrust.KeyTypes]::Bearer

    $rstr = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse

    $channel = $trustChannelFactory.CreateChannel()
    $token = $channel.Issue($rst, [ref] $rstr)

    $tokenString = ([System.IdentityModel.Tokens.GenericXmlSecurityToken]$token).TokenXml.InnerText;
    $result = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($tokenString))
    return $result
}

# Fill in values
$adfsAddress = 'https://adfshost'
$username = 'domain\username'
$password = 'password'
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$securePassword

$token = Get-AdfsToken -adfsAddress $adfsAddress -credential $credential 
$token

맨 위로 이동

프로그래밍 방식으로 테넌트 인증서 사용

관련 사항: Service Provider Foundation 개발자 가이드

문제점

인증서를 만들고 테넌트용 관리 포털에 업로드한 다음 프로그래밍 방식으로 사용할 수 있어야 합니다.

권장

이렇게 하려면 다음 절차를 수행합니다.

  1. 인증서를 만듭니다(자체 서명될 수 있음). .cer 파일 확장명이 있어야 합니다.

  2. 테넌트용 관리 포털의 내 계정 페이지에서 관리 인증서를 클릭합니다.

  3. 다음 예제와 같이 인증을 위해 요청 헤더의 인증서를 테넌트 공용 API에 전달합니다.

    참고

    이 인증서가 할당된 구독에만 액세스할 수 있습니다. 테넌트 공용 API를 통해 구독을 삭제할 수 없습니다.

    X509Certificate2 mycert3 = new X509Certificate2("C:\\WorkDocs\\Test\\Management Certs\\myCert.cer");
    HttpClient httpClient = new HttpClient();
    var handler = new WebRequestHandler();
    handler.ClientCertificates.Add(mycert3);
    handler.PreAuthenticate = true;
    httpClient = new HttpClient(handler);
    
    string tenantPublicEndpoint = "https://test.fabrikam.com:30006/";
    string subscriptionid = " 7d31eb89-bb1e-4b16-aa3c-993f978b6bc1";
    
    string subscriptionEndpoint = tenantPublicEndpoint + subscriptionid+ "/services/webspaces/defaultwebspace/sites";
    var response = httpClient.GetAsync(subscriptionEndpoint);
    var resultsStr = response.Result.Content.ReadAsStringAsync().Result;
    

맨 위로 이동

자체 서명된 인증서를 신뢰할 수 있는 인증서로 바꾸기

관련 사항: Windows Server용 Windows Azure 팩 관리

문제점

테스트 환경에 자체 서명된 인증서를 사용한 후에는 인증서를 신뢰할 수 있는 기관에서 발급된 인증서로 바꾸려고 합니다.

권장

로컬 컴퓨터의 개인 저장소에 인증서를 설치하고 IIS(인터넷 정보 서비스) 관리자의 각 웹 사이트에 인증서를 매핑합니다. 인증서는 다음 요구 사항을 충족해야 합니다.

  • 신뢰할 수 있는 인증 기관에서 온 경우

  • 유효한 날짜 범위가 있습니다.

  • 유효한 사용법 및 용도 설명 제공

  • 서버 인증 제공

  • 인증서의 도메인 이름을 웹 사이트의 이름과 일치

  • RSA-1024비트 암호화 이상

  • 프라이빗 키 포함

맨 위로 이동

인증서 경고 해결

관련 사항: Windows Server용 Windows Azure 팩 배포

문제점

인증서 경고는 신뢰할 수 있는 기관의 인증서와 함께 유지됩니다.

권장

일부 브라우저는 인증서 유효성 검사 중에 인증서에 있는 기관 정보 액세스 필드를 처리하지 않습니다. 해결 방법은 인증서 저장소에 중간 인증서를 명시적으로 설치하는 것입니다. 이 필드를 지원하는 인증 기관 목록은 Windows 및 Windows Phone 8 SSL 루트 인증서 프로그램(멤버 CA)을 참조하세요.

맨 위로 이동

SSL/TLS 설정 검토

관련 사항: Windows Server용 Windows Azure 팩 배포

문제점

통신 보안이 약하면 시스템 이벤트 로그에 Schannel 오류가 발생할 수 있습니다.

권장

Windows Azure 팩 통신 채널의 보안을 향상하려면 SSL/TLS 설정을 업데이트하는 것이 좋습니다. 이러한 변경 내용을 구현하기 전에 다른 애플리케이션 또는 서비스에 영향을 주지 않도록 해야 합니다.

Windows Azure Pack을 실행하는 각 컴퓨터에서 다음 스크립트를 실행하여 이러한 변경 작업을 수행할 수 있습니다.

# PowerShell script to secure TLS/SSL settings.
# Copyright (c) Microsoft Corporation. All rights reserved.
# 20-Jun-2015 Update-ComputerSchannelSettings.ps1

<#
.Synopsis
   Apply HTTP.SYS settings
.NOTES
   Reference: Http.sys registry settings for Windows
   https://support.microsoft.com/en-us/kb/820129
#>
function Set-HttpSysSettings()
{
    Write-Verbose -Message "$($Myinvocation.MyCommand.Name)" -Verbose

    $regPath = "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters"

    # Read original values.
    $maxFieldLength = (Get-ItemProperty -Path $regPath -Name MaxFieldLength -ErrorAction SilentlyContinue).MaxFieldLength
    $maxRequestBytes = (Get-ItemProperty -Path $regPath -Name MaxRequestBytes -ErrorAction SilentlyContinue).MaxRequestBytes
    Write-Verbose -Message "HTTP.SYS settings:`r`n  MaxFieldLength = $maxFieldLength`r`n  MaxRequestBytes = $maxRequestBytes" -Verbose

    # Is update needed?
    if ($maxFieldLength -ne 32KB -or $maxRequestBytes -ne 32KB)
    {
        # Write updated values.
        Set-ItemProperty -Path $regPath -Name MaxFieldLength -Value 32KB
        Set-ItemProperty -Path $regPath -Name MaxRequestBytes -Value 32KB

        # Read updated values.
        $maxFieldLength = (Get-ItemProperty -Path $regPath -Name MaxFieldLength).MaxFieldLength
        $maxRequestBytes = (Get-ItemProperty -Path $regPath -Name MaxRequestBytes).MaxRequestBytes
        Write-Verbose -Message "HTTP.SYS settings (updated):`r`n  MaxFieldLength = $maxFieldLength`r`n  MaxRequestBytes = $maxRequestBytes" -Verbose

        # Changes that are made to the registry will not take effect until you restart the HTTP service.
        Write-Warning -Message "HTTP.SYS settings updated; restarting the HTTP service."
        Restart-Service -Name "http" -Force -Verbose
    }

    return $false # No reboot needed.
}

<#
.Synopsis
   Apply SSL configuration settings (TLS Cipher Suite Ordering)
.NOTES
   Reference: Prioritizing Schannel Cipher Suites
   https://msdn.microsoft.com/en-us/library/windows/desktop/bb870930(v=vs.85).aspx
#>
function Set-SchannelCipherOrder()
{
    Write-Verbose -Message "$($Myinvocation.MyCommand.Name)" -Verbose
    $reboot = $false

    $regPath = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"

    # The ordered suites names need to be specified as a single string (REG_SZ)
    # with each suite separated by commas and with no embedded spaces.
    # The list of cipher suites is limited to 1023 characters.
    $cipherOrder = @(
        'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384'
        'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256'
        'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384'
        'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256'
        'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384'
        'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256'
        'TLS_RSA_WITH_AES_256_GCM_SHA384'
        'TLS_RSA_WITH_AES_128_GCM_SHA256'
        'TLS_RSA_WITH_AES_256_CBC_SHA256'
        'TLS_RSA_WITH_AES_128_CBC_SHA256'
        'TLS_RSA_WITH_AES_256_CBC_SHA'
        'TLS_RSA_WITH_AES_128_CBC_SHA'
    )
    $cipherOrderList = ($cipherOrder -join ',')

    # Read original values.
    $functions = (Get-ItemProperty -Path $regPath -Name Functions -ErrorAction SilentlyContinue).Functions
    Write-Verbose -Message "Schannel Cipher Order:`r`n  Functions = $($functions -split ',' | ConvertTo-Json)" -Verbose

    # Is update needed?
    if ($functions -ne ($cipherOrder -join ','))
    {
        # Write updated values.
        Set-ItemProperty -Path $regPath -Name Functions -Value $cipherOrderList -Force

        # Read updated values.
        $functions = (Get-ItemProperty -Path $regPath -Name Functions -ErrorAction SilentlyContinue).Functions
        Write-Verbose -Message "Schannel Cipher Order (updated):`r`n  Functions = $($functions -split ',' | ConvertTo-Json)" -Verbose

        # It is necessary to restart the computer after modifying this setting for the changes to take effect.
        Write-Warning -Message "Schannel Cipher Order updated; it is necessary to restart the computer."
        $reboot = $true ### TODO: Restart-Computer -Force -Verbose
    }

    return $reboot
}
<#
.Synopsis
   Apply TLS Protocol version configuration
.NOTES
   Reference: How to Disable SSL 3.0 in Azure Websites, Roles, and Virtual Machines
   https://azure.microsoft.com/blog/2014/10/19/how-to-disable-ssl-3-0-in-azure-websites-roles-and-virtual-machines/
#>
function Set-SchannelProtocols()
{
    Write-Verbose -Message "$($Myinvocation.MyCommand.Name)" -Verbose
    $reboot = $false

    $regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"
    $protocolSettings = @(
        [PSCustomObject]@{ Path = "$regPath\SSL 2.0\Client"; Name = "Enabled"; Value = 0 }
        [PSCustomObject]@{ Path = "$regPath\SSL 2.0\Server"; Name = "Enabled"; Value = 0 }
        [PSCustomObject]@{ Path = "$regPath\SSL 3.0\Client"; Name = "Enabled"; Value = 0 }
        [PSCustomObject]@{ Path = "$regPath\SSL 3.0\Server"; Name = "Enabled"; Value = 0 }
        [PSCustomObject]@{ Path = "$regPath\TLS 1.0\Client"; Name = "Enabled"; Value = 1 }
        [PSCustomObject]@{ Path = "$regPath\TLS 1.0\Server"; Name = "Enabled"; Value = 1 }
        [PSCustomObject]@{ Path = "$regPath\TLS 1.1\Client"; Name = "Enabled"; Value = 1 }
        [PSCustomObject]@{ Path = "$regPath\TLS 1.1\Server"; Name = "Enabled"; Value = 1 }
        [PSCustomObject]@{ Path = "$regPath\TLS 1.2\Client"; Name = "Enabled"; Value = 1 }
        [PSCustomObject]@{ Path = "$regPath\TLS 1.2\Server"; Name = "Enabled"; Value = 1 }
    )

    # Read original values.
    $currentProtocolSettings = @()
    foreach ($protocolSetting in $protocolSettings)
    {
        $value = (Get-ItemProperty -Path $protocolSetting.Path -Name $protocolSetting.Name -ErrorAction SilentlyContinue).$($protocolSetting.Name)
        $currentProtocolSettings += [PSCustomObject]@{ Path = $protocolSetting.Path; Name = $protocolSetting.Name; Value = $value }
    }
    Write-Verbose -Message "Schannel Protocol Settings: $($currentProtocolSettings | Format-Table -Autosize | Out-String)" -Verbose

    $observed = $currentProtocolSettings | ConvertTo-Json -Compress
    $expected = $protocolSettings | ConvertTo-Json -Compress

    # Is update needed?
    if ($observed -ne $expected)
    {
        # Create registry nodes.
        $protocolPaths = @(
            "$regPath\SSL 2.0"
            "$regPath\SSL 2.0\Client"
            "$regPath\SSL 2.0\Server"
            "$regPath\SSL 3.0"
            "$regPath\SSL 3.0\Client"
            "$regPath\SSL 3.0\Server"
            "$regPath\TLS 1.0"
            "$regPath\TLS 1.0\Client"
            "$regPath\TLS 1.0\Server"
            "$regPath\TLS 1.1"
            "$regPath\TLS 1.1\Client"
            "$regPath\TLS 1.1\Server"
            "$regPath\TLS 1.2"
            "$regPath\TLS 1.2\Client"
            "$regPath\TLS 1.2\Server"
        )
        foreach ($protocolPath in $protocolPaths)
        {
            if (-not (Get-Item -Path $protocolPath -ErrorAction SilentlyContinue))
            {
                New-Item -Path $protocolPath -ItemType Container -Force | Out-Null
            }
        }

        # Write updated values.
        foreach ($protocolSetting in $protocolSettings)
        {
            Set-ItemProperty -Path $protocolSetting.Path -Name $protocolSetting.Name -Value $protocolSetting.Value -Force
        }

        # Read updated values.
        $currentProtocolSettings = @()
        foreach ($protocolSetting in $protocolSettings)
        {
            $value = (Get-ItemProperty -Path $protocolSetting.Path -Name $protocolSetting.Name -ErrorAction SilentlyContinue).$($protocolSetting.Name)
            $currentProtocolSettings += [PSCustomObject]@{ Path = $protocolSetting.Path; Name = $protocolSetting.Name; Value = $value }
        }
        Write-Verbose -Message "Schannel Protocol Settings (updated): $($currentProtocolSettings | Format-Table -Autosize | Out-String)" -Verbose

        # It is necessary to restart the computer after modifying this setting for the changes to take effect.
        Write-Warning -Message "Schannel Protocols updated; it is necessary to restart the computer."
        $reboot = $true ### TODO: Restart-Computer -Force -Verbose
    }

    return $reboot
}

#-------------------------------------------------------------------------------
# Main

$reboot = $false
$reboot += Set-HttpSysSettings
$reboot += Set-SchannelCipherOrder
$reboot += Set-SchannelProtocols
if ($reboot)
{
    Write-Warning -Message "Restart the computer for settings to take effect."
    # TODO: Restart-Computer -Force -Verbose
}

SSL/TLS 유효성 검사 도구를 실행하여 개선을 위한 다른 영역을 식별할 수도 있습니다.

맨 위로 이동

여러 계정에서 관리 포털에 로그인

관련: Windows PowerShell 사용하는 Windows Server Automation용 Windows Azure 팩

문제점

여러 계정에서 관리 포털에 로그인할 수 있어야 합니다.

권장

Add-MgmtSvcAdminUser Windows PowerShell cmdlet을 사용하여 보안 주체를 추가합니다. 이러한 보안 주체는 명시적 사용자 또는 보안 그룹일 수 있습니다(토큰에 보안 그룹 정보가 포함된 경우). 다음 예제에서는 사용자를 추가합니다. (암호가 $pwd 변수에 대해 정의되었다고 가정합니다.)

Add-MgmtSvcAdminUser -Server 'mysqlserver' -UserName 'sa' -Password $pwd -Principal 'user7@contoso.com'

맨 위로 이동

참고 항목

Windows Azure 팩 문제 해결