SNMP테스트서버

잉여 위키
Chnagil (토론 | 기여)님의 2026년 9월 10일 (목) 11:32 판
둘러보기로 이동 검색으로 이동

Rocky Linux 9 · Zyxel 스위치 IPT 장애 모니터링 서버 구성 가이드

작성일: 2026-09-10 · 구성안 v1.0

0. 목적·범위·검증 수준

목적: Zyxel L3/L2 → PoE 전화기 → PC 환경에서 전화 연결 실패 시 네트워크 혼잡·패킷 폐기·링크/PoE 이벤트가 동반되는지 기록한다. 콜서버의 TCP/UDP 5060 tcpdump는 별도로 수행하며 이 문서는 해당 설정을 변경하지 않는다.

  • [확정] KVM VM / Rocky Linux 9, Zyxel L3/L2, 전화기 뒤 PC 연결, 콜서버 SIP 캡처 병행 계획.
  • [미확인] 스위치 모델·펌웨어·대수·주소·Voice VLAN·콜서버 경로, SNMPv3 알고리즘, sFlow 지원, CPU/PoE 전용 OID.
  • [제안] 먼저 Telegraf + InfluxDB OSS 2.x + Grafana OSS + rsyslog를 RPM/systemd로 직접 설치한다. 전체 포트 30초, 의심 포트/업링크 5초에서 시작하고 필요한 포트만 1초로 단축한다.
  • sFlow는 조건부 단계: Akvorado가 후보지만 모델의 exporter 지원과 배포 릴리스 설정이 확정되지 않았으므로 §12는 준비·배포 검토·수신 검증 절차다. 아직 운영 기동을 보장하는 완성 설정이 아니다. SNMP/Syslog 기본 구성은 독립적으로 진행 가능하다.
  • 실제 Rocky VM·Zyxel 장비에서 실행 시험한 문서는 아니다. 구성 예시를 정적 점검했으며 각 단계의 현장 검증을 통과한 후 진행한다.

1. 구조와 준비값

서비스 설치 방식 연결/저장
Telegraf 1.x RPM / telegraf.service 스위치 UDP/161 조회 → 로컬 InfluxDB
InfluxDB OSS 2.x RPM / influxdb.service 127.0.0.1:8086, 30일 raw bucket
Grafana OSS RPM / grafana-server.service 127.0.0.1:3000, SSH 터널 접속
rsyslog 8.x Rocky RPM / rsyslog.service UDP/514 → /var/log/zyxel/<송신IP>/events.log
Akvorado 배포 스택 별도 검토 후 공식 Docker Compose sFlow UDP/6343 → ClickHouse 등

SNMP Trap UDP/162는 이번 기본 구성에 포함하지 않는다. Rocky를 조회하는 SNMP agent인 snmpd도 불필요하다. 이 서버는 SNMP 조회자다.

준비표 — 모든 <...>를 실제 값으로 교체

자리표시자 의미
<COLLECTOR_IP> Rocky VM 고정 IPv4
<FW_ZONE> 관리 NIC에 실제 적용된 firewalld zone
<SWITCH_SOURCE_CIDR> 실제 Syslog 송신 IP /32 또는 승인된 스위치 관리 대역
<SWITCH_IP> / <SWITCH_NAME> 수집 대상 관리 IP / 식별 이름
<IFINDEX> / <PORT_LABEL> SNMP 조회로 확인한 인덱스 / 포트명
<CALLSERVER_IP> 콜서버 IP
<SNMP_USER> 등 읽기 전용 SNMPv3 계정·인증값
<NTP_SERVER> 콜서버/스위치와 맞춘 승인된 시간 서버

소규모 시작 가정: 기본 구성 4 vCPU / RAM 8GB / SSD 100~200GB. Akvorado 동시 운영은 8 vCPU / RAM 16~32GB / SSD 300~500GB부터 부하 시험한다. 이는 보장 사양이 아니며 포트 수·샘플 PPS·저장량으로 조정한다. KVM CPU 과할당, 메모리 ballooning 및 호스트 디스크 포화를 피한다.

VM은 VirtIO NIC를 KVM 관리 브리지에 연결하고, 스위치까지 라우팅 가능한 고정 IP를 사용한다. SNMP/sFlow에는 미러 포트나 promiscuous 설정이 필요 없다. 같은 VLAN이 필수도 아니다. NAT는 SNMP 접근제어와 sFlow 송신자 식별을 복잡하게 하므로 가능한 관리망 브리지/라우팅 연결을 사용한다.

관측 범위 한계

  • 전화기 연결 물리 포트의 카운터는 전화기와 PC 합산이다. IF-MIB만으로 Voice/Data를 분리할 수 없다.
  • 같은 L2 내부에서 끝나는 트래픽은 L3만 관측해서는 보이지 않을 수 있다.
  • 수집 경로가 폭주 구간과 겹치면 장애 때 데이터도 빠진다. OOB가 없으면 코어에 가까운 안정적 관리 경로를 확보한다.
  • 1초 SNMP는 1초 구간 평균이며 장비 내부 카운터 갱신이 1초보다 느릴 수 있다. Microburst 부재를 증명하지 못한다.

2. 변경 영향·백업

전제는 신규 전용 VM이다. 기존 운영 서버에 적용한다면 같은 이름의 설정을 덮어쓰지 말고 병합한다. 기존 Telegraf 입력/출력, rsyslog 입력 포트, Grafana, InfluxDB 데이터가 있으면 본 초기화 절차를 중단한다.

위험 및 롤백 원칙:

  • 패키지 설치 자체로 전화 경로를 변경하지 않는다. 다만 고주기 SNMP/sFlow는 스위치 관리 CPU와 저장량을 증가시킬 수 있다.
  • rsyslog 재시작 동안 로그 수신에 짧은 공백이 발생할 수 있다.
  • 보존기간 만료/로그 회전은 오래된 데이터를 자동 제거한다. 장애 증거는 만료 전에 별도 보관한다.
  • 방화벽은 기존 zone/SSH를 유지하고 특정 송신자 규칙만 추가한다. 실패하면 추가한 규칙만 제거한다.
  • firewall-cmd --complete-reload는 설정 백업 복원이 아니다. 사용하지 않는다.
  • VM 스냅샷은 단기 변경 복구용이며 별도 백업을 대체하지 않는다. 복원하면 스냅샷 이후 수집 데이터가 사라질 수 있다.

root 셸에서 실행한다. 아래 백업 변수는 이 작업용이며 동일 셸에서 유지한다.

umask 077
MON_BACKUP="/root/ipt-monitor-backup-$(date +%Y%m%d-%H%M%S)"
install -d -m 700 "$MON_BACKUP"
cp -a /etc/rsyslog.conf "$MON_BACKUP/"
cp -a /etc/rsyslog.d "$MON_BACKUP/"
cp -a /etc/chrony.conf "$MON_BACKUP/"
cp -a /etc/firewalld "$MON_BACKUP/"
firewall-cmd --list-all-zones > "$MON_BACKUP/firewall-runtime.txt"
firewall-cmd --permanent --list-all-zones > "$MON_BACKUP/firewall-permanent.txt"
rpm -qa | sort > "$MON_BACKUP/packages-before.txt"

firewalld가 미설치/미실행이면 해당 명령 실패를 무시한 채 진행하지 말고, 현재 호스트 방화벽 구성과 SSH 허용부터 확인한다. KVM 콘솔을 확보한다. 스위치 설정도 GUI의 configuration backup으로 별도 내려받는다.

3. 기본 패키지·시간 동기화

cat /etc/rocky-release
uname -m
ip -br address
ip route
df -hT
free -h
getenforce
ss -lntup

dnf install -y curl ca-certificates gnupg2 vim-enhanced \
    net-snmp-utils rsyslog logrotate chrony tcpdump iputils \
    sysstat policycoreutils-python-utils dnf-plugins-core

네트워크·SELinux는 일괄 비활성화하지 않는다. 신규 OS 업데이트/재부팅은 수집 시작 전 점검 시간에 수행한다.

/etc/chrony.conf의 기존 시간 서버 정책을 확인하고, 승인된 서버로 맞춘다. 다음 한 줄은 설정 파일 예시이며 셸 명령이 아니다.

server <NTP_SERVER> iburst
timedatectl set-timezone Asia/Seoul
systemctl enable --now chronyd
systemctl restart chronyd
chronyc tracking
chronyc sources -v
date -Ins

정상 기준: 선택된 소스 ^*, 동기화 정상, 콜서버 및 스위치와 시간 차이가 분석 해상도보다 충분히 작음. 1초 분석은 가능하면 100ms 미만 오차를 목표로 한다. 큰 시간 보정은 수집 시작 전에 한다.

4. 공식 저장소와 패키지 설치

이 가이드는 InfluxDB OSS 2.x / Flux용이다. InfluxDB 3의 SQL 설정과 혼용하지 않는다. 최신 버전이라는 의미가 아니라 본 가이드의 호환 대상이다. 저장소에서 설치 가능한 정확한 RPM 버전을 먼저 확인·기록한다.

공식 설치 근거: InfluxDB 2 RPM 설치, Telegraf RPM 설치, Grafana OSS RPM 설치. 지속 갱신 문서, 확인일 2026-09-10.

4.1 InfluxData 저장소

curl -fL https://repos.influxdata.com/influxdata-archive.key \
    -o /etc/pki/rpm-gpg/RPM-GPG-KEY-influxdata
gpg --show-keys --with-fingerprint /etc/pki/rpm-gpg/RPM-GPG-KEY-influxdata

확인한 공식 문서의 기본키 fingerprint: 24C975CBA61A024EE1B631787C3D57159FC2F927. 일치하지 않으면 키 교체 공지를 공식 문서에서 확인하기 전에는 import하지 않는다. gpgcheck=0 또는 --nogpgcheck로 우회하지 않는다.

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-influxdata
vi /etc/yum.repos.d/influxdata.repo

파일 내용 ($basearch는 DNF가 해석하므로 그대로 둔다):

[influxdata]
name=InfluxData Repository - Stable
baseurl=https://repos.influxdata.com/stable/$basearch/main
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-influxdata
sslverify=1

4.2 Grafana 저장소

vi /etc/yum.repos.d/grafana.repo
[grafana]
name=Grafana OSS repository
baseurl=https://rpm.grafana.com
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://rpm.grafana.com/gpg.key
sslverify=1

Grafana 키 import 요청 시 공식 키/문서와 대조한다. 패키지는 grafana이며 grafana-enterprise를 설치하지 않는다.

dnf makecache
dnf list --showduplicates telegraf influxdb2 influxdb2-cli grafana
dnf install telegraf influxdb2 influxdb2-cli grafana
rpm -q telegraf influxdb2 influxdb2-cli grafana rsyslog
telegraf --version
influxd version
influx version

influxdb2-cli가 저장소에 없다면 임의의 다른 CLI를 설치하지 말고 공식 InfluxDB 2 CLI 설치 방법으로 해당 아키텍처의 서명/체크섬 검증된 패키지를 설치한다. 서버/CLI의 버전 번호는 서로 같지 않을 수 있다.

이후 원격 운영 전 위 버전 출력을 작업 기록에 보관한다. Telegraf/Grafana는 검증된 버전을 변경 관리 대상으로 관리하고 장애 조사 중 자동 업그레이드는 하지 않는다.

5. InfluxDB 초기 설정 및 권한 분리

5.1 로컬에서만 API 수신

install -d -m 755 /etc/systemd/system/influxdb.service.d
vi /etc/systemd/system/influxdb.service.d/10-ipt-listen.conf
[Service]
Environment="INFLUXD_HTTP_BIND_ADDRESS=127.0.0.1:8086"
systemctl daemon-reload
systemctl enable --now influxdb
systemctl restart influxdb
systemctl status influxdb --no-pager
ss -lntp | grep ':8086'
curl -fsS http://127.0.0.1:8086/health

정상: 127.0.0.1:8086에만 수신, health 정상. 전체 주소로 열리면 서비스/설정의 기존 바인딩 override를 확인한다. VM 방화벽에 8086을 열지 않는다.

5.2 초기화

influx setup

대화형 입력값:

항목 입력
Username 전용 관리자 계정
Password 고유한 강한 암호
Organization network
Bucket snmp_raw
Retention 720h (30일)

이미 setup 완료로 표시되면 재초기화하지 말고 기존 조직·bucket을 확인한다. influx bucket list로 snmp_raw retention이 무제한이 아닌 720h인지 검증한다. 별도 테스트 환경이 아닌 기존 DB를 삭제해서 다시 시작하지 않는다.

influx bucket list --org network

5.3 관리자 접속과 서비스 토큰

관리자 PC에서 SSH 터널을 유지한다. 127.0.0.1은 PC 자신의 주소이며 SSH가 VM으로 전달한다.

ssh -N -L 8086:127.0.0.1:8086 -L 3000:127.0.0.1:3000 <SSH_USER>@<COLLECTOR_IP>

브라우저에서 http://127.0.0.1:8086 접속 → API Tokens → Custom Token:

토큰 이름 범위
telegraf-write snmp_raw Write만
grafana-read snmp_raw Read만
초기 Operator 토큰 관리자 초기화·백업용, 서비스에 배포 금지

발급된 토큰은 승인된 비밀 관리 위치에 보관한다. 화면/문서/채팅에 붙여넣지 않는다. 초기 CLI credential도 비밀이며 root만 읽게 유지한다. Grafana 연결에 필요한 읽기 권한과 Telegraf 쓰기 권한을 분리한다.

6. SNMP 및 MIB 사전 확인

6.1 Zyxel 측 선행 작업

모델별 UI/CLI가 다르므로 임의 명령을 넣지 않는다. 관리 화면에서 다음 항목을 구성한다.

  • SNMP 활성화, SNMPv3 읽기 전용 사용자.
  • 인증/암호화 알고리즘은 장비와 Rocky가 함께 지원하는 조합. 아래 예시는 SHA/AES이며 다른 알고리즘이면 양쪽을 같이 수정.
  • 조회 허용 원본은 Rocky 관리 IP. NAT가 있다면 장비에 보이는 실제 원본 IP 확인.
  • IF-MIB/system 조회 권한. 빈 테이블을 기능 미지원으로 단정하기 전 SNMP view 확인.
  • 포트 description에는 전화기 내선/위치나 업링크 상대를 운영 규칙에 따라 기록하되 개인정보 최소화.

6.2 CLI credential을 명령행에 노출하지 않기

아래는 root 조회용 Net-SNMP 사용자 설정이다. 기존 파일이 있으면 백업 후 병합한다. Telegraf는 이 파일을 사용하지 않는다.

install -d -m 700 /root/.snmp
vi /root/.snmp/snmp.conf
defVersion 3
defSecurityName <SNMP_USER>
defSecurityLevel authPriv
defAuthType SHA
defAuthPassphrase <SNMP_AUTH_PASSWORD>
defPrivType AES
defPrivPassphrase <SNMP_PRIV_PASSWORD>
chmod 600 /root/.snmp/snmp.conf
snmpget -v3 -t 2 -r 0 -On <SWITCH_IP> .1.3.6.1.2.1.1.3.0
snmpwalk -v3 -t 2 -r 0 -On <SWITCH_IP> .1.3.6.1.2.1.31.1.1.1.1
snmpwalk -v3 -t 2 -r 0 -On <SWITCH_IP> .1.3.6.1.2.1.31.1.1.1.18

ifName OID의 마지막 숫자가 ifIndex다. 실제 포트 번호와 같다고 가정하지 않는다. 스위치 IP·포트명·ifIndex·전화기 IP·내선을 기록하고 재부팅/스택 변경 후 재확인한다.

snmpget -v3 -t 2 -r 0 -On <SWITCH_IP> \
    .1.3.6.1.2.1.31.1.1.1.6.<IFINDEX> \
    .1.3.6.1.2.1.31.1.1.1.10.<IFINDEX> \
    .1.3.6.1.2.1.31.1.1.1.15.<IFINDEX> \
    .1.3.6.1.2.1.2.2.1.8.<IFINDEX>

정상: Counter64 / Counter64 / Mbps 단위 속도 / operStatus 값. Timeout이면 경로·ACL·SNMP credential, No Such Instance면 인덱스, No Such Object면 view/지원 확인. 지원하지 않는 필드는 수집 설정에서 제외하고 미수집으로 기록한다. 0으로 대체하지 않는다.

6.3 MIB 파일 정책

기본 수집은 숫자 OID + 명시적 field name을 사용한다. IF-MIB 파일 로딩 실패와 원격 SNMP 조회 실패는 별개다. net-snmp-config는 기본 utils 패키지에 없을 수 있어 필수 명령으로 사용하지 않는다.

rpm -ql net-snmp-libs | grep '/mibs/'
snmptranslate -On IF-MIB::ifHCInOctets

제조사 MIB는 Zyxel 공식 지원 페이지에서 정확한 모델/펌웨어용 묶음을 받는다. CPU·PoE·큐 드롭 OID는 확인 전 추가하지 않는다. SNMPv3 쓰기 권한 또는 PoE 전원 제어는 수집기에 부여하지 않는다.

7. Telegraf 구성

7.1 메인 파일과 환경 파일

기존 설정 교체 시 수집 공백 발생 가능. 신규 전용 VM에서 기본 예제 설정을 백업한 후 아래 내용으로 교체한다. /etc/telegraf/telegraf.d/에 기존 활성 conf가 있으면 먼저 내용을 확인한다.

cp -a /etc/telegraf/telegraf.conf "$MON_BACKUP/telegraf.conf.package"
ls -l /etc/telegraf/telegraf.d/
vi /etc/telegraf/telegraf.conf
[agent]
  interval = "30s"
  round_interval = true
  flush_interval = "5s"
  precision = "1ms"
  metric_batch_size = 1000
  metric_buffer_limit = 20000
  omit_hostname = false
  snmp_translator = "gosmi"

[[outputs.influxdb_v2]]
  urls = ["http://127.0.0.1:8086"]
  token = "${INFLUX_WRITE_TOKEN}"
  organization = "network"
  bucket = "snmp_raw"

[[inputs.internal]]
[[inputs.cpu]]
  percpu = false
  totalcpu = true
[[inputs.mem]]
[[inputs.disk]]
  mount_points = ["/"]
[[inputs.net]]

별도 데이터 디스크를 쓰면 실제 마운트 경로를 mount_points에 추가한다. inputs.cpu는 Rocky VM의 CPU이며 스위치 CPU가 아니다.

vi /etc/telegraf/ipt-monitor.env
INFLUX_WRITE_TOKEN='<TELEGRAF_WRITE_TOKEN>'
ZYXEL_SNMP_USER='<SNMP_USER>'
ZYXEL_SNMP_AUTH='<SNMP_AUTH_PASSWORD>'
ZYXEL_SNMP_PRIV='<SNMP_PRIV_PASSWORD>'

위 파일은 systemd EnvironmentFile 형식이다. 셸에서 source로 읽지 않는다. 비밀값에 큰따옴표/역슬래시가 있으면 TOML 확장 시 구문에 영향을 줄 수 있으므로 공식 secret store를 사용하거나 이스케이프를 검증한다.

chown root:root /etc/telegraf/ipt-monitor.env
chmod 600 /etc/telegraf/ipt-monitor.env
install -d -m 755 /etc/systemd/system/telegraf.service.d
vi /etc/systemd/system/telegraf.service.d/10-ipt-monitor.conf
[Service]
EnvironmentFile=/etc/telegraf/ipt-monitor.env

systemd가 환경 파일을 읽어 서비스에 전달한다. 일반 사용자의 읽기는 막지만 root나 동일 서비스 권한으로부터 완전히 숨기는 방식은 아니다.

7.2 전체 포트 30초 수집

/etc/telegraf/telegraf.d/10-zyxel-ports.conf를 작성한다. 한 대의 예시이며 같은 credential을 쓰는 장비는 agents에 추가한다. 인증값이 다르면 입력 블록과 환경변수 이름을 분리한다.

table 본체에는 oid를 지정하지 않는다. 필요한 열만 아래 field로 선택해 전체 테이블의 불필요한 열 조회를 피한다.

[[inputs.snmp]]
  agents = ["udp://<SWITCH_IP>:161"]
  version = 3
  sec_name = "${ZYXEL_SNMP_USER}"
  sec_level = "authPriv"
  auth_protocol = "SHA"
  auth_password = "${ZYXEL_SNMP_AUTH}"
  priv_protocol = "AES"
  priv_password = "${ZYXEL_SNMP_PRIV}"
  timeout = "2s"
  retries = 0
  interval = "30s"
  agent_host_tag = "source"
  name = "switch_system"

  [[inputs.snmp.field]]
    name = "uptime"
    oid = ".1.3.6.1.2.1.1.3.0"

  [[inputs.snmp.table]]
    name = "switch_port"
    index_as_tag = true
    inherit_tags = ["source"]

    [[inputs.snmp.table.field]]
      name = "if_name"
      oid = ".1.3.6.1.2.1.31.1.1.1.1"
      is_tag = true
    [[inputs.snmp.table.field]]
      name = "if_alias"
      oid = ".1.3.6.1.2.1.31.1.1.1.18"
    [[inputs.snmp.table.field]]
      name = "in_octets"
      oid = ".1.3.6.1.2.1.31.1.1.1.6"
    [[inputs.snmp.table.field]]
      name = "out_octets"
      oid = ".1.3.6.1.2.1.31.1.1.1.10"
    [[inputs.snmp.table.field]]
      name = "in_ucast"
      oid = ".1.3.6.1.2.1.31.1.1.1.7"
    [[inputs.snmp.table.field]]
      name = "in_mcast"
      oid = ".1.3.6.1.2.1.31.1.1.1.8"
    [[inputs.snmp.table.field]]
      name = "in_bcast"
      oid = ".1.3.6.1.2.1.31.1.1.1.9"
    [[inputs.snmp.table.field]]
      name = "out_ucast"
      oid = ".1.3.6.1.2.1.31.1.1.1.11"
    [[inputs.snmp.table.field]]
      name = "out_mcast"
      oid = ".1.3.6.1.2.1.31.1.1.1.12"
    [[inputs.snmp.table.field]]
      name = "out_bcast"
      oid = ".1.3.6.1.2.1.31.1.1.1.13"
    [[inputs.snmp.table.field]]
      name = "speed_mbps"
      oid = ".1.3.6.1.2.1.31.1.1.1.15"
    [[inputs.snmp.table.field]]
      name = "discontinuity"
      oid = ".1.3.6.1.2.1.31.1.1.1.19"
    [[inputs.snmp.table.field]]
      name = "oper_status"
      oid = ".1.3.6.1.2.1.2.2.1.8"
    [[inputs.snmp.table.field]]
      name = "in_discards"
      oid = ".1.3.6.1.2.1.2.2.1.13"
    [[inputs.snmp.table.field]]
      name = "out_discards"
      oid = ".1.3.6.1.2.1.2.2.1.19"
    [[inputs.snmp.table.field]]
      name = "in_errors"
      oid = ".1.3.6.1.2.1.2.2.1.14"
    [[inputs.snmp.table.field]]
      name = "out_errors"
      oid = ".1.3.6.1.2.1.2.2.1.20"

if_alias는 설명 변경에 따른 series 증가를 줄이기 위해 field로 저장한다. 실제 출력에 source, index, if_name 태그가 있는지 확인한다.

7.3 중요 포트 5초 수집

/etc/telegraf/telegraf.d/20-zyxel-fast.conf를 작성한다. 필요한 포트 수만큼 블록을 복제하고 IP·ifIndex·태그를 모두 바꾼다. 같은 포트의 중복 설정은 금지하며 일반 수집과 measurement를 분리한다.

[[inputs.snmp]]
  agents = ["udp://<SWITCH_IP>:161"]
  version = 3
  sec_name = "${ZYXEL_SNMP_USER}"
  sec_level = "authPriv"
  auth_protocol = "SHA"
  auth_password = "${ZYXEL_SNMP_AUTH}"
  priv_protocol = "AES"
  priv_password = "${ZYXEL_SNMP_PRIV}"
  timeout = "800ms"
  retries = 0
  interval = "5s"
  agent_host_tag = "source"
  name = "switch_port_fast"

  [inputs.snmp.tags]
    if_name = "<PORT_LABEL>"
    index = "<IFINDEX>"

  [[inputs.snmp.field]]
    name = "in_octets"
    oid = ".1.3.6.1.2.1.31.1.1.1.6.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "out_octets"
    oid = ".1.3.6.1.2.1.31.1.1.1.10.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "in_ucast"
    oid = ".1.3.6.1.2.1.31.1.1.1.7.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "in_mcast"
    oid = ".1.3.6.1.2.1.31.1.1.1.8.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "in_bcast"
    oid = ".1.3.6.1.2.1.31.1.1.1.9.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "out_ucast"
    oid = ".1.3.6.1.2.1.31.1.1.1.11.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "out_mcast"
    oid = ".1.3.6.1.2.1.31.1.1.1.12.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "out_bcast"
    oid = ".1.3.6.1.2.1.31.1.1.1.13.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "in_discards"
    oid = ".1.3.6.1.2.1.2.2.1.13.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "out_discards"
    oid = ".1.3.6.1.2.1.2.2.1.19.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "oper_status"
    oid = ".1.3.6.1.2.1.2.2.1.8.<IFINDEX>"
  [[inputs.snmp.field]]
    name = "discontinuity"
    oid = ".1.3.6.1.2.1.31.1.1.1.19.<IFINDEX>"

표준 정의: RFC 2863. 각 열의 지원 여부는 실장비에서 확인한다.

1초 수집은 해당 블록의 interval = "1s"로 변경한다. 먼저 카운터 갱신과 수집 소요시간을 확인한다. 800ms는 개별 요청 timeout이지 전체 수집 완료 보장이 아니다. 실패를 반복 재시도하지 않고 결측으로 남긴다. DB에 5초마다 묶어 써도 원래 수집 timestamp는 유지된다.

7.4 응답시간·손실 보조 수집

/etc/telegraf/telegraf.d/30-ipt-ping.conf:

[[inputs.ping]]
  urls = ["<SWITCH_IP>", "<CALLSERVER_IP>"]
  method = "native"
  privileged = true
  count = 1
  deadline = "1s"
  interval = "5s"

승인된 시험 전화기 IP를 필요 시 추가한다. ICMP 비응답 장비는 제외한다. 콜서버 Ping은 SIP 서비스 감시가 아니며 VM에서의 경로도 전화기에서의 경로와 같다고 보장할 수 없다.

/etc/systemd/system/telegraf.service.d/10-ipt-monitor.conf의 같은 [Service]에 추가한다:

CapabilityBoundingSet=CAP_NET_RAW
AmbientCapabilities=CAP_NET_RAW

Telegraf를 root로 실행하는 설정은 아니다. 공식 Ping 권한 설명. 기존 입력이 있으면 필요한 capability를 제거하지 않도록 확인한다.

7.5 검사·기동

chown root:telegraf /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.d/*-*.conf
chmod 640 /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.d/*-*.conf
systemctl daemon-reload
systemd-run --unit=ipt-telegraf-check --wait --pipe --collect \
    -p User=telegraf -p Group=telegraf \
    -p EnvironmentFile=/etc/telegraf/ipt-monitor.env \
    -p CapabilityBoundingSet=CAP_NET_RAW \
    -p AmbientCapabilities=CAP_NET_RAW \
    /usr/bin/telegraf --config /etc/telegraf/telegraf.conf \
    --config-directory /etc/telegraf/telegraf.d --test

실제로 SNMP/Ping을 한 번 수집하는 검사다. 출력의 IP 등은 사내 정보로 취급한다. --test는 InfluxDB 쓰기를 검증하지 않는다. 수집 검사 성공 후:

systemctl enable --now telegraf
systemctl restart telegraf
systemctl status telegraf --no-pager
journalctl -u telegraf -n 100 --no-pager

설정 근거: SNMP Input Plugin, Telegraf 설정. 입력과 DB 출력이 모두 성공하는지 확인하고 unauthorized, timeout, collection interval 초과, buffer/drop 메시지를 조사한다.

8. Grafana 구성과 계산

8.1 서비스

먼저 백업한 뒤 /etc/grafana/grafana.ini의 기존 섹션을 수정한다. 중복 섹션을 추가하지 않는다.

cp -a /etc/grafana/grafana.ini "$MON_BACKUP/grafana.ini.initial"
vi /etc/grafana/grafana.ini
[server]
http_addr = 127.0.0.1
http_port = 3000

[users]
allow_sign_up = false

[auth.anonymous]
enabled = false
systemctl enable --now grafana-server
systemctl restart grafana-server
systemctl status grafana-server --no-pager
curl -fsS http://127.0.0.1:3000/api/health
ss -lntp | grep ':3000'

초기 관리자로 로그인 후 즉시 강한 비밀번호로 변경한다. SSH 터널의 http://127.0.0.1:3000을 사용한다. 공유 접속이 필요하면 인증·TLS reverse proxy와 접근제어를 별도 구성하며 평문 HTTP를 전사망에 개방하지 않는다.

8.2 InfluxDB 데이터소스

Connections → Data sources → Add data source → InfluxDB:

설정 값
Name IPT-SNMP
Query language Flux
URL http://127.0.0.1:8086
Organization network
Token grafana-read 토큰
Default Bucket snmp_raw
Min time interval 1s (실제 수집 간격은 패널별로 반영)

Save & test 성공 후 Explore에서 measurement를 조회한다. Grafana 공식 연결 설정.

8.3 필드와 태그 확인

from(bucket: "snmp_raw")
  |> range(start: -10m)
  |> filter(fn: (r) => r._measurement == "switch_port_fast")
  |> limit(n: 5)

실제 source 태그를 확인해 아래 <SOURCE_TAG_VALUE>에 넣는다. 일반적으로 장비 IP지만 출력으로 확인한다. 먼저 변수 없이 한 대·한 포트의 표시를 완성한다.

8.4 In/Out bps

패널: Time series / Unit: bits/sec / 결측 구간 연결 안 함 / 시간대 Asia/Seoul / 범위 최근 15분 / refresh 5s.

from(bucket: "snmp_raw")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "switch_port_fast")
  |> filter(fn: (r) => r.source == "<SOURCE_TAG_VALUE>" and r.index == "<IFINDEX>")
  |> filter(fn: (r) => r._field == "in_octets" or r._field == "out_octets")
  |> derivative(unit: 1s, nonNegative: true)
  |> map(fn: (r) => ({r with _value: r._value * 8.0}))

derivative로 실제 timestamp 차이를 사용해 초당 값으로 바꾼 뒤 8배한다. 고정 간격 5로 나누지 않는다. 장기간 표시에서 집계한다면 rate 계산 후 aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)를 추가하고 ‘구간 내 최대 수집간격 평균’으로 표시한다. 누적 카운터를 먼저 평균내지 않는다.

nonNegative만으로 모든 리셋을 판별할 수 없다. discontinuity 변경·sysUpTime 감소·링크 변경 구간은 무효 처리한다. 첫 점은 이전 값이 없어 표시되지 않는다. 결측은 0으로 채우지 않으며 긴 결측을 가로지르는 rate는 장애 증거에 사용하지 않는다. Flux derivative.

8.5 PPS、Broadcast、Discard

위 쿼리의 _field 조건을 다음으로 바꾸고 8배하는 map 행은 제거한다. 각 계열을 별도로 표시한다.

  |> filter(fn: (r) => r._field == "in_ucast" or r._field == "in_mcast" or r._field == "in_bcast")

합계 In PPS는 세 계열의 합이다. Out PPS는 대응하는 out_ 세 계열로 만든다. Broadcast/Multicast 전용 패널도 구성해 정상 시 기준과 비교한다.

  |> filter(fn: (r) => r._field == "in_discards" or r._field == "out_discards")

위 값은 폐기 packets/sec다. 누적값이 아니라 증가율을 표시한다. 일반 수집 measurement의 in_errors/out_errors도 같은 방식으로 별도 패널을 만든다.

8.6 상태·손실·대시보드

  • oper_status는 rate로 바꾸지 않는다. 1=up, 2=down 등으로 state timeline에 표시한다.
  • speed_mbps는 Mbps 단위다. In 사용률=In bps÷(speed_mbps×1,000,000)×100. Out은 따로 계산하며 전이중의 In/Out을 합쳐 100%로 판정하지 않는다.
  • ping의 average_response_ms, percent_packet_loss는 이미 계산된 값이므로 derivative 불필요. 1패킷/5초 설정에서는 각 관측의 손실이 0% 또는 100%다.
  • LAG 논리 포트와 물리 멤버를 별도로 표시하고 합산 중복 집계를 피한다.
  • 초기 패널: 중요 포트 bps, Broadcast/Multicast PPS, Discard/Error 증가율, operStatus, Ping 지연·손실, VM CPU·메모리·디스크, Telegraf 오류·결측.
  • 스위치 CPU·PoE는 모델별 OID 확인 후 추가한다. 미설정을 0/정상으로 표시하지 않는다.

대시보드를 저장하고 JSON으로 내보낸다. 이번 Syslog 구성은 파일 조회용으로 Grafana에서 로그를 검색할 수는 없다. 별도 로그 검색 UI를 추가하기 전에는 §11의 CLI로 대조한다.

9. Zyxel Syslog 수신

9.1 포트 중복 확인

grep -RniE 'imudp|imtcp|port="514"|UDPServerRun' /etc/rsyslog.conf /etc/rsyslog.d
ss -lunp | grep ':514'

기존 입력이 있으면 module/input을 중복 생성하지 말고 기존 설정에 통합한다. 아래는 미구성 신규 VM용이다.

install -d -m 750 /var/log/zyxel
restorecon -RF /var/log/zyxel
vi /etc/rsyslog.d/30-zyxel-remote.conf
module(load="imudp")

template(name="ZyxelRemotePath" type="string"
  string="/var/log/zyxel/%fromhost-ip:::secpath-replace%/events.log")

template(name="ZyxelRemoteLine" type="string"
  string="received=%timegenerated:::date-rfc3339% reported=%timereported:::date-rfc3339% src=%fromhost-ip% host=%hostname% facility=%syslogfacility-text% severity=%syslogseverity-text% tag=%syslogtag% msg=%msg%\n")

ruleset(name="ZyxelRemoteRules") {
  action(type="omfile"
    dynaFile="ZyxelRemotePath"
    template="ZyxelRemoteLine"
    createDirs="on"
    dirCreateMode="0750"
    fileCreateMode="0640")
  stop
}

input(type="imudp" address="<COLLECTOR_IP>" port="514"
  ruleset="ZyxelRemoteRules")

송신 IP별 파일에 수신 시각과 장비 보고 시각을 함께 기록한다. 장비 Syslog에 시간대 정보가 없으면 완전한 보정은 불가능하므로 실장비 테스트로 대조한다.

rsyslogd -N1
systemctl enable --now rsyslog
systemctl restart rsyslog
ss -lunp | grep ':514'
journalctl -u rsyslog -n 100 --no-pager

재시작 중 짧은 수신 공백에 주의한다. 실패하면 변경 전 파일을 복원하고 rsyslogd -N1 검사 후 재시작한다. SELinux 거부는 다음으로 확인하며 비활성화하지 않는다.

ausearch -m AVC -ts recent
ls -Zd /var/log/zyxel

근거: imudp, omfile. 참조 문서는 최신판을 포함하므로 설치된 rsyslog의 구문 검사를 반드시 수행한다.

9.2 로그 회전과 보존

/etc/logrotate.d/zyxel-remote:

/var/log/zyxel/*/events.log {
    daily
    rotate 30
    missingok
    notifempty
    compress
    delaycompress
    create 0640 root root
    sharedscripts
    postrotate
        /usr/bin/systemctl kill -s HUP --kill-who=main rsyslog.service >/dev/null 2>&1 || true
    endscript
}

보존은 ‘30회전분’이며 매일 회전하면 약 30일이다. 정확히 30일이 지난 순간 삭제되는 방식은 아니다. 오래된 파일 삭제를 수반하므로 장애 로그는 별도 보관한다. 신규 VM의 rsyslog root 실행 기준이며 privilege drop을 사용한다면 소유자를 맞춘다.

logrotate -d /etc/logrotate.d/zyxel-remote
systemctl status logrotate.timer --no-pager
systemctl list-timers --all | grep logrotate

일일 실행이 비활성이라면 패키지 timer/cron을 확인해 활성화한다. 일일 회전만으로 하루 동안의 폭증에 따른 디스크 고갈은 막을 수 없다. 디스크 80% 예고 감시와 증가량 점검을 수행한다. 근거 없이 중요 로그를 제한해 버리지 않는다.

9.3 Zyxel 측 송신

Syslog 목적지 <COLLECTOR_IP> / UDP514. Informational을 포함하는 범위로 시작하고 상시 Debug는 피한다. Link Up/Down, STP 변경, 루프 탐지, PoE 이상·전력 부족, 재시작 등을 모델 지원 범위에서 활성화한다. 포트별 이벤트 설정이 필요하면 함께 적용한다.

10. firewalld와 접속 확인

기본 웹 접속은 SSH 터널만 사용한다. 3000/8086과 서버 수신 UDP161/162를 열지 않는다. SNMP는 서버에서 스위치 UDP161로 조회하고 응답을 받는다. 외향 제한이 있는 경우에만 기존 정책에 필요 허용을 추가한다.

10.1 Syslog만 허용

영향: 지정 송신원에서 UDP514 수신을 추가한다. zone 변경·SSH 규칙 삭제·광범위 허용은 하지 않는다. 먼저 확인:

firewall-cmd --get-active-zones
firewall-cmd --zone=<FW_ZONE> --list-all

실제 값으로 설정한다. 송신자를 엄격히 제한하려면 장비별 /32 규칙을 사용한다.

MON_ZONE='<FW_ZONE>'
MON_SYSLOG_RULE='rule family="ipv4" source address="<SWITCH_SOURCE_CIDR>" port port="514" protocol="udp" accept'
firewall-cmd --zone="$MON_ZONE" --add-rich-rule="$MON_SYSLOG_RULE" --timeout=600

10분 안에 장비 송신과 SSH 접속 유지를 확인한다. 임시 규칙은 자동 만료된다. 승인 후 동일 규칙만 영구 및 runtime에 적용:

firewall-cmd --permanent --zone="$MON_ZONE" --add-rich-rule="$MON_SYSLOG_RULE"
firewall-cmd --zone="$MON_ZONE" --remove-rich-rule="$MON_SYSLOG_RULE"
firewall-cmd --zone="$MON_ZONE" --add-rich-rule="$MON_SYSLOG_RULE"

이미 만료됐다면 remove의 not enabled를 확인하고 다음으로 진행한다. 전체 runtime 저장이나 reload로 다른 작업 변경을 포함하지 않는다.

롤백 — 이번 작업에서 새로 추가한 규칙만 제거:

firewall-cmd --zone="$MON_ZONE" --remove-rich-rule="$MON_SYSLOG_RULE"
firewall-cmd --permanent --zone="$MON_ZONE" --remove-rich-rule="$MON_SYSLOG_RULE"

10.2 실장비 도달 확인

timeout 20 tcpdump -ni any -nn 'udp dst port 514'
tail -n 50 /var/log/zyxel/<SWITCH_SYSLOG_SOURCE_IP>/events.log

VM 자신의 logger는 파일 저장 검사용이며 스위치에서의 경로·ACL 검증을 대신하지 못한다.

logger --udp --server <COLLECTOR_IP> --port 514 --tag IPT_TEST 'collector receiver test'

11. 시험 운영·장애 확인

11.1 초기 24시간

  1. 한 대·중요 포트 1~2개로 시작한다.
  2. 실제 SNMP 카운터와 InfluxDB 값 증가를 대조한다.
  3. bps/PPS 변동과 operStatus 표시를 확인한다.
  4. 정상 발신 테스트의 시각·단말 IP·Call-ID를 기록한다. 본망에서 부하용 iperf나 루프를 만들지 않는다.
  5. 별도 수집 중인 콜서버 SIP와 전후 2분의 네트워크 기록을 비교한다.
  6. 5060 외 SIP/TLS와 RTP는 해당 캡처 범위 밖임을 기록한다.
  7. 수집시간·스위치 CPU·VM CPU/IO·결측·로그 증가량이 허용 범위면 대상 장비를 늘린다.
  8. 중요 포트 1초화는 카운터 갱신을 실측한 후 진행한다.

11.2 운영 확인 명령

systemctl is-active influxdb telegraf grafana-server rsyslog chronyd
journalctl -u telegraf --since '-10 min' --no-pager
chronyc tracking
df -h
du -sh /var/log/zyxel
vmstat 1 5
iostat -xz 1 5
nstat -az | grep -E 'Udp(InErrors|RcvbufErrors|InDatagrams)'

UDP 통계는 누적값이므로 시간 차분으로 본다. VM/호스트의 수신 드롭을 스위치 송신 중단으로 오해하지 않는다. inputs.internal의 수집시간·오류와 DB 출력 drop도 대시보드에 추가한다.

11.3 장애 기록 양식

항목 기록
장애 일시·시간대 초 단위, KST
발신·착신 내선, 전화기 IP, 등록 상태
연결 위치 L2 이름, 포트, ifIndex, Voice VLAN
PC 상태 동시 정상·불통·미확인
SIP INVITE 도착, 응답 코드, Call-ID, 재전송
SNMP In/Out bps、PPS、Broadcast、Discard、operStatus
로그 Link, STP, PoE, 재부팅 등
수집 상태 NTP, 결측, VM 수신 drop, tcpdump drop

로그 검색:

grep -Ei 'link|stp|loop|poe|power|reboot|restart|topology' \
    /var/log/zyxel/<SWITCH_SYSLOG_SOURCE_IP>/events.log

메시지의 수신·보고 시각을 장애 전후와 비교한다. 키워드가 없다는 이유만으로 이벤트가 없다고 판단하지 않는다. 장비 문구는 모델에 따라 다르다.

11.4 초기 알림 제안

아래는 운영 후 Grafana 관리형 알림으로 구성할 제안값이며 자동 생성된 설정은 아니다.

  • 중요 포트 한 방향 사용률 80% 이상이 30초 지속: 혼잡 예고이며 원인 확정은 아니다.
  • 중요 포트 Discard 증가: 조사 이벤트. QoS·버퍼·정책 확인.
  • Ping 3회 연속 손실: VM에서의 도달성 이상이며 SIP 장애 확정은 아니다.
  • 고주기 데이터 15초 이상 결측: No Data를 정상으로 처리하지 않는다.
  • 디스크 사용량 80% 이상: 보존 공간 경고.
  • Broadcast PPS는 24시간 정상값을 확보한 뒤 임계값을 결정한다. 모든 현장에 공통 고정값을 적용하지 않는다.

전화 연결 실패와 높은 사용률·Discard 증가가 동반되면 혼잡이 유력하다. INVITE 불착만으로 단말 미송신과 경로 손실은 구분할 수 없다. 등록·PoE·Voice VLAN 상태와 함께 판단한다.

12. sFlow 추가 — 조건부 절차

12.1 착수 조건

Zyxel이라는 제조사명만으로 sFlow 지원을 확정할 수 없다. 정확한 모델·펌웨어의 공식 매뉴얼에서 exporter, 대상 인터페이스, sampling 범위, source/agent IP 설정을 확인한다. 확인 전 컨테이너 전체를 기동할 필요는 없다.

장비 설정 계획
Collector <COLLECTOR_IP>
UDP port 6343, 수집기와 일치
Agent / source SNMP로 도달 가능한 고정 관리 IP
Sampling 지원 범위에서 1:1024 전후를 시험 시작값으로 검토
Counter polling 10~30초 중 장비 지원값
관측 대상 중요 L2/L3 포트, 가능하면 ingress 중심

패킷 샘플링과 counter polling은 별개다. sFlow는 SIP 전체 패킷 캡처를 대체하지 않는다. IP별 사용률은 추정이고 L3만으로 같은 L2 내부 트래픽을 놓칠 수 있다. 여러 스위치·입출력의 동일 패킷을 중복 합산하지 않는다.

12.2 Akvorado 도입 방안

Akvorado 공식 프로젝트는 NetFlow/IPFIX/sFlow, SNMP 메타데이터 보강, ClickHouse 저장과 웹 분석을 제공한다. 공식 Docker Compose는 본문의 RPM 운영과 별개다. 이전 설명의 Podman Compose 호환을 전제하지 않는다. Docker와 Podman 호환 패키지도 혼용하지 않는다.

공식 .env는 여러 docker/docker-compose-*.yml을 조합한다. main은 개발 구성을 포함하므로 그대로 운영 배포하지 않는다. 공식 구성 디렉터리.

지원 확인 후 KVM 스냅샷과 방화벽 백업을 확보하고 Docker Engine의 RHEL/CentOS계 설치 방법을 검토한다. Rocky가 Docker의 공식 지원 대상과 동일하다고 가정하지 않는다. Docker CentOS 절차.

신규 전용 VM이며 패키지 충돌이 없다고 확인된 경우의 준비 명령:

rpm -q podman-docker docker-ce docker-ce-cli containerd.io
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf list --showduplicates docker-ce docker-compose-plugin
dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

충돌 패키지를 자동 삭제하지 않는다. Docker는 전송·패킷 필터 규칙을 변경할 수 있으므로 KVM 게스트에서만 적용하고 관리 경로를 검증한다. KVM 호스트에서는 실행하지 않는다.

systemctl enable --now docker
docker version
docker compose version
dnf install -y git
git clone https://github.com/akvorado/akvorado.git /opt/akvorado
cd /opt/akvorado
git tag --sort=-version:refname | head -20

기존 파일이 있는 /opt/akvorado에는 clone하지 않는다. 공식 안정 릴리스의 태그를 선택하고 해당 Changelog·문서를 읽는다. 본문에서 태그는 미확정이다.

git switch --detach <VERIFIED_STABLE_TAG>
git rev-parse HEAD
docker compose config --services
docker compose config --images
docker compose config --quiet

docker compose config --quiet는 Compose 구문만 검사한다. 앱 설정 검증과 다르다. 아래 환경값을 선택한 릴리스의 schema로 구성한 후 기동한다. 추정한 키 이름으로 작성한 YAML은 제공하지 않는다.

필수 설정 확인 사항
sFlow 입력 UDP6343 수신·바인딩
SNMP metadata agent/source 주소, 장비별 인증값, 포트명 보강
내부 네트워크 Voice/Data CIDR과 사설 IP 분류
불필요 서비스 demo exporter 비활성, Grafana 중복 배치 금지, GeoIP 의존성 확인
인증·공개 웹은 loopback+SSH 또는 인증 TLS, DB/Kafka는 외부 공개 금지
보존 원시·집계 데이터 기간, ClickHouse TTL, 용량 계획
영속화·SELinux named volume 또는 전용 bind mount 라벨, 공유 OS 경로에 :Z 사용 금지
재시작 서비스 restart policy, Docker 자동 기동

Docker 공개 포트를 firewalld INPUT 규칙만으로 제한할 수 있다고 가정하지 않는다. 실제 백엔드의 전달 규칙/DOCKER-USER 상당 경로, 상위 ACL과 관리 IP 바인딩을 확인하고 비허가 단말에서 차단되는지 시험한다. 관리 IP 바인딩은 송신원 제한이 아니다. §10 rich rule만으로 Docker의 UDP6343 제한을 완료 처리하지 않는다.

위 조건을 확정한 뒤 실행할 기동·검증 명령:

cd /opt/akvorado
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100

태그·설정이 미정인 상태에서 일괄 실행하는 명령이 아니다. 같은 릴리스의 앱 설정 검사 방법을 따르고 healthy 표시뿐 아니라 실제 데이터 표시도 확인한다.

12.3 수신·분석 합격 기준

timeout 20 tcpdump -ni any -nn 'udp dst port 6343'
ss -lunp | grep ':6343'
nstat -az | grep -E 'Udp(InErrors|RcvbufErrors|InDatagrams)'

Docker의 포트 구현에 따라 호스트 ss에 예상 소켓이 안 보일 수 있다. 실제 Compose 포트 매핑과 수신 메트릭을 함께 확인한다.

합격: 스위치 source에서 패킷 도착, 수집·디코드 카운터 증가, 오류 급증 없음, 웹에서 exporter·입력 포트·단말 IP·시간대 표시, 포트 번호의 실제 이름 매핑. tcpdump 도착만으로 성공 판정하지 않는다.

미지원 장비는 SNMP/Syslog를 유지하고 필요한 사건만 승인된 포트 미러링으로 분석한다. 미러링은 별도 vNIC·물리 연결·대역폭 검토가 필요하며 현재 관리 NIC를 임의로 미러 수신 포트로 바꾸지 않는다.

13. 백업·롤백

13.1 일반 백업

Influx CLI 관리자 인증으로 여유 공간이 있는 새 디렉터리에 저장한다. Grafana 읽기 전용·Telegraf 쓰기 전용 토큰으로는 백업할 수 없다. InfluxDB backup.

umask 077
MON_ARCHIVE="/root/ipt-monitor-save-$(date +%Y%m%d-%H%M%S)"
install -d -m 700 "$MON_ARCHIVE"
influx backup "$MON_ARCHIVE/influxdb"
tar -czf "$MON_ARCHIVE/configs.tar.gz" \
    /etc/telegraf /etc/grafana /etc/rsyslog.conf /etc/rsyslog.d \
    /etc/logrotate.d/zyxel-remote /etc/chrony.conf /etc/firewalld \
    /etc/systemd/system/telegraf.service.d \
    /etc/systemd/system/influxdb.service.d

백업에는 SNMP 비밀과 토큰이 포함된다. root 전용 권한을 유지하고 접근제어된 다른 매체에 암호화 복제한다. root 디스크에만 둔 것은 백업 완료로 간주하지 않는다.

Grafana 기본 SQLite의 실행 중 파일만 단순 복사하지 않는다. 화면 중단이 허용되는 시간에 다음을 수행한다:

systemctl stop grafana-server
tar -czf "$MON_ARCHIVE/grafana-data.tar.gz" /var/lib/grafana
systemctl start grafana-server
curl -fsS http://127.0.0.1:3000/api/health

이 동안 Telegraf 수집은 계속된다. 외부 DB를 사용하는 Grafana는 별도 DB 정합 백업이 필요하다. 장애 구간 Syslog·콜서버 pcap도 보존한다. 기록 중인 파일은 변경될 수 있으므로 닫힌 파일이나 정합 스냅샷으로 증거를 확보한다.

13.2 설정 변경 롤백

  • 고주기 SNMP 부하: 20-zyxel-fast.conf의 interval을 5/10초로 복귀 후 검사·재시작. 긴급 시 systemctl stop telegraf를 수행하고 수집 중단을 기록한다.
  • Telegraf 오류: 해당 설정의 변경 전 버전 복원 → 검사 → 재시작. DB는 삭제하지 않는다.
  • 신규 Syslog 설정만 취소하려면 아래처럼 비활성화한다. 수신 중단을 알리고 기존 파일을 수정했던 경우에는 변경 전 버전으로 복원한다.
mv /etc/rsyslog.d/30-zyxel-remote.conf /etc/rsyslog.d/30-zyxel-remote.conf.disabled
rsyslogd -N1
systemctl restart rsyslog
  • firewalld는 §10에서 추가한 정확히 일치하는 규칙만 제거한다.
  • Akvorado 중지는 /opt/akvorado에서 docker compose stop. down -v, volume 삭제, ClickHouse DROP은 하지 않는다.
  • 장비의 sFlow는 추가한 export 설정만 되돌린다. Voice VLAN·PoE·STP·QoS는 일괄 초기화하지 않는다.

13.3 데이터 복원·업그레이드

운영 InfluxDB에 full restore를 바로 수행하면 덮어쓰기 위험이 있다. 격리된 새 VM에 같은 버전으로 공식 restore 절차를 시험한다. Grafana는 중지 후 동일 구성의 데이터·설정을 복원하고 소유자/SELinux 라벨을 확인해 기동한다. 새 운영 데이터와의 통합은 별도 계획한다.

업그레이드: RPM/이미지 버전 기록 → 백업 → 시험 VM 검증 → 운영 적용. 메이저 변경·DB schema 변경 후 바이너리만 내려서 롤백하지 않는다.

14. 장애 확인표·인수 체크리스트

이상 첫 확인
SNMP timeout 같은 조건 CLI, 관리 경로·ACL·CPU·인증·암호화
No Such Object/Instance view·모델 지원·ifIndex·인터페이스 선택
Telegraf 값은 있는데 Grafana가 비어 있음 DB 쓰기 토큰·bucket·measurement/tag·UTC/KST·시간 범위
계단형 그래프·이상 피크 카운터 갱신 주기·리셋·결측·중복 수집
재부팅 후 다른 포트 표시 ifIndex 재조회, 고정 OID·태그 수정
Syslog는 도착하지만 파일 없음 ruleset·구문·권한·SELinux·실제 송신 IP
sFlow 패킷만 도착 포트 매핑·디코딩·metadata·DB·시간·필터
PoE/CPU 없음 본 구성 미포함. 모델 전용 MIB 필요
전화 장애 때 전체 데이터 결측 VM/KVM 부하·관리 경로·NTP·수신 drop

초기 구성 완료 조건

  • ☐ OS/RPM 버전과 IP·포트 대응표를 저장했다.
  • ☐ SNMPv3 읽기 전용으로 대상 조회 및 ifIndex를 확인했다.
  • ☐ 실데이터의 bytes·PPS·Broadcast·Discard가 확인된다.
  • ☐ Grafana가 누적값 대신 rate를 표시하고 상태는 원래 값으로 표시한다.
  • ☐ DB 저장·화면 표시와 재부팅 후 수집 지속을 확인했다.
  • ☐ 실장비 Syslog 저장과 logrotate dry-run을 확인했다.
  • ☐ 콜서버·스위치와 NTP가 일치한다.
  • ☐ DB/API 비공개, SSH·송신원 허용을 확인했다.
  • ☐ 결측을 0/정상으로 표시하지 않는다.
  • ☐ sFlow·PoE·CPU 미확인 항목을 완료 처리하지 않는다.
  • ☐ 보존 만료 전 장애 증거 보관과 복원 방침을 정했다.

15. 공식 자료·대상 버전

공식 자료 확인일: 2026-09-10. 지속 갱신 문서는 고정 게시일이 없으며 실제 RPM 버전을 §4 출력으로 기록한다.

대상 공식 자료
Telegraf 1.x 설치 / 설정 / SNMP / Ping
InfluxDB OSS 2.x RPM 설치 / backup
Flux derivative
Grafana OSS RPM 설치 / InfluxDB 연결
Net-SNMP snmp.conf
IF-MIB RFC 2863, 2000-06
rsyslog 8.x imudp / omfile
Akvorado 공식 프로젝트 / Compose
Docker Engine CentOS 설치 참고

추가로 필요한 정보: Zyxel L3/L2 모델·펌웨어·대수·관리 IP/Voice VLAN 구조. 확인 후 장비별 SNMPv3/Syslog/sFlow 명령과 CPU·PoE·큐 OID를 확정할 수 있다.