Compila sistemas operativos personalizados

En algunas situaciones, puede que las apps requieran que compiles tu propio sistema operativo o kernel personalizado. Si compilas kernels personalizados o creas sistemas operativos personalizados para las instancias, asegúrate de que cumplan los requisitos de este documento.

Compilar un sistema operativo personalizado es una tarea avanzada para los usuarios que tienen apps que requieren, de manera específica, un kernel personalizado. La mayoría de los usuarios debe crear instancias a partir de una de las imágenes públicas disponibles, usar la herramienta de importación de discos virtuales automatizada para importar discos a Compute Engine desde otros entornos o importar de forma manual una imagen personalizada desde un sistema con distribución común de Linux.

Requisitos de compatibilidad de hardware

Tu kernel debe ser compatible con los dispositivos siguientes:

  • PCI Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
  • ISA Bridge: Intel 82371AB/EB/MB PIIX4 ISA (rev 03)
  • Controlador de Ethernet:
    • Adaptador Ethernet Virtio-Net
    • vendedor = 0x1AF4 (Qumranet/Red Hat)
    • ID del dispositivo = 0x1000. ID de subsistema 0x1
    • Compatible con la descarga de suma de comprobación
    • Compatible con TSO v4
    • Compatible con GRO v4
  • Controlador de almacenamiento SCSI:
    • Controlador de almacenamiento Virtio-SCSI
    • vendedor = 0x1AF4 (Qumranet/Red Hat)
    • ID del dispositivo = 0x1004. ID de subsistema 0x8
    • Compatible con los comandos principales SCSI 4 y los comandos de bloques SCSI 3
    • Compatible con una sola cola de solicitud
    • Los discos persistentes presentan sectores físicos de 4 KiB y sectores lógicos de 512 bytes
    • Compatible solo con dispositivos de bloques (discos)
    • Compatible con el bit de la característica Hotplug/Events
  • Puertos en serie:
    • Cuatro puertos 16550A
    • ttyS0 en IRQ 4
    • ttyS1 en IRQ 3
    • ttyS2 en IRQ 6
    • ttyS3 en IRQ 7

Opciones requeridas de compilación de kernel de Linux

Debes compilar el kernel del sistema operativo con las opciones siguientes:

  • CONFIG_KVM_GUEST=y
    • Habilita la funcionalidad de paravirtualización.
  • CONFIG_KVM_CLOCK=y
    • Habilita el reloj paravirtualizado (si corresponde a la versión de tu kernel).
  • CONFIG_VIRTIO_PCI=y
    • Habilita los dispositivos PCI paravirtualizados.
  • CONFIG_SCSI_VIRTIO=y
    • Habilita el acceso a discos paravirtualizados.
  • CONFIG_VIRTIO_NET=y
    • Habilita el acceso a las herramientas de redes.
  • CONFIG_PCI_MSI=y
    • Habilita la entrega de interrupciones de alto rendimiento, que es necesaria para dispositivos SSD locales.

Opciones de seguridad de compilación del kernel

Usa la configuración de seguridad recomendada en las opciones de compilación de tu kernel:

  • CONFIG_STRICT_DEVMEM=y
    • Restringe /dev/mem para permitir el acceso solo al espacio PCI, el código BIOS y las regiones de datos.
  • CONFIG_DEVKMEM=n
    • Inhabilita la compatibilidad con /dev/kmem.
    • Bloquea el acceso a la memoria del kernel.
  • CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
    • Establece una memoria virtual baja que esté protegida contra la asignación de espacio de usuario.
  • CONFIG_DEBUG_RODATA=y
    • Marca los datos de solo lectura del kernel como protegidos contra escritura en las tablas de páginas para interceptar escrituras accidentales (incorrectas) en dichos datos const. Esta opción puede tener un ligero impacto en el rendimiento porque una parte del código del kernel ya no estará cubierta por un TLB de 2 MB.
  • CONFIG_DEBUG_SET_MODULE_RONX=y
    • Intercepta las modificaciones no deseadas en el texto del módulo del kernel cargable y los datos de solo lectura. Esta opción también evita la ejecución de datos del módulo.
  • CONFIG_CC_STACKPROTECTOR=y
    • Habilita la característica de GCC -fstack-protector. Esta característica coloca un valor canary al comienzo de las funciones críticas, ubicado justo antes de la dirección de regreso en la pila, y valida el valor antes de mostrarlo. Esto también provoca que los desbordamientos de búfer basado en la pila (que necesitan reemplazar esta dirección de regreso) reemplacen el valor canary, lo cual se detecta y provoca que se neutralice el ataque mediante un kernel panic.
  • CONFIG_COMPAT_VDSO=n
    • Garantiza que el VDSO no esté en una dirección predecible para fortalecer la ASLR. Si se habilita, esta característica asigna el VDSO a la dirección predecible antigua, lo que brinda una ubicación predecible para el código malicioso. Responde N aquí si ejecutas una versión de glibc reciente (2.3.3 o posterior), para quitar la asignación alta de VDSO y usar solo el VDSO aleatorizado.
  • CONFIG_COMPAT_BRK=n
    • No inhabilites la aleatorización de pila.
  • CONFIG_X86_PAE=y
    • Establece esta opción en un kernel de 32 bits, ya que se requiere PAE para la compatibilidad con NX. Esto también permite una mayor compatibilidad con el espacio de intercambio para fines sin compromiso excesivo.
  • CONFIG_SYN_COOKIES=y
    • Proporciona cierta protección contra los desbordamientos SYN.
  • CONFIG_SECURITY_YAMA=y
    • Con esto se selecciona Yama, que amplía la compatibilidad de DAC con una configuración de seguridad adicional para todo el sistema, aparte de los controles estándar de acceso discrecional de Linux. En este momento, la configuración es la restricción de permisos de ptrace.
  • CONFIG_SECURITY_YAMA_STACKED=y
    • Esta opción provoca que Yama, cuando está disponible, se apile con el LSM principal seleccionado.

Configuración de seguridad del kernel

También puedes endurecer la seguridad del kernel mediante el archivo de configuración del kernel. Edita el archivo /etc/sysctl.conf para incluir la siguiente configuración de seguridad recomendada:

# Enable syn flood protection
    net.ipv4.tcp_syncookies = 1

    # Ignore source-routed packets
    net.ipv4.conf.all.accept_source_route = 0

    # Ignore source-routed packets
    net.ipv4.conf.default.accept_source_route = 0

    # Ignore ICMP redirects
    net.ipv4.conf.all.accept_redirects = 0

    # Ignore ICMP redirects
    net.ipv4.conf.default.accept_redirects = 0

    # Ignore ICMP redirects from non-GW hosts
    net.ipv4.conf.all.secure_redirects = 1

    # Ignore ICMP redirects from non-GW hosts
    net.ipv4.conf.default.secure_redirects = 1

    # Don't allow traffic between networks or act as a router
    net.ipv4.ip_forward = 0

    # Don't allow traffic between networks or act as a router
    net.ipv4.conf.all.send_redirects = 0

    # Don't allow traffic between networks or act as a router
    net.ipv4.conf.default.send_redirects = 0

    # Reverse path filtering—IP spoofing protection
    net.ipv4.conf.all.rp_filter = 1

    # Reverse path filtering—IP spoofing protection
    net.ipv4.conf.default.rp_filter = 1

    # Ignore ICMP broadcasts to avoid participating in Smurf attacks
    net.ipv4.icmp_echo_ignore_broadcasts = 1

    # Ignore bad ICMP errors
    net.ipv4.icmp_ignore_bogus_error_responses = 1

    # Log spoofed, source-routed, and redirect packets
    net.ipv4.conf.all.log_martians = 1

    # Log spoofed, source-routed, and redirect packets
    net.ipv4.conf.default.log_martians = 1

    # Implement RFC 1337 fix
    net.ipv4.tcp_rfc1337 = 1

    # Randomize addresses of mmap base, heap, stack and VDSO page
    kernel.randomize_va_space = 2

    # Provide protection from ToCToU races
    fs.protected_hardlinks=1

    # Provide protection from ToCToU races
    fs.protected_symlinks=1

    # Make locating kernel addresses more difficult
    kernel.kptr_restrict=1

    # Set ptrace protections
    kernel.yama.ptrace_scope=1

    # Set perf only available to root
    kernel.perf_event_paranoid=2
    

Próximos pasos