← 전체 글
네트워킹/약 12분 읽기/— 조회

PLC를 의심하기 전에 스위치에서 확인해야 할 SNMP 항목

간헐적 bad quality는 대개 스위치 포트에서 시작된다. polling할 SNMP object, counter를 증가율로 보는 이유, trap이 조용히 실패하는 곳.

네트워킹SCADASNMP문제 해결알람

8초짜리 bad quality, 원인은 컨트롤러가 아니었다

remote I/O drop 하나에 물린 아날로그 tag 몇 개가 교대당 두세 번, 몇 초씩 bad quality로 바뀐다. PLC 진단 버퍼는 깨끗하다. SCADA driver log에는 request timeout이 찍히고 곧 복구된다. 재현이 안 되니 "통신 글리치"로 적히고 미결 항목 목록에서 한 달을 보낸다.

스위치는 알고 있었다. 그 drop으로 가는 copper port에 FCS error가 쌓이고 있었고, 증가 시점이 대형 mixer 기동 시각과 맞았다. 실드 처리가 부실한 drive가 모터 케이블과 같은 트레이를 지나는 구간에 노이즈를 실은 것이다. 이 중 어느 것도 SCADA에는 보이지 않았다. 스위치는 "IT 장비"였고, 아무도 object 하나 polling하지 않았기 때문이다.

스위치 상태를 운전 화면에 올리는 이유가 이것이다. packet capture나 설정 백업을 대신하려는 게 아니라, bad quality가 터진 뒤 첫 질문 — 공정 문제인가, 컨트롤러 문제인가, 네트워크 경로 문제인가 — 에 화면이 답할 수 있게 하려는 것이다.

실제로 가져올 만한 짧은 목록

MIB 전체를 넣고 싶은 마음은 참는 게 낫다. 스위치 40대에 대당 100개 point면 화면은 느려지고 알람 목록은 아무도 안 믿는다. 필요한 값은 대부분 IF-MIB(RFC 2863)와 EtherLike-MIB(RFC 3635)에 있다.

보고 싶은 것Object
Link up/downifOperStatus — 1.3.6.1.2.1.2.2.1.8
협상된 속도ifSpeed / ifHighSpeed
수신 errorifInErrors — 1.3.6.1.2.1.2.2.1.14
FCS/CRC 전용dot3StatsFCSErrors — 1.3.6.1.2.1.10.7.2.1.3
Buffer 압박ifInDiscards / ifOutDiscards
전송량ifHCInOctets — 1.3.6.1.2.1.31.1.1.1.6
포트 라벨ifAlias — 1.3.6.1.2.1.31.1.1.1.18
재부팅 감지sysUpTime — 1.3.6.1.2.1.1.3

전원 A/B, 섀시 온도, 이중화 상태는 vendor enterprise MIB에 있고 제조사마다 다르다. OID를 짐작하지 말고 해당 MIB 파일을 열어 확인한다.

ifAlias는 따로 언급할 값어치가 있다. 스위치에 설정된 port description이고, 라벨링 수단 중 제일 싸게 먹힌다. 스위치에서 PLC-2 RIO drop / 판넬 14로 넣고 그 값을 polling하면 알람 문구가 port 7이라고만 말하지 않는다. 시운전 때 한 번 해 두면 이후 모든 알람이 그 이름을 물려받는다.

일반 단말 포트는 스위치당 요약 알람 하나면 충분하다. Uplink, ring port, server port만 개별 상세를 본다.

누적값은 증상이 아니다

ifInErrors는 마지막 counter reset 이후의 누적값이다. 한 번 읽어서는 아무것도 알 수 없다. 4,182라는 숫자는 4년치 무의미한 값일 수도 있고, 죽어 가는 SFP의 4분치일 수도 있다. delta를 저장하고 증가율로 보여 줘야 한다. 분당 CRC error, 분당 discard, 시간당 link 변화 횟수, 마지막 ring topology change 이후 경과 분.

단순 delta 계산을 깨는 것이 두 가지 있다.

Counter 폭. RFC 2863은 32-bit counter가 대략 20 Mbit/s를 넘으면 부적절하고 650 Mbit/s를 넘으면 64-bit가 필요하다고 명시한다. 계산은 냉정하다. 기가비트 uplink에서 2³² octet은 약 34초면 wrap하고, 100 Mbit/s에서도 5.7분 정도다. ifHCInOctets 대신 ifInOctets를 60초 주기로 polling하면 utilization 값은 소설이 된다. high-capacity object를 쓰고, 64-bit counter가 없는 v1 대신 SNMPv2c 이상을 쓴다.

재부팅. 스위치가 재기동하면 counter가 0이 되고 delta는 크게 음수가 되거나, 잘못 처리하면 크게 양수가 된다. counter와 함께 sysUpTime을 읽고, uptime이 뒤로 갔으면 그 구간 delta를 버린다. 이 확인 하나로 가짜 spike 대부분이 사라진다.

모든 포트를 5분마다 보느니 중요한 10개 포트를 15초마다 보는 편이 낫다. flap은 짧다. 5분 주기 polling은 "볼 때는 up이었다"는 사실만 증명한다.

포트 역할처리
Ring 또는 이중화 uplinklink down, speed change, topology change 알람
PLC / remote I/Olink down과 지속적인 error-rate 증가 알람
HMI workstation생산 필수 station일 때만 알람
Engineering laptop 포트event 기록만, 운전 알람 없음
Disabled spare평소 무음, 예상 밖으로 active되면 알람

마지막 줄은 잡을 값어치가 있다. spare 포트가 올라왔다는 건 누군가 뭔가를 꽂았다는 뜻이다. IEC 62443-3-2의 conduit로 구획된 망이라면 그건 네트워크 잡담이 아니라 conduit 변경이다.

빼먹었다가 나중에 후회하는 항목은 speed change다. 청소 후 fiber uplink가 1000에서 100으로 재협상되거나, 고정 속도 장비와 auto-negotiation이 어긋나 copper port가 10 Mbit/s half-duplex로 붙어도 link-down 알람은 뜨지 않는다. 그냥 전체가 느려지고, 원인 같아 보이지 않는 late collision만 쌓인다.

Trap은 언젠가 event를 흘린다

linkDown(1.3.6.1.6.3.1.1.5.3)은 확인 응답 없는 UDP datagram 한 개다. receiver가 재기동 중이거나, community 또는 SNMPv3 engine ID가 맞지 않거나, 지난주에 firewall 규칙이 바뀌었으면 그대로 사라지고 아무도 알려 주지 않는다.

그래서 둘 다 돌린다. 속도는 trap으로, 사실 확인은 polling으로, 그리고 SNMP path 자체가 죽었을 때 알람이 되도록 heartbeat를 둔다. 다음 poll에서 이미 up으로 보이더라도 trap은 event history에 남긴다. flap 자체가 발견 내용이다. 시간당 두 번 300 ms씩 튀는 포트가 바로 그 설명 안 되는 bad quality를 만드는 물건이고, polling으로는 절대 못 본다.

ifIndex는 안정적인 key가 아니다

RFC 2863은 agent가 재초기화 후에도 ifIndex 값을 유지하기를 요구하지만, 그 약속이 모든 상황에서 지켜지지는 않는다. media module을 넣고 빼거나, major 버전으로 firmware를 올리거나, 포트 구성이 다른 대체 스위치로 교체하면 index 7이 조용히 다른 물리 포트가 될 수 있다. 알람은 계속 동작하고, 이제 엉뚱한 케이블을 가리킨다.

point는 ifName이나 ifAlias 기준으로 잡고, 하드웨어나 firmware를 건드린 뒤에는 매핑을 다시 확인한다. 확인하는 김에 poller가 새 management IP로 말하고 있는지도 본다. 교체된 스위치의 옛 주소를 계속 polling하는 것이 아무도 모르게 감시가 꺼지는 가장 흔한 경로다.

Management 경로는 좁게 유지한다

SCADA가 스위치를 polling한다고 해서 모든 HMI가 SNMP로 닿아야 하는 것은 아니다. 승인된 host 한두 대에서만 polling하고, 스위치 쪽에서 source IP를 제한하고, 심사에서 방어할 수 있는 이유가 없으면 write access는 열지 않는다.

장비가 지원하면 authPriv를 쓰는 SNMPv3를 우선한다. 사용자 인증은 RFC 3414, 그 사용자가 무엇을 볼 수 있는지 제한하는 것은 RFC 3415다. 스위치와 collector 사이에 auth/priv 암호나 알고리즘이 어긋나는 것은 흔한 시운전 실패인데, 증상이 error가 아니라 침묵이라 일부러 시험해 봐야 한다. v2c밖에 없는 장비라면 community string을 사실상 password로 취급한다. 현장마다 다르게, 화면 설정 파일에는 절대 넣지 않고, management VLAN 안으로 범위를 좁힌다.

인수인계 전에 실제로 흔들어 본다

설정을 믿지 말고, 계획된 시간에 실제 스위치 동작으로 확인한다.

  1. 화면의 스위치 이름과 판넬 위치가 실제 장비와 맞는지 본다.
  2. 중요하지 않은 test port를 뽑고, 올바른 이름의 port event가 뜨는지 확인한다.
  3. Spare 장비로 speed change를 만들고 감지되는지 본다.
  4. Vendor가 제공하는 방법으로 전원 또는 ring-state 알람을 시험한다.
  5. 스위치를 재부팅하고 counter reset 처리가 spike를 만들지 않는지 확인한다.
  6. Event timestamp를 SCADA 서버 시간과 비교한다.
  7. 알람 문구가 port 7이 아니라 영향을 받는 PLC, 서버, 판넬을 말하는지 본다.

5번이 늘 생략되는 항목이고, 6주 뒤 새벽 3시 nuisance 알람을 만드는 항목이다.

첫 화면이 답해야 하는 것

운전자에게 SNMP browser는 필요 없다. 필요한 것은 area 또는 판넬별 스위치 health, critical link 상태, ring state, 최근 flap, 활성 error-rate 알람, 그리고 마지막 poll 성공 시각이다. 마지막 항목이 중요한 이유는, poll 시각이 오래됐다는 사실이 "네트워크는 정상"과 "한 시간 전부터 안 보고 있었다"를 가르기 때문이다.

더 깊은 값은 engineering page로 넘긴다. 운전 화면이 공정 문제와 PLC 문제와 네트워크 경로 문제를 갈라 주면 제 몫은 한 것이다. counter는 전화를 받은 사람이 봐도 늦지 않다.