Apache HTTP/2 취약점(CVE-2026-119618) 점검 및 mod_http2 패치 적용

Apache HTTP/2 모듈에서 원격 코드 실행 취약점이 나왔다는 소식을 듣고 운영 중인 서버를 모두 점검했습니다. 대부분은 자동 업데이트로 이미 패치가 깔려 있었습니다. 그런데 두 대는 여전히 취약했습니다.

한 대는 업데이트가 아예 설치되지 않은 상태였습니다. 다른 한 대는 패키지가 깔렸는데도 메모리에서는 옛 모듈이 돌고 있었습니다.

이 글은 RHEL 9 계열(AlmaLinux 9) 기준입니다. 내 서버가 해당되는지 확인하는 순서와, 패치가 깔렸는데 반영되지 않은 서버를 찾아내는 방법을 다룹니다.

CVE-2026-119618 영향 범위와 HTTP/2 사용 조건 확인하기

취약점은 mod_http2의 assign_headers() 함수에서 생기는 race condition입니다. 여러 요청이 동시에 같은 자원을 건드리면 힙 메모리가 오염될 수 있습니다. 공격자는 로그인 없이 원격으로 코드를 실행할 수 있습니다.

영향 범위는 Apache HTTP Server 2.4.55부터 2.4.70까지입니다. 2026년 11월 11일에 공개됐고, 같은 날 나온 2.4.71에서 고쳐졌습니다. CVSS 점수는 9.8입니다.

조건이 하나 붙습니다. 연결이 HTTP/2로 협상돼야 문제의 코드에 닿습니다. mod_http2가 로드돼 있어도 HTTP/1.1만 쓰면 해당 함수까지 가지 않습니다.

Red Hat은 RHEL 9과 10에서 이 취약점을 Critical이 아닌 Important로 분류했습니다. 스트림마다 메모리 할당기를 따로 두는 구조라 공격이 더 어렵다는 설명입니다. 제가 확인한 시점에는 공개된 PoC도, 실제 공격 사례도 없었습니다.

웹서버 종류와 HTTP/2 활성화 여부부터 확인하기

점검은 웹서버 종류를 확인하는 데서 시작했습니다. 아홉 대 중 세 대는 Apache가 아니라 nginx였습니다. 이 서버들은 이번 건과 관계없어서 바로 뺐습니다.

Apache가 도는 여섯 대에서는 버전, 패키지, 모듈, 프로토콜 설정을 차례로 봤습니다.

httpd -v
rpm -q httpd mod_http2
httpd -M | grep -i http2
grep -Rni '^\s*Protocols' /etc/httpd/

결과는 대체로 이렇게 나왔습니다.

Server version: Apache/2.4.62 (AlmaLinux)
httpd-2.4.62-13.el9_8.9.x86_64
mod_http2-2.0.26-6.el9_8.2.alma.1.x86_64
 http2_module (shared)
 proxy_http2_module (shared)
/etc/httpd/conf/httpd.conf:372:Protocols h2 http/1.1

여섯 대 모두 Protocols에 h2가 들어 있었습니다. 기본 설정에 있는 줄이라 손대지 않았다면 대부분 이 상태일 겁니다. 그래서 HTTP/2를 안 쓰니 괜찮다는 쪽으로는 넘어갈 수 없었습니다.

버전이 2.4.62로 보여도 changelog로 백포트 패치 확인하기

여기서 헷갈리기 쉬운 부분이 있습니다. Apache 버전이 2.4.62로 나옵니다. 숫자만 보면 취약 범위 안이고, 2.4.71로 올라갈 기미도 없습니다.

RHEL 계열은 메이저 버전을 고정해 두고 보안 수정만 가져와 패키지에 붙입니다. 이걸 백포트라고 합니다. 그래서 업스트림 버전 번호로는 패치 여부를 알 수 없습니다.

판단은 패키지 changelog로 했습니다.

rpm -q --changelog mod_http2 | head -5

패치된 서버에서는 맨 위에 CVE 번호가 그대로 보였습니다.

* Wed Nov 11 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 2.0.26-6.2.alma.1
- mod_http2: heap corruption and RCE in assign_headers (CVE-2026-119618)
- mod_http2: use-after-free via shared session->bbtmp re-entrancy (CVE-2026-57941)

다섯 대에는 11월 12일 새벽에 이 패키지가 자동으로 깔려 있었습니다. 한 대만 6월 패치에서 멈춘 mod_http2-2.0.26-6.el9_8.2였습니다. 그 서버는 httpd 본체도 13.el9_8.6이었습니다. 10월에 나온 mod_vhost_alias 원격 코드 실행 수정(CVE-2026-63292)까지 빠져 있었던 셈입니다.

패키지는 설치됐는데 옛 mod_http2가 메모리에 남아 있을 때

패키지가 깔렸다고 끝난 게 아니었습니다. 다섯 대 모두 httpd는 10월 말에 시작된 그대로였습니다. 패키지는 11월 12일에 깔렸으니, 디스크 파일만 바뀌고 메모리에는 옛 모듈이 남아 있을 수 있었습니다.

리눅스는 실행 중인 프로세스가 쓰던 파일이 교체돼도 옛 파일을 놓지 않습니다. 이 파일은 /proc 아래 maps에 deleted 표시와 함께 남습니다. 이걸로 실제로 돌고 있는 코드가 무엇인지 알 수 있습니다.

for p in $(pgrep -x httpd); do grep -q 'mod_http2.so (deleted)' /proc/$p/maps && echo $p; done

다섯 대 중 네 대는 아무것도 나오지 않았습니다. 이 서버들은 매일 자정에 로그를 회전하면서 httpd를 reload하고 있었습니다. 그 덕에 패키지가 깔린 다음 날 새 모듈이 자연스럽게 올라와 있었습니다.

남은 한 대는 시험용 서버였습니다. 여기서는 httpd 프로세스 네 개가 모두 지워진 옛 mod_http2.so를 물고 있었습니다. 이 서버에는 자정 reload가 없었습니다. 그래서 10월 24일에 뜬 프로세스가 패치 전 코드로 계속 돌고 있었습니다.

httpd 본체까지 바뀌었으면 reload 대신 restart로 반영하기

Apache의 graceful reload는 설정을 다시 읽고 모듈도 다시 로드합니다. 그래서 시험 서버는 reload부터 했습니다.

httpd -t && systemctl reload httpd

이걸로 mod_http2는 새 파일로 바뀌었습니다. 그런데 다시 maps를 보니 glibc, libm, liblzma가 여전히 deleted로 남아 있었습니다. 그사이 시스템 라이브러리도 업데이트됐던 겁니다. reload로는 부모 프로세스가 물고 있는 라이브러리까지 바뀌지 않습니다.

     25 /usr/lib64/libc.so.6
     25 /usr/lib64/liblzma.so.5.2.5
     25 /usr/lib64/libm.so.6

그래서 restart까지 했습니다. 패치가 아예 없던 서버도 같은 이유로 처음부터 restart를 골랐습니다. 그 서버는 업데이트로 httpd 실행 파일 자체가 바뀌었기 때문입니다.

dnf update httpd mod_http2
httpd -t
systemctl restart httpd

restart 뒤 maps에는 공유 메모리용 /dev/zero만 남았습니다. 이건 정상입니다. 마지막으로 실제 응답이 HTTP/2로 나오는지 확인했습니다.

curl -s -o /dev/null --http2 -w "%{http_code} h%{http_version}\n" https://example.com/
200 h2

restart를 하면 몇 초 정도 연결이 끊길 수 있습니다. 운영 서버라면 접속이 적은 시간에 하는 게 낫습니다. 업데이트 전후로 /etc를 etckeeper에 커밋하려 했는데, 바뀐 설정 파일이 없어 커밋할 것이 없었습니다.

dnf-automatic이 업데이트를 받기만 하고 설치하지 않을 때

패치가 빠졌던 서버도 dnf-automatic 타이머는 매일 돌고 있었습니다. 그런데 설치는 되지 않았습니다. 원인은 설정 파일 한 줄이었습니다.

grep -E '^(upgrade_type|apply_updates)' /etc/dnf/automatic.conf
upgrade_type = default
apply_updates = no

apply_updates가 no면 업데이트를 내려받기만 하고 설치하지 않습니다. 타이머도 정상이고 실행 기록도 남으니 겉으로는 자동 업데이트가 되는 것처럼 보입니다. 다른 서버들은 모두 yes였습니다.

이 값을 yes로 바꾸고 etckeeper에 커밋했습니다. 다음 실행부터는 받은 업데이트를 바로 설치합니다.

다만 설치만으로 반영까지 되지는 않습니다. 앞에서 본 것처럼 httpd가 다시 읽어야 새 모듈이 올라옵니다. 실행 파일이 바뀌는 업데이트라면 restart를 따로 챙겨야 합니다.

패치 여부는 설치 기록이 아니라 실행 중인 프로세스로 판단하기

RHEL 계열에서는 Apache 버전 번호만 보고 판단하면 틀립니다. 패키지 changelog에서 CVE 번호를 찾아야 백포트 패치를 확인할 수 있습니다.

패키지가 깔렸다는 것도 절반일 뿐입니다. 실행 중인 httpd가 지워진 옛 파일을 물고 있지 않은지까지 봐야 실제로 막힌 겁니다. 모듈만 바뀌었으면 reload로 되지만, 실행 파일이나 시스템 라이브러리가 바뀌었으면 restart가 필요합니다.

자동 업데이트도 두 가지를 같이 봐야 합니다. 설치까지 하도록 설정돼 있는지, 그리고 설치한 뒤 서비스를 다시 읽는 경로가 있는지입니다. 이번에 걸린 두 대는 각각 이 둘 중 하나가 빠져 있었습니다.

HTTP/2를 잠시 꺼 두는 방법도 임시 대응으로는 쓸 수 있습니다. 하지만 배포판 패치가 나와 있다면 업데이트하고 반영까지 확인하는 편이 깔끔합니다.

댓글

알짜게시판

리눅스 Apache HTTP/2 취약점(CVE-2026-119618) 점검 및 mod_ht…
리눅스 PHP 원격 코드 실행 취약점 CVE-2026-109618, CVE-2026-…
리눅스 Apache에서 GPTBot·Amazonbot·AhrefsBot의 게시판 이미…
기타 Midjourney, DALL·E, ChatGPT에서 Y2K 파스텔 UI 프롬프…
리눅스 Cloudflare R2 자동 업로드 구성하기. 특정 폴더에 파일…
워드프레스 워드프레스 7.0 관리자 링크 색상 변경 후 이전 색상으…
워드프레스 캐시 환경에서 AJAX 댓글(코멘트) 분리로 서버 응답시간…
리눅스 아파치 일반 계정 파일 접근 권한 설정과 mod-ruid2 적…
델파이 Delphi IDE 메인 폼 안열림 dproj 설정으로 해결
개발팁 VSCode 한국어 설정법, Configure Display Language로 U…
기타 RustDesk 자체 서버 구축으로 공용 서버 로그인 문제 해…
리눅스 Dante SOCKS5 프록시 서버 구축 및 설정
윈도우 윈도우 실행파일(exe) 서비스 등록 자동화 쉽게 하는 방…
기타 CLIProxyAPI Windows 설치 가이드
워드프레스 그누보드7 데이터를 WordPress WXR로 변환하기
기타 Ollama 설치 경로 C드라이브 고정 문제 해결 및 드라이…
개발팁 Apache Access Log 기반 도메인별 방문자 카운터 구현
윈도우 ZImage AI 이미지 생성 환경 구축 방법
윈도우 파일 복사 후 실행 배치파일 - 에러 감지 포함
개발팁 네이버 검색 Open API
개발팁 네이버 검색광고 키워드 도구 API 검색
개발팁 MariaDB column_stats 테이블 오류 해결 방법
개발팁 PHP-FPM 에러 로그 실시간 모니터링
윈도우 윈도우11 업데이트 후 네트워크 드라이브 접근 불가 문…
개발팁 다국어 번역 함수 구현 방법
워드프레스 "치명적인 오류가 발생했습니다" 디버깅 가이드
리눅스 Apache 웹 로그 분석하기 – awk와 GoAccess 활용
길호넷 칼무리 - 외부 명령으로 캡처 자동화하기
윈도우 윈도11 강제업데이트 피하고 윈도10 계속 쓰기
리눅스 PHP 파일 업로드 용량 늘리기