node.js를 WSL2에서 구동하였는데 로컬만 접속되고 외부에서는 접속이 안돼요
Django를 WSL2에서 구동하였는데 외부에서 접속이 안돼요
와 같은 문제점을 해결하는 글입니다
현재 Window10 preview 2004 버전에서는 WSL2환경이 지원된다
5월 중으로 정식 업데이트가 된다고 하지만, Docker환경이 지원된다는 소식에 참지 못하고 프리뷰로 사용하고 있다.
크게 기존 WSL1은 Docker 사용을 비롯한 Unix소켓 지원이 안되어 Docker를 사용하려면
Windows Docker를 WSL환경에서 사용하였다.
WSL2에선 이제 Native Docker를 사용할 수 있다! 심지어 Windows Docker에서도 WSL의 Docker Daemon을 사용할지 설정할 수 도 있게 되었다.
그러나, WSL2는 로컬에서 이더넷 어댑터를 통해 연결이 되어있다.
풀어 말하자면, WSL2에서 서버를 실행하면 로컬만 연결되며, 외부와는 연결되지 않는다는 것이다
바로 이 글을 쓰게 된 이유이다.
WSL2의 네트워크 어댑터는 아래와 같이 구성 됨을 확인할 수 있다.
PS C:\scripts> ipconfig
Windows IP 구성
이더넷 어댑터 vEthernet (WSL):
연결별 DNS 접미사. . . . :
링크-로컬 IPv6 주소 . . . . : ****::****:****:****:*******
IPv4 주소 . . . . . . . . . : 172.22.192.1
서브넷 마스크 . . . . . . . : 255.255.240.0
Reddit에서 "WSL2, 이제 localhost와 연결돼요!" 라는 WSL 업데이트 소식이 도대체 무엇을 말하는지 이제야 알게 되었다
(WSL1 에선 당연히 localhost와 연결되었으니 말이다)
WSL2 내에서 서버를 동작하면 다음과 같은 과정으로 연결이 된다
로컬의 내부IP(192.168.0.20)
->WSL2 어댑터의 주소(172.22.192.40)
랩탑에서 자신의 로컬 환경을 외부에서 접속하려면 port foward작업을 통해 해결하였다
로컬의 외부IP
->로컬의 내부IP(192.168.0.20)
그렇다면 WSL2에 대해서도 연결될 수 있게 Port Forward작업을 해주면 되지 않을까?
아래처럼 말이다
로컬의 외부IP
-> 로컬의 내부IP(192.168.0.20)
-> WSL2 어댑터의 주소(172.22.192.40)
# 로컬에서 WSL2로의 Port Foward 연결
$my_wsl_address = 172.22.192.40
$port = 8000
netsh interface portproxy add v4tov4 listenport=$port listenaddress='0.0.0.0' connectport=$port connectaddress=$my_wsl_address
위의 작업으로 어느 정도 해결이 된 것 같다.
그러나, 윈도우를 새로 시작할 때마다 WSL2의 IP는 변경되기에
매번 이 작업을 수행하기엔 번거로울 것이다. 더군다나 포트마다 설정해줘야 한다.
Github의 Microsoft WSL Repository의 Issue에서도 이와 관련해 많은 내용들이 오갔고
https://github.com/microsoft/WSL/issues/4150#issuecomment-504209723
해당 커멘트를 통해 쉽게 해결할 수 있었다.
이 글을 읽는 분들을 위해 해당 스크립트를 가져왔다.
아래의 스크립트를 *.ps1
확장자로 저장하고 윈도우 작업 스케쥴러에서
트리거를 컴퓨터 시작 시
로 지정하면 해결된다.
포트 설정의 경우 스크립트 내의
$ports=@(80,443,10000,3000,5000);
에서 추가/제거를 하면 된다
wsl-connect-external.ps1
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
#[Ports]
#All the ports you want to forward separated by coma
$ports=@(80,443,10000,3000,5000);
#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
#Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
#adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}
-
Execution Policy와 관련해 오류를 내어 동작하지 않는다면?
PowerShell.exe -ExecutionPolicy Bypass -File .\wsl-forward-server.ps1
Execution Policy를 설정해 스크립트가 실행되도록 한다
도움이 된 글들
https://m.blog.naver.com/seongjin0526/221778212779
https://github.com/microsoft/WSL/issues/4150
만일, 본문에 잘못된 내용이 있다면 지적 환영합니다
댓글