리스너(Listener)는 오라클에 속한 컴포넌트 중 하나로, 원격 접속 요청을 받아들이는 역할을 한다. 이로 인해 리스너가 죽는다면 어떠한 외부 접속도 이루어지지 않는데, 대부분의 사용자는 리스너가 정상적으로 구동된 후에는 신경을 쓰지 않다. 그 이유는 리스너가 기동할 경우 계속 정상적으로 작동할 것으로 여기기 때문이다.
고객사의 AI-AS 서버에서 TO-BE 서버로 데이터를 옮기는 프로젝트를 수행했을 때의 일이다. TO-BE 서버에 DB를 옮기고 리스너를 가동했다. 데이터 검증만을 남긴 상황이었다. 그런데 애플리케이션에서 DB에 접속하지 못하는 문제가 발생했다.
담당 엔지니어가 분명 리스너를 동작시켰음에도 접속이 이루어지지 않았던 것. 그 원인은 무엇일까? 바로 리스너를 기동시키면 반드시 정상적으로 동작할 것이라고 여겼기 때문이다. 이처럼 간과하기 쉬운 리스너의 동작 원리는 다음과 같다.
기본적인 리스너의 동작 원리는 공인교육과정을 수강했다면 누구나 알만큼 쉬운 내용이다. 그러나 대부분의 이들은 여기까지만 알고 있을 뿐 그 이상을 모르는 경우가 많다. 뿐만 아니라 리스너 동작을 맹목적으로 신뢰하는 경우가 많아 예상 밖의 문제들을 간과하기 쉽다. 예컨대 다음과 같은 리스너를 제어하는 명령어에서 어떤 문제가 발생할 소지가 있을까?
바로 Lsnrctl START나 Lsnrctl STOP 뒤에 묵시적으로 적어야 하는 [listener명]을 생략할 경우 예상치 못한 문제가 발생할 수 있다. 많은 이들이 해당 명령어에 리스너 이름을 생략하는 경우가 많은데, 앞서 상황도 특정 리스너 이름을 명시하지 않았기 때문에 발생한 문제다.
그러므로 굳이 명시하지 않아도 동작하겠지만 예기치 않은 문제를 예방하기 위해서는 반드시 리스너 이름을 명시적으로 적는 것이 좋다. 리스너는 명령어에 불과하지만 실제 실행은 listener.ora의 내용에 의해 리스너가 동작한다. 기본 포트로 설치한 경우 listener.ora의 내용은 다음과 같다.
LISTENER명= (DESCRIPTION= (ADDRESS_LIST= (ADDRESS= (PROTOCOL=tcp) (host=아이피 또는 호스트명) (PORT=포트번호) )
[리스트 1]을 실행하면 60초 후에 DB에 접속 가능하다. 그렇다면 요청 즉시 접속할 수 있는 방법은 없을까?
이를 위해서는 ALATER SYSTEM REGISTER이라는 명령어를 실행해야 한다. 이 명령어는 1521 포트로 리스너를 기동할 때 PMON에서 INSTANCE를 발견해 리스너에 등록한다.
ALATER SYSTEM REGISTER 명령어를 생략할 경우 PMON이 발견 루틴을 실행할 때까지 인스턴스가 등록되지 않는다. 이와 같은 내용은 오라클 문서에 명시돼 있지만 이를 면밀히 살펴보기 전에는 알 수 없는 부분이다.
만약 기본 포트가 아닌 특정 포트로 리스너를 사용하고자 한다면 [리스트 2]와 같이 SID_LIST를 추가로 명시해야 한다. 주의할 점은 PMON을 이용해 자동으로 등록하는 것보다는 수동으로 리스너 이름과 SID_LIST_LISTENER 이름을 한 쌍으로 명시해 수행해야 한다는 것이다.
SID_LIST_LISTENER= (SID_LIST= (SID_DESC= (SID_NAME = SID명) 또는 (SERVICE_NAME=서비스명) ) )
방화벽을 설정할 때 리스너의 동작 포트 범위도 알아야 한다. 프로젝트에서는 종종 포트 범위가 중요한 이슈가 될 수 있기 때문이다.
사용자와 DB, AP와 DB, DB와 DB 간의 포트를 보안상 어느 범위로, 어느 방향으로 열어놓을지를 결정해야 한다. 이러한 고민을 간과할 경우 리스너 포트로만 열어두는 실수를 저지를 수 있다.
또 하나 간과하기 쉬운 것으로 리스너에 있는 포트만 사용 가능하다는 점이다. 정말 리스너는 1개의 포트만 사용하는 것일까?
실제로 테스트해보면 [리스트 3]과 같이 Port redirection이 일어나는 것을 확인할 수 있다.
$>netstat -an | grep 1522 tcp 0 0 :::1522 :::* LISTEN ** DB 접속 툴을 이용해 접속 ** $> lsof -i -n | grep "1.1.0.1" Oracle 3657 oracle 14u IPv6 14996 TCP 1.1.0.1:->1.1.0.4:49549 (ESTABLISHED) $>ps ef | grep 3657 oracle 3657 1 0 10:05 ? 00:00:01 oracleTESTDB (LOCAL=NO)
이처럼 1522로 접속하더라도 다른 포트로 리다이렉트(Redirect)되는데, 그 이유는 1522로 접속한 후 1522로만 접속을 맺는다면 1522 포트가 문제가 있을 때 기존에 접속했던 유저도 접속이 끊어지기 때문이다.
반면 리다이렉트를 이용할 경우 1522 포트가 끊기거나 리스너가 내려가도 기존 리다이렉트를 유지할 수 있다. 그렇다면 리스너의 포트 범위를 방화벽에서는 어떻게 처리해야 할까?
DB 서버에서 외부로 나가는 포트에 대해서만 열어주면 문제가 없다. 나가는 포트는 모든 포트를 열어줘야 하는 것이다.
지금부터는 리스너의 특별한 기능 중 차단 기능에 대해 살펴보자. 리스너를 사용하면 차단 기능은 자주 사용하는 기능은 아니지만 종종 유용할 때가 있다. 바로 초기 프로젝트에서 접근 제한할 때 그러하다.
제한이 가능하다는 것은 사용할 수 있는 유저 외에는 접근 자체가 불가능하기 때문에 사용자를 명확하게 컨트롤할 수 있다. 또한 어떤 업무로 DB에 접속했는지도 명확히 알 수 있는 이점이 있다.
리스너의 차단 기능은 다음과 같은 방법으로 사용할 수 있다.
이를 통해 특정 IP만 리스너에 접근하는 것을 허용할 수 있다. 자주 사용하는 기능은 아니지만 때때론 유용한 기능이니 기억해두자.
이 글의 주제로 리스너를 선택한 것은 항상 어려운 부분을 접했을 때 쉬운 부분은 지나치기 쉽기 때문이다. 이 글에서 소개한 내용은 리스너의 방대한 기능의 일부에 지나지 않는다. 만약 좀더 리스너에 대해 알고 싶다면 오라클 문서를 면밀히 살펴보길 바란다
- 강좌 URL : http://www.gurubee.net/lecture/2811
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.