https://jackcokebb.tistory.com/18
개요
본인은 windows wsl환경에서 개발하고 있다.
개발을 하다보면 wsl에 ssh로 접속하거나 디바이스를 서버로써 활용하고 싶을 때가 있다.
그러나 공유기 환경에서 사용하다보니 디바이스의 사설 ip가 부팅할 때마다 변경되었고,
wsl 또한 디바이스의 사설 ip와는 별개로, 가상 ip가 주어지는데 이 또한 부팅할 때마다 변경되었다.
wsl에 접근하기 위해서는
외부에 알려진 나의 공인 ip의 특정 포트를 현재 쓰고 있는 기기의 사설 ip와 포트에 포워딩해줘야 하고,
그것을 다시 wsl의 ip와 포트에 포워딩 해줘야 하는 것이다.
결과적으로,
우리는 디바이스의 사설 ip를 고정해야 하며,
부팅할 때마다 wsl의 ip를 가지고 포트를 포워딩 해줘야한다.
기기의 고정 ip 할당하기
일단 공인 ip의 특정 포트로 사용자 또는 request가 접근했을때,
쓰고자 하는 기기의 사설 ip의 특정 포트로 포워딩 되어야한다. 하지만 부팅할 때마다 사설 ip가 변경되면 포트포워딩 룰을 추가해두더라도 다음 부팅 시에는 그 룰이 무용지물이 되어버린다.
따라서 일단 사설 ip부터 고정해주자!
현재 나는 netis 공유기를 사용하고 있지만, 공유기 설정은 다른 회사 공유기더라도 대강 비슷한 것 같다.
일단 공유기 설정에 접근해준다. netis기준 192.168.1.1 로 접속하면 된다.
로그인 후에 고급설정에 들어가면, 기본 설정에 고정 ip 주소 등록 이 있다.
이런 식으로 본인이 원하는 규칙 이름과 현재 사용 중인 pc의 mac주소, ip를 등록할 수 있다.
등록하면 재부팅하더라도 이 기기는 등록된 ip로만 ip가 고정된다.
포트 포워딩 (public ip:port → private ip:port)
공유기 설정에 들어온 김에 포트도 포워딩 해주자.
외부에 노출되는 공인 ip와 포트를 사설 ip와 포트에 포워딩 해주는 것이다.
그대로 고급설정 에서 방화벽 설정 에 포트 포워딩 이 있다.
여기에 포워딩하고자 하는 포트를 명시해주자.
예를 들어 첫번째 룰은 공인 ip가 201.11.11.111 이라면,
201.11.11.111의 2222포트로 접근하면 192.xxx.xxx.xxx 의 22번 포트로 포워딩하라는 뜻이다.
나는 wsl에 ssh 로 접속하고, flask 서버도 열기 위해 22번과 5000번을 포워딩했다.
ssh의 외부 포트를 2222로 한 것은 뻔하게 22번으로 열어두면 공격이 들어올 수 도 있다고해서 2222로 지정했지만, 사실 누가 내 컴퓨터를 공격할까 싶긴 하다.
wsl에서 사전 준비
우리는 wsl의 포트 포워딩을 위해 ifconfig라는 명령어를 사용하게 된다.
하지만 이는 디폴트로 설치되어있지 않은 것 같다. 따라서 설치해주자
sudo apt-get install net-tools
만약 ssh로 wsl에 접속하려고 하는 것이라면…
openssh-server 재설치
이곳 저곳 알아본 결과 wsl를 설치할 때 기본으로 설치되는 openssh-server가 문제가 있다는 것 같다.
삭제하고 새로 깔아주자
sudo apt remove openssh-server
sudo apt update
sudo apt install openssh-server
sshd_config 파일 수정
sshd_config 파일은 ssh 설정 파일이다. ssh 서버를 열기 위해 살짝 수정해줘야한다. 수정에는 root 권한이 필요하다.
sudo vi /etc/ssh/sshd_config
Port 22
PasswordAuthentication yes
주석 처리되어 있는
#Port 22 -> 주석해제
PasswordAuthentication no 를
PasswordAuthentication yes 로 변경
#ssh 서버 재시작
sudo service ssh --full-restart
ssh 서비스 부팅 시 자동 실행 설정
윈도우를 부팅한다고 해서 자동으로 wsl이 실행되는 것은 아니다.
그럼 wsl의 ssh 서버 또한 자동으로 시작되지 않을 것이다.
요것을 자동으로 시작하도록 설정해보자!
메모장을 키고
@echo off
"C:\Windows\System32\bash.exe" -c "sudo service ssh start"
요대로 복사한뒤 파일 이름을 sshd.bat로 저장하자
window키 + r 을 눌러 실행창을 띄우고 shell:startup 을 실행하여 시작프로그램 폴더를 띄운다. 그리고 이 폴더에 sshd.bat 을 넣자!
ssh service를 sudo 비밀번호 없이 시작하도록 설정
service를 멈추거나 시작하려면 권한이 필요해서 비밀번호를 요구하게 된다. (sudo)
자동으로 시작하게 하기 위해 비밀번호를 절차를 없애보자.
#sudoers 파일 열기
sudo visudo
#열린 파일 가장 밑에 이 구문을 추가하고 저장.
%sudo ALL=NOPASSWD: /usr/sbin/service
이제 service를 실행할 때 비밀번호 절차 없이 가능하다.
스크립트 작성
재부팅될 때마다 새로 할당되는 wsl의 가상 ip를 부팅할때마다 포워드 해주기 위해 스크립트를 작성해보자
포트포워딩 스크립트(기기의 사설ip:port → wsl의 가상 ip:port)
$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,5000,22);
#[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";
}
Invoke-Expression "netsh interface portproxy show v4tov4";
이 스크립트를 그대로 메모장에 복사하고, $ports 부분에 열고자하는 port 번호를 넣는다. 본인은 아까 공유기에서 포워딩 해주었던대로 22, 5000을 넣었다.
저장할 때 .ps1확장자로 설정해주면 된다. (확장자를 제외한 파일 이름은 자유)
이 스크립트는 bash를 실행시키고 ifconfig 명령어를 실행시켜 변경된 ip를 찾고, 이전에 설정한 방화벽 설정을 지우고 변경된 ip를 적용하여 다시 방화벽 설정을 한다.
또한 열고자 하는 port에 대하여 이전 포워딩 룰을 지우고 새로 등록한다.
작업 스케줄러 작성 및 ExcutionPolicy 지정
이제 이 스크립트를 부팅할 때마다 실행하도록 설정해 주어야 한다.
window키 + r 을 눌러 실행창을 띄우고 taskschd.msc 를 실행하여 작업 스케줄러를 열어주자
- 작업 만들기
2. 일반 설정
- 작업 이름 기억하기 좋은 걸로 설정
- 가장 높은 수준의 권한으로 실행 체크
3. 트리거 설정
- 작업 시작: 로그온할 때
- 작업 지연 시간 30초 (ssh 서버 여는 시작프로그램 먼저 실행하기 위해)
4. 동작 설정
(본인은 이미 만들어 놔서 있는거임!!)
- 프로그램/ 스크립트:
- C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
- powershell 프로그램 경로임
- 인수추가:
- noprofile -executionpolicy bypass -file <아까 만든 .ps1 파일 경로>
5. 조건 설정
6. 설정 탭 설정
7. 확인 눌러서 저장!
이제 부팅할 때마다 스크립트가 실행되어 포워딩을 해줄 것이다!
스크립트 직접 돌려보기
powershell 을 관리자 권한을 열고
PowerShell.exe -ExecutionPolicy Bypass -File <아까 만든 .ps1 스크립트 경로>
이대로 실행하면 실행 결과를 볼 수 있다.
“지정된 파일을 찾을 수 없습니다.” 와 같은 오류가 뜨면 한번 더 실행해주자. 그럼 오류 없이 돌아간다.
접속 테스트
이제 뭐로 접속해야 될까??
공인 ip와 지정한 포트로 접속하면 된다.
아이패드에서 터미널(termius 앱)로 테스트
참고 및 출처
https://webisfree.com/2021-07-14/wsl2-외부-remote-ip-접속-가능하도록-설정하기-방화벽-해제
댓글