사용자 지정 IIS 7.0 서버 빌드

작성자: 마이크 볼로다르스키

소개

IIS 6.0 및 이전 버전은 서버 자체 내에서 널리 사용되는 대부분의 서버 기능을 구현했습니다. 반면, IIS 7.0 이상 웹 서버 엔진은 사실상 모든 서버 기능이 플러그형 구성 요소로 제공되는 모듈식 아키텍처를 제공합니다. 이렇게 하면 다음을 포함하여 전반적으로 엄청난 개선이 가능합니다.

  • 서버에서 로드/사용되는 기능 집합을 정확하게 제어하여 서버의 공격 노출 영역/메모리 공간을 줄이기 위해 불필요한 기능을 제거하는 기능
  • 각 기능을 타사 또는 사용자 지정 구현으로 바꾸는 기능
  • 서버 토폴로지의 역할에 따라 서버를 특수화할 수 있는 기능
  • 세분화 및 애플리케이션 위임 가능 수준에서 서버의 기능 집합에 대한 고급 제어

모듈이라고 하는 이러한 서버 구성 요소는 애플리케이션 풀 작업자 프로세스를 초기화하는 동안 로드되고 서버에서 요청 처리 서비스를 제공합니다. 각 IIS 7.0 이상 애플리케이션은 애플리케이션에 대해 사용하도록 설정된 모듈에서 제공하는 서비스 및 이러한 서비스에서 사용되는 관련 콘텐츠의 조합입니다. 서버는 모듈에서 수행되는 두 가지 주요 역할을 제공합니다.

  • 인증 또는 출력 캐싱과 같은 요청 서비스 제공(IIS 6.0의 ISAPI 필터와 유사)
  • 정적 파일 처리, CGI 또는 ASP.NET 페이지 처리와 같은 요청 처리 제공(IIS 6.0의 ISAPI 확장과 유사)

다른 모듈을 사용하도록 설정하면 서버의 애플리케이션에 필요한 서비스를 제공하도록 서버를 구성할 수 있습니다.

이 문서에 설명된 작업은 다음과 같습니다.

  • 기본적으로 서버 구성, 기본값 및 서버에 로드된 모듈 집합 검토
  • 서버를 최소 구성으로 제거하는 모든 모듈을 제거하고 사용 공간의 영향을 검사합니다.
  • 특정 시나리오를 지원하기 위해 모듈을 증분 방식으로 추가하여 사용자 지정 서버 빌드

기본 모듈 구성 검토

기본 서버 구성은 IIS 구성 디렉터리에 있는 applicationHost.config 파일에 포함되어 있습니다%windir%\system32\inetsrv\config\. 섹션 그룹에 포함된 다음 구성을 <system.webServer> 살펴봅니다.

<globalModules> 섹션. 이 서버 수준 섹션에는 서버 작업자 프로세스에서 로드한 모듈 목록과 해당 기능을 구현하는 연결된 네이티브 DLL이 포함되어 있습니다.

<modules> 섹션. 이 애플리케이션 수준 섹션에는 특정 애플리케이션에 대해 사용하도록 설정된 모듈 목록이 포함되어 있습니다. 이 섹션에서는 애플리케이션에서 활성화해야 하는 로드된 모듈의 하위 집합을 선택하고 추가 애플리케이션 수준 모듈을 로드하는 역할을 합니다.

<handlers> 섹션. 이 URL 수준 섹션에는 서버가 들어오는 요청을 처리할 특정 모듈에 매핑하는 데 사용하는 처리기 매핑이 포함되어 있습니다. 이는 IIS 6.0 스크립트맵 또는 ASP.NET 유사하며 네이티브 및 관리되는 콘텐츠 형식 처리기 모두에 대한 요청의 통합 매핑을 제공합니다.

모든 IIS 모듈에 대한 전체 설명은 IIS 7.0 이상 모듈 개요에서 사용할 수 있습니다.

구성 백업 만들기

먼저 필요한 경우 복원할 수 있도록 서버 구성을 백업합니다. 관리istrator로 실행되는 명령 프롬프트에서 다음 명령을 실행합니다.

%windir%\system32\inetsrv\appcmd add backup initial

그런 다음, 다음을 실행하여 서버 구성을 초기 상태로 복원할 수 있습니다.

%windir%\system32\inetsrv\appcmd restore backup initial

모듈의 기본 목록 검사

<system.webServer>/<globalModules> 섹션으로 이동합니다. 서버 수준에서만 구성할 수 있는 이 섹션에는 각 서버 작업자 프로세스에서 로드한 모듈이 포함되어 있습니다. 각 항목은 특정 이름의 모듈과 해당 모듈의 기능을 구현하는 DLL을 구성합니다.

<globalModules>

    <!--several modules omitted -->

    <add name="BasicAuthenticationModule" image="…\authbas.dll" />

    <add name="WindowsAuthenticationModule" image="…\authsspi.dll" />

</globalModules>

기본 서버 구성에서 다양한 모듈의 이름을 살펴보세요. IIS 6.0에서 서버의 일부로 제공되는 친숙한 서비스가 표시됩니다.

Windows 인증 모듈, NTLM 요청 인증

<add name="WindowsAuthenticationModule" image="…\authsspi.dll" />

정적 파일 처리기 모듈, 정적 파일 제공

<add name="StaticFileModule" image="…\static.dll" />

동적 압축 모듈, 응답 압축

<add name="DynamicCompressionModule" image="…\compdyn.dll" />

<system.webServer>/<modules 섹션으로> 이동합니다. 서버 또는 애플리케이션 수준에서 구성할 수 있는 이 섹션에서는 특정 애플리케이션에 대해 globalModules> 섹션에 <로드된 모듈을 지정합니다. 대부분의 경우 이 섹션에는 섹션에서 본 모듈의 이름이 나열되어 모든 애플리케이션에 대해 기본적으로 사용하도록 설정됩니다.

참고 항목

목록 끝에는 몇 가지 추가 항목이 있습니다. 이러한 모듈은 ASP.NET 확장성 모델을 사용하여 개발된 관리되는 모듈입니다. .NET을 사용하여 모듈 개발 연습에서 관리 모드를 빌드하는 방법에 대해 자세히 알아봅니다.

<system.webServer>/<handlers 섹션으로> 이동합니다. 서버, 애플리케이션 또는 URL 수준에서 구성할 수 있는 이 섹션은 요청 처리 방법을 지정합니다. 모듈은 일반적으로 각 요청에 참여하는 반면 처리기는 특정 URL에 대한 요청만 가져옵니다.

모듈의 좋은 예는 압축 모듈입니다. 압축 모듈은 각 응답을 살펴보고 필요한 경우 압축합니다. ASP.NET 페이지 처리기는 처리기의 좋은 예입니다. 확장 .aspx 있는 요청과 같이 매핑된 요청만 수신합니다. 이 <handlers> 목록은 URL과 동사를 기반으로 하는 요청과 이 요청을 처리하는 데 사용할 처리 모듈 간의 매핑을 정의합니다. 이 항목의 포커스가 아닌 각 매핑을 구성하는 데 사용되는 몇 가지 추가 정보도 있습니다.

<handlers>
    <!-- certain details omitted -->
    <add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" ... />
    <add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" ... />
    <add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST"  modules="IsapiModule" ... />
</handlers>

서버 공간 검사

  1. Internet Explorer를 열고 다음 URL을 지정하고 Enter 키를 눌러 서버에 요청합니다.

    http://localhost/iisstart.htm
    

    그러면 서버 애플리케이션 풀이 시작되고 iisstart.htm 문서를 제공합니다.

  2. 작업 관리자를 시작하고 프로세스 탭으로 이동합니다. IIS 작업자 프로세스는 다른 사용자 계정으로 실행되므로 "모든 사용자에 대한 프로세스 표시"를 검사 합니다. w3wp.exe 서버 작업자 프로세스의 크기를 확인합니다.
    Windows 작업 관리자를 보여 주는 스크린샷 프로세스 탭이 선택되어 있습니다.
    그림 1: IIS 작업자 프로세스를 보여 주는 작업 관리자

  3. 이제 다음 명령줄을 실행합니다.

    TASKLIST /fi "imagename eq w3wp.exe" /m
    

    작업자 프로세스에 의해 90개 이상의 DLL이 로드되는 것을 볼 수 있습니다. 대부분은 ...\intersrv\ 디렉터리에 있습니다. 이들 중 상당수는 globalModules> 섹션을 볼 때 첫 번째 작업에서 <본 모듈 DLL과 .NET 프레임워크 및 서버 런타임 자체를 지원하는 몇 가지 모듈 DLL입니다.

서버 제거

이전 작업에서는 인증에서 정적 파일 서비스까지 다양한 서비스를 제공하는 35개가 넘는 모듈이 포함된 서버에서 로드한 구성 요소의 기본 목록을 검사했습니다. 서버에 로드된 각 구성 요소는 서버 공간, 공격 노출 영역, 런타임 성능 및 사용하도록 설정된 기능 집합에 영향을 줍니다.

다음 작업에 필요한 기능만 사용하여 사용자 지정 서버를 빌드하기 전에 모든 모듈을 제거하고 빈 서버를 실행하여 빠르고 작고 안전한 웹 서버를 빌드합니다.

이전 작업 중에 applicationHost.config 파일을 변경한 경우 명령줄에서 실행 %windir%\system32\inetsrv\appcmd restore backup initial 하여 원래 상태로 복원할 수 있습니다.

이제 서버를 제거합니다.

  1. 텍스트 편집기를 사용하여 을 엽니다 %windir%\system32\inetsrv\config\applicationHost.config.

  2. 섹션으로 <system.webServer>/<globalModules> 이동합니다.

  3. 컬렉션의 모든 항목을 제거하여 빈 섹션 정의만 다시 기본.

    <globalModules> 
        <!—Remove Everything --> 
    </globalModules>
    
  4. 나중에 사용할 수 있는 항목을 스크래치 메모장 창에 붙여넣습니다. system.webServer>/modules 섹션과 <동일하게 반복합니다><. 이 섹션의 모든 항목을 제거하고 나중에 사용할 수 있도록 스크래치 메모장에 붙여넣습니다. 이렇게 하면 더 이상 로드하지 않는 모듈이 활성화되지 않습니다. 이러한 잘라내기 항목을 나중에 사용할 수 있는 스크래치 메모장 창에 붙여넣습니다.

  5. 섹션과 동일하게 반복합니다 <system.webServer>/<handlers> . 사용하지 않도록 설정한 모듈을 사용하여 처리기 매핑을 지정하지 않도록 하려면 이 섹션의 모든 항목을 제거합니다. 나중에 사용할 수 있는 항목을 스크래치 메모장에 붙여넣습니다. applicationHost.config 파일을 저장하여 변경 내용을 적용합니다.

제거된 서버 공간 검사

이제 제거된 서버를 로드할 준비가 완료되었습니다. 이전 단계를 반복하여 서버의 새 공간을 검사합니다.

  1. Internet Explorer를 열고 다음 URL을 지정하고 Enter 키를 눌러 서버에 요청합니다.

    http://localhost/iisstart.htm
    

    그러면 서버 애플리케이션 풀이 시작되고, 요청한 리소스를 제공하기 위해 등록된 처리기가 없으므로 브라우저에 오류를 반환해야 합니다.

  2. 작업 관리자를 실행하고 프로세스 탭으로 이동합니다. w3wp.exe 서버 작업자 프로세스의 크기를 확인합니다.

  3. 다음 명령줄을 실행합니다.

    TASKLIST /fi "imagename eq w3wp.exe" /m
    

    서버의 공간이 약 8Mb로 감소했는지 확인합니다. 서버 기간에는 빈 서버의 공간이 더 줄어듭니다.

    90개 이상에 비해 50개의 DLL만 로드됩니다. 이는 서버가 DLL 개수 차이를 직간접적으로 고려한 모듈 DLL을 로드하지 않았음을 나타냅니다. 서버에서 서비스를 사용하지 않도록 설정할 뿐만 아니라 이러한 기능에 대한 코드도 프로세스에 로드되지 않습니다. 최적화 후에는 빈 서버의 DLL 수가 상당히 낮아질 것입니다.

다음 작업에서는 원하는 기능만 사용하여 사용자 지정 서버를 빌드합니다.

사용자 지정 서버 빌드

이전 작업에서는 코어 서버 엔진만 실행되고 추가 모듈이 로드되지 않은 상태에서 서버를 최소 구성으로 제거했습니다. 이제 회사 네트워크에서 웹 파일 서버로 사용할 사용자 지정 서버를 빌드합니다. 이렇게 하려면 서버에서 다음 서비스만 제공할 수 있습니다.

  • 정적 파일 제공
  • 디렉터리 목록 제공
  • 기본 인증 및 URL 기반 권한 부여 규칙을 사용하여 콘텐츠 보호

서버가 정적 파일을 제공하도록 설정

이 작업을 수행하기 위해 이전 작업을 수행하고 실행 중인 모든 모듈을 제거하여 서버를 제거했다고 가정합니다. 이 상태에서는 모든 종류의 요청 처리를 제공하기 위해 모듈이 로드되지 않으므로 서버는 항상 모든 요청에 대해 빈 401 오류 응답을 반환합니다.

  1. 텍스트 편집기를 사용하여 을 엽니다 %windir%\system32\inetsrv\config\applicationHost.config.

  2. <system.webServer>/<globalModules> 섹션으로 이동합니다. 컬렉션 내부에 굵게 굵게 2줄을 추가합니다. 기본 컬렉션 항목을 저장하기 위해 이전에 사용한 스크래치 패드에서 복사합니다. 그러면 정적 파일에 대한 요청을 제공하는 정적 파일 처리기 모듈과 요청에 대한 기본 인증 토큰을 생성하는 익명 인증 모듈이 로드됩니다.

    <globalModules>
        <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
        <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
    </globalModules>
    
  3. <system.webServer>/<modules 섹션으로> 이동합니다. 아래 굵게 표시된 줄을 추가하여 정적 파일 처리기 및 익명 인증 모드를 사용하도록 설정합니다.

    <modules>
    
        <add name="AnonymousAuthenticationModule" />
    
        <add name="StaticFileModule" />
    
    </modules>
    
  4. <system.webServer>/<handlers 섹션으로> 이동합니다. 아래 굵게 표시된 줄을 추가하여 정적 파일 처리기를 모든 파일 요청에 매핑합니다.

    <handlers>
        <add name="StaticFile" path="*" verb="GET,HEAD"  modules="StaticFileModule" resourceType="Either" requireAccess="Read"/>
    </handlers>
    
  5. applicationHost.config 파일을 저장합니다.

  6. Internet Explorer를 열고 다음 URL을 요청합니다.

    http://localhost/iisstart.htm
    

    요청된 문서를 제공합니다. 서버에서 정적 파일 서비스 기능을 사용하도록 설정했습니다.

  7. 다음으로, 다음 URL을 요청하여 디렉터리 목록을 요청합니다.

    http://localhost
    

    처리기가 현재 로드, 사용 및 프로세스 디렉터리 목록에 매핑되지 않으므로 빈 응답이 전송됩니다(200 OK). 다음 작업에서는 처리기를 추가합니다.

서버에서 디렉터리 목록을 제공하도록 설정

이 작업을 수행하기 위해 이전 작업을 수행하고 서버를 아무것도 제거하지 않은 다음 파일 서비스 기능을 추가했다고 가정합니다.

  1. 텍스트 편집기를 사용하여 을 엽니다 %windir%\system32\inetsrv\config\applicationHost.config.

  2. 이전과 마찬가지로 아래 구성을 추가하여 디렉터리 검색 모듈을 사용하도록 설정하고 디렉터리 요청을 제공하도록 매핑합니다(누적 구성은 이전 단계를 기반으로 빌드된 이 단계 이후 아래와 정확하게 표시됩니다.)

    <globalModules>
        <add name="AnonymousAuthenticationModule" image="%windir%\system32\inetsrv\authanon.dll" />
        <add name="StaticFileModule" image="%windir%\system32\inetsrv\static.dll" />
        <add name="DirectoryListingModule" image="%windir%\System32\inetsrv\dirlist.dll" />
    </globalModules>
    
    <modules>
        <add name="AnonymousAuthenticationModule" />
        <add name="StaticFileModule" />
        <add name="DirectoryListingModule" />
    </modules>
    
    <handlers>
        <add name="StaticFile" path="*" verb="GET,HEAD" modules="StaticFileModule,DirectoryListingModule"  resourceType="Either" requireAccess="Read" />
    </handlers>
    

    이 시점에서 서버에서 디렉터리 목록 기능을 사용하도록 설정했습니다. 그러나 이 기능은 디렉터리 목록이 허용되는지 여부를 제어하는 보안상의 이유로 추가 구성을 노출합니다. 이 구성은 system.webServer>/directoryBrowse> 섹션에 지정됩니다<<.

  3. 항목을 <directoryBrowse enabled="true"/로 변경합니다.>

  4. applicationHost.config 파일을 저장합니다.

  5. Internet Explorer를 열고 다음 URL을 요청하여 디렉터리에 요청을 반복합니다.

http://localhost

요청된 디렉터리의 목록을 제공합니다. 서버에서 디렉터리 목록 기능을 사용하도록 설정했습니다.

다음으로 인증 및 권한 부여 서비스를 추가하여 서버의 콘텐츠를 무단 액세스로부터 보호합니다.

URL 권한 부여를 사용하여 리소스 보호

이 작업을 수행하기 위해 이전 작업을 수행하고 서버를 아무것도 제거하지 않은 다음 파일 서비스 및 디렉터리 목록 기능을 추가했다고 가정합니다.

  1. 텍스트 편집기를 사용하여 을 엽니다 %windir%\system32\inetsrv\config\applicationHost.config.

  2. 이번에는 두 개의 모듈을 추가합니다.

    • 서버 Windows 자격 증명에 대해 http1.1을 통한 기본 인증 체계를 지원하는 기본 인증 모듈
    • 사용자 및 역할 규칙 기반 액세스 제어를 지원하는 URL 권한 부여 모듈
  3. 이러한 모듈을 추가하려면 system.webServer>/globalModules> 섹션에 <모듈 로드 항목을 추가한 다음, 앞서 정적 파일 처리기 및 디렉터리 브라우저에서 <했던 것처럼 system.webServer>/<modules> 섹션에서 모듈을 사용하도록< 설정합니다.

    참고 항목

    이번에는 system.webServer/handlers> 섹션에 <아무것도 추가할 필요가 없습니다. 이러한 모듈은 요청 처리를 제공하지 않으므로 모든 요청에만 요청 서비스를< 제공합니다.> 아래 항목을 굵게 추가한 후의 최종 구성은 다음과 같습니다.

    <globalModules>
        <add name="AnonymousAuthenticationModule" image="%windir%\system32\inetsrv\authanon.dll" /> 
        <add name="StaticFileModule" image="%windir%\system32\inetsrv\static.dll" /> 
        <add name="DirectoryListingModule" image="%windir%\system32\inetsrv\dirlist.dll" /> 
        <add name="UrlAuthorizationModule" image="%windir%\System32\inetsrv\urlauthz.dll" />      
        <add name="BasicAuthenticationModule" image="%windir%\System32\inetsrv\authbas.dll" /> 
    </globalModules> 
    
    <modules> 
        <add name="AnonymousAuthenticationModule" /> 
        <add name="StaticFileModule" /> 
        <add name="DirectoryListingModule" /> 
        <add name="BasicAuthenticationModule" /> 
        <add name="UrlAuthorizationModule" /> 
    </modules>
    

    추가된 기능을 사용하려면 해당 기능을 구성해야 합니다.

  4. 기본 인증 서비스를 사용하도록 설정합니다. basicAuthentication> 요소로 <이동하고 사용 가능한 특성을 true로 설정합니다.

    <basicAuthentication enabled="true" />
    
  5. 익명 인증을 사용하지 않도록 설정합니다. anonymousAuthentication> 요소로 <이동하고 사용 가능한 특성을 false로 설정합니다.

    <anonymousAuthentication enabled="false" userName="IUSR" />
    

    이렇게 하면 익명 인증이 비활성화되고 액세스 권한이 부여되기 전에 기본 인증 모듈이 사용자를 성공적으로 인증해야 합니다.

  6. applicationHost.config 파일을 저장합니다.

  7. Internet Explorer를 열고 다음 URL을 요청하여 디렉터리에 요청을 반복합니다.

    http://localhost
    

    그러면 디렉터리 목록이 요청됩니다. 브라우저에서 인증하지 않았기 때문에 URL 권한 부여 모듈은 요청을 거부합니다. 기본 인증 모듈은 거부를 가로채고 기본 인증 챌린지를 브라우저로 다시 트리거하여 브라우저에 기본 인증 로그인 대화 상자를 표시합니다.

  8. 잘못된 자격 증명으로 로그인합니다. 요청이 거부되고 자격 증명을 다시 묻는 요청이 표시됩니다.

  9. 컴퓨터에 로그인하는 데 사용한 관리istrator 계정으로 로그인합니다. 서버에 인증 및 권한 부여 기능을 성공적으로 추가했음을 나타내는 디렉터리 목록이 표시됩니다.

요약

이 문서에서는 서버의 구성 요소화된 특성을 설명하고, 제공되는 IIS 기능을 검사하고, 사용자에게 필요할 수 있는 서비스만 사용하여 사용자 지정 웹 서버를 빌드하는 방법을 설명했습니다.

서버를 다시 사용하기 전에 이 연습의 일부로 수행된 서버 구성의 변경 내용을 실행 취소합니다. 이전에 백업을 만든 경우 명령줄에서 실행 %windir%\system32\inetsrv\appcmd restore backup initial 하여 복원합니다.

자세한 내용은 다음 링크를 참조하세요.