Microsoft MVP성태의 닷넷 이야기
Windows: 174. WSL 2의 네트워크 통신 방법 [링크 복사], [링크+제목 복사],
조회: 33210
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 7개 있습니다.)
(시리즈 글이 14개 있습니다.)
개발 환경 구성: 83. Hyper-V의 네트워크 유형 (1)
; https://www.sysnet.pe.kr/2/0/910

개발 환경 구성: 84. Hyper-V의 네트워크 유형 (2)
; https://www.sysnet.pe.kr/2/0/915

개발 환경 구성: 87. Hyper-V의 네트워크 유형 (3)
; https://www.sysnet.pe.kr/2/0/918

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

개발 환경 구성: 330. Hyper-V VM의 Internal Network를 Private 유형으로 만드는 방법
; https://www.sysnet.pe.kr/2/0/11299

Windows: 174. WSL 2의 네트워크 통신 방법
; https://www.sysnet.pe.kr/2/0/12347

개발 환경 구성: 517. Hyper-V Internal 네트워크에 NAT을 이용한 인터넷 연결 제공
; https://www.sysnet.pe.kr/2/0/12352

개발 환경 구성: 522. WSL 2 인스턴스와 호스트 측의 Hyper-V에 운영 중인 VM과 네트워크 연결을 하는 방법
; https://www.sysnet.pe.kr/2/0/12494

개발 환경 구성: 656. Internal Network 유형의 스위치로 공유한 Hyper-V의 VM과 호스트가 통신이 안 되는 경우
; https://www.sysnet.pe.kr/2/0/13199

개발 환경 구성: 660. WSL 2 내부로부터 호스트 측의 네트워크로 UDP 데이터가 1개의 패킷으로만 제한되는 문제
; https://www.sysnet.pe.kr/2/0/13230

개발 환경 구성: 665. WSL 2의 네트워크 통신 방법 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/13256

개발 환경 구성: 670. WSL 2에서 호스팅 중인 TCP 서버를 외부에서 접근하는 방법
; https://www.sysnet.pe.kr/2/0/13280

개발 환경 구성: 712. Windows - WSL 2의 네트워크 통신 방법 - 세 번째 이야기 (같은 IP를 공유하는 WSL 2 인스턴스)
; https://www.sysnet.pe.kr/2/0/13647

개발 환경 구성: 714. WSL 2 인스턴스와 호스트 측의 Hyper-V에 운영 중인 VM과 네트워크 연결을 하는 방법 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/13658




WSL 2의 네트워크 통신 방법

이번 글은 다음의 문서 중 네트워크 부분만을 정리한 것입니다.

Comparing WSL 1 and WSL 2
; https://learn.microsoft.com/en-us/windows/wsl/compare-versions




우선, WSL 2가 설치되면 Hyper-V의 Virtual Switch로 "
Internal network" 유형의 "WSL" 항목이 생기고, "제어판"의 네트워크 연결에서는 "vEthernet (WSL)" 어댑터로 나타납니다. (2024-06-16 업데이트: 어느 순간부터 hidden 처리되었습니다.) 따라서, WSL 2와 호스트 측의 네트워크는 "vEthernet (WSL)"에 따라 구성되는데 예를 들어 다음은 호스트 측과 "WSL 2" 측의 IP 구성을 보여줍니다.

C:\> ipconfig

...[생략]...

Ethernet adapter vEthernet (WSL):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::85ec:2234:8334:9fd4%55
   IPv4 Address. . . . . . . . . . . : 172.18.176.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

C:\> wsl hostname -I
172.18.178.192

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.178.192  netmask 255.255.240.0  broadcast 172.18.191.255
        inet6 fe80::215:5dff:fe9d:7896  prefixlen 64  scopeid 0x20<link>
        ether 00:15:5d:9d:78:96  txqueuelen 1000  (Ethernet)
        RX packets 2719  bytes 660952 (660.9 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 132  bytes 10729 (10.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

...[생략]...

하지만, 일반적인 Virtual Switch의 경우와는 다르게, WSL 스위치에 대해서는 호스트 측에서 "localhost"와 매핑할 수 있는 배려를 해두었습니다. 이로 인해 WSL 2 내에서 TCP 서버를 (에를 들어, 15000번 포트로) 열어두었다면, 그것을 호스팅하는 Windows 10 PC에서는 "localhost:15000"으로 접속을 할 수 있습니다.

하지만, 그 반대로는, 즉 호스팅 운영체제 측에서 TCP 서버 소켓을 열고 그것을 "WSL 2" 내의 응용 프로그램에서 "localhost:15000"으로 접속하는 것은 가능하지 않습니다. 만약 WSL 2 측에서 호스트 측으로 접속하고 싶다면 원칙적으로 "vEthernet (WSL)" 스위치의 네트워크를 따라 "172.18.176.1:15000"으로 접속해야 합니다.

문제는, 만약 일반적인 응용 프로그램을 만든다면 "172.18.176.1" 값을 쉽게 알 수 없다는 점인데, 다행히 "WSL 2"에서 호스팅하는 리눅스에서는 resolv.conf에 이를 기록해 둔다고 합니다.

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.18.176.1
(2024-06-16 업데이트) 근래에는 resolv.conf의 내용이 바뀌었는데,

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 10.255.255.254

저 10.255.255.254는 WSL 2 인스턴스 입장에서의 127.0.0.1과 동일한 루프백 주소입니다.

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 10.255.255.254/32 brd 10.255.255.254 scope global lo
       valid_lft forever preferred_lft forever
    ...[생략]...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    ...[생략]...

따라서 별도의 방법으로 구해야 하는데요, 문서에 보면,

Accessing Windows networking apps from Linux (host IP)
; https://learn.microsoft.com/en-us/windows/wsl/networking#accessing-windows-networking-apps-from-linux-host-ip

그냥 default 게이트웨이의 주소를 구하는 것으로 소개하고 있습니다.

ip route show | grep -i default | awk '{ print $3}'




또한 "vEthernet (WSL)" 어댑터가 일반적인 다른 Hyper-V의 Virtual Switch였다면, ("Internal network" 유형이므로) 당연히 WSL 2 내에서는 인터넷 접속이 안 되어야 합니다. 하지만, 이것 역시 가능하게 만들어 둔 배려가 있고!

그렇다면 인터넷에서 "WSL 2"로 접근하려면 어떻게 해야 할까요? 기본적으로 "vEthernet (WSL)"이 구성한 네트워크는 "internal" 유형이므로 외부에서 접근할 수 있는 방법이 없습니다. 대신 호스트 측에 포트 포워딩을 설정해 "WSL 2"로의 접근을 가능하게 만드는데요, 예를 들어, "15000" 포트로 Listen 하는 프로그램을 WSL 2에 실행한 경우, 그것을 호스트 측의 IP로 접근하고 싶다면 다음과 같은 설정을 하면 됩니다.

// netsh의 portproxy는 (WSL을 위한 것이 아닌) 원래 있던 고유의 기능입니다.

C:\temp> netsh interface portproxy add v4tov4 listenport=15000 listenaddress=0.0.0.0 connectport=15000 connectaddress=172.18.178.192

C:\temp> netsh interface portproxy show v4tov4

Listen on ipv4:             Connect to ipv4:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
0.0.0.0         15000       172.18.178.192  15000

이렇게 환경 구성이 되면, 외부에서 호스트 측의 IP(위의 글에서는 172.18.176.1을 비롯해 기타 어댑터가 소유한 IP)로 15000 포트를 지정해 접근할 수 있습니다.

참고로, 삭제는 이렇게!

C:\temp> netsh interface portproxy delete v4tov4 listenport=15000 listenaddress=0.0.0.0

위의 설정에서 한 가지 유의할 점이 있다면, listenport=15000, connectport=15000 포트 번호를 다르게 하는 것이 권장됩니다. 왜냐하면, 일단 저렇게 portproxy 설정을 하면 listenport에 대해 IP Helper(iphlpsvc) 서비스가 "0.0.0.0:15000"으로 바인딩을 하게 됩니다.

그 와중에, WSL 내에서 15000 포트를 바인딩하려고 하면, 즉 "127.0.0.1:15000" 또는 "0.0.0.0:15000"으로 바인딩 시도를 할 텐데요, 당연히 IP Helper가 열고 있는 바인딩과 충돌이 발생하므로 열리지 않습니다. 따라서 그런 문제를 피하기 위해서라도 포트 번호는 다르게 하는 것이 좋습니다.

같게 하는 경우, 약간 불편하지만 방법은 있습니다. IP Helper 서비스를 종료시켜 0.0.0.0:15000 바인딩을 내리고, WSL 내에서 15000 바인딩을 해둡니다. 어떤 식으로 하든 127.0.0.1:15000으로 바인딩이 될 텐데요, 따라서 이후 IP Helper 서비스를 올려도 0.0.0.0:15000과 충돌이 발생하지 않아 정상적으로 서비스가 운영됩니다. (또는, 어차피 바인딩의 문제이므로 port는 같더라도 listenaddress를 0.0.0.0이 아닌 192.168.100.50과 같이 외부로부터의 접근 시 사용하는 IP를 직접 지정해도 좋겠습니다.)




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/16/2024]

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

비밀번호

댓글 작성자
 



2021-03-22 11시58분
How to automatically start the Docker daemon on WSL2
; https://blog.nillsf.com/index.php/2020/06/29/how-to-automatically-start-the-docker-daemon-on-wsl2/

참고로, WSL에서 열어둔 포트가 호스트 측에서 안 보이는 경우가 있었는데 "wsl --shutdown"으로 다시 시작하면 복구가 되었습니다.
정성태
2022-03-07 10시21분
[UDP] 안녕하세요, 한가지 질문이 있는데 혹시 위의 포트포워딩 방식은 UDP 통신은 불가능한건가요?
[guest]
2022-03-07 01시56분
이름만으로 보면 udp 지원을 알 수가 없군요. ^^ v4tov4라는 걸로 봐서는 IP 레벨이므로 TCP/UDP 모두 포함할 것 같은데, 반면 UDP에서는 Listen이라는 단계가 없다는 걸 고려할 때 굳이 옵션명에 listen...을 추가했으니 마치 TCP만 되는 것 같군요. 해보시고 결과 좀 알려주세요. ^^

아래의 글에 따라,

WSL 2 내부에서 열고 있는 UDP 서버를 호스트 측에서 접속하는 방법
; https://www.sysnet.pe.kr/2/0/13268

UDP 포트 포워딩은 (현재) 지원하지 않습니다.
정성태
2022-09-05 04시53분
[이상규] 안녕하세요 감사합니다 선생님! 저는 linux로 개발하는 사람인데...이번에 로봇팔 제어하시는 분이 윈도우에서만 작업이 가능하다 하셔서....꾸역꾸역 wsl가지고 작업중이었는데 많은 도움이 됐습니다 you saved my day!
[guest]

... 151  152  153  154  155  156  157  158  159  [160]  161  162  163  164  165  ...
NoWriterDateCnt.TitleFile(s)
1048정성태5/27/201132254개발 환경 구성: 123. Apache 소스를 윈도우 환경에서 빌드하기
1047정성태5/27/201126117.NET Framework: 217. Firebird ALinq Provider - 날짜 필드에 대한 낙관적 동시성 쿼리 오류
1046정성태5/26/201130784.NET Framework: 216. 라이선스까지도 뛰어넘는 .NET Profiler [5]
1045정성태5/24/201131874.NET Framework: 215. 닷넷 System.ComponentModel.LicenseManager를 이용한 라이선스 적용 [1]파일 다운로드1
1044정성태5/24/201132437오류 유형: 122. zlib 빌드 오류 - inflate.obj : error LNK2001: unresolved external symbol _inflate_fast
1043정성태5/24/201131418.NET Framework: 214. 무료 Linq Provider - DbLinq를 이용한 Firebird 접근파일 다운로드1
1042정성태5/23/201137737개발 환경 구성: 122. PHP 소스를 윈도우 환경에서 빌드하기
1041정성태5/22/201128632.NET Framework: 213. Linq To SQL - ALinq Provider를 이용하여 Firebird 사용파일 다운로드1
1040정성태5/21/201138958개발 환경 구성: 121. .NET 개발자가 처음 설치해 본 Apache + PHP [2]
1039정성태5/17/201131656.NET Framework: 212. Firebird 데이터베이스와 ADO.NET [2]파일 다운로드1
1038정성태5/16/201133629개발 환경 구성: 120. .NET 프로그래머에게도 유용한 Firebird 무료 데이터베이스 [2]
1037정성태5/11/201128468개발 환경 구성: 119. Visual Studio Professional 이하 버전에서도 TFS의 정적 코드 분석 정책 연동이 가능할까? [3]
1036정성태5/7/201194266오류 유형: 121. Access DB에 대한 32bit/64bit OLE DB Provider 관련 오류 [11]
1035정성태5/7/201129022오류 유형: 120. File cannot be opened. Ensure it is a valid Data Link file.
1034정성태5/2/201126059.NET Framework: 211. 파일 잠금 없이 .NET 어셈블리의 버전을 구하는 방법 [2]파일 다운로드1
1033정성태5/1/201131772웹: 19. IIS Express - appcmd.exe를 이용한 applicationHost.config 변경 [2]
1032정성태5/1/201128423웹: 18. IIS Express를 NT 서비스로 변경
1031정성태4/30/201129572웹: 17. IIS Express - "IIS Installed Versions Manager Interface"의 IIISExpressProcessUtility 구하는 방법 [1]파일 다운로드1
1030정성태4/30/201151849개발 환경 구성: 118. IIS Express - localhost 이외의 호스트 이름으로 접근하는 방법 [4]파일 다운로드1
1029정성태4/28/201140979개발 환경 구성: 117. XCopy에서 파일/디렉터리 확인 질문 없애기 [2]
1028정성태4/27/201138371오류 유형: 119. Visual Studio 2010 SP1 설치 후 Windows Phone 개발자 도구로 인한 재설치 문제 [3]
1027정성태4/25/201127548디버깅 기술: 40. 상황별 GetFunctionPointer 반환값 정리 - x86파일 다운로드1
1026정성태4/25/201145836디버깅 기술: 39. DebugDiag 1.1을 사용한 덤프 분석 [7]
1025정성태4/24/201127895개발 환경 구성: 116. IIS 7 관리자 - Active Directory Certification Authority로부터 SSL 사이트 인증서 받는 방법 [2]
1024정성태4/22/201129198오류 유형: 118. Windows 2008 서버에서 Event Viewer / PowerShell 실행 시 비정상 종료되는 문제 [1]
1023정성태4/20/201130084.NET Framework: 210. Windbg 환경에서 확인해 본 .NET 메서드 JIT 컴파일 전과 후 [1]
... 151  152  153  154  155  156  157  158  159  [160]  161  162  163  164  165  ...