Atajos de teclas para Terminator, el veterano emulador de terminal

Aunque hoy en día el ecosistema de terminales se esté renovando y haya terminales de nueva generación hecha en lenguajes más jóvenes y modernos, Terminator sigue siendo una de las terminales más sólidas y válidas para quien busque un emulador de terminal avanzado en el que hacer su trabajo sin interrupciones.

Puede que uses Terminator y sólo uses su faceta de «una ventana, una terminal». Sin embargo, realmente tiene mucho más que aportarte, y te lo voy a mostrar en esta entrada de blog.

Dividir la terminal

Si estás haciendo dos cosas a la vez, como puede ser escribir un archivo de configuración a la vez que miras otro archivo como referencia; o bien escribir en un archivo de configuración a la vez que miras la salida de otro comando, tal vez te interese usar los splits para dividir la terminal en regiones.

  • Con la combinación de teclas Ctrl + Mayus + E puedes dividir verticalmente el panel actual.
  • Con la combinación de teclas Ctrl + Mayus + O puedes dividir horizontalmente el panel actual.

Un panel es cada una de las terminales reales que ves en la ventana, y que identificas porque es ese cuadrado que tiene un área rojo para el título arriba por defecto (salvo que cambies los ajustes visuales del programa).

Ten en cuenta que puedes hacer varias divisiones si quieres, pero cada vez que pulses la combinación de teclas de dividir, lo que harás es dividir el panel actual, así que salvo que cambies el tamaño de los paneles, cada uno de los nuevos paneles será más pequeño.

Un split de Terminator con dos paneles.
Un split de Terminator con dos paneles.

Movimiento por los paneles

Cuando tengas múltiples paneles, vas a poder también moverte por ellos con estas combinaciones de teclas.

Para empezar, puedes usar Alt + ←↓→↑ (o sea, cualquier tecla de dirección) para cambiar el foco del teclado a otro panel. Cada tecla de dirección es la dirección a la que mover el foco. Por ejemplo, Alt + mueve el foco al panel que haya a la derecha del que tiene el foco ahora mismo.

Algunas personas tal vez encuentren que este atajo de teclas es incómodo debido a que tienen que llevar la mano demasiado lejos en el teclado para poder pulsarlo. En las opciones de Terminator pueden cambiar el atajo de teclas por otro de su elección. Tal vez prefieran usar HJKL para este fin. O 5678, homenaje a la ZX Spectrum.

Por lo menos, estaremos de acuerdo en que es mejor eso que levantar la mano del teclado, agarrar el ratón, mover el puntero hacia otro panel, y hacer clic en él.

Si sólo quieres rotar entre dos paneles, o rotar en orden, otras combinaciones que te pueden interesar son Ctrl + Mayus + N y Ctrl + Mayus + P. N y P son las iniciales de Next y Previous, así que estas combinaciones sirven para cambiar al panel siguiente y anterior.

Finalmente, si en algún momento necesitas concentrarte en un panel, puedes pulsar la combinación Ctrl + Mayus + X para hacer zoom y ponerlo a pantalla completa, escondiendo otros paneles. Al pulsarla de nuevo, volverá a su tamaño normal y volverás a ver el resto de paneles.

Usar grupos

Los grupos te permiten agrupar (como su nombre indica) varios paneles, para que al pulsar una tecla, se envíe a la vez a todas las terminales. Esto es algo que puede ser de utilidad en algunos casos, como que te conectes a varios sistemas remotos mediante SSH y quieras mandar un comando a todas las sesiones a la vez.

Aunque lo de los grupos es un mundo, porque lo puedes combinar de formas muy diversas, te voy a derivar por el momento hasta que haga una guía sobre ese tema a la ayuda de Terminator, donde te pueden explicar cómo crear grupos concretos y agregar paneles específicos para compartirlos ahí.

Sin embargo, si quieres mandar teclas a todas las terminales a la vez, puedes usar la combinación de teclas Super + G. Generalmente, Super va a ser la tecla Windows, así que: Windows + G. Al pulsar esa tecla, se activa este modo. Lo notarás porque los paneles que se acoplan al tuyo cambian la barra de título por una azul para señalar que están en modo de escucha.

Cuando pulses una tecla, cualquier terminal que esté con el título en azul también recibirá la tecla, así que podrías mandar comandos a varias terminales a la vez. Recuerda desactivar este modo cuando hayas terminado para no cometer errores graves. Para desactivar este modo, pulsa Super + Shift + G. De nuevo, Super suele ser la tecla Windows en un teclado tradicional, o la tecla Comando en un teclado Apple.

Guía rápida sobre cron

Cron es una herramienta que te permite ejecutar comandos de forma programada. Mientras el agente de cron esté corriendo, podrás especificar cosas como pedir que un script o comando se ejecute periódicamente, cada 15 minutos, cada minuto, cada hora, cada noche, cada domingo, cada sábado a las 14:37 horas, cada día 5 de mes a las 02:51 horas… En fin, que podrás hacerlo de forma muy flexible.

Para poder modificar las tareas programadas, puedes modificar el crontab, que es la tabla de tareas periódicas. En esta guía te quiero contar cómo modificar esta tabla y el formato de lo que debes poner en el archivo.

Introducción al crontab

Para cambiar la configuración de tu agenda puedes usar el comando crontab -e desde la línea de comandos. Si ejecutas este comando, se abrirá el editor de textos por defecto que tengas configurado en tu sistema, con un archivo que puede que esté vacío o que ya contenga cosas.

Dentro de este archivo, puedes meter tres tipos de línea:

  • Líneas en blanco.
  • Líneas que comienzan con un #. Se denominan comentarios, y si no sabes de programación, te vienen bien para anotar cosas. El ordenador las va a ignorar, así que ahí es donde puedes dejar explicaciones o cualquier otro dato que quieras conservar para que puedas volver a leerlo más tarde con calma.
  • Líneas que contienen una tarea programada que quieres que cron ejecute.

Vamos a lo gordo porque realmente el formato puede resultar un poco confuso. Cada línea contiene un comando a ejecutar y el calendario que quieres que tenga.

Calendarios

El calendario especifica cuándo quieres que se repita la tarea. Por ejemplo, los jueves a las 15:30 o cada día 1 a las 02:00 AM. Para especificar el calendario, tienes que poner cinco números separados por espacios al principio de la línea. Estos cinco números siguen el siguiente formato:

minuto   hora   dia-del-mes   mes   dia-de-la-semana

Los rangos de los números son los esperables. Como minuto puedes poner un número comprendido entre 0 y 59; como hora uno entre 0 y 23. El día del mes se comprende entre 1 y 31, sabiendo que hay meses con menos días. El mes también está entre 1 y 12. Ahora bien, para el día de la semana, puedes usar un número de 1 a 7, donde 1 es lunes, 2 es martes… y así hasta 7, que es domingo; o bien puedes especificar también un 0 para el domingo, usando por lo tanto un número entre 0 y 6. Tal vez si administras sistemas esto te suene porque muchos sistemas usan esta notación igualmente, dejando el 0 para el domingo y el 6 para sábado.

Además de un número, puedes poner un asterisco (*) cuando quieras indicar que te da lo mismo lo que valga el campo. Por ejemplo, si quieres ejecutar una tarea todos los días, podrías usar asteriscos para los campos dia-del-mes, mes y dia-de-la-semana, para indicar que lo único que te importa es la hora, pero la fecha vale cualquiera. Por ejemplo, aquí van algunos calendarios:

  • 30 18 * * *: ejecutaría una tarea todos los días a las 18:30. (Me da igual el día del mes, o el mes, o el día de la semana).
  • 0 2 1 * *: ejecutará una tarea cada día 1 a las 2 de la mañana. (Sea el mes que sea).
  • 0 6 * * 1: ejecutará una tarea cada lunes a las 6 de la mañana, sea el día que sea.

Otra cosa que puedes hacer es pedirle que se ejecute cada N minutos, o cada N horas, o cada N días. Para ello le pones un asterisco (*), seguido de una barra y de cada cuánto tiempo quieres que se repita. Por ejemplo, si quieres ejecutar una tarea cada 5 minutos, puedes usar */5 * * * *, que la ejecuta sea el día que sea o la hora que sea, cada 5 minutos.

Por último, también voy a indicarte que puedes usar directamente números separados por comas para tener una mayor precisión. Así que si quieres ejecutar una tarea a las 8 de la mañana el día 1 de enero, abril, julio y octubre puedes usar la secuencia 0 8 1 1,4,7,10 *.

Establecer un calendario es una tarea que puede resultar a veces complicada de depurar, así que te voy a mencionar este enlace para que puedas simular un calendario y traducir la explicación a humano: https://crontab.run/es.

Comandos

Finalmente, luego del calendario vendría el comando que quieras que se ejecute. Aquí, ten en cuenta que es bastante probable que se ignoren las variables de entorno que hayas podido declarar en tu terminal, así como otros directorios que hayas metido al PATH, que generalmente y salvo que lo reconfigures, sólo contendrá /usr/bin y /bin. Por lo tanto, mi consejo es que en cualquier caso uses rutas absolutas para cualquier comando que vayas a ejecutar y así evitar problemas.

Por ejemplo, la siguiente regla de cron ejecutaría el script /home/danirod/scripts/send_analytics.sh cada mañana a las 7:00:

0 7 * * * /home/danirod/scripts/send_analytics.sh > /home/danirod/scripts/log

Observa que puedo poner caracteres como > o 2> para enviar la salida del comando que esté ejecutando a un archivo. Esto es aceptado y es una forma excelente de poder luego ver qué ha pasado, sobre todo en caso de error, así que no pierdas de vista la ocasión de ponerlo y guardar el log en alguna parte para poder detectar errores si compruebas que las tareas programadas no se están ejecutando bien. Solo recuerda, de nuevo, que debes usar rutas absolutas, porque si no el archivo se podría guardar en ubicaciones inesperadas.

Permisos

Como consideraciones finales, ten en cuenta que cada usuario del sistema tiene su propio crontab, para especificar su propia agenda. Los comandos se lanzan siempre bajo el usuario al que le pertenece el crontab.

Eso significa que si ejecutas crontab -e con tu perfil, los comandos correrán en tu nombre y por lo tanto tendrán los permisos que tenga tu cuenta. La cuenta root tiene su propio crontab, que puedes modificar como sudo crontab -e (o cambiando antes a root si no tienes sudo), con el que podrás hacer cualquier cosa, aunque mi consejo es que no lo emplees salvo que necesites hacer tareas restringidas (por ejemplo, reiniciar el servidor web cada noche a golpe de comando de systemctl).

¿Debe la cuenta root de una instalación GNU/Linux tener su propia contraseña?

Hoy en día, lo normal es que el procedimiento de instalación de muchas distribuciones GNU/Linux traten la cuenta que creas durante la instalación, por ejemplo, esa que creas cuando te pregunta cómo te llamas y cuál quieres que sea la contraseña de tu cuenta personal, como una cuenta administradora. Esta cuenta es normal, como cualquier otra, pero tiene permiso para utilizar el comando sudo cuando quiera ejecutar un comando administrativo que sirva para configurar la máquina y que deba ser restringido únicamente para personal autorizado.

Esta es la razón por la que, por lo general, ya no se te pide crear una contraseña para root cuando configuras la máquina. Pocas distribuciones, entre ellas Debian, continúan ofreciendo la posibilidad de establecer una contraseña separada para esta cuenta. Cuando hagas eso, tendrás tu cuenta local para el día a día, pero podrás iniciar sesión como root con la segunda contraseña que has establecido, mediante el uso de la herramienta su para cambiar temporalmente de usuario en una sesión de terminal.

Sin embargo, por lo general hoy en día no se quiere esto. Para empezar, es poco conveniente tener que recordar varias contraseñas. Por otro lado, en un sistema compartido donde se quiera dar permisos de administración a varias personas, todas las personas tendrían que compartir la misma contraseña, algo que nunca se debería hacer.

Por eso, el panorama es mejor cuando son las cuentas locales las que se marcan como administradoras de sistema, para que puedan utilizar el comando sudo y elevar temporalmente sus privilegios durante una sesión de terminal para administrar algo. Te cuento más sobre el funcionamiento de sudo en este artículo que escribí hace un tiempo:

Si tu distribución no te pregunta como paso de instalación que establezcas una contraseña para root, posiblemente te esté haciendo un favor. Esto no quiere decir que no esté prohibido. Si aun así, después de pensarlo bien, decides establecer una contraseña para root y prefieres utilizar su, adelante. Sin embargo, es una complicación más que no deberías plantearte si no lo necesitas.

Existe una razón más para mantener la cuenta de root inactiva y utilizar sudo (o doas, ya puestos en primer lugar), y es la auditoría. Lo normal es que puedas configurar sudo para dejar constancia en algún tipo de log de que has utilizado una elevación de privilegios para hacer una tarea reservada. En sistemas multiusuario, o en sistemas donde haya que aplicar un mínimo de seguridad, como servidores, puede que incluso este log sea obligatorio de recopilar para asegurarse de que no se produce un acceso no autorizado a un recurso restringido o incluso que un usuario autorizado haya decidido hacer una operación cuestionable por la que deba ser preguntado más adelante.

¿Para qué sirve Docker?

Quizá hayas escuchado hablar de Docker alguna vez. Se trata de una tecnología que promete permitir ejecutar aplicaciones y programas de ordenador en un lugar conocido como contenedor. A menudo lo usan para ejecutar aplicaciones de red que se ejecutan en servidores, pero en realidad puedes usarlo en tu propio ordenador personal para instalar programas como bases de datos, o aplicaciones alojadas que tengan interfaz web, de forma rápida y limpia.

Docker facilita el uso de cgroups

Docker se aprovecha de una tecnología presente en el núcleo Linux denominada cgroups. Esta tecnología permite limitar la cantidad de recursos que recibe un proceso en Linux, como el tiempo de CPU que recibe, la cantidad de RAM que puede usar, o incluso directorios de sistema a los que puede entrar.

Lo normal en tu ordenador es que cuando ejecutes un programa, éste tenga acceso a todos los recursos de la máquina. Eso significa que un proceso podría empezar a buscar el último decimal de pi y empezar a consumir un porcentaje importante de CPU que deje hambrientos otros programas en ejecución. O podría reservar suficiente memoria RAM como para dejar tiritando tu sistema. O entrar a cualquier directorio del disco duro para el que tenga permiso y consultar información.

Con cgroups, precisamente puedes aislar un proceso o grupo de procesos para limitar la cantidad máxima de CPU y memoria RAM que van a poder utilizar, e incluso separar la interfaz de red que usan para acceder a internet o cambiar su directorio raíz, de tal forma que sólo vean una porción pequeña del sistema de archivos para impedir que se metan donde no toca. También se puede limitar el uso de ciertas llamadas a sistema, como la posibilidad de que tengan su propia tabla de procesos en ejecución, para que no puedan ver qué procesos tienes en ejecución en tu máquina.

Y Docker precisamente lo que hace es aprovecharse de estas características y crear una forma conveniente de iniciar aplicaciones metidas en uno de esos cgroups. Para ello lo primero que hace es utilizar imágenes de Docker, que puedes ver precisamente como el conjunto de archivos que definirán el sistema de archivos virtual y limitado que verá Docker. Aquí es donde meterás los archivos que permiten funcionar tu programa. Esas imágenes también llevan metadatos, como el usuario con el que se debe ejecutar la imagen, o las variables de entorno a definir al lanzar el programa.

Una vez que tengas una imagen, puedes pedirle a Docker que la lance, creando un contenedor. Un contenedor es una ejecución de una imagen, y se llama así porque, al igual que un contenedor en un barco que transporta mercancías, todo lo que hay dentro de un contenedor está aislado de otros contenedores, y a menudo apilado en un gran sistema lleno de contenedores.

Pero una cosa muy simple que tienes que tener en cuenta es que lanzar un contenedor es simplemente una forma un poco bruta de pedirle a GNU/Linux que ejecute un programa, manteniendo el proceso bajo unas condiciones muy concretas y limitadas como las que contaba antes. La ventaja es que la operación es mucho más simple porque no hay que interactuar con cgroups a mano.

Docker no es virtualización

Es importante diferenciar Docker y cgroups de la virtualización. Cuando virtualizas, lo que haces es usar un programa que simula ser todo un ordenador completo, creando una máquina virtual. Hoy en día las máquinas virtuales son más rápidas gracias al uso de hipervisores y a cierta colaboración que ofrece la CPU del ordenador, pero esencialmente cuando instalas una distribución GNU/Linux en una máquina virtual, estás ejecutando un segundo kernel, simulado dentro de un programa que corres dentro de tu ordenador.

Pero al usar Docker, compartes el kernel de tu ordenador o servidor. En otras palabras, el mismo kernel que atiende las llamadas a sistema en los programas que ejecutas dentro de Docker es el que utilizas en tu máquina. Esta es la razón por la que si pruebas a ejecutar uname dentro de un contenedor de Docker en el que ese comando esté disponible, siempre va a reportar la misma versión del núcleo Linux que la que use tu máquina física, incluso aunque te lleves esa imagen de Docker a otros entornos con otras versiones de núcleo Linux.

Un contenedor de Docker puede pararse y reanudarse mediante operaciones como start y stop. Sin embargo, cuando detienes un contenedor de Docker, no lo estás congelando en el tiempo, que es lo que harías con una máquina virtual si suspendes su ejecución. Cuando detienes un contenedor de Docker verdaderamente detienes todos los procesos en ejecución, que se reanudarán la siguiente vez que se encienda el container.

Los overlays: el punto fuerte de Docker

Uno de los puntos fuertes de Docker es su sistema de overlays. Un overlay es una capa del sistema de archivos que se pone encima de otra, para agregar o quitar cosas.

Por ejemplo, si tienes un sistema de archivos en tu imagen de Docker que contiene 3 archivos, pero luego le pones encima usando un overlay otro sistema de archivos que contiene 2 archivos, al final solaparán y acabarás teniendo una imagen con 5 archivos. Puedes usar los overlays para agregar, modificar y quitar archivos.

Esto es fuerte porque permite crear imágenes reusables. Por ejemplo, existe una imagen de Docker llamada debian:slim, que contiene una instalación pequeña de Debian, con una shell y las herramientas mínimas para usar Docker. Mediante overlay, puedes agregar en otra imagen tus propios archivos de programa a la imagen debian:slim, y el resultado es una imagen que tiene Debian y tus archivos.

Lo normal es que una imagen final de Docker tenga varios overlays, a medida que se usan capas. Por ejemplo, la capa con Debian, la capa con un entorno de ejecución, y la capa con los archivos de programa. A este sistema, se le debe sumar también el volumen que guarda los archivos locales cuando ejecutas una imagen de Docker, para asegurarse de que algunas cosas no se pierdan cuando se detiene la ejecución de una imagen.

¿Por qué se usa tanto Docker?

Docker ha sido adoptado como una tecnología clave moderna para la industria informática y de servidores precisamente por la conveniencia a la hora de fabricar y compartir las imágenes.

Típicamente, instalar un programa en un servidor requería instalarlo a mano y configurarlo. Pero a veces, ese programa depende de paquetes que faltan en el gestor de paquetes del servidor, o pide versiones de una librería que son diferentes de las que aporta el sistema operativo.

Al usar una imagen de Docker, congelamos todo el entorno en el que se va a ejecutar el programa, y eso incluye tanto la distribución, como la versión de la distribución, como otras bibliotecas. Podrías usar la imagen de Docker de Fedora para fabricar una imagen de Docker de un programa que se ejecute sobre Fedora, y como la imagen ya trae todo lo necesario para arrancar el userland de Fedora, luego ejecutarlo en un entorno Docker en Debian, y funcionará de forma transparente.

Dos formas de habilitar sudo para una cuenta en GNU/Linux

Hoy en día, lo normal al instalar GNU/Linux en un sistema es que la primera cuenta que se configura durante la instalación esté considerada como cuenta administradora. Con el comando sudo puede identificarse para confirmar que realmente al otro lado del teclado está la persona que dice estar y no un impostor, y así ejecutar comandos o cambiar opciones que requieren permisos elevados porque introducen cambios al funcionamiento del sistema operativo, como instalar programas nuevos.

Sin embargo, ¿qué hacemos cuando queremos darle estos permisos a otra cuenta? Por ejemplo, en un entorno de trabajo grande donde tengamos varias personas que puedan administrar un sistema. No querríamos que toda la administración de la máquina caiga sobre una misma persona en una gran empresa. Tal vez haya varias personas para administrar los servidores e instalar comandos, según se pongan de acuerdo.

En ese caso, lo que tendremos que hacer es convertir una cuenta de usuario en administradora. Este es un proceso casi chamánico que requiere la intervención de otra cuenta que ya sea administradora, para darle la bienvenida a la nueva cuenta al club. Sin embargo, la forma en la que se hace este proceso depende un poco de la instalación.

El grupo de sudoers

Por lo general, hoy en día casi cualquier distribución GNU/Linux utiliza un grupo de usuarios para identificar a estas cuentas. Así, al agregar o quitar personas del grupo, se les puede dar o revocar estos permisos sin involucrar más configuración.

Este grupo llevará uno de los dos nombres. Históricamente, el grupo se denominaba wheel. Existen varias teorías sobre el origen de este nombre, ninguna posiblemente importe en este momento. Lo clave es que, a pesar de ser el nombre usado en el UNIX tradicional, muchas distribuciones GNU/Linux continúan usando este nombre a día de hoy. Red Hat y Arch Linux, por ejemplo. Esto incluye derivadas: Fedora, Manjaro, EndeavourOS…

Sin embargo, en el caso de Debian, el nombre de este grupo es sudo. Esto es importante porque también afecta a todas las distribuciones que emanan de Debian. Así, distribuciones como Ubuntu o Linux Mint también usan sudo como nombre de este grupo.

Una vez identifiques el nombre del grupo, deberás agregar al usuario que quieras dar permiso de superusuario a este grupo. En el caso de las distros que tengan un script groupadd, podrías usar ese script. Sin embargo, por lo general se da por hecho que el programa alternativo usermod es casi universal y que permite agregar a un usuario a un grupo con la siguiente invocación de terminal:

sudo usermod -aG grupo usuario

No te olvides de poner los flags -aG. El primero sirve para agregar grupos en vez de sustituirlo. Más te vale no olvidar ponerlo, o podrías borrar los grupos a los que pertenezca la cuenta en este momento. El segundo parámetro sirve para especificar precisamente esos grupos. grupo será wheel o sudo según el tipo de distribución que uses, y usuario es el nombre de la cuenta que quieres agregar.

Por ejemplo, para meter a julian al grupo de administradores en Debian, usaríamos:

sudo usermod -aG sudo julian

Y para agregar a laura al grupo de administradores de Fedora, usaríamos:

sudo usermod -aG wheel laura

Para los casos más exagerados: modificar manualmente el archivo sudoers

El archivo sudoers guarda la configuración de sudo. Es importante modificar este archivo utilizando el comando visudo, para que tras editarlo se valide. La razón de esto es que si el archivo /etc/sudoers tiene errores, es posible que sudo deje de funcionar. visudo se ocupará de avisarte si está mal configurado antes de cerrar sesión, potencialmente bloqueando el sistema.

Para modificar este archivo, generalmente basta con escribir lo siguiente en una terminal para abrir el archivo con tu editor por defecto en estos casos (nano, vim…):

sudo visudo

La forma más rápida de agregar una cuenta a este archivo es incorporando una línea que contenga lo siguiente:

[usuario] ALL=(ALL:ALL) ALL

La razón por la que hay que escribir tantas veces la palabra ALL es compleja de contar ahora y no viene al caso, pero lo podría dejar para el futuro. También puede que aprendas algo al respecto si miras el manpage que define este archivo, con man 5 sudoers.

Por ejemplo, para agregar manualmente a julian como sudoer, podrás agregar lo siguiente a tu archivo de configuración:

julian ALL=(ALL:ALL) ALL

Sin embargo, en cualquier caso, generalmente es más flexible si agregas todo un grupo de usuarios y luego usas usermod para agregar y quitar personas de un grupo.

Para permitir a todo un grupo utilizar sudo, puedes usar un formato parecido, pero poniendo un símbolo de porcentaje como prefijo. Es decir, algo como esto:

%[grupo] ALL=(ALL:ALL) ALL

Es raro que no esté, pero debería haber una línea en tu archivo de configuración que tenga este formato:

%sudo ALL=(ALL:ALL) ALL

Esta es la línea que permite a cualquier cuenta que forme parte del grupo sudo ejecutar cualquier comando del sistema como superusuario.

¿Grupos o edición manual?

Sobre qué es mejor, diría que el grupo. Es más flexible, no te obliga a editar el archivo sudoers manualmente, que siempre trae riesgos, y es más rápido. Además, un grupo te permite hacer cosas como dar permisos para leer o escribir en archivos, lo que también permite a esa cuenta poder conceder o restringir el acceso a logs y otros archivos relacionados.

Sin embargo, existen algunas situaciones donde puede venir bien editar manualmente el archivo sudoers. Este archivo es realmente complejo y puede usarse para permitir cosas como limitar qué comandos puede ejecutar una cuenta mediante sudo, e incluso permitir que una cuenta que no sea administradora pueda ejecutar algunos comandos concretos. Esto tiene casos de usos específicos, como permitir que una cuenta pueda ejecutar ciertos comandos sin darle acceso global a toda la máquina.

¿Para qué sirve sudo? Lo esencial a saber para administrarlo de forma segura

El modelo de seguridad de las distribuciones Linux y de UNIX en general, se basa en tener una cuenta administrativa, denominada root, que tiene acceso completo a la máquina y que puede cambiar toda la configuración del sistema; y cuentas locales que no tienen tantos permisos para que en el día a día se pueda usar de forma segura el sistema sabiendo que ni por accidente este se podría comprometer.

Incluso aunque seas la única persona que usa tu ordenador personal, este modelo de seguridad resulta útil, porque requiere que seas consciente cuando vas a cambiar ajustes cambian el funcionamiento del sistema operativo. Así evitas por accidente desinstalar un paquete esencial para que funcione la máquina, como el cargador de arranque. Incluso impedirá que ejecutes por accidente un script malintencionado (por ejemplo, un código que hayas descargado de internet sin leer antes de ejecutar) que trate de hacer cosas maliciosas que puedan dañar tu máquina, como borrar el directorio /usr.

Con sudo, forma corta de super user do, puedes hacer el salto de una cuenta local a una cuenta privilegiada. Por ejemplo, para ejecutar el comando privilegiado systemctl stop networking, que detendría la red, necesitarás elevar tus privilegios, para evitar que por accidente desconectes un servidor. Necesitas anteponerle la palabra sudo, y entonces al ejecutar sudo systemctl stop networking ejecutarías ese comando de forma privilegiada.

Para adquirir esos privilegios, debes estar en una lista de usuarios autorizados. Así podrás elegir quiénes pueden realmente ejecutar esos privilegios. Un administrador de un laboratorio podría estar en la lista de usuarios autorizados para preparar los ordenadores de sus estudiantes antes de una clase, pero los estudiantes podrían quedar fuera de la lista para evitar que ejecuten sudo y hagan de las suyas.

Para confirmar que realmente eres tú, sudo te pide por lo general que escribas tu contraseña antes de lanzar el comando. De este modo, verifica tu identidad. Y si en cualquier caso escribes bien la contraseña de tu cuenta, pero los administradores de tu sistema han decidido que no debes estar en la lista para ejecutar comandos privilegiados, no te va a dar permiso, mostrándote el famoso mensaje El usuario no está en el archivo sudoers; este incidente será reportado.

Por lo general sudo recuerda tu presencia durante unos minutos para que no tengas que volver a escribir la contraseña si vuelves a ejecutar inmediatamente otro comando que empiece por sudo, pero en su forma general, deberías asumir que cuando trates de ejecutar un comando privilegiado con sudo, te va a pedir la contraseña para ver que realmente eres tú y no otra persona entrando en tu ordenador porque te has dejado el portátil desbloqueado cuando has ido a por un café o al baño en un lugar con más personas.

La forma de configurar esta lista de usuarios es modificando el archivo /etc/sudoers. Y la forma correcta de hacerlo, es mediante el programa visudo, usando el comando sudo visudo. El comando visudo abre inmediatamente el archivo /etc/sudoers con tu editor de textos de terminal favorito, como Vim o Emacs, y te permite modificar su contenido. Sin embargo, cuando guardes y cierres el archivo, visudo inmediatamente validará que el archivo sea correcto, y te avisará de errores si está mal configurado.

La razón por la que debes usar visudo en vez de modificar manualmente el archivo /etc/sudoers es, porque si cometes un error en ese archivo, podrías dañar el funcionamiento de sudo. Y en sistemas donde no haya una forma alternativa de recuperar el control (por ejemplo, en esas distros GNU/Linux que directamente desactivan el inicio de sesión como root), dañar sudo podría suponer que bloquees tu ordenador. visudo siempre validará que el archivo esté correcto, y sólo guardará tus cambios si están bien y si no hay manera de bloquear el sistema.

Evidentemente, para usar visudo necesitarás ser un usuario privilegiado, así que la invocación completa es sudo visudo. Así evitamos que una persona que no tenga permisos trate de modificar la lista de usuarios privilegiados, que es algo que rompería completamente el sistema de seguridad. Solamente alguien que tenga permisos suficientes debería poder modificar la lista.

De todos modos, hay formas de configurar sudo para que se pueda dar permisos privilegiados a un usuario para ejecutar únicamente comandos concretos. De este modo, podrías darle permisos a un usuario, físico o automatizado, para que ejecute comandos como sudo systemctl restart docker, pero que a la vez le falten permisos para ejecutar otros comandos como sudo poweroff. También existen forma de configurar sudo para que ciertas cuentas de usuario o ciertos comandos no pidan contraseña.

Ejecutar comandos en el arranque de GNU/Linux con systemd

Si tienes que ejecutar un comando cuando se enciende el ordenador, como iniciar manualmente un servicio o hacer un ajuste sobre un driver, puedes orquestarlo con systemd.

En este ejemplo vamos a ver cómo ejecutar un comando, como un script, cuando se enciende el ordenador. El objetivo es que durante el proceso de arranque, se invoque el comando; por ejemplo, que si el comando es un script que debe escribir algo en un archivo, lo haga. Para ello, nos estaremos apoyando en systemd, y crearemos una unidad personalizada que ejecute ese comando durante el arranque.

Esto contrasta con otras formas de ejecutar programas al encender el ordenador, como ponerlo en el autostart de nuestro entorno de escritorio o agregarlo al .bashrc, de que se hará durante el proceso de arranque, así que normalmente se ejecutará mientras el ordenador está iniciando, antes siquiera de que pongamos la contraseña.

Creamos un script de apoyo

En este ejemplo, fabricaré un script auxiliar que será el que defina lo que quiera que ocurra cuando se encienda el ordenador. Para este caso particular, haré que mi script escriba algo sobre uno de los archivos del directorio /sys, una operación típica para modificar el funcionamiento de alguno de los dispositivos de hardware del ordenador.

Crearé un script denominado update-led.sh con el código de mi script:

$ cat > update-led.sh <<EOF
> #!/bin/bash
> echo 1 > /sys/devices/platform/leds/leds/red:standby/brightness
> EOF
$

Como este script requiere ser ejecutado como root, lo pondré en una ubicación más propia del sistema, como /usr/local/sbin, y lo haré ejecutable:

sudo mv update-led.sh /usr/local/sbin/update-led.sh
sudo chmod +x /usr/local/sbin/update-led.sh

Si ahora queremos probar que el script funciona correctamente, lo podríamos ejecutar si es que es una opción en primer lugar.

Invocar el script al arrancar el sistema

Ahora definiré una unidad de systemd que todo lo que tiene que hacer es invocar este script que he fabricado. Para ello crearé un archivo en el directorio /etc/systemd/system, que es donde se colocan las unidades personalizadas de systemd. El archivo podrá tener el nombre que más nos interese, pero deberá terminar por .service. El nombre que le demos, quitando el .service, será como luego será ejecutado mediante systemctl start y similares.

Este archivo tendrá que contener lo que describo más abajo, cambiando las siguientes líneas de interés:

  • Description será cambiado por un comentario sobre qué hace el comando, para identificarlo semanas después, por ejemplo, «arreglo para el driver de red» o «ejecuta rm -rf a .cache».
  • ExecStart será cambiado por la ruta completa al script que hayas creado en tu caso.
[Unit]
Description=Activar el LED

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/update-led.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Este servicio está declarado como oneshot. systemd es bueno ejecutando programas que tienen que estar en marcha todo el tiempo mientras el ordenador está encendido, como el sistema de audio, un agente SSH o GPG… Sin embargo, en este caso le pediremos que ejecute el comando una vez y ya está. La instrucción RemainAfterExit también se usa para señalizar que si el comando termina, todo estará correcto.

Finalmente le pediremos a systemd que active esa unidad, ejecutándola a partir del próximo reinicio. Supongamos que el archivo de unidad se denomina update-led.service, pues el nombre a activar será update-led:

sudo systemd enable update-led

Y opcionalmente si queremos probarlo ya, podemos pedirle que ejecute el script inmediatamente con:

sudo systemd start update-led