엑시엄이 보는 DB 세상
사용이 쉬워 간과하기 쉬운 리스너 1 1 6,908

by axiom 리스너 LISTENER SID_LIST_LISTENER 리스너차단 [2014.10.28]


리스너(Listener)는 오라클에 속한 컴포넌트 중 하나로, 원격 접속 요청을 받아들이는 역할을 한다. 이로 인해 리스너가 죽는다면 어떠한 외부 접속도 이루어지지 않는데, 대부분의 사용자는 리스너가 정상적으로 구동된 후에는 신경을 쓰지 않다. 그 이유는 리스너가 기동할 경우 계속 정상적으로 작동할 것으로 여기기 때문이다.

고객사의 AI-AS 서버에서 TO-BE 서버로 데이터를 옮기는 프로젝트를 수행했을 때의 일이다. TO-BE 서버에 DB를 옮기고 리스너를 가동했다. 데이터 검증만을 남긴 상황이었다. 그런데 애플리케이션에서 DB에 접속하지 못하는 문제가 발생했다.

담당 엔지니어가 분명 리스너를 동작시켰음에도 접속이 이루어지지 않았던 것. 그 원인은 무엇일까? 바로 리스너를 기동시키면 반드시 정상적으로 동작할 것이라고 여겼기 때문이다. 이처럼 간과하기 쉬운 리스너의 동작 원리는 다음과 같다.

  • [그림1] 오라클의 리스터 동작 원리
  • 오라클의 리스터 동작 원리

  • ① 클라이언트가 리스너에 접속 요청함
  • ② 리스너는 클라이언트 요청을 분석하고 이를 DB 서비스에 요청된 서비스 핸들러에 전달함
  • ③ 클라이언트는 DB에 접속함

기본적인 리스너의 동작 원리는 공인교육과정을 수강했다면 누구나 알만큼 쉬운 내용이다. 그러나 대부분의 이들은 여기까지만 알고 있을 뿐 그 이상을 모르는 경우가 많다. 뿐만 아니라 리스너 동작을 맹목적으로 신뢰하는 경우가 많아 예상 밖의 문제들을 간과하기 쉽다. 예컨대 다음과 같은 리스너를 제어하는 명령어에서 어떤 문제가 발생할 소지가 있을까?

  • - 시작 : lsnrctl START [listener명]
  • - 종료 : lsnrctl STOP [listener명]

바로 Lsnrctl START나 Lsnrctl STOP 뒤에 묵시적으로 적어야 하는 [listener명]을 생략할 경우 예상치 못한 문제가 발생할 수 있다. 많은 이들이 해당 명령어에 리스너 이름을 생략하는 경우가 많은데, 앞서 상황도 특정 리스너 이름을 명시하지 않았기 때문에 발생한 문제다.

그러므로 굳이 명시하지 않아도 동작하겠지만 예기치 않은 문제를 예방하기 위해서는 반드시 리스너 이름을 명시적으로 적는 것이 좋다. 리스너는 명령어에 불과하지만 실제 실행은 listener.ora의 내용에 의해 리스너가 동작한다. 기본 포트로 설치한 경우 listener.ora의 내용은 다음과 같다.

  • [리스트 1] 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 이름을 한 쌍으로 명시해 수행해야 한다는 것이다.

  • [리스트 2] 특정 포트로 리스너 실행
  • SID_LIST_LISTENER=
    (SID_LIST=
    	(SID_DESC=
    	    (SID_NAME = SID명) 또는 
    	    (SERVICE_NAME=서비스명)
    	)
    )
    

방화벽을 설정할 때 리스너의 동작 포트 범위도 알아야 한다. 프로젝트에서는 종종 포트 범위가 중요한 이슈가 될 수 있기 때문이다.

사용자와 DB, AP와 DB, DB와 DB 간의 포트를 보안상 어느 범위로, 어느 방향으로 열어놓을지를 결정해야 한다. 이러한 고민을 간과할 경우 리스너 포트로만 열어두는 실수를 저지를 수 있다.

또 하나 간과하기 쉬운 것으로 리스너에 있는 포트만 사용 가능하다는 점이다. 정말 리스너는 1개의 포트만 사용하는 것일까?

  • ① 클라이언트가 sqlplus를 통해 sqlplus userid/password@alias와 같이 접속을 시도하면 명시한 alias 이름을 tnsnames.ora 파일이나 names server에서 찾음
  • ② DB의 주소를 얻어 서버로 접속을 시도함
  • ③ DB에 있는 리스너에 접속하게 되면 Port redirection이 일어남

실제로 테스트해보면 [리스트 3]과 같이 Port redirection이 일어나는 것을 확인할 수 있다.

  • [리스트 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에 접속했는지도 명확히 알 수 있는 이점이 있다.

리스너의 차단 기능은 다음과 같은 방법으로 사용할 수 있다.

  • ① Sqlnet.ora를 ②와 같이 수정한다.
  • ② TCP.VALIDNODE_CHECKING = YES
  • TCP.INVITED_NODES=(아이피,아이피)
  • ③ 리스너를 재가동 한다(reload는 적용되지 않음).

이를 통해 특정 IP만 리스너에 접근하는 것을 허용할 수 있다. 자주 사용하는 기능은 아니지만 때때론 유용한 기능이니 기억해두자.

이 글의 주제로 리스너를 선택한 것은 항상 어려운 부분을 접했을 때 쉬운 부분은 지나치기 쉽기 때문이다. 이 글에서 소개한 내용은 리스너의 방대한 기능의 일부에 지나지 않는다. 만약 좀더 리스너에 대해 알고 싶다면 오라클 문서를 면밀히 살펴보길 바란다

- 강좌 URL : http://www.gurubee.net/lecture/2811

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

by lacoste [2015.02.09 09:54:58]

잘 봤습니다~

ALATER SYSTEM REGISTER  -> ALTER SYSTEM REGISTER 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입