IIS 8.5에서 SAN SSL 인증서를 신속하게 교체

IIS 8.5에서 SAN SSL 인증서를 신속하게 교체

이 특정 쿼리에 대한 해결책을 찾기 위해 검색했지만 나와 동일한 상황을 찾을 수 없습니다.

IIS 8.5에 여러 도메인이 있고 SNI를 사용하여 각 도메인에 바인딩된 SAN SSL 인증서(와일드카드 아님)가 있다고 가정해 보겠습니다.

a.domain.com
b.domain.com
c.domain.com

새 도메인을 포함하는 새 SAN을 추가하고 생성하려는 경우 d.domain.com새 인증서를 위의 3개 도메인에 다시 바인딩하지 않고도 현재 인증서를 교체할 수 있기를 원합니다. 그런 다음 새 4번째 도메인을 수동으로 바인딩할 수 있습니다. ).

이제 위의 예에서 실제로 20개의 도메인이 있다고 상상해 보십시오. 이를 수행하는 데는 상당히 시간이 많이 걸립니다. 특히 매 2주마다 새 사이트를 추가하는 경우 SSL 사이트를 다시 바인딩하는 동안의 가동 중지 시간은 말할 것도 없습니다. 대지.

이 프로세스를 자동화하기 위해 적용할 수 있는 솔루션이 있습니까? 새 인증서의 해시가 있으면 이를 수행하는 PS 스크립트를 상상할 수 있지만 내 PS-fu는 모든 사이트를 반복하고 인증서를 다시 적용하는 방법을 알아낼 만큼 강력하지 않습니다. ). 이상적으로는 새 인증서(.pfx)를 자동으로 가져오고, 이전 인증서를 제거하고, 사이트를 다시 바인딩하는 솔루션이 될 것입니다.

편집하다:확인하기 위해 모든 사이트에 하나의 IP 주소를 사용하고 있습니다.

답변1

다음 함수를 복사하여 PowerShell 창에 붙여넣습니다.

function Get-IisSslBinding{
    [CmdletBinding()]
    Param(
        [Parameter(Position=0)] [Alias("fi","sn")]
        [string]$FilterBySiteName,
        [Parameter(Position=1, ValueFromPipelineByPropertyName=$true)] [Alias("co")] [ValidateNotnullOrEmpty()]
        [string[]]$ComputerName=$env:ComputerName
    )
    Begin{
        Write-Verbose ("$(Get-Date) - INFO - Load Microsoft.Web.Administration assembly...")
        $null=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
    }
    Process{
        Foreach($computer in $ComputerName){
            Try{
                If($computer -eq "$env:ComputerName"){
                    Write-Verbose ("$(Get-Date) - INFO - Open connection to local computer [ {0} ]..." -f $computer)
                    $webServer=New-Object Microsoft.Web.Administration.ServerManager
                    $null=$webServer
                }
                Else{
                    Write-Verbose ("$(Get-Date) - INFO - Open connection to remote computer [ {0} ]..." -f $computer)
                    $webServer=[Microsoft.Web.Administration.ServerManager]::OpenRemote($computer)
                }
                # filter sites
                $sites=($webServer.Sites | Where{$_.Name -match $FilterBySiteName})
                Foreach($site in $sites){
                    Write-Verbose ("$(Get-Date) - INFO - Get binding(s) for [ {0} ]..." -f $site.Name)
                    # filter bindings
                    $siteHttpsBindings=($site.Bindings | Where{$_.Protocol -eq "https"})
                    Foreach($siteHttpsBinding in $siteHttpsBindings){
                        Write-Verbose ("$(Get-Date) - INFO - Get binding information ...")
                        New-Object -Type PSObject -Property @{
                            'ComputerName'=$computer.ToUpper()
                            'SiteId'=$site.ID 
                            'SiteName'=$site.Name
                            'BindingInformation'=$siteHttpsBinding.GetAttributeValue("bindinginformation")
                            'Thumbprint'=$siteHttpsBinding.GetAttributeValue("certificateHash")
                            'CertificateStore'=$siteHttpsBinding.GetAttributeValue("certificateStoreName")
                            'Protocol'=$siteHttpsBinding.GetAttributeValue("protocol")
                        }
                    }
                }
            }
            Catch{
                Write-Verbose ("$(Get-Date) - ERROR - {0}" -f $_.Exception.GetBaseException().Message)
            }
            Finally{
                Write-Verbose ("$(Get-Date) - INFO - Dispose web server resources...")
                $webServer.Dispose()
            }
        }
    }
    End{
        Write-Verbose ("$(Get-Date) - INFO - Done")
    }
}
##
function Set-IisSslBinding{
    [CmdletBinding()]
    Param(
        [Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true)] [Alias("oh")] [ValidateNotnullOrEmpty()]
        [string]$Thumbprint,
        [Parameter(Position=1, Mandatory=$true)] [Alias("nh")] [ValidateNotnullOrEmpty()]
        [string]$AfterThumbprint,
        [Parameter(Position=2, Mandatory=$false, ValueFromPipelineByPropertyName=$true)] [Alias("sn")] [ValidateNotnullOrEmpty()]
        $SiteName,
        [Parameter(Position=3, Mandatory=$false, ValueFromPipelineByPropertyName=$true)] [Alias("co")] [ValidateNotnullOrEmpty()]
        [string[]]$ComputerName=$env:ComputerName
    )
    Begin{
        Write-Verbose ("$(Get-Date) - INFO - Load Microsoft.Web.Administration assembly...")
        $null=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
    }
    Process{
        Foreach($computer in $ComputerName){
            Try{
                If($computer -eq "$env:ComputerName"){
                    Write-Verbose ("$(Get-Date) - INFO - Open connection to local computer [ {0} ]..." -f $computer)
                    $webServer=New-Object Microsoft.Web.Administration.ServerManager
                    $IsCertificateInStore=((Get-ChildItem -Path CERT:\LocalMachine\My) -match $AfterThumbprint)
                }
                Else{
                    Write-Verbose ("$(Get-Date) - INFO - Open connection to remote computer [ {0} ]..." -f $computer)
                    $webServer=[Microsoft.Web.Administration.ServerManager]::OpenRemote($computer)
                }
                # If(-not $IsCertificateInStore){
                    # Write-Verbose ("$(Get-Date) - INFO - The computer [ {0} ] does not contain the certificate [ {1} ]... " -f $computer,$AfterThumbprint)
                    # Break
                # }
                Write-Verbose ("$(Get-Date) - INFO - Filter sites...")
                $sites=($webServer.Sites|where{$_.Name -match $SiteName})
                Foreach($site in $sites){
                    #filter bindings
                    $siteHttpsBindings=($site.Bindings|where{$_.Protocol -eq "https"})
                    Foreach($siteHttpsBinding in $siteHttpsBindings){
                        Switch($siteHttpsBinding.GetAttributeValue("certificateHash")){
                            $Thumbprint{
                                Write-Verbose ("$(Get-Date) - INFO - Remove old certificate [ {0} ]... " -f $siteHttpsBinding.GetAttributeValue("certificateHash"))
                                $BindingMethod=$siteHttpsBinding.Methods["RemoveSslCertificate"]
                                $BindingMethodInstance=$BindingMethod.CreateInstance()
                                $BindingMethodInstance.Execute()
                                Write-Verbose ("$(Get-Date) - INFO - Add new certificate [ {0} ]..." -f $AfterThumbprint)
                                $BindingMethod=$siteHttpsBinding.Methods["AddSslCertificate"]
                                $BindingMethodInstance=$BindingMethod.CreateInstance()
                                $BindingMethodInstance.Input.SetAttributeValue("certificateHash", $AfterThumbprint)
                                $BindingMethodInstance.Input.SetAttributeValue("certificateStoreName", "My")
                                $BindingMethodInstance.Execute()
                                New-Object -Type PSObject -Property @{
                                    'ComputerName'=$computer.ToUpper()
                                    'SiteId'=$site.ID 
                                    'SiteName'=$site.Name
                                    'BindingInformation'=$siteHttpsBinding.GetAttributeValue("bindingInformation")
                                    'Thumbprint'=$siteHttpsBinding.GetAttributeValue("certificateHash")
                                    'PreviousThumbprint'=$Thumbprint
                                }
                            }
                            Default{
                                Write-Verbose ("$(Get-Date) - INFO - Could not get https binding(s) attribute for [ {0} ]" -f $site.Name)
                                break
                            }
                        }                
                    }
                }
            }
            Catch{
                Write-Verbose ("$(Get-Date) - ERROR - {0}" -f $_.Exception.GetBaseException().Message)
            }
            Finally{
                Write-Verbose ("$(Get-Date) - INFO - Dispose web server resources...")
                $webServer.Dispose()
            }
        }
    }
    End{
        Write-Verbose ("$(Get-Date) - INFO - Done.")
    }
}

그런 다음 다음을 실행합니다.

  1. 모든 사이트와 해당 바인딩을 나열하려면 다음을 수행하세요.

Get-IisSslBinding

  1. 모든 사이트와 해당 SSL 바인딩을 업데이트하려면 다음 안내를 따르세요.

Get-IisSslBinding | Set-IisSslBinding -AfterThumbprint AAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCC

** 새 SSL 인증서가 이미 SSL 저장소에 있는지 확인하세요. 또한 Get-IisSslBinding매개 -FilterBySiteName변수 기능을 통해 터치해야 할 정확한 사이트를 타겟팅할 수 있습니다.

관련 정보