WSL(Windows Subsystem for Linux)은 Microsoft가 Windows 10과 Windows Server 2019 이상 버전에서 제공하는 기능으로, 사용자가 Windows 환경에서 직접 Linux 배포판을 실행할 수 있도록 해주는 기능이다. 이를 통해 Windows 사용자들은 별도의 가상 머신이나 듀얼 부팅 없이도 Linux의 다양한 기능과 도구들을 사용할 수 있다.
wsl은 윈도우와 함께 구동되는데 서로 파일시스템도 공유하고 연동이 된다는 점이 매우 편리하다. 사용해 보면서 느낀 하나의 불편한 점은 wsl에서 제공하는 ubuntu는 새로 구동할 때마다 ip가 바뀐다는 점이었다. wsl 우분투 환경에서 서비스를 배포해보려고 했던 나에게 ip가 유동적으로 바뀐다는 것은 매우 디메리트였다.
그래서 오늘은 wsl에서 고정ip 처럼 우분투를 사용할 수 있는 방법에 대해서 소개해보려 한다.
ip고정
1) wsl ip확인
현재 윈도우환경에서 내가 사용하는 ip와 wsl의 ip주소는 서로 다르다. 때문에 리눅스 환경과 상호작용 하기 위해서는 리눅스의 ip를 알아야만 한다. powershell과 wsl 우분투 터미널을 연다. 나 같은 경우 윈도우에서 제공하는 windows terminal을 사용하고 있다. 이 터미널의 장점은 한 실행창 내에서 여러 개의 터미널을 관리할 수 있다는 점이다.
아래 사진을 보면 powershell과 wsl 터미널이 탭으로 동시에 실행되는 것을 확인할 수 있다. 여러개의 터미널을 켜놓고 작업하다 보면 굉장히 지저분한데 windows terminal을 사용하면 폰트도 깔끔하고 각 터미널마다 다른 배경화면을 제공해서 구분도 쉽다.
파워셸과 ubuntu터미널은 명령어가 서로 다르기 때문에 ip를 확인하는 명령어도 서로 다르다.
#powershell
ipconfig
ipconfig명령어를 치게되면 현재 내 pc가 사용 중인 ip주소가 나오게 된다. 현재 나는 노트북 와이파이 환경에서 작업 중이기 때문에 무선 lan주소가 출력된다. Ipv4주소에 192.xxx..xxx.xxx의 형태의 숫자가 바로 내 ip주소이다.
#wsl
ifconfig
wsl은 윈도우 환경 내에 캡슐화되어 있다. 때문에 ip주소도 다른데 eth0의 inet주소가 바로 wsl의 ip주소이다. 172.xxx.xxx.xxx의 형태로 되어있는 것을 볼 수 있고 내 pc(윈도우)의 ip인 192.xxx.... 와 다른 것을 알 수 있다. wsl은 기본적으로 윈도우가 부팅될 때 함께 시작되는데 재부팅될 때마다 다른 ip가 부여된다. 즉 wsl에 서비스를 올리게 되면 재부팅을 할 때마다 설정을 변경해 줄 수도 있게 된다는 의미이다.
2) 포트포워딩
위에서 wsl은 윈도우 환경에 캡슐화되어있다고 말한 적 있다. 즉 외부에서 wsl로 직접접근이 불가능한데 윈도우 위에서 wsl이 구동 중이기 때문에 내 pc의 ip로 들어오는 요청을 우분투로 보내주어야 wsl에 요청이 전달된다. 즉, wsl로 서비스를 배포했을 때 클라이언트가 wsl환경에서 구동 중인 서버로 요청을 보내려면 1) 내 pc(window) ip로 요청을 보내고 2) window는 wsl서버로 요청을 포트포워딩을 하는 두 가지 선행과정이 필요하다.
#nginx서버 구동
실제 서버에 접근 가능한지 테스트 해보기 위해 nginx서버를 설치하고 구동시켜 보자. wsl터미널에서 실행하도록 한다.
#wsl terminal
#nginx 설치
sudo apt install nginx
#nginx서버 구동
sudo systemctl start nginx
#nginx상태 확인
sudo systemctl status nginx
정상적으로 서버가 구동중이면 다음과 같은 메시지가 보일 것이다. 이제 브라우저에서 리눅스 주소로 접속해 보자.
#브라우저 접속
nginx는 wsl에 설치되면 80번 포트로 접근이 가능하다. 브라우저에 wsl ip주소를 입력한다.
잘 실행이 되었다면 다음과 같은 메시지를 확인할 수 있을 것이다. 앞서 wsl에는 직접적인 접근이 불가능하다고 했는데 브라우저에서 실행되는 것이 이상할 수 있다. 그 이유는 로컬환경에서 실행했기 때문이다. 만약 다른 기기에서 접속을 시도한다면 당연히 안될 것이다. 그래서 실제로 내 pc로 들어오는 요청이 wsl로 전달되려면 포트포워딩을 해서 192.xxx로의 요청이 172.xx라는 주소로 매핑되도록 해주어야 한다.
#포트포워딩
window pc로 들어오는 요청을 wsl에 연결해 주려면 window 측에서 작업을 해주어야 한다. 받은 것을 보내주어야 하니 당연하다고 볼 수 있다. 아래 명령어를 통해 포트포워딩 규칙과 목록을 볼 수 있다.
#powershell
#포트포워딩 내역 조회
netsh interface portproxy show all
#포트포워딩 추가
netsh interface portproxy add v4tov4 listenport=<HOST_PORT> listenaddress=0.0.0.0 connectport=<WSL_PORT> connectaddress=<WSL_IP>
#예시
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=172.xxx.xxx.xxx
#포트포워딩 삭제
netsh interface portproxy delete v4tov4 listenport=80 listenaddress=0.0.0.0
-listenport: 내 window pc로 전달받을 포트번호를 지정한다. nginx는 80번 포트를 사용하니 통일감을 위해 80으로 한다.
-listenaddress: 어떤 ip로부터의 요청을 받을지 정한다. `0.0`0.0`은 모든 요청을 받겠단 뜻이다.
-connectport: wsl의 port를 연결한다. nginx가 80번 포트에서 돌아가고 있기 때문에 80으로 한다.
-connectaddress: wsl ip를 기입한다.
나는 기존에 ssh접속을 위해 wsl 22번 포트에 포트포워딩 규칙을 추가해 놓았기 때문에 그 내역이 존재한다. 만약 맨 처음이라면 아무것도 조회되지 않을 것이다.
위 명령어는 관리자권한으로만 수행가능하다. 때문에 powershell을 관리자권한으로 실행해야 한다. 규칙이 추가되고 내역을 조회하니 80번 포트로의 요청이 wsl로 잘 연결되었음을 확인할 수 있다.
#테스트
192.xxx로 시작하는 현재 pc의 ip로 브라우저에서 접속을 시도해도 nginx서버의 index페이지가 잘 보이는 것을 확인할 수 있다. 성공적으로 포트포워딩이 되었다.
3) ip고정하기, 작업 스케줄러
ip를 고정해야 하는 이유는 포트포워딩과정을 살펴보면 알겠지만 wsl의 ip주소를 명시적으로 기입하여 포트포워딩을 해주어야 한다는 것 때문이다. 재부팅이 되면서 wsl의 ip가 달라지면 기존의 포트포워딩 규칙이 쓸모없게 되고 요청을 wsl로 넘겨줄 수 없다.
이런 이유로 wsl의 ip고정이 필요한데 wsl은 자체적으로 ip를 고정하는 기능을 제공하지 않는다. 때문에 window에서 wsl의 ip변경에 따라 포워딩 규칙을 새로 생성해주어야 한다. 이를 위해 파워셸 스크립트와 윈도우 작업 스케줄러를 사용할 것이다.
`작업 스케줄러`는 특정 조건에 따라서 작업을 수행할 수 있도록 해주는 기능이다. 예를 들어 윈도가 시작할 때마다 특정 동작(포트포워딩 규칙을 추가한다)이 수행되도록 할 수 있다. 이 때 실행될 작업을 스크립트로 작성할 수 있는데 이 때 파워셸 스크립트가 사용된다.
윈도우가 시작될 때 wsl은 같이 부팅된다. 동시에 wsl ip가 할당되는데 그 시점의 wsl의 ip주소를 알아내어 기존 포트포워딩 규칙을 삭제하고 새로 알아낸 wsl ip를 포트포워딩에 추가해 주도록 스크립트를 작성해 보도록 하겠다.
#powershell 스크립트파일 생성
일단 ps1확장자를 가진 파일을 하나 생성해 준다. ps1확장자는 powershell 스크립트 파일을 말하며 작업 스케줄러에서 해당 파일을 실행하면 스크립트가 실행되도록 할 수 있다.
#powershell 스크립트 작성(wsl_portforward.ps1)
#기존포트포워딩 삭제
netsh interface portproxy delete v4tov4 listenport=80 listenaddress=0.0.0.0
#재부팅되어 리셋된 wsl ip를 변수에 할당
$wsl_ip = wsl hostname -I | Out-String
$wsl_ip = $wsl_ip.Trim()
#새로운 ip로 포트포워딩
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=$wsl_ip
해당 스크립트가 실행되면 기존의 80번 포트와 관련된 포트포워딩규칙이 삭제되고 wsl의 ip주소를 얻어 새로운 규칙을 추가하게 된다.
wsl_ip라는 변수에 동적으로 wsl의 ip주소를 할당하여 포트포워딩을 수행한다. 이 때 바로 변수를 넣어 포트포워딩을 하게 되면 포트포워딩이 제대로 수행되지 않는다. 아마 윈도우에서 보안관련 정책으로 동적인 값으로 요청을 수행하면 차단하는 듯 하다. 때문에 Out-String으로 문자열로 변환한 후에 사용해야 문제가 생기지 않는다. Trim()은 Out-String작업 후 생기는 공백문자를 삭제해준다.
처음 동적인 변수로 그대로 스크립트를 실행했을 때 포트포워드도 정상적으로 수행되어 보였는데 실제로는 포트포워딩이 작동하지 않아 문제를 찾는데 한참 걸렸다. ip주소는 동적인 변수에 담지 말고 문자열로 변환해서 사용하도록 하자.
#스크립트 실행 테스트
파워셸에서 작성한 스크립트가 올바로 작동하는지 테스트해보자. 변경된 부분을 알기 위해 기존 80->80번 포트로 연결되던 것을 80->90으로 되도록 스크립트(wsl_portforward.ps1) 내용을 변경했다.
#스크립트 실행권한 설정
Set-ExecutionPolicy RemoteSigned
#스크립트파일 실행
C:\wsl_portforward.ps1
#변경된 규칙 확인
netsh interface portproxy show all
실행에 앞서 스크립트를 실행한다는 것은 운영체제에 접근할 수 있다는 뜻이기 때문에 실행권한에 엄격한 규칙이 있다. 때문에 `Set_ExecutionPolicy RemoteSigned` 를 사용해서 해당 pc에서 작성된 스크립트는 모두 실행 가능하도록 설정해 준
다.
이제 스크립트를 실행해 보자.
변경사항이 잘 반영되었다. wsl포트가 90번으로 연결된 것을 확인할 수 있다. 90번으로 바꿨던 스크립트는 다시 원래대로 80으로 돌려놓도록 하자.
이제 이 스크립트만 실행되면 wsl ip는 마치 고정 ip인 것처럼 사용이 가능하다. 어떻게 변경이 되어도 새로 포트포워딩을 해주기 때문이다. 이제 마지막 하나의 작업이 남았다. 다음 시간에는 이 스크립트가 윈도우가 부팅될 때마다 실행될 수 있도록 작업 스케줄러에 스크립트를 등록해 보고 테스트해보도록 하자.
'공부하자 > wsl' 카테고리의 다른 글
[wsl]wsl2(Ubuntu 22.04) ip고정하기 -2(윈도우 작업 스케줄러) (0) | 2024.07.04 |
---|