개발자 튜토리얼: K패치로 Ubuntu 20.04 LTS Focal Fossa Linux Kernel에 라이브 패치 적용하기
라이브 패치는 중단 없이 Linux Kernel을 업데이트하는 방법입니다. Kernel 업데이트는 시스템을 재부팅할 때까지 적용되지 않기 때문에 Linux Kernel 라이브 패치는 서버를 재부팅하지 않고 심각한 Linux Kernel 취약성을 패치하는 데 가장 일반적으로 사용됩니다.
서비스 연속성 및 가동 시간 향상 외에도 대규모 서버를 보유한 조직은 라이브 패치를 사용하여 여러 시스템을 재부팅하는 데 필요한 조정 및 계획과 관련된 관리 오버헤드를 피할 수 있습니다.
이 튜토리얼에서는 Kpatch를 사용하여 실행 중인 Ubuntu 20.04 LTS Focal Fossa Kernel의 동작을 중지하지 않고 변경하는 방법을 보여드리며, 다음 내용을 변경합니다. /proc/uptime
(그리고 uptime
명령)을 사용하여 시스템의 보고된 가동 시간을 10년으로 늘릴 수 있습니다.
Kpatch는 Red Hat에서 만들었으며 RHEL 및 그 파생 제품에서 작동합니다. Red Hat은 각각 다른 배포판에 중점을 두고 있는 다음 회사들과 마찬가지로 RHEL 고객을 위한 상용 라이브 패치 서비스를 제공합니다:
- Ubuntu용 정식 라이브 패치 서비스;
- 대부분의 주요 Linux 배포판용 KernelCare;
- Oracle Linux용 Ksplice;
- SUSE 엔터프라이즈 Linux용 SUSE 라이브 패치(이전에는 Kgraft로 알려 짐).
이 튜토리얼에서 Kpatch를 선택한 이유는 소스 코드가 무료로 제공되고 정기적으로 업데이트되는 몇 안 되는 솔루션 중 하나이기 때문입니다. 다음에 대한 다른 튜토리얼이 있습니다. K패치로 데비안 10 Linux Kernel 라이브 패치하기 - 도 확인해보세요.
전제 조건
이 튜토리얼을 따르기 위한 시스템 사전 요구 사항은 다음과 같습니다.
- x86_64/amd64 아키텍처에서 Ubuntu 20.04 Focal Fossa를 실행하는 테스트(비프로덕션) 시스템입니다.
- 20Gb의 디스크 여유 공간. (Linux Kernel 소스 코드는 디스크에서 약 909Mb를 차지하며 컴파일 시 17Gb로 증가합니다.)
- Kernel이 커스터마이징되지 않았으며, Debian에서 제공하는 표준 Kernel을 사용하고 있습니다.
- Kernel에는 라이브 패치가 내장되어 있습니다. 이 명령을 사용하면 두 개의 값이 다음과 같이 설정됩니다.
y
에 대한CONFIG_HAVE_LIVEPATCH
그리고CONFIG_LIVEPATCH
:
grep LIVEPATCH /boot/config-$(uname -r)
- 설치된 gcc 버전이 원래 Kernel을 빌드하는 데 사용된 버전과 일치합니다. (이 경우
kpatch-build
명령은 버전이 일치하지 않으면 실패합니다. 이 문제는 옵션을 사용하여 재정의할 수 있습니다.--skip-gcc-check
사용은 권장하지 않습니다.)- 설치된 gcc 버전을 확인합니다:
gcc --version (if gcc not installed run ”sudo apt install gcc”)
- 현재 Kernel을 컴파일하는 데 사용된 gcc의 버전을 확인합니다:
cat /proc/version
- 설치된 gcc 버전을 확인합니다:
1. 종속성 패키지 설치
- 설치 및 구성
sudo
.As
root
:apt-get install sudo adduser <user> sudo
어디
<user>
는 일반 사용자의 사용자 이름입니다. (이후의 모든 명령은 이 사용자로 수행해야 합니다.) - 패키지를 설치합니다.
sudo apt-get -y update sudo apt-get -y upgrade sudo apt-get -y 빌드-에센셜 데브스크립트 설치 ccache gawk libelf-dev libssl-dev Linux 소스 플렉스 들소
2. Kpatch 설치
Focal Fossa의 kpatch 패키지가 오래되었으므로 소스에서 설치해야 합니다.
git clone https://github.com/dynup/kpatch.git
cd kpatch && make && sudo make install
3. Linux Kernel 소스 코드 사본 받기
- (선택 사항) 작업 디렉터리를 만들어서 이동합니다.
mkdir kernel && cd $_
- Linux Kernel 소스 코드를 추출합니다.
tar xaf /usr/src/linux-source-5.4.0.tar.bz2
참고: 5.4.0은 이 글을 작성하는 시점의 Ubuntu 20.04용 Linux Kernel 버전입니다. usr/src에 있는 가장 최신 버전을 확인하여 대체해야 합니다.
4. Linux Kernel 구성 파일 생성
- Linux Kernel은 배포와 함께 제공된 구성 파일의 설정을 사용하여 컴파일됩니다. 복사본을 가져와 일부 설정을 변경하여
kpatch-build
는 실행 중인 Kernel과 동일한 설정으로 Linux Kernel을 컴파일할 수 있습니다.cd linux-source-5.4.0/ cp /boot/config-$(uname -r) .config
- Kpatch를 사용하기 위해 필요한 Kernel 설정이 활성화되어 있는지 확인합니다. 모두 'Y'를 반환해야 합니다.
scripts/config -s DYNAMIC_FTRACE_WITH_REGS scripts/config -s FUNCTION_TRACER scripts/config -s HAVE_DYNAMIC_FTRACE_WITH_REGS scripts/config -s HAVE_FENTRY scripts/config -s HAVE_LIVEPATCH scripts/config -s KALLSYMS_ALL scripts/config -s KALLSYMS scripts/config -s LIVEPATCH scripts/config -s MODULES scripts/config -s MODULE_SIG scripts/config -s SYSFS scripts/config -s SYSTEM_TRUSTED_KEYRING
- Kernel 구성 항목의 값을 변경합니다.
scripts/config --set-str SYSTEM_TRUSTED_KEYS ""
- 소스 디렉터리를 그대로 둡니다.
cd ..
5. 패치 만들기
패치 소스 파일은 diff
명령을 원본 및 변경된 소스 코드 파일에서 실행합니다.
'빠른 시작' 섹션에 표시된 패치 예제는 kpatch 깃허브 페이지 의 출력을 변경합니다. /proc/meminfo
. 다른 많은 Kpatch 문서에서 이 예제를 재현하고 있기 때문에 저는 조금 더 흥미롭고 안전하면서도 다른 것을 원했습니다.
이 예제는 uptime
명령을 사용하여 서버 가동 시간이 10년 늘어난 것처럼 보이게 할 수 있습니다.
- 작업 디렉터리에서 파일을 복사합니다.
cp linux-source-5.4.0/fs/proc/uptime.c .
- 수정합니다. 26줄에서 변경합니다:
(unsigned long) uptime.tv_sec,
에
(unsigned long) uptime.tv_sec + 315576000,
파일을 저장합니다.
- 패치 파일을 생성합니다.
diff -u linux-source-5.4.0/fs/proc/uptime.c ./uptime.c > uptime.patch
- 설치 디버그 심볼 패키지 Kernel:
sudo apt 설치 Linux-이미지-$(uname -r)-dbgsym
- 패치 모듈을 생성합니다. (처음 이 작업을 수행할 때는 Kernel 소스 코드를 컴파일해야 하므로 몇 시간이 걸립니다. 이후 빌드는 몇 분 단위로 훨씬 더 빨라집니다.)
kpatch-build -t vmlinux -v /usr/lib/debug/boot/vmlinux-5.4.0-37-generic uptime.patch
- 완료되면 Linux 로드 가능한 Kernel 모듈 파일 (
.ko
)에 패치를 적용합니다.ls -l *.ko
6. 패치 테스트
- 패치 모듈을 로드하기 전에 현재 가동 시간을 확인하세요.
cat /proc/uptime && uptime -p
- 패치 모듈을 로드합니다.
sudo kpatch load livepatch-uptime.ko
- 가동 시간을 다시 확인하세요.
cat /proc/uptime && uptime -p
가동 시간이 10년 이상 개선된 것을 확인할 수 있을 것입니다. (내부 값은 변경되지 않았으며 인쇄된 내용만 변경되었습니다.)
- 패치 모듈을 언로드합니다.
sudo kpatch unload livepatch-uptime.ko
- 가동 시간이 이전 값으로 돌아갔는지 확인합니다.
cat /proc/uptime && uptime -p
결론
Kpatch로 Linux Kernel을 실시간으로 패치하는 것은 어렵지 않습니다. 어려운 점은 시스템을 중단시키지 않고 나중에 제공되는 다른 패치와 함께 작동할 수 있는 패치를 작성하는 것입니다. 대부분의 패치는 단순한 diff
다양한 배포판에서 실행되는 여러 Kernel 버전에 대한 철저한 테스트가 필요합니다.
패치 작성자는 숙련된 C 프로그래머이자 숙련된 Linux Kernel 개발자여야 하며, Kernel을 컴파일하고 모든 Kernel 버전에 대한 패치를 테스트하려면 하드웨어와 자동화 도구에 많은 투자가 필요합니다. 이러한 기술의 희소성과 인프라 비용으로 인해 공급업체는 실시간 패치 서비스에 대한 비용을 청구해야 합니다.
그리고 Linux Kernel 보안 패치 적용 방법에 대한 명시적인 가이드도 읽어보세요: 3가지 방법. 이 문서에서는 재부팅하지 않고 Linux Kernel을 업데이트하는 방법을 설명하며, 가장 많이 사용되는 몇 가지 Linux Kernel에 대한 세 가지 방법을 다룹니다.