eBPF 보안 에이전트, inode 캐시 도입으로 커널 CPU 비용 90% 감소
- 파일 열기마다 dentry를 거슬러 올라가 정책을 찾던 경로를 (mount namespace ID, mount ID, inode 번호) 3개 필드 키의 LRU 해시 캐시로 대체해 커널 CPU 비용을 약 90% 줄임
- 같은 파일을 20만 번 여는 벤치마크에서 커널 사이클이 280억에서 30.3억으로 줄었고, 커널 CPU는 perf의 cycles:k 이벤트로 측정함
- 캐시 적용 전에는 tail_call_security_check가 스택의 89.2%, is_restricted_filepath가 81.9%, path_check_callback이 63.7%를 차지했지만, 적용 후 is_restricted_filepath와 path_check_callback은 각각 약 0.02%로 줄어 플레임그래프에서 사라짐
- dentry는 포인터라 eBPF 맵에 저장할 수 없어 inode 기반 캐시를 택했고, inode 번호가 마운트 트리별로만 유일해 mntns_id와 mount_id를 키에 함께 넣음. 정책은 공간 절약을 위해 비트마스크로 저장하고 access_index가 비트 위치를 가리킴
- 저장소를 오픈소스로 공개했고(github.com/bomfather/agent), LRU 해시 맵 크기는 max_entries 10000으로 잡음
Hacker News opinions
제목에 'Not AI Gen' 강조해놨는데 정작 솔루션 이름이 Agent라니 ㅋㅋ
Agent는 예전부터 계속 돌아가는 데몬을 뜻하는 말이었음. 성능 모니터링 에이전트 많이 쓰던 사람들은 다 알지. AI가 쓰는 것도 맞는 용법인데 무조건 AI로 읽는 게 좀 아쉽더라.
기사 읽고 좀 헷갈렸음. 메모이제이션이 eBPF에서 새롭냐고 묻는 건 핀트가 아니고, 진짜 문제는 eBPF 제약 안에서 경로:정책 매핑 캐시 키를 어떻게 만드느냐임. 제목을 'eBPF에서 파일 경로 캐시 키 계산하기'로 했으면 훨씬 재밌었을 텐데.
캐싱 자체는 eBPF든 LSM이든 새롭지 않음. SELinux 커널 AVC가 같은 방식이고, 링크도 걸어놨더라.
약어를 하나도 모르겠음. 조금만 풀어 썼으면 개발자 더 많이 읽을 텐데.
기술 글은 기술 독자 대상으로 쓰는 거고, 리눅스 세계에서 eBPF가 그렇게 마이너한 기술도 아님. 모두를 만족시키려다 보면 글이 나빠짐.
디렉터리를 위쪽 경로에서 옮기면 캐시가 깨지는 거 아님? 사용자 동작으로 정책이 바뀌면 보안 문제가 될 것 같은데.
작성자임. 좋은 지적 고마움. 보호 중인 디렉터리는 접근 권한 있는 사람만 옮길 수 있으니 악의적 이동은 가정 안 했음. 디렉터리가 이동하면 관련 inode를 캐시에서 빼는 방안도 생각 중임.
90% 빨라진 케이스가 같은 파일을 계속 여는 경우라 별로 일반적이지 않음. 같은 파일을 두 번 다시 안 여는 워크로드에선 캐시 쓰기 때문에 오히려 조금 느려질 텐데, 헤드라인이 좀 과함.
bind mount처럼 다른 경로로 보이게 파일을 로드하는 경우는 경로 기반 규칙이 어떻게 처리함?
사용자 권한이 도중에 바뀌면 어떻게 되는 거임?
권한 변경, 디렉터리 이동, 하드링크 추가, 삭제가 일어날 때 캐시 무효화는 어떻게 하고 크기 제한은 있음?
이동은 권한 없이도 가능하고 NFS처럼 커널을 거치지 않는 경우도 있음. 계산된 정책이 경로 전체의 함수라면 경로 전체랑 관련 inode를 키로 잡아야 하는 거 아님? 커널에 경로 기반 LSM 중에 이런 캐싱 안 쓰는 것도 있는데, 코너 케이스까지 되면서 실전에서 빨라지면 진짜 관심 있음.
메모이제이션은 메모리를 써서 CPU를 아끼는 건데, 글쓴이는 CPU만 쟀고 메모리는 안 잰 듯. 추가 메모리가 크진 않겠지만 '측정하고 가정하지 말자'는 원칙이 아쉽더라.
'Not AI Gen'이라니. 사람이 쓴 건 좋은데 AI로 한 번 다듬으면 더 좋았을 것 같기도 하고 ㅋㅋ. 폰트랑 줄간격이 읽기 좋아서 글은 편하게 읽혔음.