← ~/notes · 3 min read

서버가 자꾸 꺼진다 — Intel I219-V NIC가 가짜 전원 버튼을 누르고 있었다

몇 주 멀쩡했던 Proxmox 호스트가 어느 날부터 외부 접속이 끊겼다. systemd 로그에서 'Power key pressed short'를 발견했지만 누른 사람이 없었다.

목차
  1. 처음 본 단서
  2. 더 깊이 파기
  3. 왜 갑자기?
  4. 두 층 방어
  5. 1) NIC 오프로딩 끄기 — 근본
  6. 2) Power Key 무시 — 안전망
  7. 검증
  8. 처음에 헷갈렸던 것들
  9. 정리

집에 있는 Proxmox 호스트(vm0.lab-it.net)가 어느 날부터 갑자기 외부에서 안 잡혔다. Cloudflare Tunnel 503, SSH 타임아웃, 모든 VM 접근 불가.

처음엔 그냥 재부팅으로 넘겼다. 그런데 다음날 또. 그 다음날 또.


처음 본 단서

journalctl --boot=-1로 전 부팅의 마지막 로그를 보니 이게 떴다.

systemd-logind[xxx]: Power key pressed short.
systemd-logind[xxx]: Powering off...
systemd[1]: Stopped target Graphical Interface.
...

아 누가 전원 버튼을 눌렀구나. 처음엔 그렇게 결론 내렸다. 가족 중에 누가 청소하다가 살짝 눌렀나? 본체에 케이블 정리하다가?

사용자한테 “혹시 누가 만진 거 아닌지 확인해주세요” 했더니 돌아온 답:

누가 껐을리가 없음 몇 주 동안 정상적으로 작동했고 끌 사람도 없어

맞는 말이다. 몇 주 멀쩡하다가 갑자기 매일 꺼지는 게 사람 손 탓일 수가 없다. 다시 봐야 했다.


더 깊이 파기

journalctl -k --boot=-1로 커널 로그를 따로 보니 시점이 보였다. Power key 신호가 들어오기 직전에 이런 게 있었다.

e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
  TDH                  <87>
  TDT                  <a3>
  next_to_use          <a3>
  next_to_clean        <85>
buffer_info[next_to_clean]:
  time_stamp           <100bcec73>
  next_to_watch        <87>
  jiffies              <100bcef00>
  next_to_watch.status <0>
e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly

e1000e는 인텔 I219-V 같은 칩셋의 이더넷 드라이버다. 이게 하드웨어 유닛이 멈췄다(Unit Hang) 고 판단해서 NIC을 강제 리셋한다. 리셋이 진행되는 동안 PCI 버스에 노이즈가 발생하고, 그 노이즈가 ACPI 전원 버튼 신호로 잘못 해석되는 케이스가 있다.

systemd-logind는 ACPI Power Button 이벤트를 보면 그게 진짜 사람 누름이든 가짜 신호든 구분 못 한다. 기본 동작은 “정상 종료(HandlePowerKey=poweroff)”. 그러니 NIC 한 번 뻗을 때마다 서버가 깔끔하게 셧다운된다.

누가 누른 게 아니라 NIC이 누르고 있었다.


왜 갑자기?

e1000e 드라이버에는 오래된 버그가 있다 — 특정 오프로딩 기능(TSO/GSO/GRO/LRO)이 켜진 상태에서 트래픽 패턴이 일정 조건에 걸리면 NIC 큐가 멈춘다. 커널 메일링 리스트에 수년간 보고된 문제다.

평소엔 트리거 안 되다가 어느 시점에 트래픽이 늘거나 패턴이 바뀌면 갑자기 매일 발생한다. 내 경우엔 허니팟이 본격 가동되면서 들어오는 패킷 수가 늘어난 시점과 일치했다.


두 층 방어

원인 분석한 만큼, 한 군데만 막아선 안 된다.

1) NIC 오프로딩 끄기 — 근본

/etc/network/interfaces에 post-up 훅으로 ethtool 호출.

iface nic2 inet manual
    post-up /usr/sbin/ethtool -K $IFACE tso off gso off gro off lro off || true

부팅마다 인터페이스 올라올 때 자동으로 오프로딩 4종 비활성화. NIC이 자체적으로 큐 처리하는 대신 커널이 다 처리하니 hang 트리거가 사라진다. 약간의 CPU 비용은 있지만 트래픽 양 자체가 작아 무시 가능.

2) Power Key 무시 — 안전망

NIC이 또 hang을 일으키더라도 이젠 호스트 자체는 종료되지 않게.

/etc/systemd/logind.conf:

HandlePowerKey=ignore
HandlePowerKeyLongPress=poweroff

짧게 누르면(또는 가짜 신호 들어오면) 무시. 정말 종료하고 싶으면 길게 누르면 됨. 가족이 “왜 전원 안 꺼져?” 할 가능성은 있지만, 어차피 무인 서버라 상관 없다.

systemctl restart systemd-logind

재시작 후 적용.


검증

배포하고 며칠 관찰. 더 이상 자동 셧다운 없음. 가끔 dmesg에 e1000e hang 감지 로그가 한 번씩 뜨긴 한다 — 하지만 NIC이 자기가 알아서 reset하고 끝나고, 호스트는 살아남는다.

$ uptime
 up 8 days, 3:47, 1 user, load average: 0.41 0.38 0.35

처음에 헷갈렸던 것들

“전원 버튼 = 사람”이라는 가정. 로그에 Power key pressed short가 찍혀 있으면 자동으로 사람이 눌렀다고 가정하기 쉽다. 하지만 ACPI 이벤트는 누른 사람이 없어도 발생할 수 있다. 메인보드 칩셋 결함, 펌웨어 버그, 드라이버 hang의 부산물 등.

한 줄 로그만 보고 결론 내리지 말기. Power key pressed short 직전에 무엇이 있었는지가 진짜 단서였다. 단일 메시지는 끝나는 지점이지 시작점이 아니다.

“몇 주 멀쩡했음”이 강한 신호. 사용자가 “원래는 됐는데 어느 날부터 안 됨”이라고 하면 평소 환경에서 갑자기 트리거된 변수가 있다는 뜻. 내 경우엔 트래픽 증가가 트리거였다.


정리

증상표면 원인진짜 원인
서버 자동 종료Power key pressed shorte1000e NIC hang의 부산물 ACPI 신호
외부 접속 불가Cloudflare Tunnel 503호스트가 종료된 후 재부팅 안 됨
매일 같은 시간대 발생우연트래픽 패턴이 e1000e 버그 조건 충족
조치위치효과
NIC 오프로딩 비활성화/etc/network/interfaceshang 자체 예방
HandlePowerKey=ignore/etc/systemd/logind.confhang이 일어나도 호스트 생존

서버 운영의 절반은 로그를 어디까지 거슬러 올라가서 읽느냐다. 끝줄만 보면 사람 탓을 하게 된다.