Microsoft MVP성태의 닷넷 이야기
개발 환경 구성: 493. OpenVPN의 네트워크 구성 [링크 복사], [링크+제목 복사]
조회: 13167
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

(시리즈 글이 4개 있습니다.)
개발 환경 구성: 491. 윈도우에 OpenVPN 설치 - 서버 측 구성
; https://www.sysnet.pe.kr/2/0/12224

개발 환경 구성: 492. 윈도우에 OpenVPN 설치 - 클라이언트 측 구성
; https://www.sysnet.pe.kr/2/0/12225

개발 환경 구성: 493. OpenVPN의 네트워크 구성
; https://www.sysnet.pe.kr/2/0/12226

개발 환경 구성: 515. OpenVPN - 재부팅 후 ICS(Internet Connection Sharing) 기능이 동작 안하는 문제
; https://www.sysnet.pe.kr/2/0/12325




OpenVPN의 네트워크 구성

지난 글에서 설명한,

윈도우에 OpenVPN 설치 - 서버 측 구성
; https://www.sysnet.pe.kr/2/0/12224

윈도우에 OpenVPN 설치 - 클라이언트 측 구성
; https://www.sysnet.pe.kr/2/0/12225

방식으로 설치했으면 VPN 서버와 그 서비스에 접속한 클라이언트 PC는 다음과 같은 네트워크 구성을 갖게 됩니다.

openvpn_network_1.png

OpenVPN은 저 그림에서 "VPN이 제공하는 가상 네트워크: 10.8.0.0"을 제공하기 위해 서버와 클라이언트 모두에 제품 설치 시 "TAP-Windows Adapter V9"이라는 Network Adapter를 생성합니다. (제어판의 "Network Connections"에서 확인할 수 있습니다.)

실제로 VPN 서버와 클라이언트 PC에서 ipconfig을 실행해 보면 각각의 네트워크 환경이 나옵니다.

// [서버]

C:\> ipconfig

Windows IP Configuration

...[생략]...

Unknown adapter Local Area Connection:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::a135:b01c:66f4:5d58%10
   IPv4 Address. . . . . . . . . . . : 10.8.0.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.252
   Default Gateway . . . . . . . . . :

...[생략]...


// [클라이언트]

C:\>ipconfig

Windows IP Configuration

...[생략]...

Unknown adapter Local Area Connection:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::2143:82b7:fd24:b855%89
   IPv4 Address. . . . . . . . . . . : 10.8.0.6
   Subnet Mask . . . . . . . . . . . : 255.255.255.252
   Default Gateway . . . . . . . . . :

...[생략]...

따라서, (방화벽에서 Ping 허용이 되었다면) 서버는 클라이언트에게 ping 10.8.0.6으로, 클라이언트는 서버에게 ping 10.8.0.1로 접근 여부를 쉽게 확인할 수 있습니다.




그렇다면 이제 통신은 어떤 식으로 이뤄질까요? 이에 대한 힌트를, OpenVPN의 클라이언트 측에서 접속했을 때 출력한 로그를 통해 알 수 있습니다.

...[생략]...
Thu Jun 11 09:42:24 2020 C:\WINDOWS\system32\route.exe ADD 10.8.0.0 MASK 255.255.255.0 10.8.0.5
...[생략]...

(클라이언트 측의) openvpn.exe가 실행하는 위의 명령어로 인해 (클라이언트 측의) 윈도우 운영체제에는 다음과 같은 route 테이블이 구성됩니다.

C:\> route PRINT -4
===========================================================================
Interface List
...[생략]...
 79...00 ff ed bb 9a ae ......TAP-Windows Adapter V9
...[생략]...
===========================================================================

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1     192.168.0.19    291
         10.8.0.0    255.255.255.0         10.8.0.5         10.8.0.6     25
         10.8.0.4  255.255.255.252         On-link          10.8.0.6    281
         10.8.0.6  255.255.255.255         On-link          10.8.0.6    281
         10.8.0.7  255.255.255.255         On-link          10.8.0.6    281
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    331
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    331
...[생략]...
===========================================================================
Persistent Routes:
  Network Address          Netmask  Gateway Address  Metric
...[생략]...
===========================================================================

이로 인해 클라이언트 측에서는 "10.8.0.0" 관련 패킷이 발생하는 경우 "10.8.0.6" 주소를 소유한 Network Adapter(TAP-Windows Adapter V9)가 통신을 담당하게 됩니다. 하지만, 그 외의 주소에 대한 통신은 "192.168.0.19" 주소를 소유한 기존 Network Adapter가 처리합니다.

이런 상황에서는 웹 브라우저를 이용해 10.8.0.0 이외의 사이트에 접속하는 경우 클라이언트 측의 기존 네트워크 망을 이용해 통신을 하게 되고, 예를 들어 "https://ipconfig.tools/en/"과 같은 사이트를 방문하게 되면 보이는 IP 주소가 OpenVPN을 사용하기 전과 달라지는 것이 없습니다.




물론, 대개의 경우 위와 같은 네트워크 구성은 VPN을 사용하려는 목적에 부합합니다. 하지만, 때로는 모든 통신을 VPN 서버 측의 네트워크로 라우팅 되는 것을 원할 수도 있습니다. (예를 들어, 비주얼 스튜디오의 업데이트 속도를 빠르게 하기 위해 VPN 서버 측의 네트워크를 사용하고 싶을 수 있습니다.)

이러한 구성을 OpenVPN에서 하려면, 서버 측의 server.ovpn 파일에 다음의 구성을 활성화해야 합니다

push "redirect-gateway def1 bypass-dhcp"

위의 설정으로 변경하고, 서버 측 OpenVPN을 다시 실행한 후, 클라이언트 측에서 연결을 다시 하면 이번에는 클라이언트 측의 연결 로그에 다음과 같은 route 명령어를 볼 수 있습니다.

Thu Jun 11 10:02:42 2020 C:\WINDOWS\system32\route.exe ADD 52.231.8.55 MASK 255.255.255.255 192.168.0.1
Thu Jun 11 10:02:42 2020 ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=35 and dwForwardType=4
Thu Jun 11 10:02:42 2020 Route addition via IPAPI succeeded [adaptive]
Thu Jun 11 10:02:42 2020 C:\WINDOWS\system32\route.exe ADD 0.0.0.0 MASK 128.0.0.0 10.8.0.5
Thu Jun 11 10:02:42 2020 ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=25 and dwForwardType=4
Thu Jun 11 10:02:42 2020 Route addition via IPAPI succeeded [adaptive]
Thu Jun 11 10:02:42 2020 C:\WINDOWS\system32\route.exe ADD 128.0.0.0 MASK 128.0.0.0 10.8.0.5
Thu Jun 11 10:02:42 2020 ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=25 and dwForwardType=4
Thu Jun 11 10:02:42 2020 Route addition via IPAPI succeeded [adaptive]
Thu Jun 11 10:02:42 2020 C:\WINDOWS\system32\route.exe ADD 10.8.0.0 MASK 255.255.255.0 10.8.0.5
Thu Jun 11 10:02:42 2020 ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=25 and dwForwardType=4
Thu Jun 11 10:02:42 2020 Route addition via IPAPI succeeded [adaptive]

이로 인해 라우팅 테이블의 설정이 바뀌는데,

C:\> route PRINT -4
===========================================================================
Interface List
 89...00 ff ed bb 9a ae ......TAP-Windows Adapter V9
...[생략]...
===========================================================================

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1     192.168.0.19    291
          0.0.0.0        128.0.0.0         10.8.0.5         10.8.0.6     25
         10.8.0.0    255.255.255.0         10.8.0.5         10.8.0.6     25
         10.8.0.4  255.255.255.252         On-link          10.8.0.6    281
         10.8.0.6  255.255.255.255         On-link          10.8.0.6    281
         10.8.0.7  255.255.255.255         On-link          10.8.0.6    281
...[생략]...
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    331
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    331
...[생략]...
===========================================================================
Persistent Routes:
  Network Address          Netmask  Gateway Address  Metric
...[생략]...
===========================================================================

보는 바와 같이 "Destination"의 설정에 "0.0.0.0" 항목이 2개로 늘어났는데 "10.8.0.6" Interface의 Metric이 "192.168.0.19"가 가진 291보다 낮은 25로 설정되어 우선순위가 더 높아졌습니다.




그렇다면, 이제 웹 브라우저 등을 이용해 서버에 접속하려고 하면 "10.8.0.6"이 속한 네트워크로의 우선순위가 높아져 그쪽으로 패킷이 흐르게 됩니다. 하지만, 여기서 문제가 하나 발생합니다. VPN 서버는 "10.8.0.0" 네트워크로 흘러 들어오는 패킷을 자신이 기존에 속한 네트워크로 라우팅 하지는 않는다는 점입니다.

따라서, 이로 인해 "push "redirect-gateway def1 bypass-dhcp" 설정이 적용된 OpenVPN 네트워크에서는 클라이언트 측의 컴퓨터에서 웹 브라우징 등이 안 되는 문제가 발생합니다. (사실 설정에 따른 것이므로, 이것은 문제라고 볼 수 없고 의도된 현상입니다.)

이 문제를 해결하려면, VPN 서버 측에서 "10.8.0.0"으로 흘러온 패킷을 VPN 서버의 또 다른 네트워크 어댑터 - 즉, 인터넷이 연결된 네트워크 어댑터로 흘러들어가도록 만들어야 하고, 이것을 쉽게 할 수 있는 것이 바로 "ICS (Internet Connection Sharing)"를 설정하는 것입니다.

아래의 그림은,

openvpn_network_2.png

VPN 서버 측에서 인터넷과 연결된 "Ethernet 2" 어댑터의 속성 창을 통해 ICS를 활성화시켜 "TAP-Windows Adapter V9"으로부터의 라우팅을 허용하게 만듭니다. 이렇게 구성이 되면, 웹 브라우저를 실행해 외부 사이트에 접속하는 경우, 가령 "https://ipconfig.tools/en/" 등의 사이트를 방문하면 사용된 IP 주소가 VPN 서버 측의 IP인 것을 확인할 수 있습니다.




참고로, OpenVPN의 문제인지 ICS의 문제인지는 알 수 없으나 종종 클라이언트에서의 인터넷 접속이 잘 안 될 때가 있습니다. 그런 경우에는 서버 측의 ICS를 재활성하든가, 클라이언트 측의 VPN 접속을 다시 해보면 잘 되기도 합니다. (불안정한 원인을 잘 모르겠군요. ^^)

게다가 이론상 ICS로 인해 클라이언트 측의 네트워크 동작에 문제가 없어야 하는 것이 맞지만 웬일인지 오피스 제품의 Outlook을 실행했을 때 첫 화면에서 "We are unable to connect right now. Please check your network and try again later."라는 오류가 발생하는 걸로 봐서 100% 안정적인 통신이 보장된다고 볼 수 없습니다.

마지막으로, ICS와 함께 Bridge로 엮은 구성을 다룬 다음의 글을 소개하며 글을 마칩니다. ^^

Hyper-V Internal 네트워크 VM 의 인터넷 접속
; https://www.sysnet.pe.kr/2/0/1335

Hyper-V의 네트워크 유형 (2)
; https://www.sysnet.pe.kr/2/0/915

따지고 보면, OpenVPN의 네트워크 구성과 "Hyper-V Internal 네트워크 VM 의 인터넷 접속" 글에서 다룬 네트워크 구성은 다를 바 없습니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 6/19/2020]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2021-11-09 04시59분
[질문드립니다] 수고하십니다. 질문 하나 드려도 될까요
route.exe ADD 52.231.8.55 MASK 255.255.255.255 192.168.0.1 << 이렇게 서버쪽에서 미리 설정해 둘 수 있는 방법이 있을까요? client가 접속하면 자동적으로 routing 경로가 추가되도록~
[guest]
2021-11-09 09시05분
그게 되려면 ovpn 서버와 클라이언트 측에서 그 용도로 동작하도록 정의한 옵션이 있어야 하는데... 글쎄요. 그 옵션이 있을까요? ^^ 혹시 발견하시게 되거든 덧글 부탁드립니다.
정성태
2022-03-16 09시21분
[guest] 10.8.0.5라는 GW는 어떻게 알수있나요
[guest]
2022-03-16 09시26분
본문에서, 해당 주소는 "OpenVPN의 클라이언트 측에서 접속했을 때 출력한 로그를 통해 알 수" 있다는 것으로 출력 결과에 설명했는데요. 그리고 "route PRINT -4"로도 알아내는 것을 역시 본문에서 설명했습니다.
정성태

1  2  3  4  [5]  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13501정성태12/25/20232087개발 환경 구성: 700. WSL + uwsgi - IPv6로 바인딩하는 방법
13500정성태12/24/20232178디버깅 기술: 194. Windbg - x64 가상 주소를 물리 주소로 변환
13498정성태12/23/20232822닷넷: 2186. 한국투자증권 KIS Developers OpenAPI의 C# 래퍼 버전 - eFriendOpenAPI NuGet 패키지
13497정성태12/22/20232294오류 유형: 885. Visual Studiio - error : Could not connect to the remote system. Please verify your connection settings, and that your machine is on the network and reachable.
13496정성태12/21/20232307Linux: 66. 리눅스 - 실행 중인 프로세스 내부의 환경변수 설정을 구하는 방법 (gdb)
13495정성태12/20/20232317Linux: 65. clang++로 공유 라이브러리의 -static 옵션 빌드가 가능할까요?
13494정성태12/20/20232500Linux: 64. Linux 응용 프로그램의 (C++) so 의존성 줄이기(ReleaseMinDependency) - 두 번째 이야기
13493정성태12/19/20232546닷넷: 2185. C# - object를 QueryString으로 직렬화하는 방법
13492정성태12/19/20232262개발 환경 구성: 699. WSL에 nopCommerce 예제 구성
13491정성태12/19/20232232Linux: 63. 리눅스 - 다중 그룹 또는 사용자를 리소스에 권한 부여
13490정성태12/19/20232345개발 환경 구성: 698. Golang - GLIBC 의존을 없애는 정적 빌드 방법
13489정성태12/19/20232133개발 환경 구성: 697. GoLand에서 ldflags 지정 방법
13488정성태12/18/20232067오류 유형: 884. HTTP 500.0 - 명령행에서 실행한 ASP.NET Core 응용 프로그램을 실행하는 방법
13487정성태12/16/20232381개발 환경 구성: 696. C# - 리눅스용 AOT 빌드를 docker에서 수행 [1]
13486정성태12/15/20232194개발 환경 구성: 695. Nuget config 파일에 값 설정/삭제 방법
13485정성태12/15/20232088오류 유형: 883. dotnet build/restore - error : Root element is missing
13484정성태12/14/20232161개발 환경 구성: 694. Windows 디렉터리 경로를 WSL의 /mnt 포맷으로 구하는 방법
13483정성태12/14/20232297닷넷: 2184. C# - 하나의 resource 파일을 여러 프로그램에서 (AOT 시에도) 사용하는 방법파일 다운로드1
13482정성태12/13/20232818닷넷: 2183. C# - eFriend Expert OCX 예제를 .NET Core/5+ Console App에서 사용하는 방법 [2]파일 다운로드1
13481정성태12/13/20232267개발 환경 구성: 693. msbuild - .NET Core/5+ 프로젝트에서 resgen을 이용한 리소스 파일 생성 방법파일 다운로드1
13480정성태12/12/20232602개발 환경 구성: 692. Windows WSL 2 + Chrome 웹 브라우저 설치
13479정성태12/11/20232299개발 환경 구성: 691. WSL 2 (Ubuntu) + nginx 환경 설정
13477정성태12/8/20232481닷넷: 2182. C# - .NET 7부터 추가된 Int128, UInt128 [1]파일 다운로드1
13476정성태12/8/20232206닷넷: 2181. C# - .NET 8 JsonStringEnumConverter의 AOT를 위한 개선파일 다운로드1
13475정성태12/7/20232278닷넷: 2180. .NET 8 - 함수 포인터에 대한 Reflection 정보 조회파일 다운로드1
13474정성태12/6/20232133개발 환경 구성: 690. 닷넷 코어/5+ 버전의 ilasm/ildasm 실행 파일 구하는 방법 - 두 번째 이야기
1  2  3  4  [5]  6  7  8  9  10  11  12  13  14  15  ...