자습서: Always On VPN 배포 - Windows 10+ 클라이언트에 대한 Always On VPN 프로필 구성하기

적용 대상: Windows Server 2022, Windows 서버 2019, Windows 서버 2016, Windows Server 2012 R2, Windows Server 10, Windows Server 11

자습서의 마지막 부분에서 ProfileXML PowerShell 구성 스크립트를 사용해 Always On VPN 설정을 구성하고 클라이언트 연결에 대한 사용자 터널을 만드는 방법을 알아봅니다.

CSP(구성 서비스 공급자)에 대한 Always on VPN 구성 옵션에 대한 자세한 내용은 VPNv2 구성 서비스 공급자 를 참조하세요.

필수 조건

자습서: Always On VPN 배포 - 인증 기관 템플릿 구성하기 를 완료합니다.

Always On VPN 클라이언트 프로필 생성하기

이 섹션에서는 VPN 테스트 클라이언트가 성공적인 VPN 연결을 설정할 수 있는지 확인하기 위하여 VPN 클라이언트 연결을 만듭니다. 이렇게 하면 다음 섹션에서 내보내기용 EAP 설정을 만들기 또한 가능합니다.

EAP 설정에 대한 자세한 내용은 EAP 구성 을 참조하세요.

  1. Active Directory 만들기 테스트 사용자 에서 만든 VPN 사용자로 도메인에 가입된 VPN 클라이언트 컴퓨터에 로그인합니다.

  2. 시작 메뉴 VPN 을 입력하여 VPN 설정 을 선택합니다. ENTER 키를 누릅니다.

  3. 세부 정보 창에서 VPN 연결 추가 를 선택합니다.

  4. VPN 공급자 의 경우 Windows(기본 제공) 를 선택합니다.

  5. 연결 이름Contoso VPN 을 입력합니다 .

  6. 서버 이름 또는 주소 의 경우 VPN 서버의 외부 FQDN(예: vpn.contoso.com)을 입력합니다.

  7. VPN 형식 의 경우 IKEv2 를 선택합니다.

  8. 로그인 정보 유형 에 대해 인증서 를 선택합니다.

  9. 저장을 선택합니다.

  10. 관련 설정에서 어댑터 변경 옵션 을 선택합니다.

  11. Contoso VPN 을 마우스 오른쪽 단추로 클릭하고 속성 을 선택합니다.

  12. 보안 탭에서 데이터 암호화 에 대해 최대 강도 암호화 를 선택합니다.

  13. EAP(확장할 수 있는 인증 프로토콜) 사용 을 선택합니다. 그런 다음 EAP(확장 가능 인증 프로토콜) 사용 에 대해 Microsoft: PEAP(보호된 EAP)(암호화 사용) 를 선택합니다.

  14. 속성 을 선택하여 보호된 EAP 속성을 열고 다음 단계를 완료합니다.

    1. 이러한 서버에 연결하려면 NPS 서버의 이름을 입력합니다.

    2. 신뢰할 수 있는 루트 인증 기관 의 경우 NPS 서버의 인증서를 발급한 CA(예: contoso-CA)를 선택합니다.

    3. 연결하기 전에 알림 의 경우 사용자에게 새 서버 또는 신뢰할 수 있는 CA에 권한을 부여하도록 요청하지 않음 을 선택합니다.

    4. 인증 방법 선택 에서 스마트 카드 또는 기타 인증서 를 선택합니다.

    5. 구성을 선택합니다.

      1. 이 컴퓨터의 인증서 사용 을 선택합니다.

      2. 이러한 서버에 연결하려면 NPS 서버의 이름을 입력합니다.

      3. 신뢰할 수 있는 루트 인증 기관 에서 NPS 서버의 인증서를 발급한 CA를 선택합니다.

      4. 새 서버 또는 신뢰할 수 있는 인증 기관을 허가하도록 사용자에게 묻지 않음 을 선택합니다.

      5. 확인 을 선택하여 스마트 카드 또는 기타 인증서 속성을 닫습니다.

      6. 확인 을 선택하여 보호된 EAP 속성을 닫습니다.

    6. 확인 을 선택하여 Contoso VPN 속성을 닫습니다.

  15. 네트워크 연결 창을 닫습니다.

  16. 설정에서 Contoso VPN 을 선택한 다음, 연결 을 선택합니다.

Important

VPN 서버에 대한 템플릿 VPN 연결이 성공했는지를 확인합니다. 이렇게 하면 다음 단계에서 EAP 설정을 사용하기 전에 EAP 설정이 올바른지를 확인할 수 있습니다. 계속하기 전에 한 번 이상 연결해야만 합니다. 그렇지 않으면 프로필에 VPN에 연결하는 데 필요한 모든 정보가 포함되지 않습니다.

Windows VPN 클라이언트 구성

이 섹션에서는 PowerShell 스크립트를 사용해 Windows VPN 클라이언트를 수동으로 구성합니다.

  1. VPN 사용자로 VPN 클라이언트 컴퓨터에 로그인합니다.

  2. 관리자로 Windows PowerShell ISE(통합 스크립팅 환경)를 엽니다.

  3. 다음 스크립트를 복사하여 붙여넣습니다.

    
    # Define key VPN profile parameters
    # Replace with your own values
    
    $Domain = 'corp' # Name of the domain.
    
    $TemplateName = 'Contoso VPN' # Name of the test VPN connection you created in the tutorial. 
    
    $ProfileName = 'Contoso AlwaysOn VPN' # Name of the profile we are going to create.
    
    $Servers = 'aov-vpn.contoso.com' #Public or routable IP address or DNS name for the VPN gateway.
    
    $DnsSuffix = 'corp.contoso.com' # Specifies one or more commas separated DNS suffixes. 
    
    $DomainName = '.corp.contoso.com' #Used to indicate the namespace to which the policy applies. Contains `.` prefix.
    
    $DNSServers = '10.10.0.6' #List of comma-separated DNS Server IP addresses to use for the namespace.
    
    $TrustedNetwork = 'corp.contoso.com' #Comma-separated string to identify the trusted network.
    
    
    #Get the EAP settings for the current profile called $TemplateName
    
    $Connection = Get-VpnConnection -Name $TemplateName
    
    if(!$Connection)
    {
        $Message = "Unable to get $TemplateName connection profile: $_"
        Write-Host "$Message"
        exit
    }
    
    $EAPSettings= $Connection.EapConfigXmlStream.InnerXml
    
    $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
    
    # Define ProfileXML
    $ProfileXML = @("
    <VPNProfile>
      <DnsSuffix>$DnsSuffix</DnsSuffix>
      <NativeProfile>
    <Servers>$Servers</Servers>
    <NativeProtocolType>IKEv2</NativeProtocolType>
    <Authentication>
      <UserMethod>Eap</UserMethod>
      <Eap>
        <Configuration>
        $EAPSettings
        </Configuration>
      </Eap>
    </Authentication>
    <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
      </NativeProfile>
    <AlwaysOn>true</AlwaysOn>
    <RememberCredentials>true</RememberCredentials>
    <TrustedNetworkDetection>$TrustedNetwork</TrustedNetworkDetection>
      <DomainNameInformation>
    <DomainName>$DomainName</DomainName>
    <DnsServers>$DNSServers</DnsServers>
    </DomainNameInformation>
    </VPNProfile>
    ")
    
    #Output the XML for possible use in Intune
    $ProfileXML | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.xml')
    
    # Escape special characters in the profile (<,>,")
    $ProfileXML = $ProfileXML -replace '<', '&lt;'
    $ProfileXML = $ProfileXML -replace '>', '&gt;'
    $ProfileXML = $ProfileXML -replace '"', '&quot;'
    
    # Define WMI-to-CSP Bridge properties
    $nodeCSPURI = "./Vendor/MSFT/VPNv2"
    $namespaceName = "root\cimv2\mdm\dmmap"
    $className = "MDM_VPNv2_01"
    
    try
    {
    
        # Determine user SID for VPN profile.
        $WmiLoggedOnUsers = (Get-WmiObject Win32_LoggedOnUser).Antecedent
        If($WmiLoggedOnUsers.Count -gt 1) { 
            $WmiLoggedOnUsers = $WmiLoggedOnUsers -match "Domain=""$Domain"""
        }
    
        $WmiUserValid = ($WmiLoggedOnUsers | Select-Object -Unique -First 1) -match 'Domain="([^"]+)",Name="([^"]+)"'
    
        If(-not $WmiUserValid){
            Throw "Returned object is not a valid WMI string"
        }
    
    
        $UserName = "$($Matches[1])\$($Matches[2])"
    
        $ObjUser = New-Object System.Security.Principal.NTAccount($UserName)
        $Sid = $ObjUser.Translate([System.Security.Principal.SecurityIdentifier])
        $SidValue = $Sid.Value
        $Message = "User SID is $SidValue."
    
        Write-Host "$Message"
    
    }
    catch [Exception] 
    {
    
        $Message = "Unable to get user SID. $_"
        Write-Host "$Message" 
        exit
    }
    
    try 
    {
        # Define WMI session.
        $session = New-CimSession
        $options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
        $options.SetCustomOption("PolicyPlatformContext_PrincipalContext_Type", "PolicyPlatform_UserContext", $false)
        $options.SetCustomOption("PolicyPlatformContext_PrincipalContext_Id", "$SidValue", $false)
    
    }
    catch {
    
        $Message = "Unable to create new session for $ProfileName profile: $_"
        Write-Host $Message
        exit
    }
    
    try
    {
        #Detect and delete previous VPN profile.
        $deleteInstances = $session.EnumerateInstances($namespaceName, $className, $options)
    
        foreach ($deleteInstance in $deleteInstances)
        {
            $InstanceId = $deleteInstance.InstanceID
            if ("$InstanceId" -eq "$ProfileNameEscaped")
            {
                $session.DeleteInstance($namespaceName, $deleteInstance, $options)
                $Message = "Removed $ProfileName profile $InstanceId" 
                Write-Host "$Message"
            }
            else 
            {
                $Message = "Ignoring existing VPN profile $InstanceId"
                Write-Host "$Message"
            }
        }
    }
    catch [Exception]
    {
        $Message = "Unable to remove existing outdated instance(s) of $ProfileName profile: $_"
        Write-Host $Message
        exit
    
    }
    
    try
    {
        # Create the VPN profile.
        $newInstance = New-Object Microsoft.Management.Infrastructure.CimInstance $className, $namespaceName
        $property = [Microsoft.Management.Infrastructure.CimProperty]::Create("ParentID", "$nodeCSPURI", "String", "Key")
        $newInstance.CimInstanceProperties.Add($property)
        $property = [Microsoft.Management.Infrastructure.CimProperty]::Create("InstanceID", "$ProfileNameEscaped", "String", "Key")
        $newInstance.CimInstanceProperties.Add($property)
        $property = [Microsoft.Management.Infrastructure.CimProperty]::Create("ProfileXML", "$ProfileXML", "String", "Property")
        $newInstance.CimInstanceProperties.Add($property)
        $session.CreateInstance($namespaceName, $newInstance, $options)
    
        $Message = "Created $ProfileName profile."
        Write-Host "$Message"
    
    }
    catch [Exception]
    {
    
        $Message = "Unable to create $ProfileName profile: $_"
        Write-Host "$Message"
        exit
    }
    
    $Message = "Script Complete"
    Write-Host "$Message"
    
    
  4. 스크립트 $Domain, $TemplateName, $ProfileName, $Servers, $DnsSuffix, $DomainName, $DNSServers.맨 위에 있는 다음 변수에 대한 값을 설정합니다. 이러한 변수를 설정하는 방법에 대한 자세한 내용은 VPNv2 CSP 를 참조하세요.

  5. 스크립트를 실행하려면 Enter 키를 누릅니다.

  6. Windows PowerShell ISE에서 다음 명령을 실행하여 스크립트가 성공적으로 실행됐는지 확인합니다.

        Get-CimInstance -Namespace root\cimv2\mdm\dmmap -ClassName MDM_VPNv2_01
    
  7. 다음 출력이 나타납니다(가독성을 위해 ProfileXML 값이 잘렸습니다).

    
    AlwaysOn                : True
    ByPassForLocal          : 
    DeviceTunnel            : 
    DnsSuffix               : corp.contoso.com
    EdpModeId               : 
    InstanceID              : Contoso%20AlwaysOn%20VPN
    LockDown                : 
    ParentID                : ./Vendor/MSFT/VPNv2
    ProfileXML              : <VPNProfile>...</VPNProfile>
    RegisterDNS             : 
    RememberCredentials     : True
    TrustedNetworkDetection : corp.contoso.com
    PSComputerName          : 
    `
    

이제 Always On VPN에 관한 사용자 터널을 구성했습니다. 디바이스 터널을 구성하는 방법을 알아보려면 Windows 클라이언트에서 VPN 디바이스 터널 구성 을 참조하세요.

다음 단계