Tagged: SNMP

CentOS에서 SNMP 설치 및 설정하기

SNMP(Simple Network Management Protocol) 은 원래 네트워크 장비를 관리하기 위한 통신 규약입니다. 그런데, 이제는 네트워크 장비뿐만아니라 컴퓨터, 전자장비까지 확장해서 사용하고 있습니다. 리눅스 시스템에서도 SNMP를 사용할 수 있습니다.

이를 이용하면 SNMP 를 이용해서 중앙집중식으로 각각의 장비들의 자원, 자원사용량등을 장비에 거의 모든 것을 알 수 있고 가지고 올 수 있습니다. 저의 경우에는 Cacti 라는 시스템 자원 모니터링 시스템에서 원격 시스템의 자원 사용량을 가지고 오기 위해서 각 서버마다 SNMP를 사용합니다.

준비

이 문서는 다음과 같은 환경에서 작성되었습니다.

  • CentOS 7
  • X86_64

SNMP는 서버/클라언트 구조를 가지고 있습니다. 중앙 집중식으로 한 곳에서 정보를 모을 경우에는 중앙 서버를 제외하고 SNMP 데몬만 설치해주면 됩니다.

설치

설치는 Yum 을 이용해 다음과 같이 해주면 됩니다.

위에 뒷부분 ‘net-snmp-utils’ 는 SNMP 데몬하고는 아무런 관련이 없기 때문에 설치를 않해되 되지만 SNMP 데몬의 제대로 동작하는지를 테스트하기 위해서는 설치해주는 것이 좋습니다. ‘net-snmp-utils’ 는 말 그대로 SNMP를 다루기위한 여러가지 명령어들이 들어 있습니다.

설정

CentOS7 의 특징은 데몬이 실행될때에 옵션을 제공해 줄 수 있는데, 이를 위해서 ‘/etc/sysconfig’ 디렉토리에 데몬이름으로 파일을 가지게 됩니다. 그러면 데몬 실행 프로그램에서 이를 import 해서 사용하곤 하는데 SNMP 데몬도 이와 같습니다.

먼저 데몬 실행 옵션을 다음과 같이 설정 해줍니다.

위 옵션들은 다음과 같습니다.

  • -Ls 는 로그 메시지 stderr, stdout 으로 내보내고 로그레벨을 정한다. 기본은 -Lsd 로 d 는 LOG_DEBUG 을 말한다. 로그의 수준은 0 ~ 7 까지 존재하는데 다음과 같다.

    이는 -LSwd 나 -LS4d 식으로 숫자와 알파벳으로 지정할 수 있다. -LSed / -LS3d 같은 예제이다. 또, -LS1-5d 처럼 로그레벨 수준을 어디서 어디까지로 정할 수도 있다. 위 예제에서는 데몬 메시지를 syslog 로 보내는데 로그 레벨 1~5까지를 보내라는 뜻이다.
  • -Lf 는 지정한 파일로 로그 메시지를 보낸다. 위 예제에서는 /dev/null 임으로 로그 메시지를 삭제하는 효과를 보인다.
  • -p 는 pid 파일을 지정해 준다.

다음으로 SNMP 자체 설정을 합니다. 아래의 예제는 시스템 자원을 읽기 전용으로만 설정하는 것입니다.

SNMP 설정은 ‘sec.name’ 별로 설정을 할 수 있습니다. sec.name 을 여러게 정의하면 group도 여러개 설정할  수 있고 이렇게 되면 access 도 여러개 설정할 수 있습니다. 주목할 것은 access 에서 뒷부분에 read, write, notif 가 보이는데, 위 예제가 시스템 자원을 읽기만 할 것이기 때문에 read 부분만 all 로 하고 나머지를 none 으로 한 것입니다.

마지막으로 systemd 에 snmpd 를 활성화 해주고 시작해 줍니다.

로깅 변경

위 설정대로 하면 snmpd 로그가 /var/log/messages 에 저장이 됩니다. 하지만 /var/log/messages 는 커널 메시지도 저장되고 하는 중요한 것이여서 별도 파일에 저장하는 것이 좋습니다.

이를 위해서 snmpd 를 위한 별도의 로그 파일 설정을 해주는데, 먼저 /etc/sysconfig/snmpd 설정을 다음과같이 바꿔 줍니다.

rsyslog 데몬에서 다음과 같이 설정해 줍니다.

위에 예제에서 첫번째라인은 로그레벨 6 에 대해서는 /var/log/message 에서 제외하고 로그레벨6은 /var/log/snmpd.log 에 저장하도록 지정한 것입니다.

이렇게 해주고 데몬을 재시작 해줍니다.

로그 로테이션도 설정해 줍니다.

만일 일일이 출력하고 싶지 않다면 /etc/snmp/snmpd.conf 파일에 다음과 같이 설정해 줍니다.

 

Firewalld 설정

CentOS 7 에서는 iptables 에서 firewalld 로 변경되었습니다. snmpd 를 위해 firewalld 를 설정해 줘야 합니다.

먼저 snmp 관련해서 방화벽 열기위한 정보를 xml 파일로 작성해 줍니다.

그리고 다음과 같이 public zone 에 등록해줍니다.

 

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’ 를 수정할때는 오타 를 항상 조심해야 한다.

SNMP Extend

snmpd 는 시스템의 자원들에 대해서 SNMP 프로토콜을 통해서 볼 수 있는 기능을 제공 한다. 그런데, 알고 싶은 자원들에 대한 목록들을 조회하기 위해 MIB 값들이 할당되어 있으며 자주 사용되는 운영체제, 라우터, 스위치 같은 장비들에 대한 MIB 값들을 미리 할당되어 전 세계적으로 표준으로 재정해 사용하고 있다.

그런데, 표준으로 재정된 MIB 값외에 사용자가 필요한 자원들을 조회하기 위한 MIB 값을 등록해야 하는데 이때 사용하는 것이 SNMP Extend 를 사용하면 된다.

SNMP Extend 는 ‘.1.3.6.1.4.1.2021.8.10’ 같은 MIB 에 조회하고자하는 값들을 등록하면 된다.

예를들면 다음과 같다.

이렇게 하면 ‘.1.3.6.1.4.1.2021.8.10.101’ 를 뿌리로하는 MIB 를 조회하면 iostate 으로 조회된 값이 등록되어 SNMP 프로토콜을 이용해서 원격에서도 조회가 가능하다.

테스트를 해보면 snmpwalk 명령어를 이용해서 다음과 같이 해보자

‘-v 1’ 은 snmpd 의 version 1 을 지정해주는 것이다. 만일 이게 안된다면 ‘-v2c’ 로 지정해서 해보자

이렇게해서 무언가 나온다면 정상이다.

만일 ‘Timeout’ 에러 메시지를 만단다면 다음과 같이 퍼미션을 조정해주자.

흥미롭게도 snmpd 는 /etc/hosts.allow, /etc/hosts.deny 두개의 파일을 참조하는데, 퍼미션이 없다면 ‘Timeout’ 이 오류를 내다.