윈도 WSL 2에서 슬랙웨어 돌리기

1   WSL 2 설치하기

관리자 권한으로 파워셸을 실행한다.

powershell

파워셸에서 다음의 명령들로 WSL 2를 설치한 후 재부팅한다.

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

wsl_update_x64.msi(원본)를 실행해서 리눅스 커널을 갱신한다.

WSL 2를 기본 버전으로 설정한다.

wsl --set-default-version 2

2   슬랙웨어 설치하기

WSLackware를 설치한다.

wsl --import wslackware C:\WSLackware install.tar.gz

슬랙웨어를 시작한다.

wsl -d wslackware

root의 비밀번호를 설정하고 새 사용자를 추가한 후 WSL를 종료한다.

passwd
adduser
exit

새 사용자로 WSL를 다시 시작한다.

wsl -d wslackware -u user

root로 로그인한 다음 WSLackware에서 빠진 패키지들을 설치한다.

su -
slackpkg update
slackpkg install slackware64
slackpkg update
slackpkg upgrade-all
slackpkg clean-system
exit

3   기본 배포본 설정하기

WSLackware를 기본 배포본으로 설정하면 -d wslackware를 입력하지 않아도 된다.

wsl --set-default wslackware
wsl -u user

4   기본 사용자 설정하기

기본 사용자를 root가 아닌 다른 사용자로 설정하면 -u user를 입력하지 않아도 된다. WSL를 실행한 후 /etc/wsl.conf 파일을 생성한다.

cat<<EOT > /etc/wsl.conf
[user]
default=user
EOT
exit

이제 wsl --shutdown한 후 그냥 wsl만 실행하면 WSLackware에서 user로 로그인한다.

5   $HOME 디렉토리에서 시작하기

그냥 wsl를 시작하면 현재 디렉토리에서 bash를 시작한다. 리눅스의 $HOME 디렉토리에서 시작하려면 ~를 추가하면 된다.

wsl ~

6   X 서버 설정하기

이제 X 프로그램들을 실행하기 위해 VcXsrv를 설치한다.

6.1   방화벽 설정

WSL 2는 가상머신에 호스트와 다른 IP 주소를 할당하기 때문에 방화벽에서 공공접근을 허용해야 한다. wf.msc를 시작한 후 Inbound RulesVcXsrv windows xserver (Protocol TCP)의 설정을 다음과 같이 바꾼다.

  • General Action: Allow the connection
  • Scope Remote IP address: These IP addresses에 호스트의 공공 IP 주소를 입력한다. 참고로 여기서 언급한 172.16.0.0/12는 실패했다. 이 설정과 관련이 있을 것 같지만 Group Policy 때문에 수정이 불가능했다. 공공 IP 주소가 없는 다른 컴퓨터에서는 172.16.0.0/12와 192.168.0.0/16를 허용해서 성공했다.

6.2   접근 제한을 해제하는 방법

VcXsrv를 다음과 같이 실행한다.

"C:\Program Files\VcXsrv\vcxsrv.exe" -ac -multiwindow

6.3   .Xauthority 파일을 이용하는 방법

위에서는 VcXsrv의 -ac 옵션을 이용해서 접근 제한을 해제했다. 이 문서에 따르면 이 방법보다는 .Xauthority 파일을 생성하는 것이 더 안전해 보인다.

WSL에서 다음을 실행한다. 여기서 {some-pass-phrase}에 비밀번호를 입력하는데 출처는 못 찾았지만 $ 심볼이 들어가니까 Invalid MIT-MAGIC-COOKIE-1 key 오류가 났다. 어차피 MD5 체크섬이 추가되는데 왜 이런지는 모르겠다. 안전하게 알파벳과 숫자로만 구성하면 된다.

export DISPLAY=a.b.c.d:0.0
magiccookie=$(echo -n '{some-pass-phrase}' | md5sum | awk '{print $1}')
xauth add $DISPLAY . $magiccookie
xauth list
userprofile=$(wslpath $(/mnt/c/Windows/System32/cmd.exe /c "echo %USERPROFILE%" | tr -d '\r\n'))
cp ~/.Xauthority "$userprofile"

이제 VcXsrv를 다음과 같이 실행한다.

"C:\Program Files\VcXsrv\vcxsrv.exe" -auth "%USERPROFILE%\.Xauthority" -multiwindow

이제 WSLackware에서 DISPLAY를 호스트의 공공 IP 주소 a.b.c.d로 설정한 후 xterm을 테스트해 본다.

export DISPLAY=a.b.c.d:0.0
xterm&

호스트의 IP 주소나 호스트명이 계속 바뀔 경우 DISPLAY 변수값도 같이 바뀌어야하기 때문에 .Xauthority 파일을 계속 갱신해야된다는 문제가 있다. 이런 경우에는 접근 제한을 해제하는 방법을 쓰는 것이 더 좋아 보인다.

6.4   윈도 로그인시 자동으로 X 서버 시작하기

Task Scheduler에서 “At log on” 태스크로 다음 중 하나의 vcxsrv.exe 명령이 실행되게 하면 된다.

  • "C:\Program Files\VcXsrv\vcxsrv.exe" -ac -multiwindow
  • "C:\Program Files\VcXsrv\vcxsrv.exe" -auth "%USERPROFILE%\.Xauthority" -multiwindow

7   SSH로 원격 접속하기

7.1   프락시 점프

우선 윈도 머신 win의 sshd를 설정한다. WSL에서는 X11Forwarding yes/etc/ssh/sshd_config 파일에 추가하고 sshd를 시작한다. 이제 원격 머신에서 윈도의 SSH를 점프해서 WSL로 접속하면 된다. ~/.ssh/config에 다음 설정을 추가한다.

Host wsl
ProxyJump win
HostName a.b.c.d
User username
ForwardX11 yes
ForwardX11Trusted yes

문제는 WSL가 아직 정적 IP 주소를 지원하지 않기 때문에 위의 정보를 ~/.ssh/config에 정적으로 저장할 수 없다. 그래서 다음과 같은 셸 스크립트로 필요할 때마다 ~/.ssh/config를 갱신해야 한다. sshwsl 셸 스크립트를 다음과 같이 작성한다.

#!/bin/sh
ip=$(ssh win wsl hostname -I 2> /dev/null | tr -d ' ')
if [ "$ip" != "" ]; then
        sed -i '/^Host wsl$/,/^HostName /{s/^\(HostName \)\(.*\)$/\1'$ip'/}' ~/.ssh/config
        ssh wsl
fi

윈도 머신과 WSL의 SSH 포트가 같으면 localhost나 WSL의 IP 주소인 a.b.c.d 모두 WSL로만 접속되는 문제가 있었다. 윈도 머신의 공공 도메인으로 접속하면 윈도로 접속이 되었지만 localhost와 WSL의 주소가 구분이 안 되는 단점 때문에 WSL의 포트를 다르게 설정했다.

이 문제의 단점은 WSL을 재시작할 때마다 IP 주소가 바뀌기 때문에 .ssh/known_hosts에 자료를 추가하겠냐고 계속 물어 본다.

7.2   프락시 점프와 포트 포워딩

다른 방법으로는 WSL에서 윈도 머신으로 비밀번호 없는 개인/공개키를 이용해서 SSH 세션을 실행한 다음 포트 포워딩으로 WSL에 SSH 접속하는 방법이 있다. WSL을 시작할 때마다 자동으로 윈도 머신에 SSH 세션을 생성하면 된다. 이를 위해서는 WSL에서 윈도 머신의 SSH 세션을 영구적으로 살려 놓을 필요가 있다. WSL의 ~/.ssh/config에 다음을 추가하면 된다.

RemoteForward 2222 localhost:22
ServerAliveInterval 60

리눅스 머신의 ~/.ssh/config는 다음과 같다.

Host wsl
ProxyJump win
HostName localhost
Port 2222
User username
ForwardX11 yes
ForwardX11Trusted yes

이 방법의 단점은 비밀번호가 없는 개인키를 도난당할 경우 보안에 구멍이 생길 위험이 있다.

이 영구적인 SSH 세션을 자동으로 실행하기 위해서 다음의 명령을 Task Scheduler의 “At log on” 태스크로 생성한다.

C:\Windows\System32\wsl.exe -u root /etc/rc.d/rc.M

WSL에서 /etc/rc.d 디렉토리 안의 rc.* 파일들 중 다음의 파일들만 남기고 실행 권한을 제거한다.

  • rc.M: 시스템 초기화
  • rc.atd: 지정 시각에 작업 수행
  • rc.crond: 지정 간격으로 작업 수행
  • rc.inet2: rc.sshd 실행
  • rc.local: 사용자 초기화 스크립트 실행
  • rc.sshd: SSH 실행
  • rc.syslog: 시스템 로깅

/etc/rc.d/rc.local에 다음을 추가한다.

# by user
for i in /usr/local/etc/rc.d/rc.* /root/etc/rc.d/rc.*; do
	if [ -x $i ]; then
		$i start
	fi
done

for i in /home/user/usr/local/etc/rc.d/rc.*; do
	if [ -x $i ]; then
		su - user -c "$i start"
	fi
done

8   Vim에서 대문자 입력 문제

윈도 머신에서 직접 WSL을 실행하거나 ssh로 접속하면 Vim이 제대로 작동한다. 그런데 리눅스 머신에서 ssh로 윈도 머신에 먼저 접속한 다음 wsl아니 ssh로 WSL에 접속하면 Vim에서 대문자가 입력 안 되는 문제가 생긴다. TERM=vt100 vim실행하면 흑백으로 대문자를 사용할 수 있다. 또는 screen 안에서 vim을 실행하면 컬러화면을 쓸 수 있다.

그런데 SSH ProxyJump로 WSL에 접속하면 이런 문제가 없다. 윈도 호스트에서 SSH로 접속하면 같은 문제가 있는 걸 보면 단순히 SSH가 문제를 해결하는 건 아닌 것 같다. 아마도 리눅스 머신에서 윈도 호스트를 점프해서 접속해서 그런 것 같다.

9   사라지는 X윈도 클라이언트 문제

X윈도 클라이언트를 실행한 후 얼마간의 시간이 지나면 창이 사라지는 문제가 있다. 해결책은 다음과 같다.

sysctl -w net.ipv4.tcp_keepalive_intvl=60 \
          net.ipv4.tcp_keepalive_probes=5 \
          net.ipv4.tcp_keepalive_time=300

10   XTerm 단축 아이콘 만들기

10.1   접근 제한을 해제하는 방법의 경우

명령창에서 다음을 실행하면 XTerm이 바로 뜬다.

wsl ~ DISPLAY=$(/sbin/ip route | sed '/^default/!d; s/^default via \(.*\) dev eth0 $/\1/'):0.0 xterm -ls

10.2   .Xauthority 파일을 이용하는 방법의 경우

명령창에서 다음을 실행하면 XTerm이 바로 뜬다.

wsl ~ DISPLAY=a.b.c.d:0.0 xterm -ls

10.3   명령창 제거하기

하지만 같은 명령으로 단축 아이콘을 만들면 명령창까지 같이 뜬다. 이를 방지하기 위해서는 다음과 같이 run.js 자바스크립트 파일을 만든다.

WScript.CreateObject("WScript.Shell")
.Run(WScript.arguments(0), 0)

단축 명령을 다음과 같이 생성한다.

C:\Users\user\usr\local\bin\run.js "C:\Windows\System32\wsl.exe ~ DISPLAY=$(/sbin/ip route | sed '/^default/!d; s/^default via \(.*\) dev eth0 $/\1/'):0.0 xterm -ls"

또는

C:\Users\user\usr\local\bin\run.js "C:\Windows\System32\wsl.exe ~ DISPLAY=a.b.c.d:0.0 xterm -ls"

10.4   XTerm 아이콘 이미지 만들기

아이콘은 여기서 내려받은 후 다음과 같이 변환하면 된다.

convert mini.xterm_256.png mini.xterm_256.ico

11   NTP 데몬 설정하기

정확히 알지 못 하는 이유로 WSL의 시간이 윈도의 시간과 달라졌다는 걸 확인했다. 그래서 시간을 맞춰 주는 NTP 데몬을 설정했다.

chmod a+x /etc/rc.d/rc.ntpd
sed -i 's/^#\(server\)/\1/' /etc/ntp.conf
/etc/rc.d/rc.ntpd start

참고문헌

이 칸을 비워 두세요.