snmpd 로 인해 발생한 시스템 접속 불가 문제

제가 운영하는 시스템에는 snmpd 가 기본으로 서비스되고 있습니다. 각종 시스템의 상태를 파악하기 위해서 snmpd 를 활용하는 거지요. 그런데, 얼마전에 이 snmpd  때문에 아주 큰 문제가 된 일이 있었습니다.

이 문서는 그것이 무엇이며 왜 발생했고 어떻게 처리하는지에 대한 문서 입니다.

snmpd

snmpd 는 국제표준으로 IT기기에 각종 상태들을 네트워크를 통해서 제공할 수 있도록 설게된 SNMP를 제공하는 데몬이다. 수 많은 서버에 기본으로 탑재되어 있어 별다른 노력없이 사용이 가능하다.

리눅스 플랫폼에서 snmpd 를 사용하는데 있어 현재 인자값 사용에 문제가 있다. 인자값의 잘못된 사용으로 인해서 리눅스 전체 시스템에 미치는 영향은 치명적이다 못해 시스템을 재부팅한다하더라도 콘솔접속이 되지 않는한 문제를 해결될 수 없다.

Problems

대부분의 리눅스는 많은 배포판을 이룬다. 내가 테스트한 배포판은 Ubuntu 12.0.4 LTS 와 CentOS 6, 7 이다. 여기서는 Ubuntu 배포판을 기반으로 내용을 전개할 것이다. snmpd 의 문제만 체크하면 되는 것이기에 기타 하드웨어 스펙과 배포판에 설치된 각종 라이브러리등은 중요하지 않아 기술하지 않는다.

이제 문제에 접근해보자. Ubuntu 에서 snmpd 를 설치하면 다음과 같은 파일이 설치된다.

파일내용
/etc/default/snmpdsnmpd 의 init 파일에서 사용되는 snmpd 데몬 실행 옵션
/etc/init.d/snmpdsnmpd 데몬 init 스크립트

주목해야할 파일은 ‘/etc/default/snmpd’ 파일이며 이 파일에서 주목해야할 내용은 다음과 같다.

snmpd 데몬의 기본 운영을 바꾸기 위해서는 ‘/etc/default/snmpd’ 파일에서 위 내용을 편집하면 된다.

그럼, 거두절미하고 문제를 재현해보자. 미리 경고하지만 이는 반드시 콘솔접속이 되는 테스트 서버에서 해야한다. 오직 리모트로만 접속할 수 있는 서버이고 이 문제를 재현했다면 영원히 그 서버에 접속할 방법은 없다.

옵션을 다음과 같이 바꾼다.

자세히 보지 않으면 뭐가 바뀌었는지 알수 없게 된다. ‘-Lf’ 를 빠졌다. 이렇게 바꾸고 snmpd 를 재시작하면 문제가 재현된다.

증상

snmpd 를 재시작한 터미널에서는 별다른 증상을 알 수가 없다. 이제 다른 터미널을 열고 snmpd 를 재시작한 서버에 접속해보자. 아마 다음과 같이 나올 것이다.

root 계정이던 일반 계정이든 아무 상관이 없다. 바로 이게 문제다. 아무것도 접속할 수 없다.

콘솔에서 접속해도 다음과 같은 증상이 나온다.

원인분석

원인은 ‘/etc/default/snmpd’ 에서 정의한 snmpd 의 시작 옵션에 있다. snmpd 는 다음과 같이 커맨드라인에서 시작할 수 있다.

문제는 snmpd 에서 옵션은 반드시 ‘-L’, ‘-a’ 등과 같이 – 로 시작한다. 이것이 없이 그냥 값을 주게되면 그것은 바로 [LISTENING ADDRESSES] 가 된다. 여기서 중요한 것이 [LISTENING ADDRESSES]는 어떤값들이 올수 있느냐인데 이는 snmpd 맨페이지(man)를 통해서 확인할 수 있다.

결론만 말하면 <transport-address> 없이 그냥 문자열을 주게되면 snmpd 는 그것을 Unix Domain Socket 으로 인식하게 된다. 위 맨페이지에서 마지막에 나온 설명이 이것을 말해준다.

문제가 된 옵션을 다시보면

‘/dev/null’ 은 snmpd 에서 Unix Domain Socket 으로 인식하게 된다.

/dev/null

/dev/null 은 major 1, Minor 3 값을 가지는 Char device 파일이다. 이 파일은 특수한 장치 파일인데, 실제로는 없는 존재하지 않는 커널에서 제공하는 장치파일로서 Input/Output 을 empty 화시켜준다.

이 파일들은 아주 많은 프로그램에서 사용되지는데 대표적인 것으로 sshd 가 있다.

위에서 아래쪽을 보면 TYPE 이 CHR 이며 DVICE 1,3 나오는 ‘/dev/null’ 이 보인다.

그런데, 이것을 위에 문제처럼 snmpd 의 Unix Domain Socket 으로 하게되면 /dev/null 는 더 이상 장치파일이 아닌 소켓 파일로 변경되어 이 장치를 사용하는 모든 프로그램에 문제가 발생하게 된다. 다음과 같이 이전에 장치파일이 아닌 그냥 일반파일로 변경된것을 알 수 있다.

그리고 netstat 로 보면 snmpd 가 /dev/null 을 Unix Domain Socket 으로 사용하고 있다는 것이 보인다.

해결방법

가장 좋은 방법은 아직 연결이 유지되고 있는 터미널에서 ‘/etc/default/snmpd’ 의 옵션을 고쳐주는 것이다. 그리고 반드시 재부팅을 해줘야 한다.

그런데, 재부팅을 해서는 안되는 서버라면 어떻게 해야 할까?

첫째, ‘/etc/default/snmpd’ 에서 옵션을 변경하고 snmpd 를 정지시킨다. 재시작해줘도 /dev/null 파일이 장치로 복구가 안된다.

둘째, /dev/null Unix Domain Socket 파일을 삭제한다. 더이상 장치 파일이 아니기 때문에 과감히 삭제한다.

셋째, /dev/null 파일을 다시 만들어 준다.

위와같이 장치파일을 생성해주자 마자 바로 sshd 가 복구된다.

문제의 핵심

문제는 /dev/null 를 Domain Unix Socket 이던 무엇이던간에 프로그램에서 파일이 속성을 변경되도록 했다는데 있다. 애초에 snmpd 인자로 /dev/null 을 주었던게 문제였고 그 이전에 오타발생이 문제였다.

비단 snmpd 만 인자값으로 Unix Domain Socket 을 사용한다고 생각하지 않는다. 리눅스에는 수많은 프로그램들이 존재하고 snmpd 와 같이 옵션으로 Unix Domain Socket 을 받는 경우도 분명 존재한다. 그것도 하필이면 /dev/null 를 준다면 똑같은 문제가 발생할 수 있다.

위의 snmpd 문제로 영향받는 프로그램들

위 문제(snmpd 로 발생되는 문제) 로 영향받는 프로그램들은 /dev/null 장치를 사용하는 프로그램이라면 다 영향을 받는다.

  • sshd
  • nginx ← 동작에는 문제가 없어 보이지만 재시작하면 다음과 같이 나오면서 시작되지 않는다.

  • proftpd ← 재시작하면 다음과 같이 나오면서 시작이되지만 정상적으로 동작이 되지 않는다.

  • Tomcat ← 재시작하면 다음과 같이 나오면서 시작되지만 접속하면 아무것도 안된다. 이것은 아마도 bash 이 오류를 내면서 톰캣 시작시 세팅되는 환경변수들이 셋업되지 않았기 때문인것으로 보인다.

/dev/null 이 없어짐으로 인해서 bash 가 제대로 동작하지 않아 쉘스크립트로 작성된 대부분의 init 스크립트가 제대로 동작하지 못해 대부분의 프로그램들에 문제가 발생한다.

CentOS 6,7

운이 좋게도 CentOS 7 은 배포판 패키징으로 옵션 설정이 없다.

CentOS 에서는 ‘/etc/sysconfig/snmpd’ 에 옵션 설정을 할 수 있다.

여기서 CentOS 7 에서 상태가 심각했다. CentOS 7 에서는 Init System 이 systemd 로 변경되었다. 사실 systemd 는 Init System 프로그램을 넘어서 CentOS 7 배포판의 중추신경계역활을 하게됨에 따라 지대한 영향을 미친다.

이에 따라서 systemd를 제어하는 systemctl 명령어로 그 어떤 것도 실행되지 않았다. 거기다 /dev/null 를 새로 생성하더라도 systemd 가 복구되지 않았다. 무조건 재부팅이 요구된다.

CentOS 6 에서는 ubuntu 처럼 다음과 같이 옵션이 나온다.

역시 옵션은 ‘/etc/sysconfig/snmpd’ 에서 설정할 수 있으며 주석으로 다음과 같이 되어 있다.

CentOS 6과 7의 차이

아마도 개인적인 추측인데, CentOS 7 로 넘어오면서 기본 옵션이 변경된데에는 systemd 의 도입때문으로 보인다. systemd 의 도입으로 각 데몬 프로그램들은 systemd 가 상태, 로깅들을 담당하게 되어 이전 CentOS 6 과는 다르게 각 데몬 프로그램들 각자가 로깅을 할 필요가 없게 되었다.

최종결론

어찌되었든 /dev/null 파일을 삭제하거나 일반파일로 바꾸거나 해서는 안된다. 그렇게되면 sshd 는 접속을 거부할 것이다. 혹시나 다른 방법으로 슈퍼유저인 root 로 커맨드를 날릴 수 있다면 당황하지 말고 다음과 같이하면 적어도 sshd 는 돌아온다.

그리고 ubuntu 에서 ‘/etc/default/snmpd’ 를 수정할때는 오타 를 항상 조심해야 한다.

One comment

  1. Hestia

    좋은 팁이네요, snmpd 의 syslog 옵션 바꾸다가 -Lf 를 지우고 snmpd를 재시작 이후로 상기 증상이 나타나서 /dev/null 삭제 후 재생성, 재부팅으로 문제 해결하였습니다.
    감사합니다.

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">