web-dev-qa-db-ja.com

Windowsで保護されたIIS 7.5サーバー上のディレクトリにログインできないのはなぜですか?

統合Windows認証によって保護されているadminサブディレクトリを含むWebサイトがあります。リモートPCから問題なく動作します。しかし、サーバー自体でこれらのページにアクセスしようとすると、認証エラーが発生します。 localhostではなく、適切なホスト名を使用しています。試してみましたChromeおよびIE、同じ結果。

助言がありますか?

9
user21146

IIS 5.1。で導入されたWindowsループバックチェックが実行されています。これは、システムに対する特定の種類のリフレクション攻撃を回避するためのセキュリティ機能です。

Microsoftには、回避策を説明する KB記事 があります。基本的には、ループバックチェックを無効にするか、特定のホスト名(ローカルホスト名やサイト名など)がバック接続できるようにレジストリを変更します。

PowerShell経由でチェックを無効にできます:

New-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa -Name "DisableLoopbackCheck" -Value "1" -PropertyType dword

以下はマイクロソフトの公式指示です。以下の手順は再起動を示していますが、IEは通常、すぐに変更を反映することに気づきました。

方法1:ホスト名を指定する(NTLM認証が必要な場合に推奨される方法)

  1. DisableStrictNameCheckingレジストリエントリを1に設定
  2. Startをクリックし、Runをクリックし、regeditと入力して、[〜#〜] ok [〜#〜]
  3. レジストリエディターで、次のレジストリキーを見つけてクリックします。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
  4. MSV1_0を右クリックし、Newをポイントして、Multi-String Value
  5. BackConnectionHostNamesと入力し、ENTERを押します。
  6. BackConnectionHostNamesを右クリックし、Modifyをクリックします。
  7. Value dataボックスに、ローカルコンピューター上にあるサイトのホスト名を入力し、[〜#〜をクリックします] ok [〜#〜]
  8. レジストリエディターを終了し、IISAdminサービスを再起動します。

方法2:ループバックチェックを無効にします(あまり推奨されない方法)

  1. DisableStrictNameCheckingレジストリエントリを1に設定
  2. Startをクリックし、Runをクリックし、regeditと入力して、[〜#〜] ok [〜#〜]
  3. レジストリエディターで、次のレジストリキーを見つけてクリックします。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
  4. Lsaを右クリックし、Newをポイントして、DWORD Valueをクリックします。
  5. DisableLoopbackCheckと入力し、ENTERを押します。
  6. DisableLoopbackCheckを右クリックし、Modifyをクリックします。
  7. Value dataボックスに、1と入力し、[〜#〜] ok [をクリックします〜#〜]
  8. レジストリエディターを終了して、コンピューターを再起動します。

補遺:

DisableStrictNameCheckingレジストリエントリを1に設定するには:

  1. Startをクリックし、Runをクリックし、regeditと入力して、[〜#〜] ok [〜#〜]
  2. レジストリエディターで、次のレジストリキーを見つけてクリックします。HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
  3. Parametersを右クリックし、Newをポイントして、DWORD Valueをクリックします。
  4. DisableStrictNameCheckingと入力し、ENTERを押します。
  5. DisableStrictNameCheckingを右クリックし、Modifyをクリックします。
  6. Value dataボックスに、1と入力し、[〜#〜] ok [をクリックします〜#〜]
  7. レジストリエディターを終了して、コンピューターを再起動します。
18
phoebus

次に、ループバックチェックの設定を管理するために記述したPowerShellコマンドレットを示します。これには、Windows認証を使用するすべてのIIS Webサイトのホスト名を取得しようとし、バック接続のホスト名を設定するコードが含まれています。

Import-Module WebAdministration

function Add-BackConnectionHostName
{
    <#
    .SYNOPSIS
    Adds the back connection hostnames that will bypass the server loopback check.
    .DESCRIPTION
    Adds the hostname to the list of back connection hostnames that will bypass the server loopback check. Back connection Host names  
    can be used to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861.
    .EXAMPLE
    Add-BackConnectionHostName mywebsite.mydomain.tld
    .EXAMPLE
    Add-BackConnectionHostName mywebsite1.mydomain.tld, mywebsite2.mydomain.tld
    .PARAMETER Hostname
    The Hostname to add to the back connection hostnames list.
    .LINK
    Remove-BackConnectionHostName
    Get-BackConnectionHostName
    Enable-ServerLoopbackCheck
    Disable-ServerLoopbackCheck
    Get-ServerLoopbackCheck
    "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.Microsoft.com/en-us/kb/896861)
    #>
    [CmdletBinding(SupportsShouldProcess = $true)]
    param
    (
        [Parameter(ValueFromPipeline = $true, Mandatory = $true)]
        [string] $Hostname
    )

    begin
    {
        $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0"
        $propertyName = "BackConnectionHostNames"
        $key = Get-Item $keyPath
        $property = $null
        $propertyValues = $null

        if ($key -ne $null)
        {
            $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue

            if ($property -eq $null)
            {
                $property = New-ItemProperty $keyPath -Name $propertyName -Value $null -PropertyType ([Microsoft.Win32.RegistryValueKind]::MultiString) -ErrorAction Stop

                Write-Verbose "Created the $($propertyName) property."
            }

            if ($property -ne $null)
            {
                $propertyValues = $property.$propertyName
            }
        }
    }

    process
    {
        if ($property -ne $null)
        {
            foreach ($hostNameValue in $Hostname)
            {
                if ([string]::IsNullOrWhiteSpace($hostName) -eq $false -and $propertyValues -notcontains $hostNameValue)
                {
                    $propertyValues += $hostNameValue

                    Write-Verbose "Added $($hostName) to the back connection hostnames."
                }
                else
                {
                    Write-Verbose "Back connection Host names already has an entry for $($hostName)."
                }
            }
        }
    }

    end
    {
        if ($propertyValues -ne $null)
        {
            $propertyValues = $propertyValues | ?{ [string]::IsNullOrWhiteSpace($_) -eq $false } | Sort -Unique
            Set-ItemProperty $keyPath -Name $propertyName -Value $propertyValues
        }
    }
}

function Remove-BackConnectionHostName
{
    <#
    .SYNOPSIS
    Removes the hostname from the list of back connection hostnames that will bypass the server loopback check.
    .DESCRIPTION
    Removes the hostname from the list of back connection hostnames that will bypass the server loopback check.
    .EXAMPLE
    Remove-BackConnectionHostName mywebsite.mydomain.tld
    .EXAMPLE
    Remove-BackConnectionHostName mywebsite1.mydomain.tld, mywebsite2.mydomain.tld
    .PARAMETER Hostname
    The Hostname to remove from the back connection hostnames list.
    .LINK
    Add-BackConnectionHostName
    Get-BackConnectionHostName
    Enable-ServerLoopbackCheck
    Disable-ServerLoopbackCheck
    Get-ServerLoopbackCheck
    "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.Microsoft.com/en-us/kb/896861)
    #>
    [CmdletBinding(SupportsShouldProcess = $true)]
    param
    (
        [Parameter(ValueFromPipeline = $true, Mandatory = $true)]
        [string] $Hostname
    )

    begin
    {
        $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0"
        $propertyName = "BackConnectionHostNames"
        $key = Get-Item $keyPath
        $property = $null
        $propertyValues = $null

        if ($key -ne $null)
        {
            $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue

            if ($property -ne $null)
            {
                $propertyValues = $property.$propertyName
            }
            else
            {
                Write-Verbose "The $($propertyName) property was not found."
            }
        }
    }

    process
    {
        if ($property -ne $null)
        {
            foreach ($hostNameValue in $Hostname)
            {
                if ($propertyValues -contains $hostNameValue)
                {
                    $propertyValues = $propertyValues | ? { $_ -ne $hostName }

                    Write-Verbose "Removed $($hostName) from the $($propertyName) property."
                }
                else
                {
                    Write-Verbose "No entry for $($hostName) was found in the $($propertyName) property."
                }
            }
        }
    }

    end
    {
        if ($property -ne $null)
        {
            $propertyValues = $propertyValues | ?{ [string]::IsNullOrWhiteSpace($_) -eq $false } | Sort -Unique

            if ($propertyValues.Length -ne 0)
            {
                Set-ItemProperty $keyPath -Name $propertyName -Value $propertyValues
            }
            else
            {
                Remove-ItemProperty $keyPath -Name $propertyName

                Write-Verbose "No entries remain after removing $($hostName). The $($propertyName) property was removed."
            }
        }
    }
}

function Get-BackConnectionHostName
{
    <#
    .SYNOPSIS
    Gets the list of back connection hostnames that will bypass the server loopback check.
    .DESCRIPTION
    Gets the back connection hostnames that will bypass the server loopback check. Back connection Host names can be used to address 
    the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861.
    .EXAMPLE
    Get-BackConnectionHostName
    .LINK
    Add-BackConnectionHostName
    Remove-BackConnectionHostName
    Enable-ServerLoopbackCheck
    Disable-ServerLoopbackCheck
    Get-ServerLoopbackCheck
    "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.Microsoft.com/en-us/kb/896861)
    #>
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
    )

    begin
    {
        $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0"
        $propertyName = "BackConnectionHostNames"
        $key = Get-Item $keyPath
        $property = $null

        if ($key -ne $null)
        {
            $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue

            if ($property -eq $null)
            {
                Write-Verbose "The $($propertyName) property was not found."
            }
        }
    }

    process
    {
        $propertyValues = $null

        if ($property -ne $null)
        {
            $propertyValues = $property.$propertyName
        }

        return $propertyValues
    }

    end
    {
    }
}

function Enable-ServerLoopbackCheck
{
    <#
    .SYNOPSIS
    Enables the server loopback check. Enabled is the normal state for a Windows Server.
    .DESCRIPTION
    Enables the server loopback check. Having the loopback check enabled is the normal state for a Windows Server. Disabling the loopback check can be used to address 
    the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. It is NOT the preferred method. See the KB article for more details.
    .EXAMPLE
    Enable-ServerLoopbackCheck
    .LINK
    Add-BackConnectionHostName
    Remove-BackConnectionHostName
    Get-BackConnectionHostName
    Enable-ServerLoopbackCheck
    Get-ServerLoopbackCheck
    "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.Microsoft.com/en-us/kb/896861)
    #>
    [CmdletBinding(SupportsShouldProcess = $true)]
    param
    (
    )

    begin
    {
        $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
        $propertyName = "DisableLoopbackCheck"
        $key = Get-Item $keyPath
        $property = $null

        if ($key -ne $null)
        {
            $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue

            if ($property -eq $null)
            {
                Write-Verbose "The $($propertyName) property was not found."
            }
        }
    }

    process
    {
        if ($property -ne $null)
        {
            Set-ItemProperty $keyPath -Name $propertyName -Value 0
        }
    }

    end
    {
    }
}

function Disable-ServerLoopbackCheck
{
    <#
    .SYNOPSIS
    Disables the server loopback check for all hostnames. Enabled is the normal state for a Windows Server.
    .DESCRIPTION
    Disables the server loopback check for all hostnames. Having the loopback check enabled is the normal state for a Windows Server. Disabling the loopback check can be used 
    to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. It is NOT the preferred method. See the KB article for more details.
    .EXAMPLE
    Disable-ServerLoopbackCheck
    .LINK
    Add-BackConnectionHostName
    Remove-BackConnectionHostName
    Get-BackConnectionHostName
    Enable-ServerLoopbackCheck
    Get-ServerLoopbackCheck
    "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.Microsoft.com/en-us/kb/896861)
    #>
    [CmdletBinding(SupportsShouldProcess = $true)]
    param
    (
    )

    begin
    {
        $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
        $propertyName = "DisableLoopbackCheck"
        $key = Get-Item $keyPath
        $property = $null

        if ($key -ne $null)
        {
            $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue

            if ($property -eq $null)
            {
                Write-Verbose "The $($propertyName) property was not found."
            }
        }
    }

    process
    {
        if ($property -ne $null)
        {
            Set-ItemProperty $keyPath -Name $propertyName -Value 1
        }
        else
        {
            $property = New-ItemProperty $keyPath -Name $propertyName -PropertyType ([Microsoft.Win32.RegistryValueKind]::DWord) -Value 1
        }
    }

    end
    {
    }
}

function Get-ServerLoopbackCheck
{
    <#
    .SYNOPSIS
    Gets the status of the server loopback check. Enabled is the normal state for a Windows Server.
    .DESCRIPTION
    Gets the status of the server loopback check. Having the loopback check enabled is the normal state for a Windows Server. Disabling the loopback check can be used 
    to address the problem with IIS sites using Windows Authentication that is described in Microsoft KB896861. It is NOT the preferred method. See the KB article for 
    more details.
    .EXAMPLE
    Get-ServerLoopbackCheck
    .LINK
    Add-BackConnectionHostName
    Remove-BackConnectionHostName
    Get-BackConnectionHostName
    Enable-ServerLoopbackCheck
    Disable-ServerLoopbackCheck
    "You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version" (http://support.Microsoft.com/en-us/kb/896861)
    #>
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
    )

    begin
    {
        $keyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
        $propertyName = "DisableLoopbackCheck"
        $key = Get-Item $keyPath
        $property = $null

        if ($key -ne $null)
        {
            $property = Get-ItemProperty $keyPath -Name $propertyName -ErrorAction SilentlyContinue
        }
    }

    process
    {
        $loopbackCheckStatus = "Enabled"

        if ($property -ne $null)
        {
            switch ($property)
            {
                0 { $loopbackCheckStatus = "Enabled" }
                1 { $loopbackCheckStatus = "Disabled" }
                default { $loopbackCheckStatus = "Unknown" }
            }
        }

        return $loopbackCheckStatus
    }

    end
    {
    }
}

function Get-WebsiteHostname
{
    <#
    .SYNOPSIS
    Gets the hostnames for the IP addresses bound to a web site.
    .DESCRIPTION
    Gets the hostnames for the IP addresses bound to a web site. Where a Host header exists, the Host header is used; otherwise, the IP address is looked up
    in DNS to see if a PTR record exists.
    .EXAMPLE
    Get-WebSiteHostname $webSite
    .EXAMPLE
    Get-WebSiteHostname -Name 'Default Web Site'
    .EXAMPLE
    Get-Website | Get-WebSiteHostname
    .LINK
    Get-Website 
    #>
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
        [string] $Name
    )

    process
    {
        $siteHostnames = @()

        foreach ($webSiteName in $Name)
        {
            $bindings = Get-WebBinding -Name $Name

            foreach ($binding in $bindings)
            {
                $bindingInfo = $binding.bindingInformation.Split(':')
                $hostHeader = $bindingInfo[2]
                $bindingInfoAddress = $null
                $isValidIP = [System.Net.IPAddress]::TryParse($bindingInfo[0], [ref] $bindingInfoAddress)
                $siteHostname = $null

                if ($bindingInfo -eq '*')
                {
                    Write-Warning "The $($webSiteName) web site has a binding address set to All Unassigned."
                }
                elseif ([string]::IsNullOrWhiteSpace($hostHeader) -eq $false)
                {
                    $siteHostname = $hostHeader
                    Write-Verbose "The $($webSiteName) web site has a Host header set to $($siteHostname)."
                }
                elseif ($isValidIP -eq $true)
                {
                    $siteHostname = (Resolve-DnsName $bindingInfoAddress -DnsOnly PTR -ErrorAction SilentlyContinue).NameHost

                    if ($siteHostname -ne $null)
                    {
                        Write-Verbose "The $($webSiteName) web site has an IP Address $($bindingInfoAddress) that resolves to $($siteHostname)."
                    }
                    else
                    {
                        Write-Warning "The $($webSiteName) web site has an IP Address $($bindingInfoAddress) with no PTR record."
                    }
                }
            }

            if ($siteHostname -ne $null)
            {
                $siteHostnames += $siteHostname
            }
        }

        return $siteHostnames | Sort -Unique
    }
}

# Use the IIS administration commandlets and the ones above to do the 
# following:
#   1. Get all the IIS web sites that use Windows authentication.
#   2. Get the hostnames from either the Host header setting or the
#      DNS reverse lookup of the hostnames from the IP address.
#   3. Add the hostnames to the BackConnectionHostNames registry key.
#   4. Display the contents of the BackConnectionHostNames registry key.

$windowsAuthenticatedWebSites = Get-Website | ?{ (Get-WebConfiguration -Filter '/system.web/authentication' -PSPath $_.PSPath).mode -eq 'Windows' }
$webSiteHostnames = $windowsAuthenticatedWebSites | Get-WebsiteHostname
$webSiteHostNames | Add-BackConnectionHostName

Get-BackConnectionHostName
1
JamieSee