📖Windows 운영 체제에서 Linux 실행 환경을 제공하는 기술로서 Windowns10 이상의 버전에서만 사용가능하다.
wsl은 Windows와 Linux 커널 간의 가상화를 사용해서 실행 환경을 제공한다. 또한, Linux 환경 액세스를 지원하여 소프트웨어 및 도구를 설치하고 실행하는 것도 가능하게 해준다.
그렇다면 어떤 원리로 동작하게 되는지 아래 그림을 통해 알아보자.
그럼에서 볼 수 있듯이 Hyper-V(하이퍼브)
의 도움으로 windows usermode와 linux usermode가 액세스하고 접근이 가능하다.
wsl을 사용하기 이전까지는 VM(이하 가상머신)
을 사용해서 리눅스를 동작시켰다. 하지만 wsl을 통해 windows 환경에서 리눅스가 네이티브하게 동작 할 수 있게 된 것이다. 여기서 큰 역할을 하는 것이 하이퍼브
이다.
하이퍼브
에 대해 간단히 이야기하자면 하이퍼브
는 가상화 기술 및 가상화 플랫폼으로 하드웨어 가상화를 통해서 가상머신
을 호스팅하고 관리 할 수 있다.
그렇다면 windwos에서 wsl로 외부접속을 하는 흐름에 대해서 그림을 통해 알아보자.
위 그림에서 보여지는 흐름의 예시 상황은 다음과 같다.
그렇다면 예시를 순서로 나열했을 때 어떻게 흘러가는지 알아보자.
포트포워딩
을 수행한다.이런 흐름을 통해 외부접속이 이루어진다. 즉, windows PC에서 구동중인 wsl에 배포된 Application에 접속하기 위해서는 포트 포워딩 설정이 필요하다.
포트포워딩은 쉽게 설명해서 공개된 ip:port
를 내부 ip:port
로 전달해주는 개념이라고 이해하면 된다.
그렇다면 어떻게 설정을 하는지 알아보자.
wsl의 내부 ip를 확인하기 위하여 ifconfig를 사용해야하는데 해당 툴을 설치해주자.
# 설치
sudo apt-get install net-tools
# 실행
ifconfig
실행을 했을 때 ip가 출력이 되면 성공적으로 설치가 된 것이다.
wsl에 기존에 설치된 openssh-server 문제가 있다는 이야기가 많아서 삭제하고 새로 깔아주자.
sudo apt remove openssh-server # 기존 설치 삭제
sudo apt update # 패키지 업데이트
sudo apt install openssh-server # 재설치
이후 설치된 openssh-server 설정을 변경해주자
# sshd_config
sudo vim /etc/ssh/sshd_config
# Port 22를 주석해제
Port 22
# PasswordAuthentication no 또는 주석을 변경
PasswordAuthentication yse
# 서버 재시작
sudo service ssh --full-restart
다음은 포트 포워딩을 해주기 위한 스크립트 .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=@(80,443,5000,22);
$addr='0.0.0.0';
$ports_a = $ports -join ",";
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
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";
}
Invoke-Expression "netsh interface portproxy show v4tov4";
스크립트에 대한 설명은 다음과 같다.
$remoteport
및 IP 주소 확인 : wsl의 ifconfig
명령어를 bash
로 수행하여 네트워크 정보 획득 후 ip가 있는 경우 $remoteport
에 저장$ports
에 배열 형태로 포워딩을 희망하는 포트
들을 저장New-NetFireWaalRule
명령을 이용해 외부 포트 연결 허용
netsh interface portproxy
명령을 사용해 windows pc 포트 포워딩
설정Windows PowerShell 관리자 권한으로 실행 후 아래 명령어로 스크립트를 실행한다.
# ports_wsl.ps1 파일과 동일한 디렉토리에서
.\ports_wsl.ps1
아래 형태의 화면이 나오면 접속 가능하다. 이 때 접속을 요청할 IP는 아래에 보이는 172.17.209.130의 위치에 적혀있는 ip로 접속 요청을 하면된다.
혹시 아래와 같은 문구가 나오면 다음과 같이 조치한다.
이 시스템에서 스크립트를 실행할 수 없으므로 C:\ports_wsl.ps1 파일을 로드 할 수 없습니다.
자세한 내용은 about_Executio n_Policies(https://go.microsoft.com/fwlink/?LinkID=135170)를%EB%A5%BC) 참조하십시오.
PowerShell 관리자 권한 실행 → ‘Set-ExecutionPolicy RemoteSigned’ 입력 후 ports_wsl.ps1 스크립트 재실행을 수행한다.
이제 wsl의 설정을 완료했으니 Windows 머신의 포트 액세스를 허용해주자.
위 절차를 완료하고 해당 인바운드 규칙 이름을 찾아서 규칙 사용을 실행하면 된다. 여기까지 설정을 완료해도 접속을 시도하면 timeout
에러가 발생한다.
마지막으로 wsl에 한가지 설정을 추가하자.
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=<WSL2_IP>
위와 같이 설정하면 Windows 호스트 머신의 80번 포트로 들어오는 요청이 wsl의 내부 ip 주소로 전달되어 접근이 가능하게 된다. 희망하는 포트가 여러개일 경우 모든 포트를 설정해주어야한다.
위 사진에서보면 5432
포트가 127.0.0.1:5432
로만 접속이 가능하다면 외부에서는 해당 포트로 아무리 접속을 하고 싶어도 하지 못한다. 이럴때는 각 서버(DB, WAS 등)에서 설정을 통해 0.0.0.0
으로 접속을 허용해 주어야하고, 127.0.0.1:5432
가 0.0.0.0:5432
로 변경 또는 추가가 되어있어야 접속이 가능하다.
또는 tcp(Ipv4)
로 구동되어야하는 프로세스가 tcp6(Ipv6)
로 구동된다. 이 때 Ipv6
를 미사용하게 설정하면된다. 다음 절차를 따라하자.
# 입력
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
# 결과 net.ipv6.conf.all.disable_ipv6 = 1
# 입력
sudo sysctl -a | grep net.ipv6.conf | grep disable_ipv6
# 결과
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
이렇게 설정을 완료해주면 windows 공개 ip:port를 통해 접속이 가능하다.