이번 시간에는 (본 blog의 취지하고는 다소 거리가 멀 수도 있지만) 이례적으로 Windows program 즉, WireGuard Windows 버젼에 관한 이야기를 꺼내 보고자 한다. 😎
WireGuard Windows Project
목차
1. WireGuard Windows Project 소개
2. Build script와 Install program 분석
3. WireGuard Windows 코드 분석
3. WireGuard Windows 코드 분석
4. WireGuard Auto Connect 기능 구현하기
5. References
TV 드라마를 보다 보면, 전문 의사들의 얘기를 담은 의학드라마와 율사(변호사, 검사, 판사)들의 얘기를 담은 법학드라마는 많은데, 컴퓨터 프로그래머 들의 애환(?)을 얘기하는 컴학(?) 드라마는 왜 거의 없는 걸까 ? 😂
"Computer Science 전공생과 이제 막 회사에 입사한 신입 직원들이여~ WireGuard code를 study하자. WireGuard는 다양한 OS(Linux, Windows, macOS, FreeBSD, OpenBSD, Android, iOS) 환경에서 다양한 programming language(C, Go, Rust, Kotlin/Java, Swift 등)를 이용하여 최고 수준의 코드로 구현되어 있는 만큼, 이를 하나씩 분석해 보는 것만으로도 자신의 개발 skill을 한단계 upgrade할 수 있는 좋은 기회가 되기에 충분하다" - Slowboot
1. WireGuard Windows Project 소개
Wireguard는 Linux는 물론이고, Windows, macOS, FreeBSD, OpenBSD, Android, iOS 등 다양한 OS 환경을 지원한다. Wireguard protocol 자체는 IPsec이나 OpenVPN 기술에 비해 매우 발전된 protocol이므로, 이를 분석하는 것만으로도 의의가 있다고 하겠다. 뿐만아니라, 다양한 OS 환경에서 다양한 programming language(C, Go, Rust, Kotlin/Java, Swift 등)를 이용하여, 최고 수준의 코드로 구현되어 있는 만큼, 이를 하나씩 파헤쳐 보는 것만으로도 개발자의 skill을 한단계 upgrade할 수 있는 좋은 기회가 될 것으로 보인다. 😍
1.1 wireguard-windows의 개요
먼저, Wiregurd windows project는 아래 site에서 확인 가능하다.
[그림 1.1] wireguard-windows project github
이 중, wiregurd windows driver 부분은 별도의 project로 관리되고 있다.
[그림 1.2] wireguard-nt project github
일반적으로 생각하는 것과는 다르게, Wireguard-windows application(wireguard.exe)은 Golang으로 작성한 UI(2개의 windows service 포함)와 C로 구현한 driver 제어용 API 계층(dll) 및 NDIS miniport driver(sys file)를 하나로 합친 형태로 구성되어 있다. 😍
Wireguard-windows는 다양하면서도 독특한 특징을 제공하고 있는데, 이를 간단히 정리해 보면 다음과 같다.
- (Windows용 UI임에도 불구하고) UI code는 C#(WinForms or WPF) 등의 전통적인 방법을 사용하지 않고, 특이하게도 Golang을 기반으로 구현되어 있다.
- 설치 program은 open source인 WIX(Windows Installer XML)을 기반으로 한다.
- 설치 program을 포함하여 전체 build 과정을 batch file에서 처리하도록 하고 있다(Windows이지만 UNIX 계열에 익숙한 개발 구조).
- 개발 환경으로 Visual Studio가 별도로 필요 없다. 또한, 심지어 Ubuntu에서도 build가 가능하다.
- UI, dll, driver code가 하나의 파일(exe)로 합쳐져서 생성되고, exe를 실행하면 필요한 파일로 분리되어 설치된다.
- Wireguard Driver(wireguard.sys)는 wireguard.dll에 통합되어 배포된다.
- Wireguard 핵심 코드(= wireguard driver)인 noise IK handshaking 부분은 WDK 즉, Windows Driver Kit 드라이버를 기반으로 하며, NDIS Miniport 드라이버로 형태로 되어 있다.
- 사용자가 직접 개발한 UI(예: C# UI)에 wireguard engine을 쉽게 접목할 수 있도록 tunnel.dll 이라는 이름의 DLL을 제공한다.
1.2 wireguard-windows build 하기
먼저, wireguard-windows source를 내려 받아 build를 해 보기로 한다. 나중에 다시 설명하겠지만, wireguard-windows에 포함된 wireguard driver(kernel code)는 prebuilt 상태로 배포되고 있어, Visual studio 기반의 개발 환경을 따로 구축할 필요가 없다. 즉, 아래와 같이, 명령 창에서 batch 파일을 한번 실행해 주는 것으로 전체 build가 가능하다.
D:\workspace\project> git clone https://github.com/WireGuard/wireguard-windows
D:\workspace\project> cd wireguard-windows
D:\workspace\project> .\build.bat
[그림 1.3] wireguard-windows 전체 build 하기
📌 심지어는 Go를 별도로 설치하지 않아도, build가 가능하다. 그 이유는 build 시 go compiler를 download 받아 .deps/go 아래에 풀어 사용하기 때문이다.
위의 과정을 통해 얻게되는 최종 Build 결과물은 다음과 같다.
PS D:\workspace\project\wireguard-windows> cd .\amd64\
PS D:\workspace\project\wireguard-windows\amd64> dir
디렉터리: D:\workspace\project\wireguard-windows\amd64
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2025-08-04 오후 12:37 135168 wg.exe # 사용자 영역의 제어 프로그램임.
-a---- 2025-08-04 오후 12:37 8450560 wireguard.exe #설치 파일임.
Wireguard windows 버전의 S/W 아키텍쳐는 다음과 같다.
wireguard.exe와 wg.exe를 차례로 실행시켜 보자.
📌 위의 그림은 wireguard.exe를 실행한 후, 터널 설정을 하고난 이후의 모습에 해당한다.
wg.exe 실행 결과를 보니, linux 환경에서의 내용과 동일한 모습을 하고 있다. 😁
📌 Windows 환경에서는 UI 및 서비스 코드에서 해당 처리가 모두 가능하므로, 사실상 wg.exe를 사용할 일이 없긴 하다.
Wireguard~ 알면 알수록 참으로 잘 만들어져 있다는 것을 느낌을 받는다. 😍
1.3 tunnel.dll build 하기
앞서도 잠시 언급한 바와 같이, 사용자가 직접 만든 UI에 wireguard engine을 붙여 사용하고자 할 경우를 위하여, wireguard는 tunnel.dll 이라는 이름의 DLL을 별도로 제공하고 있다. 이를 build하는 방법은 아래와 같다.
D:\workspace\project> cd embeddable-dll-service
D:\workspace\project\embeddable-dll-service> .\build.bat
PS D:\workspace\project\wireguard-windows\embeddable-dll-service> cd .\amd64\
PS D:\workspace\project\wireguard-windows\embeddable-dll-service\amd64> dir
디렉터리: D:\workspace\project\wireguard-windows\embeddable-dll-service\amd64
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2025-08-04 오후 1:50 3037696 tunnel.dll
tunnel.dll을 어떻게 사용하는 지는 아래 글에 자세히 설명되어 있다. 😋
또한, 아래 folder에는 tunnel.dll을 사용하여 만든 (.net 5 기준으로 되어 있기는 하지만) C# demo application code도 위치하고 있으니, 함께 참조하기 바란다.
wireguard-windows/embeddable-dll-service/csharp
1.4 wireguard.dll과 wireguard.sys driver build 하기
한편, 앞서 prebuilt 형태로 제공되는 wireguard driver는 wireguard-windows code와는 별도로 관리되고 있다고 하였다.
위의 github site 내용을 보면, 아래의 환경에서 build가 가능한 것으로 특정하고 있다. 실제로 이 내용은 Windows 10이 한창 사용되었을 즈음(2015 ~ 2021년)의 환경이라고 볼 수 있다.
General requirements:
- Visual Studio 2019 with Windows SDK
- Windows Driver Kit
- Windows 10 (이 부분은 실제로 언급되어 있지는 않음)
📌 필자는 2-3년전 쯤에 위 환경에서 wireguard-nt code가 정상 build됨을 확인한 바가 있다. 😗
문제는 현재(이 글을 쓰는 시점 즉, 2025년 8월) 대부분의 Windows 개발 환경은 아래와 같고, 이 환경에서 build를 시도할 경우, 감당할 수 정도로 무수히 많은 에러를 마주하게 된다는 점이다. 😓
- Windows 11
- Visual Studio 2022
- Windows Driver Kit 최신 버젼
📌 위의 환경 구성(설치 방법)과 관련해서는 인터넷에 관련 내용이 잘 나와 있는 관계로, 여기서는 별도로 소개하지는 않는다.
그렇다면, 위의 환경에서도 어떻게 하면 build에 성공할 수 있을까 ? 그 과정을 아래에 정리해 보았다.
참고로, wireguard-windows project만 사용할 경우 즉, wireguard driver code를 수정할 필요가 없다면, 굳이 아래 내용을 따라해 볼 필요는 없다.
<Windows 11/Visual Studio 2022 환경에서 wireguard-nt build 하기>
1) git clone https://github.com/WireGuard/wireguard-nt
-> 먼저 wireguard-nt code를 내려 받는다.
2) visual studio 2022 구동 후, 일괄 build#1
-> 이후, Visual Studio 2022를 구동한 후, 일괄 build를 시도해 본다.
악~ 아래와 같은 겁나(?) 많은 에러가 출력된다. 😂
-> 우선, 일단 이 부분이 출력되지 않도록 wireguard-nt.props 파일을 수정해 본다.
[그림 1.9] wireguard-nt.props 파일 수정 - Windows7 부분 제거
4) visual studio 2022 구동 후, 일괄 build#2
-> 다시 일괄 build를 시도해 보면, (다행히도) 전과는 다르게 wireguard driver 등이 build되는 것이 보인다. 최종 결과를 확인해 보니, api 관련 코드를 제외한 나머지(wireguard.sys, example.exe, setupapihost.dll) 부분이 제대로 build 된다.
[그림 1.10] 중간 build 결과물
api/ code 부분만 해결하면 되는데, 문제는 아직까지도 Visual Studio 2022 상에는 상당히 많은 error와 warning이 보인다는 것이다.
[그림 1.11] wireguard-nt code 최초 build 하기(#2)
api code 관련하여 지나치게 많은 warning message가 보이므로, 이를 한방에 무시할 방법을 찾도록 한다.
<예>
configuration.c(45,39): warning C5287: 피연산자는 서로 다른 열거형 형식 'WG_IOCTL_INTERFACE_FLAG' 및 'WIREGUARD_INTERFACE_FLAG'입니다. 이 경고를 무시하려면 명시적 캐스트를 사용하세요.
configuration.c(45,39): warning C5287: 피연산자는 서로 다른 열거형 형식 'WG_IOCTL_INTERFACE_FLAG' 및 'WIREGUARD_INTERFACE_FLAG'입니다. 이 경고를 무시하려면 명시적 캐스트를 사용하세요.
아래와 같은 방법을 warning을 error로 처리하지 않도록 설정을 변경해 본다.
프로젝트 -> 속성(Property) 메뉴 선택 -> C/C++ -> 일반 선택 -> 경고를 오류로 처리 수정(예 => 아니오) -> 적용 -> 확인
[그림 1.12] wireguard-nt code 최초 build 하기(#2)
-> 결과에 커다란 차도(?)가 없는 듯하다.
7) wireguard-inf.h 파일을 못 찾는 문제 해결
-> 어찌된 일인지, api/ code에서 사용하는 wireguard-inf.h 파일이 보이질 않는다.
api\driver.c(25,10): error C1083: 포함 파일을 열 수 없습니다. 'wireguard-inf.h': No such file or directory
아래 위치에 wireguard-inf.h 파일이 생성된 듯 보이니, 이를 임시로 복사해 보도록 한다. 정상적으로 build가 진행될 경우라면, 아래와 같은 일을 수동으로 할 필요가 없지만 말이다.
$ cp Release/amd64/api-intermediate/wireguard-inf.h wireguard-nt/api/
8) ARM/ARM64 부분 제거
-> build 결과 중에 ARM을 지원하지 않는다는 내용이 보인다. 일단 x64용 파일만 의미가 있으니, ARM/ARM64 부분은 모두 막도록 한다.
[그림 1.13] wireguard-nt.props 파일 수정 - ARM/ARM64 부분 제거
9) api code 중, warning 관련 적극적인 해결
-> 여전히 api build 결과물인 wireguard.dll이 만들어지지 않는다. 아래 내용이 여전히 해결되지 못한 듯 보인다.
configuration.c(45,39): warning C5287: 피연산자는 서로 다른 열거형 형식 'WG_IOCTL_INTERFACE_FLAG' 및 'WIREGUARD_INTERFACE_FLAG'입니다. 이 경고를 무시하려면 명시적 캐스트를 사용하세요.
위의 에러(warning 포함)를 발생시키는 관련 코드를 들여다 보니, 모두 static_assert( ) 함수들인데, 대세에 크게 영향이 없을 듯 보이니, 일단 모두 막아 보기로 한다.
10) visual studio 2022 구동 후, 일괄 build#4
-> 아직도 Visual Studio 상에는 많은 warning message가 출력되고 있지만, 뒷단에서는 아래와 같이 원하는 build 결과물이 만들어지는 것을 알 수 있다.
(뭔가 깔금하지는 않을지라도) 대략적으로 이와 같은 방식으로 진행한다면, 원하는 결과물을 만들어 낼 수가 있을 것이다.
<여기서 잠깐 !>
__________________________________________________________________________________________
Wireguard를 구현한 Thirdy party 제품 중에 TunSafe이라는 제품(tun interface 기반/사용자 영역에서 동작하는 app 방식)이 있다. Windows, MacOS, Linux, FreeBSD 버젼을 지원하는데, C++과 Assembly(암호 알고리즘)를 기반으로 구현되어 있다. 7년 전에 활발히 개발된 이후, 별다른 진행 사항이 없는 것이 좀 아쉽기는 하지만, 나름 의미가 있어 보여, build 방법을 정리해 본다.
📌 C++ 기반의 코드에 관심이 있거나, 사용자 영역에서 동작하는 small size binary가 필요(embedded linux 기기에 탑재 시 활용)가 경우에 도움이 될 듯하다.
<Windows용 binary build 하기>
1) git clone https://github.com/TunSafe/TunSafe
2) Visual Studio 2019에서 TunSafe.sln loading
-> upgrade 하지 않도록 선택함.
-> 이후, TunSafe.vcxproj, ts.vscproj 수정 : v141 -> v142
3) util_win32.cpp LoadFileSane()에서 compile error 발생하여 수정함(버그가 1개 존재함).
if (!f) return false;
--->
if (!f) return nullptr;
4) 이후 build하여 TunSafe.exe 얻음.
chyi@starwars-1:/mnt/d/workspace/project/WG/TunSafe/build/Win32_Debug$ ls -la
total 12420
drwxrwxrwx 1 chyi chyi 4096 Aug 5 2025 .
drwxrwxrwx 1 chyi chyi 4096 Aug 5 2025 ..
-rwxrwxrwx 1 chyi chyi 1169408 Aug 5 2025 TunSafe.exe
-rwxrwxrwx 1 chyi chyi 6942720 Aug 5 2025 TunSafe.pdb
drwxrwxrwx 1 chyi chyi 4096 Aug 5 2025 obj
-rwxrwxrwx 1 chyi chyi 225280 Aug 5 2025 ts.exe
-rwxrwxrwx 1 chyi chyi 4378624 Aug 5 2025 ts.pdb
<Linux용 binary build 하기>
1) sudo apt install libc++-dev
2) sudo sudo apt install g++-12
-> 아래 내용 참조하여 12 값 선택함.
chyi@earth:/mnt/hdd/workspace/wireguard/TunSafe$ clang -v
Ubuntu clang version 14.0.0-1ubuntu1.1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12 <------------------ 여기 나온 12 참조하여 위의 install 명령 실행
Candidate multilib: .;@m64
Selected multilib: .;@m64
Found CUDA installation: /usr/local/cuda, version
3) make 실행
-> build_linux.sh 파일 아래와 같이 수정
#clang++-6.0 -c -march=skylake-avx512 crypto/poly1305/poly1305-x64-linux.s crypto/chacha20/chacha20-x64-linux.s
#clang++-6.0 -I . $CURARGS -DWITH_NETWORK_BSD=1 -mssse3 -pthread -lrt -o tunsafe \
clang++ -c -march=skylake-avx512 crypto/poly1305/poly1305-x64-linux.s crypto/chacha20/chacha20-x64-linux.s
clang++ -I . $CURARGS -DWITH_NETWORK_BSD=1 -mssse3 -pthread -lrt -o tunsafe \
4) build 결과물
chyi@earth:/mnt/hdd/workspace/wireguard/TunSafe$ ls -l tunsafe
-rwxrwxr-x 1 chyi chyi 341504 8월 5 13:26 tunsafe
chyi@earth:/mnt/hdd/workspace/wireguard/TunSafe$ ./tunsafe --help
Usage: tunsafe <cmd> [<args>]
tunsafe filename.conf
Available subcommands:
show: Shows the configuration and status of the interfaces
set: Change the configuration or the peer list
start: Start TunSafe on an interface
stop: Stop TunSafe on an interface
genkey: Writes a new private key to stdout
genpsk: Writes a new preshared key to stdout
pubkey: Reads a private key from stdin and writes its public key to stdout
To see more help about a subcommand, pass --help to it
(내용이 너무 장황해 지는 관계로) TunSafe 관련 코드 분석 및 동작 시험은 독자 여러분의 몫으로 남긴다. 😋
_______________________________________________________________________________________
끝으로, 아래 site에는 wireguard를 기반으로 하는 많은 awesome open source project 들이 정리되어 있다. 왜 wireguard를 study해야 하는지에 대한 또 다른 이유가 여기에 있다고 말하고 싶다. 🔖
2. Build script와 Install program 분석
이번 장에서는 전체 build script와 install program 코드를 분석해 보고자 한다. 예상과는 달리, 전체 source code를 build하기 위해 Visual Studio와 같은 IDE 환경을 필요로 하지 않는다. 왜냐하면 Build & Install script는 (마치 Linux의 shell script 처럼) 모두 batch file로 구현되어 있기 때문이다. (DOS 시절에나 쓸법한) Windows의 batch file을 모르는 사람은 없겠지만, 이러한 기능도 제공하고 있구나 싶을 정도로 재밌고 독특한 코드가 눈에 들어온다. 💯
2.1 전체 Build 하기
전체 build script 즉, build.bat는 아래와 같이 크게 3단계의 작업으로 요약해 볼 수 있다.
[그림 2.1] 전체 Build script(= build.bat) 내용 중 일부 발췌
<build.bat 파일에서 하는 일>
1) Go compiler, GCC toolchain(mingw), make, wireguard-tools source code 및 wireguard-nt prebuilt binary(wireguard.dll) 등의 zip 파일을 내려 받아 압축을 푼다.
2) x86_64-w64-mingw32-winres program의 입력으로 wireguard.dll, icon files, version string 및 resources.rc 파일을 사용하여, resources_amd64.syso 결과 파일을 만든다.
3) 2)단계에서 생성한 resource_amd64.syso 파일과 go source code를 대상으로 go compile을 수행하여, 최종적으로 wireguard.exe 파일을 생성한다.
1장에서도 잠시 언급한 바 있지만, 최종 결과 파일은 아래와 같은 1개의 exe 파일로 만들어진다. 일반적인 경우라면, exe, dll, resource files, driver files(sys, inf) 등 다양한 결과물이 생성되는 것이 맞겠지만, wireguard windows의 경우는 이를 단 하나의 파일로 통합하고 있다. 가히 예술의 경지 그 자체라 말할 수 있겠다. 👍
2.2 Install program
Wireguard-Windows project는 (open source인) WIX(Windows Installer XML) toolset을 기반으로 msi 설치 파일을 만든다. Install용 build.bat script에서 하는 일을 요약해 보면 다음과 같다.
[그림 2.4] Installer Build script(= build.bat) 내용 중 일부
<build.bat 파일에서 하는 일>
1) wix-binaries.zip 파일을 download 한 후, 압축을 푼다.
2) x86_64-w64-mingw32-gcc compiler로 customactions.c 파일을 compile하여 customactions.dll을 생성한다. 이 파일에는 msi 파일 설치 후 벌어지는 일련의 action이 정의되어 있다. 즉, UI를 launching하고, service를 구동하는 코드가 구현되어 있다.
3) 마지막으로 wix toolset(candle.exe, light.exe)을 이용하여 wireguard.wxs에 정의된 내용을 토대로 msi 파일을 생성해 낸다.
지금까지 전체 code build와 wix install program을 이용해 msi 파일을 생성하는 절차를 가볍게 살펴 보았다. 이어지는 장에서는 wireguard.exe를 구성하는 세부 요소들을 하나씩 분석해 보도록 하자. 😀
3. WireGuard Windows 코드 분석
이번 장에서 살펴볼 내용은 WireGuard Windows 전체 code가 되겠다. 결론부터 얘기하자면, WireGuard Windows는 아래에 보이는 하나의 그림으로 표현해 볼 수 있을 것 같다. 😎
<WireGuard Windows의 구성>
- UI: Golang으로 구현
- 2개의 Windows 서비스(Manager, Tunnel): Golang으로 구현
- wireguard DLL(사용자 영역/Windows Driver간의 interface): C로 구현
- NoiseIK handshaking을 담당하는 Windows Driver: C로 구현
자, 그럼 지금부터 위의 4가지 구성요소를 바탕으로, 어떻게 해서 위와 같은 그림이 나오게 되는지를 파헤쳐 보도록 하자.
3.1 사용자 영역 구조
Wireguard-windows의 사용자 영역에는 Golang을 기반으로 구현된 UI와 2개의 windows service(WireGuardManager, Tunnel)가 자리하고 있다.
📌 UI는 Manager Server가 loading시켜 준다.
참고로, Wireguard-windows UI & 서비스 코드를 이해하기 위해서는 아래와 같은 사전 지식이 필요하다.
1) UI를 구현하는데 사용한 Walk(Windows Application Library Kit) framework(Golang)
2) Golang으로 구현한 windows service wraper
[그림 3.3] Walk: Windows Application Library Kit
3.2 UI 주요 Page 정리
UI source code 분석에 앞서 wireguard UI의 대략적인 모습을 먼저 파악할 필요가 있다.
[그림 3.4] WireGuard Windows UI 첫 Page
(2개의 tab, 우측 중앙 버튼, 좌측 하단의 list control, 2개의 button)
[그림 3.5] Add Empty Tunnel 선택 화면
[그림 3.6] Tunnel 정보 입력 후 화면 - 중앙의 Activate 버튼과 하단의 Edit 버튼
[그림 3.7] Activate 버튼 선택 후 화면
[그림 3.8] 로그 tab 내용 확인 - 하단의 Save 버튼
📌 UI 화면 관련하여, 이 밖에도 좀 더 내용이 있지만 생략하기로 한다.별것 없는 화면 구성 같아 보여도, 생각 보다 많은 기능이 구비되어 있다. WireGuard는 허접한 3류 program이 아니다. 앞서도 언급했듯이, 자신의 개발 skill을 upgrade하기에 충분히 훌륭한 코드로 만들어져 있다는 사실을 다시한번 강조하고 싶다. 💗
일일이 설명할 수는 없지만, 위의 UI code는 아래와 같은 파일로 구성되어 있다. 파일명이 직관적으로 되어 있어, 각각의 역할을 쉽게 알아차릴 수가 있다. 다만, 앞서 언급한 Walk(Windows Application Library Kit) framework의 내용을 이해하지 못한 상태에서 코드를 들여다 보면, 코드에 대한 이해가 쉽지 않을 것으로 예상된다.
-rw-rw-r-- 1 chyi chyi 4108 4월 14 17:34 aboutdialog.go - about dialog 창
-rw-rw-r-- 1 chyi chyi 18292 4월 14 17:34 confview.go - configuration view 창
-rw-rw-r-- 1 chyi chyi 10660 4월 14 17:34 editdialog.go - edit diaglog(환경 설정 내용 편집) 창
-rw-rw-r-- 1 chyi chyi 1036 4월 14 17:34 filesave.go - file 저장 관련 코드
-rw-rw-r-- 1 chyi chyi 3824 4월 14 17:34 iconprovider.go - icon provider 코드
-rw-rw-r-- 1 chyi chyi 6912 4월 14 17:34 listview.go - 화면 좌측 list view 코드
-rw-rw-r-- 1 chyi chyi 5526 4월 14 17:34 logpage.go - log 출력용 tab 관련 코드
-rw-rw-r-- 1 chyi chyi 6097 4월 14 17:34 managewindow.go - main window page 관련 코드
-rw-rw-r-- 1 chyi chyi 2670 4월 14 17:34 raise.go - UI raise 코드
-rw-rw-r-- 1 chyi chyi 10751 4월 14 17:34 tray.go - Tray 관련 코드
-rw-rw-r-- 1 chyi chyi 18622 4월 14 17:34 tunnelspage.go - tunnel tab 관련 코드
-rw-rw-r-- 1 chyi chyi 2893 4월 14 17:34 ui.go - UI main 코드
-rw-rw-r-- 1 chyi chyi 3267 4월 14 17:34 updatepage.go - update(upgrade) page 코드
3.3 Manager 및 Tunnel Service
Wireguard Windows에는 2개의 Service 즉, Manager Service와 Tunnel Service가 존재한다. Windows Service는 부팅 시 자동으로 실행되며, background에서 동작한다. 각각의 Service의 life cycle(Start/Stop/Pause 등)은 Windows SCM(Service Control Manager)에 의해 제어된다.
(Golang package에서) Service 프로그램은 main() 함수에서 svc.Run() 메서드를 호출하는 것으로 시작한다. svc.Run()은 첫번째 파라미터로 서비스명을, 두번째 파라미터로 svc.Handler 인터페이스를 구현한 오브젝트를 갖는다. 다시 svc.Handler 인터페이스는 Execute() 라는 하나의 메서드를 갖는데, 실제 이 메서드 안에서 서비스의 모든 동작 코드가 구현된다고 이해하면 된다.
아래 코드는 Manager Service와 Tunnel Service의 Execute method 내용 중 일부를 발췌한 것이다.
3.4 UI와 Manager Service 및 Tunnel Service 간의 통신
한편, UI와 Manager Service 간에는 2개의 pipe를 통해 상호간 통신(IPC)을 하게 된다.
📌 실제로는 Manager Service -> UI 방향으로 향하는 Event pipe가 하나 더 존재한다.
아래 type은 UI와 WireGuardManager간에 교환되는 IPC 명령을 정리한 것이다.
- StoredConfigMethodType
- RuntimeConfigMethodType
- StartMethodType
- StopMethodType
- WaitForStopMethodType
- DeleteMethodType
- StateMethodType
- GlobalStateMethodType
- CreateMethodType
- TunnelsMethodType
- QuitMethodType
- UpdateStateMethodType
- UpdateMethodType
[그림 3.13] Manager Service의 ipc_server code flow
(전체 코드 흐름을 분석할 때) 이 내용을 기초로 UI -> Manager Service -> Tunnel Service -> Driver 까지의 흐름을 파악해 볼 수 있는데, 이를 하나의 그림으로 정리해 보면 다음과 같다.
참고로, (Driver 부분은 다음 절에서 언급하겠지만) UI <-> Driver 간에는 UI -> Driver로 명령을 전달하는 흐름과 Driver -> UI로 설정 정보 및 Event를 전달하는 흐름을 생각해 볼 수가 있다. 실제 코드도 이에 대한 내용을 고민하여 설계 및 구현되어 있다고 보면 될 듯하다.
3.4 WireGuard DLL과 Driver
마지막으로 살펴 볼 내용은, WireGuard-NT driver와 이를 사용자 영역의 Service와 연결해 주는 API 계층 코드( wireguard.dll) 부분이 되겠다.
먼저 WireGuard-NT driver는 아래 그림에 표시된 NDIS miniport driver 형식으로 구현되어 있다. 그림을 통해서도 알 수 있듯이. NDIS miniport driver는 kernel 상에 존재하며, 패킷이 지나가는 길목에 자리하고 있어서 송신 혹은 수신 패킷을 마음껏 제어하는 것이 가능하다. 이는 linux kernel에 구현된 wireguard kernel module의 개념과 유사하다고 볼 수 있다.
[그림 3.15] NDIS miniport driver 개요 [출처 - 참고문헌 3]
📌 보통, windows 환경에서 Firewall/NAT/VPN 기능을 구현할 때, 대부분 위의 driver 형태를 기반으로 설계된다.wireguard.dll에서 제공하는 API 함수를 열거해 보면 다음과 같은데, 각각의 함수 내부를 따라가 보면 windows ioctl 함수 즉, DeviceIoControl( ) 함수가 호출되는 것을 알 수 있다.
- WireGuardCreateAdapter
- WireGuardOpenAdapter
- WireGuardCloseAdapter
- WireGuardGetAdapterLUID
- WireGuardGetAdapterState
- WireGuardGetConfiguration
- WireGuardGetRunningDriverVersion
- WireGuardDeleteDriver
- WireGuardSetAdapterLogging
- WireGuardSetAdapterState
- WireGuardSetConfiguration
- WireGuardSetLogger
참고로, DeviceIoControl( ) system call 함수에 대한 wireguard.sys driver의 counter part 함수는 driver/ioctl.c에 모두 정의되어 있다.
[그림 3.16] wireguard.dll과 wireguard.sys(driver)와의 관계
📌 wireguard.sys driver는 C:\windows\System32\drivers 아래에 설치된다.
위의 그림과는 달리, api/ 디렉토리 build 시, 실제 wireguard.dll은 아래와 같은 형태로 만들어 진다.
[그림 3.17] wireguard.dll 파일의 구조
WDK를 기반으로 구현되어 있는 wireguard.sys driver는 linux kernel용 wireguard와 많은 부분에서 차이가 있다. 파일 이름만 봐서는 linux kernel 용 wireguard와 거의 비슷하게 되어 있긴 하지만 말이다.
chyi@earth:/mnt/hdd/workspace/wireguard/wireguard-nt/driver$ ls -l *.c
-rw-rw-r-- 1 chyi chyi 13679 8월 4 21:14 allowedips.c
-rw-rw-r-- 1 chyi chyi 8529 8월 4 21:14 cookie.c
-rw-rw-r-- 1 chyi chyi 86609 8월 4 21:14 crypto.c
-rw-rw-r-- 1 chyi chyi 40778 8월 4 21:14 device.c
-rw-rw-r-- 1 chyi chyi 24858 8월 4 21:14 ioctl.c
-rw-rw-r-- 1 chyi chyi 6029 8월 4 21:14 logging.c
-rw-rw-r-- 1 chyi chyi 1885 8월 4 21:14 main.c
-rw-rw-r-- 1 chyi chyi 10187 8월 4 21:14 memory.c
-rw-rw-r-- 1 chyi chyi 30709 8월 4 21:14 noise.c
-rw-rw-r-- 1 chyi chyi 4935 8월 4 21:14 peer.c
-rw-rw-r-- 1 chyi chyi 7002 8월 4 21:14 peerlookup.c
-rw-rw-r-- 1 chyi chyi 7082 8월 4 21:14 queueing.c
-rw-rw-r-- 1 chyi chyi 6441 8월 4 21:14 ratelimiter.c
-rw-rw-r-- 1 chyi chyi 5448 8월 4 21:14 rcu.c
-rw-rw-r-- 1 chyi chyi 22314 8월 4 21:14 receive.c
-rw-rw-r-- 1 chyi chyi 18887 8월 4 21:14 send.c
-rw-rw-r-- 1 chyi chyi 37968 8월 4 21:14 socket.c
-rw-rw-r-- 1 chyi chyi 10767 8월 4 21:14 timers.c
📌 wireguard driver code는 추후 별도로 정리해야 할 듯하다. 😓
________________________________________________________________________________
지금까지 분석한 내용을 토대로, Wireguard Windows의 전체 S/W Architecture를 하나의 그림으로 표현해 보면 다음과 같다.
이상으로 조금은 아쉽지만, Wireguard Windows 프로젝트 코드를 대략적으로 분석하고, 주요 구성 요소간의 상관 관계를 파악해 보았다. 늘 그렇지만, 부족한 부분은 독자 여러분의 몫이다. 😓 -> 😋
이어지는 장에서는 Wireguard Windows 코드를 확장하여, 필자가 원하는 기능을 추가해 보고자 한다.
4. WireGuard Auto Connect 기능 구현하기
이번 장에서는 (필자가 개발 중인) WireGuard Auto Connect 기능을 Go code와 연결시키는 내용에 대해서 소개해 보고자 한다. 사실 이 작업을 하기 위해 1 ~ 3장의 내용을 구구절절이 설명했다고 해도 과언이 아니다. 😋
To be continued...
5. References
[1] https://github.com/WireGuard/wireguard-windows/blob/master/docs/buildrun.md
[2] https://git.zx2c4.com/wireguard-nt/about/
[3] https://windriver.jungo.com/manual/ch2_understanding_device_drivers.html
[4] https://dev.to/cosmic_predator/writing-a-windows-service-in-go-1d1m
-> golang으로 windows service 만들기
[5] https://karthikkaranth.me/blog/calling-c-code-from-go/
-> go code에서 C code 호출하기
[6] https://www.moonding.co.kr/analyzing-pe-files-using-windows-service/
[7] https://ianix.com/wireguard/wireguard-deployment.html
[8] Wireguard references
https://slowbootkernelhacks.blogspot.com/2024/12/wireguard-for-zephyr-rtos.html
https://slowbootkernelhacks.blogspot.com/2020/09/wireguard-vpn.html
https://slowbootkernelhacks.blogspot.com/2023/02/nanopi-r4s-pq-wireguard-vpn-router.html
https://slowbootkernelhacks.blogspot.com/2024/06/layer-2-wireguard-vpn.html
https://slowbootkernelhacks.blogspot.com/2024/05/nanopi-wireguard-go-quantum-safe-vpn.html
https://slowbootkernelhacks.blogspot.com/2023/02/esp32-wireguard-nat-router-pqc.html
https://slowbootkernelhacks.blogspot.com/2023/01/orangepi-r1-plus-lts-pqc-wireguard-vpn.html
https://slowbootkernelhacks.blogspot.com/2020/09/wireguard-vpn.html
https://slowbootkernelhacks.blogspot.com/2023/02/nanopi-r4s-pq-wireguard-vpn-router.html
https://slowbootkernelhacks.blogspot.com/2024/06/layer-2-wireguard-vpn.html
https://slowbootkernelhacks.blogspot.com/2024/05/nanopi-wireguard-go-quantum-safe-vpn.html
https://slowbootkernelhacks.blogspot.com/2023/02/esp32-wireguard-nat-router-pqc.html
https://slowbootkernelhacks.blogspot.com/2023/01/orangepi-r1-plus-lts-pqc-wireguard-vpn.html
[9] And, Google~
Slowboot