SSI는 Server Side Includes의 약자로 서버측에서 해석되는 문서를 지칭한다. 보통 HTML 문서는 웹 서버에서 아무런 처리 없이 클라이언트측으로 전송해 주지만 SSI 문서에 대해서는 클라이언트 측으로 보내주기 전에 웹 서버가 HTML 문서 안에 있는 내용 중에 웹 서버가 인식하는 특별한 명령어들을 처리(Parsing이라 한다)한 후에 전송해 주게 된다. SSI 문서는 CGI처럼 동적인 문서를 생성하는데 사용될 수 있다. 그러나 CGI가 아주 다양한 형태의 문서를 생성하는데 이용될 수 있는 반면 SSI는 현재 날짜, 파일의 최신 갱신일, 다른 문서의 포함 등 제약된 형태의 동적인 문서를 생성해 낼 수 있다.
SSI의 동작원리
클라이언트가 SSI 문서를 요청하면 서버는 먼저 현재 서버의 상태, 클라이언트의 요청정보, 클라이언트 정보를 환경변수로 저장한 후, SSI 문서를 읽어들인다. SSI 문서의 각행을 처리하다가 SSI 명령을 만나면 SSI 명령을 해석한 결과(문자로)로 대치한다. 이 과정을 문서끝끼지 반복한 후, 그 결과를 클라이언트에 전송하게된다. 따라서 클라이언트 측에서는 원문서의 내용은 전혀 볼 수가 없으며, 다만 해석된 결과만을 보게된다.
SSI 문서에 대해서는 웹 서버가 일일이 내용을 해석해야 하기 때문에 웹 서버의 성능을 떨어뜨릴 수 있고 보안측면에서 익명 사용자가 nobody 권한으로 서버측 프로그램을 수행시킬 수 있다는 위험성이 있다. 따라서 SSI를 사용할 때는 이러한 약점을 고려해야만 한다.
SSI 명령어의 형식
<!--#command opt1="value1" opt2="value" -->
여기서 command는 다음에 설명한 SSI 명령어이며, opt는 명령어에따라 취해지는 매개변수이다. SSI는 하나의 태그내에 하나의 명령밖에 사용할 수 없으며, <!--#command 사이에 어떠한 공백도 포함되서는 안된다. 그러나 하나 이상의 opt를 포함할 수는 있다.
config
주로 SSI 명령어들의 출력형식을 지정하기 위해서 사용되며 반드시 다른 명령어와 함께 사용해야 된다.
errmsg
에러가 발생했을 경우, 출력될 오류를 지정한다. 에러가 발생한 경우 서버의 에러 로그(/usr/local/apache/error_log)에도 기록된다. value는 임의의 텍스트이다.
<!--#config errmsg="파일을 읽을 수 없습니다" ->
timefmt
날짜를 출력할 때 어떤 형식을 쓸 것인가를 결정한다. 이 값은 유닉스의 strftime 라이브러리 함수와 호환되어야 한다. timefmt에서 사용가능한 값은 다음과 같다.
%a 서버의 locale에 따라 표시되는 축약된 형태의 요일명
%A 서버의 locale에 따라 표시되는 요일명
%b 서버의 locale에 따라 표시되는 축약된 형태의 월명
%B 서버의 locale에 따라 표시되는 월명
%d 일을 10진수로 표시
%m 월을 10진수로 표시
%U 첫 번째 일요일을 기준으로 몇번째 주인가를 10진수로 출력
%W 첫 번째 월요일을 기준으로 몇번째 주인가를 10진수로 출력
%w 그 주의 몇 번째 날일가를 10진수로 출력
%x 날짜만 서버의 locale에 적합한 형태로 표시
%y 연도를 두자리 십진 수로 표시
%Y 연도를 4자리 10진 수로 표시
%H 시간을 24시로 표시
%l 시간을 12시로 표시
%j 일년을 기준으로 몇 번째 날인가를 표시
%M 분을 십진 수로 표시
%p 출력된 시간에따라 a.m, p.m으로 표시
%S 초를 십진수로 표시
%X 시간만 서버의 locale에 적합한 형태로 표시
%Z Time Zone를 출력
<!--#config timefmt="%Y년 %m월 %d일" -->
sizefmt
파일의 크기를 보여줄 때의 형식을 지정해 준다. 가능한 값은 bytes, abbrev 이다. bytes를 쓸 경우 바이트 단위로 크기를 출력하고(1,234,567과 같은 형식), abbrev를 쓸 경우 킬로바이트 또는 메가바이트 단위로 크기를 출력한다.
include는 어떤 문서의 내용을 SSI 문서에 삽입시키는 명령어이다. 삽입되는 문서는 웹 상에서 접근가능한 문서이어야 한다. 이 명령어는 다음 두 매개변수를 사용할 수 있다. 일반적으로 Copyright와 같이 대부분의 문서에 포함된 동일한 내용을 변경할 때 유용하다.
virtual
서버에 있는 문서에 대한 가상 절대 경로를 지정한다. 일반 문서(Text, HTML)나 또는 SSI 문서를 지정할 수 있으며, SSI와 삽입될 문서가 서로다른 디렉토리에 있는 경우에 주로 사용된다.
<!--#include virtual="/~artech/sign.txt" -->
file
SSI 문서에 대한 상대 경로를 지정한다. "../"나 절대경로는 사용할 수 없다. vitual과 마찬가지로 일반문서나 SSI 문서를 지정할 수 있다. SSI 문서와 삽입될 문서가 같은 디렉토리에 있는 경우에 주로 사용된다.
echo는 SSI 변수(include variable)의 값을 출력할 수 있도록 해준다. 날짜는 config 명령으로 지정한 timefmt에 따라 출력된다. 매개변수로는 var이 올 수 있으며 매개변수의 값으로 SSI 변수(SSI 전용환경 변수, CGI 환경변수와 일반 환경변수)의 이름을 지정한다.
var
값으로는 SSI 변수를 취한다.
당신은 <!--#echo var="REMOTE_HOST" -->로부터 오셨습니다.
주의:
환경변수는 항상 대문자를 사용해야 하지만 SSI에서는 몇몇 문자만 대문자를 사용해도 된다.
SSI는 서버측 문서와 클라이언트측 문서가 다르기 때문에 클라이언트측에서 서버측 문서의 내용을 볼 수 없다. 그러나 확장자가 .shtml이기 때문에 이 문서가 SSI 문서이며, 서버측에서 실행되는 문서라는 것은 쉽게 알아낼 수 있다.
따라서 악의적인 사용자는 이 SSI 문서를 반복적으로 요청함으로서 서버측에 의도적인 부하를 줄 수 있다. 이러한 문제 점을 해결하는 방법은 여러 가지가 있지만 가장 안전하며 보편적인 방법은 XBitHack를 사용하는 것이다.
XBitHack는 NCSA 계열의 서버에서 지원하는 기능으로 SSI 문서와 일반문서를 구분하기위해 접미사(확장자)를 사용하는 것이 아니라 x 비트(실행비트), 즉 사용권한(permission)의 실행 비트의 존재여부로 판정하는 것이다.
전역설정(/usr/local/apache/conf/access.conf)
XBitHack 기능을 서버 전체에 적용하려면 전역 ACF(Access Configuration File - conf/access.conf)의 DocumentRoot 부분을 다음과 같이 변경하면 된다.
<Directory /usr/local/apache/htdocs>
Options Indexs FollowSymLink
AllowOverride none
XBitHack on
</Drectory>
XBitHack에서 사용할 수 있는 옵션은 다음과 같다.
off
XBitHack를 사용하지 않음(기본값)
on
사용자의 실행비트가 켜져있는 문서만 SSI 문서로 처리.
full
on과 동일하며, 그룹의 실행비트가 켜져있는 SSI 문서를 클라이언트의 캐쉬와 프록시 서버에 캐쉬되도록 한다.
사용자 설정
XBitHack을 서버 설정과는 무관하게 사용자별(디렉토리별)로 사용하려면 SSI 문서를 포함하는 디렉토리에 다음과 같은 디렉토리별 ACF(Per-directory ACF) 파일을 두면 된다.
.htaccess
XBitHack on
주의:
사용자가 디렉토리별 ACF 파일을 사용하기위해서는 전역 ACF(conf/access.conf) 파일의 DocumentRoot 부분이 다음과 같아야 한다.
<Directory /usr/local/apache/htdocs>
Options Indexs FollowSymLink
AllowOverride All
</Drectory>
SSI 문서의 사용
위와 같이 서버나 개인 사용자의 설정이 끝나면 SSI 문서의 사용권한을 다음과 같이 설정함으로서 접미사(확장자)가 .html인 SSI 문서를 사용할 수 있다.
chmod 744 include.html
SSI 문서와 일반 문서의 접미사(확장자)는 모두 .html이지만 일반문서의 사용권한은 644이고, SSI 문서의 사용권한은 744이므로 서버는 이 사용권한에 의해 SSI 문서와 일반문서를 구분할 수 있게된다.
SSI의 예