본문으로 건너뛰기
피드

eBPF로 USB 전송을 실시간으로 훔쳐보는 시스템 전체 스니퍼

devops 약 7분
vote
0
댓글
북마크

usbsnoop은 리눅스 시스템 전체의 USB 트래픽을 실시간으로 보여주는 eBPF 기반 도구다. 컨트롤러별 트레이스포인트나 usbmon 없이, 모든 호스트 컨트롤러 드라이버가 지나가는 URB 제출과 완료 지점을 잡아 전송 내용, 지연시간, 에러, SCSI 명령까지 확인할 수 있다.

  • 1

    usb_submit_urb와 usb_hcd_giveback_urb 두 지점을 fentry로 후킹해 USB 전송의 시작과 완료를 연결함

  • 2

    URB 포인터를 키로 하는 LRU 해시를 사용해 제출 시각과 완료 시각을 매칭하고 지연시간을 계산함

  • 3

    컨트롤 전송의 SETUP 패킷, 대용량 저장장치의 SCSI 명령, 에러, 페이로드 미리보기, NDJSON 출력까지 지원함

  • usbsnoop은 리눅스 시스템 전체 USB 트래픽을 실시간으로 보여주는 eBPF 도구임

    • xHCI, EHCI, OHCI, dwc 같은 호스트 컨트롤러 종류와 상관없이 동작하는 구조
    • 컨트롤러별 트레이스포인트도, usbmon 설정도 필요 없다고 함
    • CO-RE 기반이라 커널 버전 차이를 어느 정도 흡수하는 쪽으로 설계됨
  • 핵심 아이디어는 USB 전송이 반드시 지나가는 두 지점을 잡는 것

    • usb_submit_urb는 전송이 큐에 들어간 시점, 즉 호스트가 장치에 뭔가 보내거나 받을 준비를 한 순간
    • usb_hcd_giveback_urb는 전송이 완료된 시점, 즉 상태 코드와 실제 이동한 바이트 수가 나온 순간
    • URB 포인터를 키로 LRU 해시에 시작 시간을 저장했다가 완료 시점에 꺼내서 submit에서 complete까지의 지연시간을 계산함
sequenceDiagram
    participant 앱_드라이버 as 앱/드라이버
    participant USB스택 as 리눅스 USB 스택
    participant eBPF as usbsnoop eBPF
    participant 장치 as USB 장치
    앱_드라이버->>USB스택: URB 제출
    USB스택->>eBPF: usb_submit_urb 후킹
    USB스택->>장치: 전송 실행
    장치-->>USB스택: 응답 또는 에러
    USB스택->>eBPF: usb_hcd_giveback_urb 후킹
    eBPF-->>앱_드라이버: 이벤트, 지연시간, 페이로드 출력
  • 출력은 “한 줄에 한 이벤트”라서 바쁜 USB 버스에서도 훑어보기 좋게 만든 쪽임
    • 처음 보는 장치는 버스-디바이스 번호, VID:PID, 제품명, 링크 속도를 legend로 찍음
    • 이후 이벤트는 짧은 DEV 태그, 시간, SUBMIT/CMPLT, 전송 타입, 엔드포인트, 방향, 바이트 수, 상태, 지연시간, 커널 드라이버를 보여줌
    • 데이터가 텍스트처럼 보이면 텍스트로, 아니면 hexdump로 렌더링함

💡

> --json을 쓰면 NDJSON으로 이벤트를 뽑을 수 있어서 jq나 파일 저장으로 실행 간 페이로드 차이를 비교하기 좋음.

  • 컨트롤 전송은 8바이트 SETUP 패킷까지 해석함

    • GET_DESCRIPTOR, SET_CONFIGURATION 같은 표준 요청 이름을 디코딩
    • 장치를 꽂고 enumeration 과정에서 어떤 vendor control request와 HID report가 오가는지 바로 볼 수 있음
    • 하드웨어 USB 스니퍼 없이 주변기기 리버스 엔지니어링을 할 수 있다는 게 꽤 큼
  • 대용량 저장장치 쪽도 그냥 바이트 덤프만 하는 게 아님

    • Bulk-Only Transport 래퍼를 읽어서 SCSI 명령으로 보여줌
    • 예를 들면 READ(10) lba=... blocks=..., WRITE(10), CSW PASS/FAIL 같은 식
    • 펌웨어나 드라이버가 실제로 어떤 블록을 읽고 쓰는지 추적할 때 유용함
  • 에러 추적과 성능 분석도 들어가 있음

    • --errors-only는 stall, timeout, babble, CRC 에러 같은 실패 완료만 보여줌
    • --secs로 시간 제한 실행을 하면 디바이스별 요약과 log2 지연시간 히스토그램을 출력함
    • 필터링은 커널 안에서 처리되므로 걸러진 트래픽은 유저스페이스까지 올라오지 않음

⚠️주의

> scatter-gather 페이로드를 완전히 읽으려면 x86-64에서 KASLR로 랜덤화된 page_offset_basevmemmap_base 주소를 넘겨야 함. 안 넘기면 메타데이터는 보이지만 SG 페이로드 바이트는 빠짐.

  • 설치와 실행도 개발자 장난감답게 단순하게 밀어붙임
    • GitHub에서 바로 실행하려면 yeet run github:yeet-src/usbsnoop
    • 로컬 빌드는 make
    • 필요 조건은 clang, bpftool, BTF가 있는 커널
    • 빌드 과정에서 커널 BTF를 vmlinux.h로 덤프해 struct urb, usb_device, 장치 디스크립터를 참조함

기술 맥락

  • 이 도구가 재밌는 이유는 USB 컨트롤러별 구현을 따라가지 않고 공통 병목을 잡았기 때문이에요. 리눅스 USB 스택에서 전송은 결국 URB 제출과 완료라는 형태로 흐르기 때문에, 그 두 함수만 보면 시스템 전체 USB 흐름을 꽤 넓게 관찰할 수 있어요.

  • eBPF를 쓴 것도 현실적인 선택이에요. 커널 모듈을 새로 넣거나 usbmon을 설정하는 방식은 운영 환경에서 부담이 크거든요. fentry로 커널 함수 입구를 붙잡으면 필요한 이벤트만 낮은 오버헤드로 가져올 수 있고, 필터도 커널 쪽에서 먼저 적용할 수 있어요.

  • URB 포인터를 LRU 해시 키로 쓰는 구조는 요청과 응답을 매칭하려는 선택이에요. 제출 시점에는 시작 시간을 찍고, 완료 시점에는 같은 URB를 찾아 지연시간과 상태를 계산해요. HTTP 요청과 응답을 묶는 것처럼 USB 전송을 한 쌍으로 보는 셈이에요.

  • scatter-gather 페이로드 처리가 까다로운 건 데이터가 하나의 연속 버퍼에 없기 때문이에요. 대용량 전송은 여러 페이지에 흩어진 버퍼를 쓰는 경우가 많아서, 페이지를 커널 가상주소로 바꾸려면 아키텍처와 KASLR 주소 정보를 알아야 해요. 그래서 이 기능은 x86-64에서 추가 플래그가 필요해요.

USB 디버깅은 보통 귀찮고 장비 의존적인데, 이 도구는 커널 공통 경로를 잡아서 꽤 우아하게 풀었음. 특히 리버스 엔지니어링, 펌웨어 디버깅, 수상한 HID 입력 추적 같은 데 바로 써먹을 수 있는 냄새가 남.

댓글

댓글

댓글을 불러오는 중...

devops

SaaS 늘어나는데 ERP·CRM 운영팀은 아직 온프레미스 시절에 멈춰 있음

클라우드와 하이브리드 전환이 빨라지면서 ERP, CRM, HRIS 같은 엔터프라이즈 애플리케이션 지원 조직의 역할이 흔들리고 있음. 인포테크리서치그룹은 업무량 데이터, 역할 재설계, 자원 산정을 기반으로 지원 조직을 다시 짜야 한다고 봄.

devops

선거철마다 쏟아지는 인공지능·데이터센터 공약, 전기랑 물 계획은 어디 갔나

6·3 지방선거 광역단체장 후보 54명 중 약 70%가 인공지능이나 데이터센터 관련 공약을 내놨지만, 전력·용수 조달 계획은 비어 있는 경우가 많다는 지적이 나왔다. 데이터센터 유치가 지역 경제 공약으로 포장되고 있지만, 실제로는 재생에너지, 송전망, 냉각수, 화석연료 의존까지 같이 따져야 하는 인프라 이슈다.

devops

무료 풀 BGP 피드, 실험실 라우터에 IPv4·IPv6 라우팅 테이블 넣어보기

이 글은 실험 환경에서 유럽 기준 풀 BGP 피드를 받아볼 수 있게 IPv4뿐 아니라 IPv6까지 제공한다는 안내다. 사용자는 ASN 65001, 상대 ASN 57355, eBGP 멀티홉, 긴 타이머 등을 맞춰 라우터에 세션을 구성해야 한다. 운영망에 가볍게 붙일 성격은 아니고, BGP 학습이나 랩 테스트용으로 자기 책임하에 써야 하는 자료다.

devops

미국 AI 클라우드는 상장 러시, 한국 MSP는 수익성 벽에 막혔다

미국에서는 AI 인프라와 클라우드 기업들이 성장성을 바탕으로 증시에 입성하는 반면, 한국 MSP 기업들은 낮은 수익성과 CSP 의존 구조 때문에 IPO 문턱을 넘기 어렵다는 분석이 나왔다. 메가존클라우드는 지난해 매출 1조7496억원을 냈지만 영업이익은 2억3300만원에 그쳐 사실상 0%대 영업이익률로 평가받고 있다.

devops

Zig 빌드 시스템 대수술…빌드 러너 쪼개고 증분 빌드 밀리초대로 간다

Zig 개발 로그에서 빌드 시스템이 configurer와 maker 프로세스로 분리되는 큰 변경이 소개됐다. `zig build -h` 기준 평균 실행 시간이 150ms에서 14.3ms로 줄었고, 새 ELF 링커는 Zig 컴파일러 자체를 LLVM·LLD 포함 상태로 빌드할 수 있는 단계까지 올라왔다.