Post

WSL 외부접속 및 ssh 자동 시작

목차


WSL 외부접속 및 ssh 자동 시작


윈도우가 시작되었을 때 기본적으로 wsl ssh 서비스는 자동으로 시작되지 않는다.

이를 스크립트를 통해 자동으로 시작시키도록 한다.

Win + R 키를 눌러 shell:startup 명령어 실행시키면 파일 탐색기가 실행되며 시작 프로그램 이라는 폴더가 나온다.

해당 폴더에 wsl_connect.bat 파일 생성

아래 내용 복사

(관리자권한을 획득한 뒤 파워쉘 및 bash 직접실행을 통해 ssh 및 기타 서비스를 실행시킴.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@echo off
set uaccheck=0

:: Get Admin Permission

:CheckUAC
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' NEQ '0' (
    goto UACAccess
) else ( goto Done )

:UACAccess
echo "Request to get admin permission"
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\uac_get_admin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\uac_get_admin.vbs"
"%temp%\uac_get_admin.vbs"
del "%temp%\uac_get_admin.vbs"
exit /b

:Done
echo "Success to get admin permission"
echo.

:: WSL port forwarding powershell script
powershell.exe C:\Users\HOME_NAME\AppData\wsl_connect.ps1

:: bash service start
"C:\Windows\System32\bash.exe" -c "sudo service ssh start"
"C:\Windows\System32\bash.exe" -c "sudo service nginx start"
"C:\Windows\System32\bash.exe" -c "sudo service php7.2-fpm start"

exit /b

파워쉘 스크립트를

Win + R 키를 눌러 appdata 명령어 실행시키면 파일 탐색기가 실행되며 AppData 폴더가 나온다.

해당 폴더에 wsl_connect.ps1 파일 생성

해당 파일에 아래 내용 복사

열고싶은 포트를 $ports 변수의 리스트에 추가한다.

첫 줄의 파일 path를 수정한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# PowerShell.exe -noexit C:\test.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=@(9232,8888,44433,3333);

#[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";

# iex "netsh interface portproxy reset";

for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  echo $port
  echo $addr
  echo $remoteport
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
  iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
  # iex "netsh interface portproxy add v4tov4 listenport=$port connectport=$port connectaddress=$remoteport";
}

# Invoke-Expression "netsh interface portproxy show v4tov4";

만약 powershell 스크립트가 정상적으로 실행되지 않는다면

  1. 파워쉘을 관리자 권한으로 실행시킨다.
  2. get-ExecutionPolicy 로 현재 권한 상태를 확인한다.
    1. 에러가 날 경우 아마 Restricted 상태이기에 발생하는 문제일 것이다.
    1
    2
    3
    4
    5
    6
    
     Restricted : default설정값으로, 스크립트 파일을 실행할 수 없다.
     AllSigned : 신뢰할 수 있는(서명된) 스크립트 파일만 실행할 수 있다.
     RemoteSigned : 로컬에서 본인이 생성한 스크립트와, 신뢰할 수 있는(서명된) 스크립트 파일 실행할 수 있다.
     Unrestricted : 모든 스크립트 실행가능하다.
     ByPass : 경고/차단 없이 모든 것을 실행가능하도록한다.
     Undefined : 권한을 설정하지 않았다.
    
  3. Set-ExecutionPolicy RemoteSigned 명령어를 통해 권한을 RemoteSigned 로 변경해준다.
  4. 파워쉘 스크립트를 실행한다!

wsl을 키고 루트 접속한 뒤

배쉬 스크립트에서 루트 권한 없이 service 명령어를 실행시켜야 하므로

/etc/sudoers 파일을 루트권한으로 열고 맨 마지막 줄에 아래 라인을 추가한다.

wsl 디폴트 계정명은 wsl.exe를 실행시켰을 때 whoami 명령어를 치면 알 수 있다.

1
계정명 ALL=NOPASSWD: /usr/sbin/service

vi로 열었으면 수정이 끝난 뒤 :w! 명령어를 통해 강제로 저장하고 빠져나온다.

다시 시작하거나 wsl_connect.bat 파일을 실행시키면 정상적으로 외부접속이 가능할 것이다.

(만약 다른 컴퓨터에서 외부접속이 안된다 하면 공유기 포트포워딩 설정, 윈도우 방화벽 설정 추가 확인 바람.)

This post is licensed under CC BY 4.0 by the author.