NGINX Plus를 사용한 Microsoft AD FS의 고가용성

Microsoft AD FS(Active Directory Federation Services)를 사용하면 Windows Server에서 애플리케이션을 호스팅하는 조직이 Extranet을 통해 신뢰할 수 있는 비즈니스 파트너의 직원에게 SSO(Single Sign-On) 액세스를 확장할 수 있습니다. 비즈니스 파트너 간의 ID 정보 공유를 페더레이션(Federation)이라고 합니다.

실제로 AD FS를 사용한다는 것은 페더레이션에 속한 회사의 직원이 로컬 환경에만 로그인하면 된다는 의미입니다. 신뢰할 수 있는 비즈니스 파트너에 속한 웹 애플리케이션에 액세스하면 로컬 Microsoft AD FS 서버는 보안 토큰 형식으로 파트너의 AD FS 서버에 식별 정보를 전달합니다. 토큰은 로컬 Active Directory에 저장된 직원의 개별 속성(사용자 이름, 비즈니스 역할, 직원 ID 등)인 여러 클레임으로 구성됩니다. 파트너의 AD FS 서버는 토큰의 Claim을 파트너의 애플리케이션이 이해하는 Claim에 매핑한 다음 직원이 요청된 종류의 액세스 권한이 있는지 확인합니다.

AD FS 2.0 이상에서는 HA(High Availability)를 활성화하여 애플리케이션의 인증 서비스에 탄력성과 확장성을 추가할 수 있습니다. Microsoft AD FS 팜이라고도 하는 AD FS HA 클러스터에서는 여러 AD FS 서버가 단일 데이터 센터 내에 배포되거나 데이터 센터 전체에 분산됩니다. 모든 활성 HA에 대해 구성된 클러스터에는 트래픽을 AD FS 서버 전체에 고르게 분산하기 위한 Load Balancer가 필요합니다. Active‑Passive HA 배포에서 Load Balancer는 기본 장애가 발생할 때 백업 AD FS 서버에 대한 장애 조치를 제공할 수 있습니다.

이 포스트에서는 각각 Microsoft AD FS 3.0 및 Microsoft AD FS 4.0 Server 2012 R2 및 Windows Server 2016을 실행하는 환경에서 HA를 제공하도록 NGINX Plus를 구성하는 방법을 설명합니다.

목차

1. Microsoft AD FS용 표준 HA 토폴로지
2. 표준 HA 토폴로지에서 NGINX Plus 사용
2-1. AD FS 서버의 부하를 분산하도록 NGINX Plus 구성
3. WAP 서버 Load Balancing을 위해 NGINX Plus 구성
3-1. SSL 구성 Pass-Through
3-2. HTTPS Re‑Encryption 구성
4. WAP 서버가 없는 토폴로지에서 NGINX Plus 구성

1. Microsoft AD FS 용 표준 HA 토폴로지

이 포스트에서는 설명을 위해 표준 Microsoft AD FS 팜 토폴로지를 사용합니다. 권장 사항이거나 가능한 모든 배포 시나리오를 다루기 위한 것은 아닙니다. 온프레미스(On-premise) 배포의 경우 표준 팜은 DMZ 네트워크에서 하나 이상의 WAP(Web Application Proxy) 서버 앞에 있는 회사 인트라넷에 있는 하나 이상의 Microsoft AD FS 서버로 구성됩니다. WAP 서버는 외부 사용자가 회사 인트라넷에서 호스팅되는 웹 애플리케이션에 액세스할 수 있도록 하는 Reverse Proxy 역할을 합니다.

WAP에는 서버 클러스터를 구성하거나 HA를 지원하는 기본 제공 방법이 없으므로 Load Balancer를 WAP 서버 앞에 배포해야 합니다. Load Balancer는 Microsoft AD FS 용 HA를 활성화하기 위해 DMZ와 Intranet 사이의 경계에도 배치됩니다. 표준 Microsoft AD FS 팜에서 Windows Server 2012 및 2016의 NLB(Network Load Balancing) 기능은 Load Balancer 장치 역할을 합니다. 마지막으로 방화벽은 일반적으로 Load Balancer의 외부 IP 주소 앞과 네트워크 영역 사이에 구현됩니다.

2. Microsoft AD FS 표준 HA 토폴로지에서 NGINX Plus 사용

언급한 대로 NLB는 Microsoft AD FS 팜에 대한 Load Balancing을 수행할 수 있습니다. 그러나 기능 세트는 매우 기본적입니다(기본 상태 확인 및 제한된 모니터링 기능). NGINX Plus에는 Production Microsoft AD FS 환경에서 HA에 중요한 기능을 많이 갖추고 있지만 가볍습니다.

여기에 설명된 표준 토폴로지 배포에서 NGINX Plus는 NLB를 대체하여 모든 WAP 및 Microsoft AD FS 팜에 대한 트래픽 Load Balancing합니다. 그러나 올바른 Microsoft AD FS 작업을 위해서는 WAP 서버에서 실제 SSL 인증서를 확인해야 하므로 NGINX Plus가 AD FS 서버에 대한 SSL 연결을 Terminate하지 않습니다(자세한 내용은 이 Microsoft TechNet 문서 참조).

Production 환경에서는 NGINX Plus 자체에 대한 HA도 구현하는 것이 좋지만 여기에서는 표시하지 않습니다.

Microsoft AD FS

2-1. Microsoft AD FS 서버의 부하를 분산하도록 NGINX Plus 구성

Load Balancing Microsoft AD FS 서버를 위한 NGINX Plus 구성은 간단합니다. 위에서 언급한 것처럼 AD FS 서버는 WAP 서버의 실제 SSL 인증서를 확인해야 하므로 DMZ‑Intranet 경계에서 NGINX Plus 인스턴스를 종료하거나 처리하지 않고 SSL 암호화 트래픽을 ADFS 서버로 전달하도록 구성합니다.

필수 지시문 외에도 다음 지시문을 구성에 포함합니다.

  • zone은 모든 NGINX Plus Worker Process가 Upstream 그룹의 서버에 대한 구성 및 런타임 상태 정보에 액세스할 수 있는 공유 메모리 영역을 할당합니다.
  • hash는 Source IP 주소(클라이언트)를 기반으로 클라이언트와 AD FS 서버 간에 세션 지속성을 설정합니다. 클라이언트가 AD FS 서버와 단일 TCP 연결을 설정하더라도 세션 지속성이 활성화되지 않은 경우 특정 조건에서 일부 애플리케이션이 여러 로그인 Redirect을 겪을 수 있기 때문에 이는 필요합니다.
  • status_zone은 NGINX Plus API가 이 서버에 대한 메트릭를 수집한다는 의미이며, 이는 내장된 실시간 활동 모니터링 대시보드에 표시될 수 있습니다(API 및 대시보드는 별도로 구성됨).
stream {
    upstream adfs_ssl {
        zone adfs_ssl 64k;
        server 10.11.0.5:443; # AD FS server 1
        server 10.11.0.6:443; # AD FS server 2
        hash $remote_addr;
    }

    server {
        status_zone adfs_ssl;
        listen 10.0.5.15:443;
        proxy_pass adfs_ssl;
    }
}

WAP 서버의 트래픽이 NGINX Plus를 통해 AD FS 서버로 흐르도록 하려면 페더레이션 서비스 이름(이 예에서는 fs.example.com)을 NGINX Plus가 수신 대기 중인 IP 주소에 매핑해야 합니다. Production 배포의 경우 DMZ에 DNS 호스트 A 레코드를 추가합니다. 테스트 배포의 경우 각 WAP 서버의 호스트 파일에 항목을 만드는 것으로 충분합니다. 호스트 파일에서 fs.example.com을 10.0.5.15에 바인딩하는 것이 여기에서 수행하는 작업입니다.

Microsoft AD FS

WAP 서버의 트래픽이 AD FS 서버에 도달하는지 테스트하기 위해 ipconfig /flushdns 명령을 실행하여 DNS를 Flush한 다음 브라우저에서 SSO 페이지(https://fs.example.com/)의 AD FS에 로그인합니다. adfs/ls/idpinitiatedsignon.htm:

3. WAP 서버 Load Balancing을 위해 NGINX Plus 구성

이제 외부 클라이언트에서 WAP 서버로의 HTTPS 연결 부하를 분산하도록 NGINX Plus를 구성합니다. 모범 사례에 따르면 트래픽은 AD FS 서버에 도달할 때 여전히 SSL 암호화되므로 HTTPS 트래픽을 WAP 서버로 전달하도록 NGINX Plus를 구성하는 두 가지 접근 방식(SSL Pass‑Through 또는 SSL Re‑Encryption) 중 하나를 사용합니다.

3-1. SSL 구성 Pass-Through

더 쉬운 구성은 NGINX Plus가 변경되지 않은 SSL 암호화 TCP 트래픽을 WAP 서버로 전달하도록 하는 것입니다. 이를 위해 AD FS Load Balancing을 위해 이전 것과 유사한 Stream Context 가상 서버를 구성합니다.

여기서 NGINX Plus는 다른 고유 IP 주소인 10.0.5.100에서 외부 트래픽을 수신합니다. Production 환경의 경우 게시된 애플리케이션의 외부 FQDN은 공개 영역의 DNS 호스트 A 레코드 형식으로 이 주소를 가리켜야 합니다. 테스트의 경우 클라이언트 컴퓨터의 호스트 파일에 항목이 있으면 충분합니다.

Note: 이 서버와 동일한 IP 주소에서 수신하도록 Stream Context에서 추가 HTTPS 서비스를 구성하려는 경우 트래픽을 다른 Upstream으로 올바르게 라우팅하기 위해 map과 함께 ssl_preread 지시문을 사용하여 SNI(Server Name Indication)를 활성화해야 합니다.

stream {
    upstream wap {
        zone wap 64k;
        server 10.11.0.5:443; #WAP server 1
        server 10.11.0.6:443; #WAP server 2
        least_time connect;
    }
  
    server {
        status_zone wap_adfs;
        listen 10.0.5.100:443;
        proxy_pass wap;
    }
}

3-2. HTTPS Re‑Encryption 구성

SSL Pass‑Through의 대안으로 HTTPS 트래픽을 허용하도록 HTTP Context에서 가상 서버를 구성하여 NGINX Plus의 전체 Layer 7 기능을 활용할 수 있습니다. NGINX Plus는 클라이언트의 HTTPS 연결을 종료하고 WAP 서버에 대한 새 HTTPS 연결을 생성합니다.

인증서 및 비밀 키 파일인 example.com.crt 및 example.com.key에는 CN(Common Name) 또는 SAN(Subject Alternative Name) 속성에 게시된 애플리케이션의 외부 FQDN이 포함되어 있습니다. 이 예에서 FQDN은 fs.example.com입니다.

proxy_ssl_server_nameproxy_ssl_name 지시문은 SSL 클라이언트 Hello에서 보낼 원격 호스트 이름을 지정하는 필수 SNI(Server Name Indication) 헤더를 활성화합니다. 헤더는 게시된 애플리케이션의 외부 FQDN(이 예에서는 fs.example.com)과 일치해야 합니다.

proxy_set_header 디렉티브를 사용하여 WAP 서버에 관련 정보를 전달하고 로그에 기록할 수 있습니다.

  • X-Real-IP 헤더에는 $remote_addr 변수에 기록된 Source(클라이언트) IP 주소가 포함되어 있습니다.
  • X-Forwarded-For는 클라이언트의 IP 주소가 추가된(또는 클라이언트 요청에 헤더가 없는 경우 해당 주소만) 클라이언트 요청의 헤더를 전달합니다.
  • x-ms-proxy 헤더는 사용자가 Proxy 서버를 통해 라우팅되었음을 나타내며 NGINX Plus 인스턴스를 해당 서버로 식별합니다.

여기에 표시된 지시문 외에도 NGINX 및 NGINX Plus는 SSL/TLS의 성능과 보안을 개선할 수 있는 여러 기능을 제공합니다.

http {
    upstream wap {
        zone wap 64k;
        server 10.0.5.11:443;
        server 10.0.5.10:443;
        least_time header;
    }

    server {
        listen 10.0.5.100:443 ssl;
        status_zone fs.example.com;
        server_name fs.example.com;
        ssl_certificate     	/etc/ssl/example.com/example.com.crt;
        ssl_certificate_key 	/etc/ssl/example.com/example.com.key;

        location / {
            proxy_pass https://wap; # 'https' enables reencrypt 
            proxy_ssl_server_name on;
            proxy_ssl_name $host;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header x-ms-proxy $server_name;
        }
    }
}

4. WAP 서버가 없는 토폴로지에서 NGINX Plus 구성

외부 클라이언트가 Microsoft AD FS 서버에 액세스할 수 있도록 하는 경우 DMZ와 회사 Intranet 사이의 경계에서 외부 트래픽을 종료하고 x-ms-proxy 헤더를 삽입하여 외부 인증 시도를 식별하는 것이 가장 좋습니다. WAP 서버는 이 두 가지 기능을 모두 수행하지만 이전 섹션에서 구성한 대로 NGINX Plus도 수행합니다.

예를 들어 IP 네트워크 및 신뢰 수준과 같은 고급 클레임 규칙을 사용하지 않는 경우와 같은 일부 사용 사례에는 WAP 서버가 필요하지 않습니다. 이러한 경우 WAP 서버를 제거하고 DMZ와 Intranet 사이의 경계에 NGINX Plus를 배치하여 내부 AD FS 서버에 대한 요청을 인증할 수 있습니다. 따라서 하드웨어, 소프트웨어 및 운영 비용이 절감됩니다.

이 구성은 표준 HA 토폴로지의 구성을 대체합니다. 이는 WAP 서버 Load Balancing을 위한 HTTPS Re‑Encryption 구성과 거의 동일하지만 여기서 NGINX Plus는 외부 요청을 내부 네트워크의 Microsoft AD FS 서버로 직접 load balancing합니다.

upstream adfs {
    zone adfs 64k;
    server 192.168.5.5:443; # AD FS Server 1
    server 192.168.5.6:443; # AD FS Server 2
    least_time header;
 }

server {
    listen 10.0.5.110:443 ssl;
    status_zone adfs_proxy;
    server_name fs.example.com;
    ssl_certificate         /etc/ssl/example.com/example.com.crt;
    ssl_certificate_key     /etc/ssl/example.com/example.com.key;
  
    location / {
        proxy_pass https://adfs;
        proxy_ssl_server_name on;
        proxy_ssl_name $host;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header x-ms-proxy $server_name;
    }
 }

NGINX 및 NGINX Plus의 최신 소식을 빠르게 전달 받고 싶으시면 아래 뉴스레터를 구독하세요.