sábado, 14 de septiembre de 2024

grub: con contraseña (grub 2.12-5)


A partir de este momento llamaremos grub a grub2

Voy a actualizar este manual que realice en el año 2007: Grub - protegido con contraseña, ya que grub a tenido mejoras con el paso de los años, por tanto ya va siendo hora que actualizara este manual. En el momento de escribir este manual, la versión que estoy usando de grub es: 2.12-5. Para saber que versión de grub estoy usando, usamos el siguiente comando como administrador: grub-install --version y nos devuelve: grub-install (GRUB) 2.12-5

 



Información

En este manual se puede proteger: de forma individual o todo el conjunto, por usuario o por superusuario:

- Las entrada de cada sistema operativo
- Los diferentes versiones del kernel de cada sistema operativo
- Los submenus de cada sistema operativo
- Las opción de edición de lineas del kernel (e)
- La consola de comandos (c)
- Las opciones personalizadas (Reiniciar, Apagar)
- Test de memoria
- Entradas en la BIOS/EFI

Observación: las opciones de edición de lineas del kernel (e) y la consola de comandos (c), solo estarán permitidas al superusuario (superuser) del grub.

Nota muy importante: Los usuarios y las contraseña que vamos a usar, son creadas exclusivamente para el GRUB. Estos usuarios y contraseñas son independientes de los usuarios y contraseñas del sistema operativo. Puedes crear uno o varios superusuarios y/o usuarios para el grub. Tu, como administrador, puedes hacer que coincidan ambas cosas o ninguna, yo te aconsejo que uses usuarios y contraseñas distintas.

 




Estas son las siguientes rutas y ficheros para realizar la configuración:

- /boot/grub/grub.cfg : En este archivo se carga la configuración por defecto, pero nosotros NO lo modificaremos, ya que cuando se actualice el grub, perderemos las modificaciones que hicimos. (utilizaremos los script de configuración)

- /etc/grub.d/00_header : Es un scripts que se utilizan para generar el grub.cfg en el añadiremos los superusuarios y/o usuarios y sus repectivas contraseñas

 - /etc/grub.d/01_password : Es un scripts nuevo personalizado, que vamos a utilizar para añadir los superusuarios y/o usuarios y sus respectivas contraseñas, a este fichero le tenemos que dar los permisos: 755 usando el comando: chmod

- /etc/grub.d/10_linux : Es un scripts que se utilizan para generar el grub.cfg, en el se encuentra toda la información de los sistemas operativos linux

- /etc/grub.d/30_os-probe : Es un scripts que se utilizan para generar el grub.cfg, en el se encuentra toda la información de los sistemas operativos windows, mac y otras distribuciones de linux


Observación: En caso de realizar la configuración en el archivo: /boot/grub/grub.cfg, no tenéis que usar el comando: update-grub, simplemente con reiniciar el sistema los cambios surten efectos. Por el contrario, cuando hagamos las modificaciones en los archivos: 00_header, 01_password, 10_linux y 30_os_probe, para que los cambios surtan efectos, tenemos que usar el comando: update-grub, para que genere el archivo grub.cfg con la nueva configuración.

En: /etc/grub.d/00_header o /etc/grub.d/01_password pondremos los superusuarios, los usuarios y contraseñas de ambos usando la siguiente estructura:

Los superusuarios usan la siguiente estructura:

set superusers="nombre"

si son mas de un superusuario, la estructura es la misma, pero se separan por comas:

set superusers="nombre,nombre2,nombre3,..."

Para las contraseñas usaremos password (para contraseña en texto plano, sin protección) o password_pbkdf2 (para contraseña cifrada, con protección) :

password nombre contraseña
password_pbkdf2 nombre
grub.pbkdf2.sha512.10000.2F865AB7ECA17DE39

Nota Importante: si un usuario no se declara como superusers es un usuario normal, por tanto es obligatorio declarar los usuarios administradores en la línea: set superusers="nombre,nombre2,nombre3,..."

Vamos a requerir los siguientes parámetros (usaremos todos o solo algunos, dependiendo de nuestras necesidades):

- grub-mkpasswd-pbkdf2
- set superusers
- password
- password_pbkdf2
- --user
- --unrestricted

En este manual quiero proteger las opciones:

- Edición de líneas de kernel (e)
- Consola de comandos (c)



Ejemplos con contraseña en texto plano

Si queremos proteger todo el menú del GRUB, para que solo el administrador pueda arrancar el sistema, modificaremos el archivo: /etc/grub.d/00_header
o /etc/grub.d/01_password añadiendo al final la siguiente estructura (Elegimos root como set superusers, usuariodebian como contraseña en texto plano sin protección) :

======================================================

cat << EOF
set superusers="root"
password root usuariodebian
EOF

======================================================

Si fueran mas de un usuario, se tiene añadir tantas líneas password como usuarios se necesiten, con sus respectivas contraseñas. Si un usuario no ha sido definido como superusuario en: set superusers, serán un usuarios normales (sin privilegios de administrador).

======================================================

cat << EOF
set superusers="root,onubatux"
password root usuariodebian
password onubatux 1234
password diego abcd
EOF

======================================================

Recordemos: las opciones de edición (e) y línea de comandos (c), únicamente las pueden usar superusuarios (set superusers).

Y como hemos usado el script: 00_header o 01_password para realizar la configuración, tenemos que usar el siguiente comando, para que genere el archivo grub.cfg


# udpate-grub

Vemos que las contraseñas van en texto plano sin protección, eso no es bueno, pues un atacante podría ver el contenido de la contraseña, solamente mirando el archivo /etc/grub.d/00_header
o 01_password por lo que sería mejor guardarlas cifradas



Ejemplos con contraseña encriptada con protección

El contenido es casi igual del anterior, pero cambiando la línea password por password_pbkdf2, que tiene una cadena hash de sha512 , es decir, un algoritmo fuerte.

Para generar la contraseña, usaremos el siguiente comando (no es necesario ser administrador): grub-mkpasswd-pbkdf2, que nos devuelve una cadena hash generada a partir de una contraseña que introduciremos:

$ grub-mkpasswd-pbkdf2
Introduzca la contraseña:
Reintroduzca la contraseña:
El hash PBKDF2 de su contraseña es
grub.pbkdf2.sha512.10000.012345678901234567890...


Recordamos la estructura:

password_pbkdf2 nombre contraseña_cifrada_pbkdf2


El ejemplo, quedaría así (he recortado la contraseña, para que el ejemplo sea mas facil de ver y de comprender):


======================================================

cat << EOF
set superusers="root,onubatux"
password root
grub.pbkdf2.sha512.10000.
012345678901234567890...
password onubatux grub.pbkdf2.sha512.10000.
012345678901234567890...
password diego grub.pbkdf2.sha512.10000.
012345678901234567890...
EOF

======================================================

En el ejemplo anterior, los usuarios root y onubatux tienen acceso a todo el grub, pero a diego solo se le permite usar las entradas, no puede cambiar ningún parámetro de arranque usando (e) y abrir la consola de comandos (c)



Opciones del GRUB para Permitir o Restringir acceso

En el archivo: /boot/grub/grub.cfg, se encuentran las configuraciones del grub, pero como dije al principio de este manual, nosotros usaremos los scripts:
/etc/grub.d 01_password, /etc/grub.d/10_linux y /etc/grub.d/30_os-probe para hacer las modificaciones necesarias que necesitamos, para generar grub.cfg.

Las configuración que nos interesa a nosotros se encuentra, en las líneas quecomienzan por: echo "menuentry y echo "submenu

======================================================

echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS}...

echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS}...


echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}"

======================================================

 

Opciones que podemos usar

Podemos usar una de estas dos opciones, en un menú echo menuentry : --users nombre o --unrestricted

Para que un menú lo puedan usar todos los usuarios (es decir no tenga contraseña) usaremos: 
--unrestricted

echo menuentry --unrestricted 

Para que un menú solo pueda ser usado por un solo usuario (recordar: el superusuario siempre podrá usar cualquier opción) en un menuentry:

echo menuentry --users nombre  

Para que puedan usarlo varios usuarios, se escribe el nombre de los usuarios separados por coma:

echo menuentry --users nombre,nombre2,

 

Por ejemplo, vamos a permitir que el usuario: diego pueda elegir la opción de título "Debian GNU/Linux". La sección en Debian tendría un aspecto como este:

La opción es modificar los scripts /etc/grub.d/10_linux y/o /etc/grub.d/30_os-probe.

En el fichero /etc/grub.d/10_linux se encuentran las entradas del sistema operativo principal que ha instalado el grub, que es Debian en este manual. Las líneas echo menuentry que hay que localizar son las siguientes:

Estas líneas hacen referencia a la opción de título "Debian GNU/Linux". Si queremos que sea seleccionada por el usuario: diego, pasaríamos a tener lo siguiente:


echo "menuentry --users diego '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
else
echo
"menuentry --users diego '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"


La opción titulada "Advanced options for Debian GNU/Linux" es un submenú con varias opciones de arranque de Debian con diferentes versiones del kernel. La línea que controla este submenú es la siguiente, Para hacer, como en el caso anterior, que el usuario: diego sea el que pueda acceder a esta opción del menú, escribimos lo siguiente:

echo "submenu --users diego '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"


En el fichero /etc/grub.d/30_os-probe se encuentran las entradas del resto de sistemas operativos que tengamos instalados, distintos al principal como otras distribuciones GNU/Linux, Microsoft Windows o Mac OS


Realizadas las modificaciones en los scripts, el siguiente paso es generar el fichero grub.cfg para ello usamos uno de los siguientes comandos:

# update-grub

 

Vamos a proteger todo y luego desprotegemos lo que nos interese


Por defecto cuando cargamos la siguiente configuración en el archivo: /etc/grub.d/00_header o /etc/grub.d/01_password. Se protege todo el grub con contraseña. Entonces a partir de este momento para usar cualquier opción es necesario usar contraseña.

 

Código dentro de: /etc/grub.d/00_header o /etc/grub.d/01_password

 

#! /bin/sh                                                                                              
set -e                                                                                                    
                                                                                                              
cat << EOF                                                                                           
set superusers="root"                                                                        
password_pbkdf2 root grub.pbkdf2.sha512.10000.0123456789..   
EOF                                                                                                       

 

Vamos a desproteger o permitir el acceso a todos los usuarios a: 

 

- Las entradas de Debian GNU/Linux  (sistema operativo por defecto o principal)
- Las opciones avanzadas de Debian GNU/Linux
(sistema operativo por defecto o principal)
- La entradas a las otras distribuciones de GNU/Linux que tengamos instalado
-
Las opciones avanzadas de las otras distribuciones de GNU/Linux que tengamos instalado
- Las entradas de Windows que tengamos instalados
- Las entradas de Mac OS que tengamos instalados. 

 

  Permitir el acceso al sistema operativo Debian GNU/LInux por defecto o principal.  

 

En este manual solo quiero proteger las opciones:

- Edición de líneas de kernel (e)
- Consola de comandos (c

 

En mi caso el sistema operativo principal es Debian, y el grub lo esta gestionando Debian. Yo necesito que todos los usuarios del ordenador puedan ejecutar Debian sin tener que poner usuario y contraseña, el proceso es el siguiente:

Vamos a editar el archivo: /etc/grub.d/10_linux

# nano /etc/grub.d/10_linux
 

Buscamos las siguientes lineas para permitir la entrada en el kernel por defecto,(aproximadamente: 142 y 144 en debian stable 140 y 142 en debian testing):

echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"   
else                                                                                                                          
echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option   'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"                

Y después de: menuentry le añadimos: --unrestricted

echo "menuentry
--unrestricted '$(echo "$title" | grub_quote)' ${CLASS}      $menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed   "s/^/$submenu_indentation/"                                                                        
else                                                                                                               
echo "menuentry --unrestricted '$(echo "$os" | grub_quote)' ${CLASS}        \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed                "s/^/$submenu_indentation/"                                                                         

Y ahora buscamos la siguiente línea (aproximadamente: 389 en debian stable y 392 en debian testing), para permitir la entrada en las opciones avanzadas, para poder seleccionar cualquier otro kernel que tengamos instalado:


echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"                              

 

Y después de: menuentry le añadimos: --unrestricted

 

echo "submenu --unrestricted '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"          

 

Una vez realizadas las modificaciones, guardamos los cambios pulsando la teclas ctrl + o o pulsando la tecla F2, y luego pulsando la tecla intro. Ahora actualizamos el grub, usando alguno de estos dos comandos:

# update-grub


A partir de ahora cualquier usuario del ordenador, puede arrancar Debian GNU/Linux con cualquier de los kernel que tenga instalado.

 

  Permitir el acceso a las otras distribuciones de Linux, a Windows y a Mac OS 

Si además de Debian, tenemos otras distribución de Linux, Windows o Mac OS. vamos a permitir que todos los usuarios del ordenador puedan usarlo.

La configuración es el archivo: /etc/grub.d/30_os-prober

# nano /etc/grub.d/30_os-prober

Para permitir el uso de cualquier otra distribución de Linux, con el kernel por defecto, buscamos la siguiente línea: (aproximadamente:288 en debian stable y
272 en debian testing)

menuentry '$(echo "$OS $onstr" | grub_quote)' $CLASS --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' {         

 

Y le añadimos: --unrestricted 

 

menuentry --unrestricted '$(echo "$OS $onstr" | grub_quote)' $CLASS --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux- simple-$boot_device_id' {                                                                                           

 

Para permitir el uso de las opciones avanzadas de otra distribución de Linux, buscamos la siguiente línea: (aproximadamente: 303 en Debian (stable 12) y 287 en Debian testing) 


echo "submenu '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {"

 

Y le añadimos: --unrestricted 

 

echo "submenu --unrestricted '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {"     


Para permitir el uso de windows buscamos la siguiente linea: (aproximadamente: 189 en Debian (stable 12) y 173 en Debian testing)

 

menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {

Y le añadimos: --unrestricted

menuentry --unrestricted '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' { 

 

Para permitir el uso de Mac OS buscamos la siguiente linea: 

 

menuentry ' $(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' {

Y le añadimos: --unrestricted

 

menuentry --unrestricted ' $(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' {

 

Una vez realizadas las modificaciones, guardamos los cambios pulsando la teclas ctrl + o o pulsando la tecla F2, y luego pulsando la tecla intro. Ahora actualizamos el grub, usando alguno de estos dos comandos:

# update-grub


  Permitir el uso de Reiniciar o Apagar  

 

Si tienes entradas personalizadas de Reiniciar o Apagar, despues de: menuentry, tienes que añadir, --unrestricted

 

menuentry --unrestricted "Reiniciar el ordenador" {reboot}

menuentry --unrestricted "Apagar el ordenador" {halt}

 

Una vez realizadas las modificaciones, guardamos los cambios pulsando la teclas ctrl + o o pulsando la tecla F2, y luego pulsando la tecla intro. Ahora actualizamos el grub, usando alguno de estos dos comandos:

# update-grub

 

RESUMEN

Vamos a proteger las opciones de edición (e) y la consola de comandos (c) del grub

 

 

 



1- Generamos la contraseña cifrada:

grub-mkpasswd-pbkdf2 

 



 

2- La configuración se puede hacer en: /etc/grub.d/00_header pero para evitar errores y que sea todo mas fácil de comprender, prefiero hacerlo en un archivo nuevo con el siguiente contenido, que le llamare: 

/etc/grub.d/01_password

======================================================

#! /bin/sh
set -e
 
cat << EOF
set superusers="
root"
password_pbkdf2
root grub.pbkdf2.sha512.10000.0123456789...
EOF

======================================================  

 



3- Ahora le ponemos los permisos necesarios

# chmod 755 01_password

 


 

4- En el siguiente archivo localizamos las entradas: echo menuentry y echo submenu y les añado: --unrestricted (las entradas se encuentran aproximadamente en las líneas: 142, 144 y 389 repectivamente en Debian stable 12 y 140,142 y 392 respectivamente en Debian testing)

/etc/grub.d/10_linux

====================================================== 

echo "menuentry --unrestricted '$(echo "$title" | grub_quote)' ${CLASS} 

echo "menuentry --unrestricted '$(echo "$os" | grub_quote)' ${CLASS} 

echo "submenu --unrestricted
'$(gettext_printf "Advanced options for %s" "${OS}

======================================================  

 





5- En el siguiente archivo localizamos las entradas: menuentry y echo submenu y les añado: --unrestricted (las entradas se encuentran aproximadamente en las líneas: 189 windows, 288 y 303 otros linux respectivamente en Debian stable 12, 173 windows, 272 y 287 otros linux respectivamentes en Debian testing)

/etc/grub.d/30_os-prober

====================================================== 

Para permitir el uso de cualquier otra distribución de Linux, con el kernel por defecto, buscamos la siguiente línea: (aproximadamente: 288 en Debian (stable 12) y 272 en Debian testing) 

 

menuentry --unrestricted '$(echo "$OS $onstr" | grub_quote)' $CLASS --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux- simple-$boot_device_id' {  

 

Para permitir el uso de las opciones avanzadas de otra distribución de Linux, buscamos la siguiente línea: (aproximadamente:303 en (Debian stable 12) y 287 en Debian testing) 


echo "submenu --unrestricted '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {"    

 

Para permitir el uso de windows buscamos la siguiente linea: (aproximadamente: 189 en Debian (stable 12) y 173 en Debian testing)

 

menuentry --unrestricted '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {

======================================================

 

6- Actualizamos y generamos el nuevo grub usando el siguiente comando:

# update-grub