Tutorial para desarrolladores: Live patching Ubuntu 20.04 LTS Focal Fossa Linux kernel con Kpatch
Live patching es una forma de actualizar un kernel Linux sin interrupción. Dado que las actualizaciones del kernel no surten efecto hasta que se reinicia el sistema, el parcheado en vivo del kernel de Linux se utiliza más comúnmente para parchear vulnerabilidades graves del kernel de Linux sin reiniciar los servidores.
Además de mejorar la continuidad del servicio y el tiempo de actividad, las organizaciones con grandes flotas de servidores también utilizan la aplicación de parches en tiempo real para evitar la sobrecarga administrativa asociada a la coordinación y planificación necesarias para reiniciar varios sistemas.
Este tutorial mostrará cómo usar Kpatch para cambiar el comportamiento de un kernel Ubuntu 20.04 LTS Focal Fossa en ejecución sin detenerlo, cambiando el contenido de /proc/uptime
(y el uptime
) para que el tiempo de funcionamiento del sistema sea 10 años mayor.
Kpatch fue creado por Red Hat y funciona con RHEL y sus derivados. Red Hat ofrece un servicio comercial de parches en vivo para los clientes de RHEL, al igual que las siguientes empresas, cada una de las cuales se centra en distribuciones diferentes:
- Servicio Canonical Livepatch para Ubuntu;
- KernelCare para la mayoría de las principales distribuciones de Linux;
- Ksplice para Oracle Linux;
- SUSE Live Patching (anteriormente conocido como Kgraft) para SUSE Enterprise Linux.
Obtenga una prueba GRATUITA de 7 días con soporte de KernelCare
Hemos elegido Kpatch para este tutorial porque es una de las pocas soluciones cuyo código fuente está disponible libremente y se actualiza con regularidad. Tenemos otro tutorial sobre Live patching del kernel Linux de Debian 10 con Kpatch - échale un vistazo también.
Requisitos previos
Estos son los requisitos previos del sistema para seguir este tutorial.
- Un sistema de prueba (no de producción) que ejecuta Ubuntu 20.04 Focal Fossa en una arquitectura x86_64/amd64.
- 20 Gb de espacio libre en disco. (El código fuente del kernel de Linux ocupa unos 909 Mb en disco, que crecen hasta los 17 Gb cuando se compila).
- Su núcleo no ha sido personalizado; está utilizando el estándar suministrado por Debian
- Su kernel tiene parcheado en vivo incorporado. Utilice este comando y espere ver dos valores establecidos en
y
paraCONFIG_HAVE_LIVEPATCH
yCONFIG_LIVEPATCH
:
grep LIVEPATCH /boot/config-$(uname -r)
- La versión de gcc instalada coincide con la utilizada para compilar el núcleo original. (La
kpatch-build
fallará si las versiones no coinciden. Esto se puede anular con la opción--skip-gcc-check
aunque se desaconseja su uso).- Para ver la versión de gcc instalada:
gcc --version (if gcc not installed run ”sudo apt install gcc”)
- Para ver la versión de gcc utilizada para compilar el kernel actual:
cat /proc/version
- Para ver la versión de gcc instalada:
1. Instalar paquetes de dependencia
- Instalar y configurar
sudo
.En
root
:apt-get install sudo adduser <user> sudo
donde
<user>
es el nombre de usuario para un usuario normal. (Todos los comandos posteriores deben realizarse como este usuario). - Instalar paquetes.
sudo apt-get -y update sudo apt-get -y upgrade sudo apt-get -y install build-essential devscripts ccache gawk libelf-dev libssl-dev linux-source flex bison
2. Instalar Kpatch
El paquete kpatch de Focal Fossa está desactualizado, por lo que debe instalarlo desde el código fuente.
git clone https://github.com/dynup/kpatch.git
cd kpatch && make && sudo make install
3. Obtener una copia del código fuente del núcleo Linux
- (Opcional) Crear y mover a un directorio de trabajo.
mkdir kernel && cd $_
- Extraiga el código fuente del núcleo de Linux.
tar xaf /usr/src/linux-source-5.4.0.tar.bz2
Nota: 5.4.0 es la versión del kernel Linux para Ubuntu 20.04 en el momento de escribir estas líneas. Debe comprobar y sustituir la versión más reciente presente en /usr/src.
4. Crear el archivo de configuración del núcleo Linux
- El núcleo de Linux se compila utilizando los parámetros de un archivo de configuración suministrado con su distribución. Haz una copia y cambia algunos parámetros para
kpatch-build
puede compilar un núcleo Linux con la misma configuración que su núcleo en ejecución.cd linux-source-5.4.0/ cp /boot/config-$(uname -r) .config
- Compruebe que los ajustes necesarios del kernel están habilitados para utilizar Kpatch. Todos deben devolver 'y'.
scripts/config -s RASTREO_DINÁMICO_CON_REGS scripts/config -s FUNCTION_TRACER scripts/config -s RASTREO_DINÁMICO_CON_REGLAS scripts/config -s TENER_FENTRÍA scripts/config -s HAVE_LIVEPATCH scripts/config -s KALLSYMS_ALL scripts/config -s KALLSYMS scripts/config -s LIVEPATCH scripts/config -s MÓDULOS scripts/config -s MODULE_SIG scripts/config -s SYSFS scripts/config -s SISTEMA_TRUSTED_KEYRING
- Cambia el valor de un elemento de configuración del kernel.
scripts/config --set-str SYSTEM_TRUSTED_KEYS ""
- Deje el directorio de origen.
cd ..
5. Crear un parche
Un archivo fuente de parche es la salida de diff
ejecutado en los archivos de código fuente original y modificado.
El ejemplo de aplicación de parches que se muestra en la sección "Inicio rápido" del Página de kpatch en github cambia la salida de /proc/meminfo
. Muchos otros artículos de Kpatch reproducen este ejemplo, así que quería algo diferente y un poco más interesante, aunque seguro.
Este ejemplo cambia la salida del uptime
para darles la ilusión de que el tiempo de actividad de su servidor ha aumentado una década.
- Todavía en su directorio de trabajo, copie un archivo.
cp linux-source-5.4.0/fs/proc/uptime.c .
- Edítalo. En la línea 26, cambia:
(unsigned long) uptime.tv_sec,
a
(unsigned long) uptime.tv_sec + 315576000,
Guarda el archivo.
- Crea el archivo del parche.
diff -u linux-source-5.4.0/fs/proc/uptime.c ./uptime.c > uptime.patch
- Instale depurar paquetes de símbolos núcleo:
sudo apt install linux-image-$(uname -r)-dbgsym
- Crea el módulo del parche. (La primera vez que lo haga, tardará algunas horas, ya que hay que compilar el código fuente del kernel. Las siguientes compilaciones son significativamente más rápidas, del orden de minutos).
kpatch-build -t vmlinux -v /usr/lib/debug/boot/vmlinux-5.4.0-37-generic uptime.patch
- Cuando termine, tendrá un Linux Módulo de núcleo cargable archivo (
.ko
) para el parche.ls -l *.ko
6. Prueba del parche
- Antes de cargar el módulo de parches, compruebe el tiempo de actividad actual.
cat /proc/uptime && uptime -p
- Carga el módulo patch.
sudo kpatch load livepatch-uptime.ko
- Comprueba de nuevo el tiempo de actividad.
cat /proc/uptime && uptime -p
Debería ver que su tiempo de actividad es diez años mejor. (El valor interno no se ha cambiado, sólo lo que se imprime).
- Descarga el módulo patch.
sudo kpatch unload livepatch-uptime.ko
- Comprueba que el tiempo de actividad ha vuelto a su valor anterior.
cat /proc/uptime && uptime -p
Conclusión
Parchear en vivo el kernel de Linux con Kpatch no es difícil. Lo difícil es escribir un parche que no bloquee el sistema y que funcione con otros parches que vengan después. La mayoría de los parches se crean a partir de algo más que un simple diff
y necesitan pruebas exhaustivas en múltiples versiones del kernel ejecutadas en diversas distribuciones.
Los redactores de parches tienen que ser tanto programadores expertos en C como desarrolladores experimentados del núcleo de Linux, y compilar el núcleo y probar los parches para cada versión del mismo requiere una gran inversión en hardware y herramientas de automatización. La escasez de personal cualificado y el coste de la infraestructura obligan a los proveedores a cobrar por los servicios de parcheo en tiempo real.
Y no olvide leer nuestra guía explícita sobre Cómo aplicar los parches de seguridad del núcleo de Linux: 3 Maneras Diferentes. El artículo explica cómo actualizar los kernels de Linux sin reiniciar, cubriendo tres métodos diferentes para algunos de los kernels de Linux más populares.