Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

miércoles, 26 de julio de 2017

Conociendo iproute en Linux

Finalmente el uso del comando ip se ha vuelto una necesidad; hace muchos años se lleva diciendo que el comando ip iba a sustituir al famoso ifconfig, entre otros, pero siempre ha habido gente que conociendo el archi-conocido comando, no necesitaba ahondar más y recurrir a su "primo" iproute (que contiene el comando ip, entre otros) para manipular la configuración de red en Linux. La cuestión es que ahora las nuevas versiones, tales como Debian 9, ya no usan el comando ifconfig, con lo que lo que antes era cuestión de gustos, ahora se ha vuelto necesario aprender a usar. En su momento expliqué las ventajas del comando ip para la manipulación de la tabla ARP, pero ahora es necesario dar un paso más y dominarlo un poco más a fondo para que, al menos, podamos defendernos con iproute, concretamente con el comando ip.

iproute_portada

El comando ip agrupa una serie de "subcomandos" que pueden controlar desde la propia IP, valga la redundancia, hasta otros factores relacionados con ésta, tales como la tabla ARP, la conectividad y la puerta de enlace. Englobar todos los parámetros de todas las opciones es una tarea prácticamente imposible, con lo que nos centraremos en aquellas opciones y/o comandos que, en mi opinión, son los más útiles e importantes en el día a día, pues serán los que más posibilidades tienen de ser usados.

Empecemos con el comando más básico e importante de todos, el comando: el comando ip addr. Este comando sería el equivalente al clásico ifconfig y es sin lugar a dudas el que más probabilidades tiene de ser usado. Dicho comando tiene diferentes opciones que permitirán tanto mostrar como modificar y/o eliminar nuestra ip actual. Veamos cómo hacerlo:

Para mostrar nuestra IP podemos usar uno de los siguientes comandos:
ip addr
ip addr show
ip addr show dev ens33

Los dos primeros comandos mostrarían la IP de todas las interfaces de red, mientras que el tercero mostraría la IP de la interfaz con nombre ens33 (algo equivalente a hacer un ifconfig de una interfaz de red concreta).

Obviamente podemos hacer más cosas con este comando, tales como la asignación o eliminación de IP a una interfaz de red, cosa tan sencilla como hacer:
ip addr add 192.168.1.2/24 dev ens33
ip addr del 192.168.1.2/24 dev ens33

Otra funcionalidad muy útil sería la manipulación de la interfaz de red en sí; es decir la activación y desactivación de la interfaz de red o la activación y desactivación de algunas características de dicha interfaz... Dicha funcionalidad se denominaría ip link, y con ella podríamos hacer cosas tan interesantes como las siguientes:

Activación de la interfaz de red ens33:
ip link set dev ens33 up

Desactivación de la interfaz de red ens33:
ip link set dev ens33 down

Obviamente podemos manipular más características de la interfaz de red... No todas son usadas habitualmente pero hay algunas que nos pueden resultar realmente interesantes:

Activación/Desactivación de modo promiscuo en interfaz de red ens33:
ip link set dev ens33 promisc on
ip link set dev ens33 promisc off

Activación/Desactivación del arp en la interfaz de red ens33:
ip link set dev ens33 arp on
ip link set dev ens33 arp off

Activación/Desactivación de la gestión del tráfico multicast en la interfaz ens33;
ip link set dev ens33 multicast on
ip link set dev ens33 multicast off

También podemos usar la herramienta ip link para añadir interfaces de red virtuales para luego asignarles una ip y activarlas... Obviamente dichas interfaces virtuales también pueden ser eliminadas. Esto requiere una combinación de las utilidades ip link e ip addr, pero el proceso es relativamente sencillo:

Para crear una interfaz de red virtual plenamente funcional, lo primero que haremos será crear dicha interfaz virtual. Al ser una interfaz virtual, ésta dependerá de una interfaz física (en este caso ens33):
ip link add link ens33 name ens33.1 type vlan id 100

Luego únicamente habría que asignarle una dirección IP a dicha intefaz, con nombre ens33.1, y activarla, cosa que ya hemos visto antes y que sería tan sencillo como hacer:
ip addr add 192.168.1.10/24 dev ens33.1
ip link set dev ens33.1 up

Por último podemos también eliminar las interfaces de red que hayamos creado mediante este método, mediante el comando:
ip link delete ens33.1 

No podríamos repasar el comando ip sin mencionar la definición de puertas de enlace mediante el comando ip route. Lo primero que tendríamos que conocer de dicho comando sería la tabla de enrutamientos que se tiene actualmente, lo cual se puede hacer de dos formas:
ip route 
ip route show

Además de dicho listado, también podemos usar el comando ip route para denegar una IP de forma parecida como haríamos con iptables; si bien esta utilidad tiene muchísimas más limitaciones que iptables. Podemos denegar el acceso a una IP de forma simple o también podemos especificar de qué IP denegar el acceso a otra IP. Por ejemplo:

Para denegar el acceso a una IP:
ip route add prohibit 192.168.1.1

Para denegar el acceso a una IP desde una IP de origen determinada:
ip route add prohibit 192.168.1.1 from 192.168.1.2

Además de estas dos funcionalidades, tendríamos la posibilidad de establecer la puerta de enlace, lo cual se puede añadir de esta forma:
ip route add default via 192.168.1.1

Para eliminar una regla añadida simplemente habría que recurrir al parámetro: del; tal y como veis a continuación:
ip route del prohibit 192.168.1.1
ip route del default via 192.168.1.1

Además de estas opciones, hay otra que si bien no especialmente utilizada a nivel de escritorio, a nivel de servidor se trata de una herramienta de un valor incalculable... Se trata de ss, el equivalente al siempre útil netstat, cuya función es listar los puertos de red del sistema. No se trata de un parámetro del comando ip y por eso lo he dejado para el final, pero se trata de una de las herramientas otorgadas por iproute que tiene un gran valor en la administración de servidores. Afortunadamente la curva de aprendizaje con esta utilidad es mínima pues el comando ss usa los mismo parámetros que netstat con lo que podremos hacer acciones como las siguientes:

Listar todas las conexiones:
ss -a

Listar todas las conexiones tcp y udp, mostrando el número de puerto en vez de el nombre correspondiente a dicho puerto.
ss -tuna

Con este conjunto de comandos (más los del manejo de arpwatch cuyo enlace se encuentra en el primer párrafo de este artículo) tendríamos un dominio global de las funcionalidades más importantes de iproute, pudiendo desenvolvernos con soltura con esta herramienta para poder manipular adecuadamente nuestra configuración de red.

Espero que os haya resultado útil.

Saludos.

miércoles, 12 de julio de 2017

Variables de entorno y variables de shell en Linux

A la hora de trabajar con la consola de GNU/Linux; ya sea para ejecutar scripts, programas o simplemente ejecutar algunos comandos, a veces necesitamos recurrir a unos comandos de forma recurrente, comandos que generalmente tienen una composición relativamente compleja, con muchos parámetros, argumentos, etc... Esto de por sí generalmente no suele ser demasiado problemático a la hora de ejecutarlo una sola vez, pero cuando queremos hacerlo de forma recurrente es preferible tenerlo almacenado en una variable a la que podamos recurrir cuando queramos sin tener que repetir siempre lo mismo... Además el uso de éstas puede resultarnos muy útil también pues podemos tenerlas incluidas desde el inicio de la sesión, pudiendo ayudarnos en ciertas tareas... Para ello hemos de tener en cuenta que tenemos dos tipos de variables: De entorno y de shell.

Shell_entorno_bash

La diferencia entre ambas es sutil, pero importante, ya que dependiendo de la que elijamos, puede tener una repercusión u otra... Aún así empecemos por lo más básico, el listado de las variables actuales, lo cual se puede hacer mediante dos métodos:

Para listar las variables de entorno haríamos:
env

Mientras que para las variables de shell sería:
set

Dependiendo del comando introducido tendremos un resultado u otro,  y es que cada tipo de variable tiene un propósito muy diferente... Mientras que la variable de shell se encuentra únicamente disponible para dicha shell/consola en concreto, la variable de entorno  se encontraría disponible para dicha shell y cualquier subshell que se haya podido invocar tras la declaración de dicha variable, siendo una variable mucho más accesible que la otra y pudiendo ser usada para facilitar varias tareas. Ahora bien; ¿Cómo crear una variable?

Comencemos con lo más básico, la variable de shell: Declarar una variable de shell es tan sencillo como hacer:

variable='aquello a lo que queramos hacer referencia'

Pongamos un pequeño ejemplo; vamos a crear una variable que liste los ficheros de log del directorio /var/log:

logs='ls -lp /var/log/ |grep -v /'

Esta declaración de variable puede recordarnos a la declaración de una variable dentro de un script de bash; y es que en verdad estaríamos haciendo lo mismo; es decir que estaríamos limitando la validez de la variable a una shell en concreto. En caso de ser en la consola, solamente se limitaría a ésta, mientras que en un script la variable solamente viviría durante la ejecución de éste. Al igual que en un script, la forma de llamar a esta variable sería usando el carácter $ seguido del nombre de la variable; es decir que en este caso sería:

$logs

Generalmente este tipo de variables serán usadas o bien en scripts concretos o en situaciones puntuales en las que en una misma sesión queramos recurrir a un dato/comando recurrentemente, pero si queremos algo más flexible y persistente, este tipo de variables no nos serán especialmente útiles.

Para situaciones en las que queramos que tanto la shell, como subshells como scripts ejecutados posteriormente (desde dicha shell/subshell), puedan recurrir a la variable, necesitaremos algo más persistente; necesitaremos una variable de entorno cuya creación difiere ligeramente de las de shell pues se crea de la siguiente forma:

export variable='aquello a lo que queramos hacer referencia'

Lo cual si aplicásemos a nuestro ejemplo anterior sería:
export logs='ls -lp /var/log/ |grep -v /'

Gracias a esto, dicha variable podría ser accedida por scripts ejecutados posteriormente o por cualquier subshell, dandonos una enorme flexibilidad...

Obviamente, al igual que una variable puede ser creada, también puede ser removida. Para remover una variable, sea del tipo que sea, solamente habría que hacer:

unset variable

Lo que en nuestro caso significaría:
unset logs

Gracias a lo cual la variable habría sido eliminada.

Lo ideal, especialmente con las variables de entorno, es incluirlas dentro de un script de arranque para cerciorarnos que siempre estarán accesibles... Se puede usar cualquier script , pero el script estándar en el que se incluyen este tipo de variables es el script .bashrcincluido dentro de la carpeta home de todos los usuarios, pues se ejecuta automáticamente al iniciar sesión el usuario y sabremos que cualquier función y/o script que éste ejecute podrá recurrir a la variable en cuestión. La única pega que tiene esta medida es que requiere modificar todos los .bashrc de todo los usuarios que necesitemos que usen esta variable, con el fin de que no haya problema alguno, pero una vez hecho ese esfuerzo, tendremos la certeza de que la variable siempre será exportada. Solamente tendremos que añadir la variable de entorno a dicho fichero y con ello ya tendríamos el problema resuelto.

Espero que os haya resultado útil.

Saludos.