X 윈도우 시스템은 그래픽 인터페이스를 제공하기 위한 통신 프로토콜과 그 기능을 제공하는 네트웍 기반의 윈도우 시스템이다. 이처럼 X 윈도우에서 실행되는 프로그램을 흔히 클라이언트라고 부르는데, 클라이언트에서 실행되는 애플리케이션(X 클라이언트라고 한다)은 디스플레이 장치(비디오 카드와 모니터 등)를 직접 액세스하지 않는다. 대신, 현재 사용중인 디스플레이 장치를 통제하는 X 서버와 통신을 수행한다. 다시 말해 X 윈도우에서 작동하는 프로그램은 직접 그래픽 작업을 하지 않고 X 서버를 통해 수행하는 것이다. 대부분의 리눅스 사용자는 보통 1개의 X 서버와 여러 개의 X 클라이언트가 하나의 컴퓨터에서 작동할 것이다. 하지만 실제로 1대의 컴퓨터에서 여러 X 서버를 수행하는 것이 가능하며 네트웍을 통해 리모트 컴퓨터가 X 클라이언트를 실행할 수도 있다. 이 때 리모트 컴퓨터가 수행하는 X 클라이언트 화면은 자신의 로컬 시스템(X 서버가 동작하는)으로 출력되도록 할 수도 있다. 보다 쉽게 말해 어떤 프로그램을 한 컴퓨터에서 실행하고 그 프로그램이 수행되는 화면은 다른 컴퓨터의 모니터를 통해 볼 수 있다는 말이다. 예를 들면 시간이 많이 걸리는 계산을 수행하는 프로그램을 슈퍼 컴퓨터에서 수행하도록 하고 결과 화면은 우리가 갖고 있는 리눅스 시스템을 통해 볼 수 있다는 뜻이다.X 서버에서 발생할 수 있는 보안 문제X 윈도우 시스템은 네트웍을 통해 클라이언트가 수행되는 컴퓨터와 실제로 그 결과가 표시되는 화면이 부착된 컴퓨터가 다를 수 있음을 알았다. 여기서 발생할 수 있는 보안 문제는 X 서버에 대한 접근을 어떻게 조절할 것이냐 하는 것이다.지금 우리가 사용하는 리눅스 시스템에서 작동하는 X 서버에 접근할 수 있는 누구나 접근 권한을 갖고 우리의 리눅스 시스템에 해로운 일을 할 수 있다. 예를 들면 xkill이나 xterminate 명령을 통해 리눅스 시스템에서 작동하는 윈도우의 실행을 중단시킬 수 있다. 또한 XWatchWin 명령으로 현재 리눅스 시스템에서 작동하는 모든 내용을 훔쳐 볼 수 있으며 사용자가 어떤 작업을 수행하는지도 알 수 있다. 물론, 이는 리눅스 시스템의 문제는 아니다. 단지 X 윈도우가 애초에 그런 식으로 설계되었을 뿐이며 이런 문제가 발생하는 것은 순전히 우리가 사용하는 X 서버에 대해 적절한 접근 제어를 하지 않는 경우에만 발생하게 된다.호스트 기반 액세스 제어앞서 언급한 문제를 피하기 위해 보통 X 서버에 대한 접근 권한을 아무에게나 주지 않는다. 접근 권한은 디스플레이 장치를 소유한 사용자가 적절하게 조절할 수 있으며 이것이 일반적으로 쉽게 사용하는 호스트 기반의 액세스 제어이다. 다음과 같은 명령을 리눅스 X 윈도우 시스템에서 수행해보자.[boid@foobar7 boid]$ xhost +access control disabled, clients can connect from any host앞과 같은 명령은 현재 리눅스 시스템에서 수행되는 X 서버에 대해 누구나 접근 가능한 권한을 주는 것이다. 따라서 어떤 호스트에서 실행되는 클라이언트라도 이 서버에서 수행되는 X 서버에 접근할 수 있다.다음과 같은 명령으로 호스트 기반의 액세스 제어를 할 수 있어 허락된 호스트 컴퓨터에서 실행되는 클라이언트만이 시스템의 X 서버에 접근할 수 있다. 즉 이 시스템에서 수행되는 X 서버가 통제하는 디스플레이 장치를 사용할 수 있게 되는 것이다.[boid@foobar7 boid]$ xhost -access control enabled, only authorized clients can connect특정 호스트가 이 시스템에서 수행되는 X 서버에 대한 접근 권한을 갖도록 하려면 다음과 같은 명령을 사용하면 된다.[boid@foobar7 boid]$ xhost + foobar.sogang.ac.krfoobar.sogang.ac.kr being added to access control list앞의 예제는 foobar.sogang.ac.kr 호스트에서 수행되는 클라이언트는 이 리눅스 시스템의 X 서버를 액세스할 수 있음을 의미한다. 보통 옵션없이 xhost 명령을 내리면 현재 어떤 시스템에 접근 권한을 주고 있는지 알 수 있다. 네트웍에 연결된 상태라면 xhost - 명령으로 다른 호스트에서 자신이 사용하는 리눅스 시스템의 X 서버에 대한 불법적인 접근을 하지 못하도록 하는 것이 좋다.이렇게 호스트 단위로 X 서버에 대해 접근 권한을 주는 것을 호스트 기반의 액세스 제어라고 한다. 이와 같은 호스트 단위의 액세스 제어는 하나의 시스템을 한 명의 사용자만이 사용하는 싱글유저 시스템에 적절하다. xhost를 이용한 호스트 기반의 접근 제어 방식은 호스트 이름 혹은 IP 주소를 기반으로 X 서버에 대한 접근 권한을 검사하므로 IP 속이기 공격에 취약할 수 있다. 또한 호스트 기반의 접근 제어는 호스트 단위로 접근 권한을 주므로 하나의 호스트(웍스테이션)를 한 명의 사용자가 사용하는 환경에서만 활용 가능하다. 여러 사용자가 하나의 웍스테이션에 동시에 로그인해 사용하는 환경에서는 특정 호스트에게 X 서버에 대한 접근 권한을 주는 것이 곤란하기 때문이다.MIT Magic Cookiexhost는 호스트 단위의 접근 제어로 기본적이면서도 간단하다. xhost를 주로 사용하는 이유는 매우 간단하게 사용할 수 있기 때문이다. 그러나 xhost는 IP 속이기 공격에 취약하고 멀티유저 환경에서는 그리 적절하지 않다. 그래서 X 윈도우 시스템은 보다 강력한 인증 방식을 제공하고 있다. 여기서는 MIT Magic Cookie(이하 MMC)를 통해 강력한 인증 방식에 대해 알아보도록 하자.어떻게 동작하는가MMC를 이용하면 클라이언트는 128비트의 쿠키를 연결 설정 정보와 함께 보내준다. 클라이언트가 전송한 이 쿠키값이 X 서버가 저장한 쿠키값과 일치하면 X 서버는 이 클라이언트에 대해 X 서버에 대한 접근을 허락하게 된다. 암호 역할을 하는 이런 쿠키값은 쉽게 추측될 수 없도록 만들어진다. xdm(X Display Manager)은 MMC 방식의 인증 방법이 사용되면 쿠키값을 자동으로 생성하며 쿠키값은 사용자의 홈 디렉토리에 존재하는 .Xauthority 파일에 저장된다. 또한 쿠키값은 xdm에 의해 자동으로 X 서버에 전달된다. 이런 MMC 방식은 1대의 웍스테이션에 여러 사용자가 로그인하는 멀티유저 환경에 적합하다. 호스트 단위의 인증 방식이 아니므로 사용자가 서로를 방해할 가능성이 없기 때문이다. 그러나 쿠키값이 암호화되지 않고 전달되므로 네트웍에서 가로채기 공격에 매우 취약할 수 있다. 따라서 물리적으로 가로채기 공격에 대해 안전한 환경에서 사용하는 것이 좋다.쿠키값 생성하기MMC 방식의 인증을 사용하기 위해 먼저 쿠키 생성에 대해 알아야 한다. 이를 위해 xauth 사용법을 알아야 한다. xauth는 .Xauthority 파일의 쿠키 내용을 추가, 삭제, 리스트를 출력하는 유틸리티이다. xhost가 호스트 기반 인증 방식을 사용하기 위해 필요한 유틸리티라면 xauth는 MMC 방식의 인증 방식을 사용하기 위한 필수 유틸리티이다. 우선 쿠키값을 생성하는 방법을 알아보도록 하자. xauth를 이용해 쿠키값을 설정하는 방법은 보통 다음과 같다.xauth add foo.bar.com:0 MIT-MAGIC-COOKIE-1 9050bbfceec3118788df6524d 36f4970여기서 add는 사용자의 홈 디렉토리에 존재하는 .Xauthority 파일에 쿠키값을 추가하라는 의미이고 foo.bar.com:0은 foo.bar.com 호스트에 연결된 디스플레이 장치를 가리킨다. 실제로 하나의 호스트에 여러 디스플레이 장치가 연결될 수 있으므로 디스플레이 장치 번호를 지정하는 것은 중요하다. MIT-MAGIC-COOKIE는 지금 설정하는 값이 MMC 방식의 쿠키값을 말하며 그 뒤에 나오는 32자리 숫자는 128비트 쿠키값이다. 앞과 같은 형태로 .Xauthority 파일에 쿠키값을 설정할 수 있다. 여기서 중요한 것은 물론, 128비트의 쿠키값이다. 쿠키값은 X 서버에 대해 마치 암호와 같이 사용되어 쿠키값을 알고 있는 클라이언트에 대해서만 X 서버에 대한 권한을 주는 것이다. 따라서 쿠키값을 쉽게 추측 가능하거나 세션마다 동일한 쿠키값을 사용하면 보안에 심각한 위험이 생기게 된다. 이런 상황에서 쿠키값을 적절하게 만들어주는 유틸리티가 바로 mcookie로, 대부분의 리눅스 배포본에 포함되어 있다. mcookie는 /dev/random, /dev/urandom, /dev/audio, /proc/stat, /proc/loadavg 등 항상 예측하기 어려운 값을 갖는 파일 내용을 인수로 128비트 난수를 생성한다. 다음은 mcookie를 실행시키는 모습이다.[boid@foobar7 boid]$ mcookie337ebeb6ed2a05de45fc2a7a1b5d7416xauth의 인수 중 마지막 쿠키값은 mcookie를 이용해 비교적 안전한 값으로 설정할 수 있다. 쿠키값 설정은 단지 사용자의 홈 디렉토리에 존재하는 .Xauthority 파일에 쿠키값을 생성하는 역할만 한다. X 윈도우를 시작할 때 쿠키값을 설정하고 X 윈도우가 이를 사용하도록 해야 한다. 그러기 위해서는 X 서버를 실행할 때 -auth 옵션 뒤에 .Xauthority 파일의 위치를 지정해야 한다.보통 리눅스에서 X 윈도우를 실행시키는데 사용하는 명령은 startx이다. 이는 X 윈도우를 실행하기 위한 쉘 스크립트로, /usr/bin/X11 디렉토리에서 찾을 수 있다. 만약 다음과 유사한 내용이 startx 스크립트에 들어있다면 X 윈도우를 실행할 때 자동으로 쿠키값이 생성되고 X 서버는 이런 쿠키값을 사용한다고 할 수 있다.# set up default Xauth info for this machinemcookie=`mcookie`serverargs="$serverargs -auth $HOME/.Xauthority"xauth add $display . $mcookiexauth add `hostname -f`$display . $mcookiexinit $clientargs -- $display $serverargs쿠키값 전달하기MMC 방식의 인증 방법을 다시 정리하면 사용자의 홈 디렉토리에 존재하는 .Xauthority 파일에 쿠키값을 설정한 후 X 윈도우를 시작할 때 쿠키값을 X 서버가 사용하도록 지정하게 된다. 쿠키값은 .Xauthority 파일에 저장되어 항상 일정한 것은 아니고 X 윈도우 서버가 시작되는 세션마다 새로 설정되어 X 서버에 넘기게 된다. 이렇게 설정되어 실행된 X 서버는 쿠키값을 가진 클라이언트에 대해서만 X 서버에 대한 접근 권한이 허락된다. 이제 이렇게 실행된 서버에 접근하기 위해서는(리모트에서 실행된 X 윈도우 애플리케이션을 로컬 X 디스플레이에 표시하기 위해서는) 각 클라이언트에 대해 쿠키값을 전달하는 일을 해야 된다. 만약 쿠키값을 클라이언트가 알지 못하면 지금 실행한 X 서버에 대해 접근 권한을 갖지 못하기 때문이다. 일단 X 서버가 작동하는 리눅스 시스템에 다음과 같이 쿠키값이 설정되어 있다고 가정하자./user/home/boid> xauth listfoobar4:0 MIT-MAGIC-COOKIE-1 5a4664334779795a557a4a4d57504c38foobar4.sogang.ac.kr/unix:0 MIT-MAGIC-COOKIE-1 5a4664334779795a557 a4a4d57504c38이제 또 다른 리모트 시스템에서 X 서버가 실행되고 있는 시스템의 디스플레이 장치를 이용해 X 애플리케이션을 실행시켜 보자./user/home/boid> telnet foobar7Trying 163.239.135.64...Connected to foobar7.Escape character is '^]'.Kernel 2.2.12-20kr on an i586login: boidPassword: Last login: Mon Jan 17 20:15:59 from foobar4[boid@foobar7 boid]$ echo $DISPLAYfoobar4.sogang.ac.kr:0.0[boid@foobar7 boid]$ xvXlib: connection to "foobar4.sogang.ac.kr:0.0" refused by serverXlib: Client is not authorized to connect to Serverxv: Can't open display앞의 예제처럼 X 서버가 허락하지 않은 다른 시스템에서는 X 서버 사용이 허가되지 않는다. 이제 현재 로그인된 리모트 시스템에서 실행되는 X 애플리케이션이 X 서버의 디스플레이 장치를 이용하기 위해 쿠키값을 설정해야 한다. [boid@foobar7 boid]$ xauth add $DISPLAY . 5a4664334779795a557a4a4d57504c38[boid@foobar7 boid]$ xv앞서 X 서버에 설정되어 있는 동일한 쿠키값을 클라이언트(즉 X 애플리케이션이 실행되는 리모트 시스템)에 설정되면 X 서버에 대한 접근 권한을 갖게 된다. 물론 이는 동일한 쿠키값을 알고 있는 클라이언트에 대해 X 서버가 접근을 허락하기 때문이다. 따라서 쿠키값을 갖는 모든 클라이언트는 X 서버에 대한 접근 권한이 생기게 된다. 만약 쿠키값이 설정되었음에도 불구하고 X 애플리케이션이 실행되지 않는다면 다음과 같은 명령으로 DISPLAY 환경 변수의 값을 살펴봐야 한다.[boid@foobar7 boid]$ echo $DISPLAYfoobar4.sogang.ac.kr:0.0DISPLAY 환경 변수는 디스플레이 장치를 가진, 즉 X 서버가 작동하는 호스트 이름과 디스플레이 장치를 정확하게 지정해야 한다. 대부분의 리눅스 시스템은 원격지에서 로그인하는 경우에 자동으로 디스플레이 환경 변수를 적절하게 설정하게 된다. 따라서 적절한 쿠키값 설정으로 X 서버에 대한 접근 설정이 완료된다고 할 수 있다.만약 X 서버가 실행되고 있는 호스트가 foo이고 X 애플리케이션을 실행시킬 리모트 호스트가 bar라고 했을 때, rsh 명령을 통해 다음과 같이 한 번에 쿠키값을 전달해주는 방법도 있다.foo% xauth extract - foo:0