Permitir a un usuario ejecutar un comando como root usando sudo

En otra entrada ya se trataron las diferencias entre los comandos sudo y su.

En esta entrada voy a explicar cómo configurar el archivo /etc/sudoers para permitir a un usuario determinado ejecutar uno (o varios) comandos que requieran permisos de administrador sin que tenga estos permisos en otras tareas.

Como ejemplo voy a usar el comando shutdown que sirve para apagar/reiniciar el sistema y que en la mayoría de distribuciones solo lo puede ejecutar el usuario root, aunque la aplicación es la misma para cualquier otro programa.

Antes de trabajar con el archivo /etc/sudoers estaría bien leerse su entrada del manual (man 5 sudoers) para entender mejor la sintaxis y el funcionamiento y saber qué estamos haciendo exactamente. Si no quieres, simplemente deberías conocer los siguientes datos:

  • Es un archivo muy importante y delicado y cualquier pequeño error de sintaxis puede dejarte sin permisos de administrador.
  • Para evitar sustos existe el comando visudo que abre el archivo en el editor configurado por defecto (generalmente nano) y comprueba la sintaxis antes de guardarlo, evitando así errores fatales.
  • También existe la posibilidad de no modificar directamente el archivo sino añadiendo nuevo contenido dentro del directorio /etc/sudoers.d/

Evidentemente, para editar este archivo, se necesitan permisos de administrador por lo que tienes que ingresar con la cuenta de root (su o sudo -s).

Ahora ejecuta visudo y al final del archivo (puedes añadir una línea comentada, que empiece con el carácter #, para saber donde comienzan los cambios que tu has realizado y/o explicarlos) escribe lo siguiente:
usuario ALL=NOPASSWD: comando
Cambiando usuario por el usuario que quieras y comando por la ruta completa al programa que quieres que pueda ejecutar. Para averiguar las rutas completas puede usar which comando.
NOPASSWD sirve para no requerir que el usuario introduzca su contraseña.

Ejemplo:
pi ALL=NOPASSWD: /sbin/shutdown
Permitirá al usuario pi ejecutar el comando shutdown para poder apagar mi Raspberry Pi sin tener más permisos de administrador ni introducir contraseña alguna.

Ahora el usuario en cuestión simplemente tiene que ejecutar sudo comando y podrá usar dicho comando como si fuera administrador, pero sin el peligro de que tenga más permisos de los realmente necesarios.

Servicios al inicio con rcconf

rcconf es una herramienta muy útil para controlar los servicios que se inician durante el arranque del sistema.

Probablemente ya conozcas la aplicación que suelen traer los diferentes entornos al estilo Aplicaciones al inicio, pero ahí solo se incluyen los programas que se ejecutan una vez el usuario ha iniciado sesión. En cambio rcconf muestra todos los que se ejecutan durante las fases previas del arranque, por ejemplo, el servidor gráfico y el gestor de inicio (X y mdm, gdm,…), servidores que tengas instalados, el servidor de sonido, cron,…

Es una herramienta específica de Debian y suele venir instalada por defecto en sus derivadas, aunque siempre puedes hacer uso de aptitude para conseguirla:
aptitude install rcconf

Requiere permisos de administrador, por lo que habrá que iniciar sesión como root primero. Luego lo ejecutamos:
rcconf

Como podrás observar se trata de una interfaz bastante sencilla de usar: una simple lista con algunos de los servicios, marcados aquellos que se inician al arranque y dos botones de aceptar y cancelar. La navegación se realiza con las flechas de dirección del teclado, se marcan/desmarcan las casillas con la tecla espacio y finalmente tabluador para seleccionar entre Aceptar y Cancelar e INTRO para elegir.

Hay que tener en cuenta que los cambios no son instantáneos, es decir, no cierra los procesos que desmarcas ni inicia los nuevos marcados, sino que eso ocurrirá durante el siguiente arranque.
Si quieres cerrar un servicio actualmente abierto, se suele así:
service stop
Y para iniciarlo sustituye el stop por start. O restart para reiniciarlo.

Si esto no funciona puedes buscar con ps -A el PID (el número que identificar un proceso) y matarlo con kill -9

Ficheros de texto: finales de línea

Cuando usamos un sistema diferente al que la mayoría es normal que haya veces que choquemos de golpe por incompatibilidades que nos dificultan el trabajo, por muy estúpidas que puedan parecer.

Una de ellas son los finales de línea, es decir, la forma que tienen los sistemas operativos de identificar que en un archivo hay una nueva línea cuando se trabaja con texto plano.

En ASCII (el código de caracteres latinos más básico usado en informática) existen, dentro de los caracteres de control, dos que han sido usados para marcar nuevas líneas. Estos son LF (nueva línea, generalmente representado como \n) y CF (retorno de carro o carriage return, también representado como \r). Este último es una herencia de las máquinas de escribir antiguas, teletipos y demás dispositivos mecánicos, pero que no tiene ningún sentido hoy en día pues los ordenadores ya no se ayudan de piezas móviles para procesar el texto.

El verdadero problema viene cuando los desarrolladores deciden usar diferentes implementaciones para su software, ya sean sistemas operativos, aplicaciones de cualquier tipo, protocolos de red,… ya que se está dificultando el uso tanto a usuarios como a otros desarrolladores.

El sentido común parece indicar, por lo menos desde mi punto de vista, que con el carácter de nueva línea (LF) debería valer. Y lo mismo debieron pensar los creadores de Unix y gracias a ellos es el carácter que se usa hoy en día en Unix y sistemas similares entre los que se incluye GNU/Linux.

Por el contrario, Microsoft durante el desarrollo inicial de DOS decidió mantener la convención LF + CR que se usaba en sistemas que trataban de mantener la compatibilidad con aquellos teletipos, impresoras,… que necesitaban un carácter para marcar el carriage return. Y esto es, por inercia, lo que se usa hoy en día en el sucesor de DOS: Windows.

Y, a su bola, Apple en sus SO de la familia Apple II y Mac OS 9 y anteriores, usó únicamente el carácter CR para marcar las nuevas líneas, lo cual síº que es totalmente desconcertante. Aunque a partir de Mac OS X se han unido a la convención del resto de sistemas Unix: solo LF.

Aunque no todas las aplicaciones están obligadas a seguir el estándar usado por el sistema donde se estén ejecutando, es lo común. Por ejemplo, en la mayoría de lenguajes de programación, para conseguir compatibilidad multiplataforma se ofrece una capa de abstracción en la que se establece el estándar para la nueva línea, generalmente el carácter \n y el compilador o intérprete se encarga de traducirlo al carácter de nueva línea nativo del sistema donde se está ejecutando la aplicación.

Puede que ya te hayas dado cuenta de este problema si alguna vez has abierto un documento creado en GNU/Linux con el bloc de notas de Windows y te das cuenta de que en vez de separar las líneas incluye unos símbolos (rectángulos vacíos) en su lugar. Esto puede resultar bastante tedioso si te trata de un archivo largo.

Para evitar estos problemas existen varias soluciones:

  • Usar software que identifique automáticamente el tipo de archivo. Por ejemplo, cualquier editor de textos que NO sea el bloc de notas de Windows.
  • Especificar el final de línea al guardar: Muchos editores, por ejemplo gedit, te pregunta el tipo de final de línea que se quiere usar: Unix/Linux (LF), Mac (CR) o DOS/Windos (CRLF).
  • Convertir los finales de línea: Existen comandos como dos2unix, unix2dos, mac2unix, unix2mac, mac2dos, dos2mac únicamente diseñados para realizar estas tareas.

WIFI en la Raspberry Pi

Para este artículo doy por seguro que tienes una Raspberry Pi debidamente configurada y con Raspbian instalado, aunque todo debería funcionar de la misma forma en cualquier otra distribución.

El primer paso es conseguir una tarjeta WIFI, ya que la Raspberry Pi no incluye esta característica. La única interfaz de red disponible es el puerto RJ-45 (Ethernet) del modelo B.
Hoy en día los pinchos-WIFI por USB son bastante baratos y fáciles de conseguir e incluso es posible que el fabricante incluyera uno con el router wifi. Antes de comprar uno nuevo tienes que tener en cuenta cuál es el chipset y buscar si los drivers necesarios están disponibles para Linux. Y no solo si están disponibles, sino también el nivel de compatibilidad, ya que algunos no aprovechan todo el potencial de las tarjetas wifi. Aquí tienes una lista bastante exhaustiva con todos los drivers disponibles para el kernel Linux. La wiki de aircrack-ng también tiene bastante información al respecto. Otro aspecto tener en cuenta la libertad de software, pues muchos de estos drivers son privativos.

Muchos chipsets tienen ya sus drivers incluidos en el kernel, por lo que funcionan siguiendo el modelo plug & play. Pero si ves que el sistema no lo detecta nada más enchufarlo, los siguientes pasos te pueden ayudar a encontrar los drivers necesarios.
Nada más introducir el pincho-WIFI en el sistema, abre la terminal y ejecuta:
dmesg|tail
dmesg es el log de control del kernel y tail limita la salida del mismo a las últimas 10 líneas. Deben aparecer una serie de líneas relacionadas con el último evento ocurrido, es decir, la introducción del USB. En mi caso, son las siguientes:
[12199.268244] zd1211rw 1-2:1.0: phy1
[12199.268263] usbcore: registered new interface driver zd1211rw
[12199.294189] usb 1-2: firmware: failed to load zd1211/zd1211b_ub (-2)
[12199.294192] usb 1-2: Direct firmware load failed with error -2
[12199.294193] usb 1-2: Falling back to user helper
[12199.294533] zd1211rw 1-2:1.0: couldn't load firmware. Error number -2

zd1211 es lo que me interesa (probablemente en tu caso será otro nombre diferente) ya que es el nombre del driver que necesito.
El siguiente paso es buscarlo en los repositorios (aptiutude search zd1211) e instalar el/los paquetes necesarios. Si estás usando un chipset que requiere drivers privativos para funcionar debes considerar activar los repositorios non-free o el correspondiente para tu distribución.

Otras formas de identificar la tarjeta de red puede ser usando el comando lsusb que lista todos los dispositivos conectados por USB, y posteriormente buscando en las listas de drivers cuáles son los necesarios para hacer funcionar dicho hardware.

Una vez configurado, el comando ifconfig y iwconfig deberían ser capaces de activar la interfaz de red correspondiente, normalmente wlan0.

Ahora, para que se conecte automáticamente en cada inicio, se puede usar wpa_supplicant. Para esto primero hay que configurar network manager en el archivo /etc/network/interfaces. El que trae Raspbian por defecto nos vale:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

La configuración de wpa_supplicant la haremos en el archivo /etc/wpa_supplicant/wpa_supplicant. Aquí escribimos lo siguiente:

network={
ssid="Nombre_de_la_Red"
scan_ssid=1
psk="contraseña"
}

Debería funcionar tanto para redes WPA, WEP o aquellas abiertas (eliminando la línea psk, aunque solo lo he podido probar en WPA.

wpa_supplicant tiene bastantes más opciones necesarias para usos más complejos. Puedes leer más en la wiki de Arch Linux o en sus entradas del manual:
man 5 wpa_supplicant.conf
man wpa_supplicant

Para aplicar la configuración basta con reiniciar el servicio wpa_supplicant, pero como no he encontrado cómo hacer esto, toca reiniciar:
sudo shutdown -r now

Mantener youtube-dl siempre actualizado

Como parece ser que la compatibilidad de youtube-dl se rompe con facilidad con muchas de las páginas de las que permite descargar vídeos y hay que actualizar manualmente cada pocos meses, los desarrolladores han incluido una nueva opción para actualizar la aplicación.

Simplemente busca la última versión disponible en la página oficial y descargarla. Pero como la aplicación suele estar en /usr/bin o similares, hay que ejecutar esta opción como root para poder completar el proceso.

La sintaxis es la siguiente:
youtube-dl --update

Si la has instalado desde los repositorios, tendrás la página del manual en tu sistema donde podrás aprender toda la funcionalidad de está aplicación:
man youtube-dl

Copiar al portapapeles desde la terminal con xclip

xclip es una herramienta que nos permite trabajar con el portapapeles del servidor gráfico (X.org). Está disponible en los repositorios de Debian y derivadas por lo que se puede instalar fácilmente con aptitude:
aptitude install xclip

El uso es muy sencillo. Por defecto toma valores del archivo que se le indique o desde la entrada estándar, es decir, la salida de otro comando redirigida por un pipe:
el_programa_que_sea | xclip

Para pegar el contenido que ha copiado puedes usar el argumento -o
xclip -o
Esto solo lo mostrará en pantalla, aunque puedes usarlo para pegarlo en un archivo con los elementos > y >>. O redirigirlo a otro programa a través de un pipe. Revisa la página de conceptos básicos para aprender más sobre esto.

Si quieres que el contenido pueda ser utilizado por otras aplicaciones, tienes que especificar el portapapeles a utilizar. En este caso -selection clipboard
xclip -selection clipboard

Entonces si, por ejemplo, quieres copiar un archivo entero y pegarlo en un procesador de textos, puedes valerte del siguiente comando:
xclip -selection clipboard archivo

O si quieres copiar la salida en pantalla del proceso de instalación de un paquete:
aptitude install paquete | xclip -selection clipboard

Este programa tiene funcionalidad más avanzada que puede comprobar desde su página del manual:
man xclip

Comandos útiles que quizás no conocías

Si sabes usarlo, la consola y las aplicaciones con interfaz de texto (CLI) para algunas tareas son mucho más eficientes en cuanto a tiempo y recursos, más estables, menos proclives a presentar errores y más universales (no cambia como se hace una acción entre entornos de escritorio diferentes y hay muchas que son comunes a otros *NIX). Es por esto, y porque algunas tareas más avanzadas solo se pueden realizar de esta forma, que es bastante útil saber usarlas.
Por eso aquí os presento algunos comandos que considero bastante útiles y de los cuales puede haber algunos que no conozcas. También tienes una lista más completa aquí.

  • df: Muestra el espacio disponible en disco. Para que muestre los resultados de una forma más comprensible, con prefijos binarios (Mebi, Gibi,…) añade el argumento -h.
  • du: Muestra el espacio en disco que ocupa un archivo/carpeta/árbol de directorios. Para que muestre los resultados de una forma más comprensible, con prefijos binarios (Mebi, Gibi,…) añade el argumento -h.
  • diff archivo1 archivo2: Compara dos archivos línea por línea mostrando sus diferencias.
  • cat archivo: Muestra el contenido de un archivo. tac hace lo mismo pero mostrando el archivo en orden inverso.
  • less: Ajustan un archivo o la salida de un programa al tamaño de ventana/pantalla disponible permitiendo desplazamiento.
  • locate: Busca archivos en una base de datos que suele estar configurada para actualizarse automáticamente con frecuencia (también se puede hacer manualmente con updatedb). find es otra herramienta para realizar búsquedas, pero más lenta a la vez que avanzada, ya que busca directamente los archivos en el disco y no en una base de datos y permite usar criterios de búsqueda como fecha de modificación.
  • grep: Limita la salida mostrada de un programa/archivo a los criterios de búsqueda establecidos (admite expresiones regulares, REGEX).
  • wget: Descarga contenido usando los protocolos HTTP(s), FTP(s). Si una descarga es parada a la mitad permite retomarla desde donde se dejó si se ejecuta de nuevo con el argumento -c.
  • ps: Ejecutado con el argumento -A muestra todos los procesos activos.
  • uptime: Muestra el tiempo que el sistema lleva encendido.
  • date: Muestra la fecha y hora actuales.
  • kill PID: Mata el proceso con el PID indicado. Los PIDs de los procesos en ejecución pueden comprobarse con el comando ps -A. xkill: Se matará el proceso iniciado por la ventana gráfica sobre la que haga click a continuación.
  • .

  • which: Busca la ubicación del ejecutable correspondiente a una orden.
  • file archivo: Muestra el tipo de documento que es el archivo especificado.

La mayoría de estos comandos tienen diversos argumentos y cuentan con funcionalidad más avanzada, por lo que es recomendable leer sus respectivas páginas del manual: man programa_del_que_se_quiere_leer_el_manual.