sábado, 24 de octubre de 2020

Servidor de correo: Correo entrante

La máquina no va a existir porque sí. Vamos a ver que todo tiene un porqué. En este caso, va a ser un servidor de correo.

En principio basta con instalar Postfix. Lo configuramos como Sitio de Internet y configuramos correctamente el nombre de la máquina. Lo interesante vendrá después.

Ya que tenemos un cortafuegos, vamos a tener que autorizar las conexiones que correspondan al correo electrónico:

iptables -A INPUT -p tcp -m tcp --dport smtp -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport smtp -j ACCEPT
ip6tables -A INPUT -p tcp -m tcp --dport smtp -m state --state NEW,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport smtp -j ACCEPT

Y activar la regla de Postfix correspondiente en fail2ban: en la sección [postfix] del fichero /etc/fail2ban/jail.local añado la línea

enabled = true

De momento no voy a poner modos más agresivos ni jaulas extra. En vez de cargar la jaula a mano, como en la entrada anterior, también basta con

/etc/init.d/fail2ban reload

Bendito sysvinit.

El Postfix en realidad se configura solo, con lo anterior ya recibiría correo. Pero no lo queremos "simplemente" para eso. En mi caso, este servidor va a encargarse de todo el correo de un dominio, y evidentemente no voy a crear todos los usuarios que tiene ese dominio como usuarios UNIX (sería de locos). Así que tienen que ser usuarios virtuales. Lo más cómodo es que el propio dominio sea un dominio virtual.

Para ello, en /etc/postfix/main.cf añadimos estas líneas (donde, evidentemente, he cambiado el dominio) al final:

#Dominios virtuales
virtual_mailbox_domains = example.com
virtual_mailbox_base = /var/mail/v
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 1000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/virtual

Los usuarios que tienen que tener cuenta se definen en el fichero /etc/postfix/vmailbox que tenemos que crear y que queda así:

# /etc/postfix/vmailbox:
# Recuerda ejecutar postmap /etc/postfix/vmailbox
# despues de modificar este fichero
compras@example.com	    example.com/compras/
ventas@example.com	    example.com/ventas/
legal@example.com	    example.com/legal/
# Descomenta la línea de demajo para tener un buzon catch-all.
# @example.com	        example.com/catchall/
#...Se pueden añadir otros dominios...

Los otros usuarios a tener en cuenta son esos usuarios que todo dominio debe tener, que redirigimos en el fichero /etc/postfix/virtual que también tenemos que crear:

#/etc/postfix/virtual
# Recuerda ejecutar postmap /etc/postfix/virtual
# despues de modificar este fichero
postmaster@example.com          postmaster
root@example.com                root

A Postfix no se le da nada bien crear los directorios Maildir que hemos indicado, y además es quisquilloso con los permisos. Hay que crear el directorio padre (que al crearse en /var/mail aparecerá como root:mail con permisos 2750) y para cada usuario crear el suyo con unos permisos específicos:

mkdir /var/mail/v
chmod g+w /var/mail/v
mkdir /var/mail/v/example.com
chmod g+w /var/mail/v/example.com
mkdir /var/mail/v/example.com/compras
chown 5000:5000 /var/mail/v/example.com/compras
mkdir /var/mail/v/example.com/ventas
chown 5000:5000 /var/mail/v/example.com/ventas
mkdir /var/mail/v/example.com/legal
chown 5000:5000 /var/mail/v/example.com/legal

...y así sucesivamente. Ya solo necesitamos activarlo todo, primero los mapas y después el propio Postfix:

postmap /etc/postfix/vmailbox
postmap /etc/postfix/virtual
/etc/init.d/postfix/restart

Y ya podemos empezar a recibir correo, para los usuarios definidos, en el nuevo servidor.

miércoles, 21 de octubre de 2020

Aumentando la seguridad

En la entrada anterior apliqué unas reglas de cortafuegos muy monas, y activé fail2ban.

Pero dichas reglas son solamente para IPv4, y hay que repetirlas en IPv6. Pero ojo, que en IPv6 el ICMP no es simplemente un protocolo de apoyo, es parte fundamental de la infraestructura, y si los paqutes no pasan, no hay comunicación (véase RCF 4890):

ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p tcp -m tcp --dport ssh -m state --state NEW,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-replay -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type ttl-exceeded -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -J INPUT DROP
ip6tables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport http -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport https -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport domain -j ACCEPT
ip6tables -A OUTPUT -p udp -m udp --dport domain -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-reply -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type ttl-exceeded -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -J OUTPUT DROP
ip6tables -J FORWARD DROP

Para conseguir que las reglas se mantengan al reiniciar, basta con instalar el paquete iptables-persistent.

Por fail2ban para IPv6 no tenemos que preocuparnos, ya que funciona automáticamente.

La otra cosa pendiente es que no vale de mucho parar a un atacante por unos minutos si después vuelve a las andadas. La configuración por defecto de fail2ban prohíbe la entrada de paquetes durante 10 minutos. Esto para los ataques casuales, pero a los atacantes serios no. Pero subir el tiempo puede dejarle fuera a uno mismo si tiene problemas con la configuración del teclado, por ejemplo.

La solución a este tipo de problemas es prohibir el acceso de nuevo, por más tiempo, a los reincidentes. Siguiendo (un poco) los pasos de The art of web, creamos dos jaulas nuevas, cada una de ellas más dura que la anterior.

En /etc/fail2ban/jail.local añadimos estas líneas:

[sshd-fail2ban-L1]
# 3 veces en 6 horas, 24 horas
enabled = true
port = ssh
filter = sshd-fail2ban-L1
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 21600
bantime = 86400

[sshd-fail2ban-L2]
# 3 veces en 7 días, 30 días
enabled = true
port = ssh
filter = sshd-fail2ban-L2
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 604800
bantime = 2592000

A continuación, creamos el fichero /etc/fail2ban/filter.d/sshd-fail2ban-L1.conf con este contenido (ojo al espacio final en ignoreregex) como filtro:

[DEFAULT]
[Definition]
failregex = \[sshd\] Ban <HOST>
ignoreregex =

Y este otro contenido (la misma advertencia) como el fichero /etc/fail2ban/filter.d/sshd-fail2ban-L2.conf como el otro filtro:

[DEFAULT]
[Definition]
failregex = \[sshd-fail2ban-L1\] Ban <HOST>
ignoreregex =

Ahora basta con un par de órdenes y ya tenemos un sistema un poco más robusto:

fail2ban-client add sshd-fail2ban-L1
fail2ban-client start sshd-fail2ban-L1
fail2ban-client add sshd-fail2ban-L2
fail2ban-client start sshd-fail2ban-L2

lunes, 12 de octubre de 2020

Asegurando el servidor

El servidor que migré ayer a Devuan va a estar abierto a Internet, ese lugar tan grande. Así que no puede ser fácilmente accesible.

Lo primero será que no se pueda entrar como root mediante ssh (el acceso por consola debe seguir siendo posible, para un posible rescate). Así que eliminamos esa opción:

PasswordAuthentication no
PermitRootLogin without-password

Claro que antes nos hemos asegurado el acceso mediante clave pública ssh, metiéndola en /root/.ssh/authorized_keys.

El siguiente paso es poner un sistema que nos asegure que los niñatillos que se dedican a probar accesos se queden fuera. Para esto, yo suelo elegir fail2ban. Basta con instalarlo y, muy importante, copiar el fichero /etc/fail2ban/jail.conf como /etc/fail2ban/jail.local.

Inicialmente activaré solo la regla relativa a SSH, ya que es el único servicio que estará activo en la máquina. Para ello, en /etc/fail2ban/jail.local añadiremos

enabled=true

en la sección [sshd] de/etc/fail2ban/jail.local.

Tras ello, las reglas de cortafuegos.

Realmente, ¿qué tráfico necesita tu máquina? Es algo que tienes que pensar dos veces, y luego prohibe todo lo demás.

Los paquetes que correspondan a conexiones de salida ya establecidas, conexiones abiertas por nosotros, hay que permitirlos, o no habrá comunicación:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

El tráfico de entrada SSH evidentemente hay que permitirlo:

-A INPUT -p tcp --dport ssh -m state --state NEW,ESTABLISHED -j ACCEPT

Y queremos que funcione el ping:

-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

¿Algo más? De momento no. todo lo demás, prohibido.

-P INPUT DROP

El tráfico de salida también hay que permitirlo, pero solo para lo que lo necesitemos. En primer lugar, el tráfico de salida correspondiente a conexiones de entrada ya establecidas:

-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

En nuestro caso, queremos las actualizaciones de paquetes y otras consultas de ese estilo a sitios web:

-A OUTPUT -p tcp --dport http -j ACCEPT
-A OUTPUT -p tcp --dport https -j ACCEPT

Evidentemente tiene que funcionar el DNS, o no hacemos nada:

-A OUTPUT -p tcp --dport domain -j ACCEPT
-A OUTPUT -p udp --dport domain -j ACCEPT

Y también queremos que funcione el ping:

-A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
-A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

Todo lo demás, incluso de salida, prohibido.

-P OUTPUT DROP

La tabla FORWARD no la utilizaremos, ya que este sistema no es un enrutador:

-P FORWARD DROP

Con esto nos aseguramos un cortafuegos bastante restrictivo, y sin embargo utilizable.

domingo, 11 de octubre de 2020

Vamo' a migra' un server

Quiero poner un servicio de correo electrónico donde no está. Y eso es una migración. Y lo voy a hacer de on-premises a eso que llaman "la nube". Aunque lo local sea mi servidor casero y la nube sea un servidor contratado con un servicio de hosting.

Así que lo primero es pagar por, e instalar el servidor remoto. De entre las opciones disponible, he elegido Debian 9 (Stretch), porque me será sencillo migrarlo a Devuan.

Así que una vez creado el servidor, de nombre mercurio, el mensajero de los dioses, le instalo lo mínimo que requiero siempre (es decir, vim, htop y aptitude) y a actualizarlo a Devuan.

El primar paso desde Stretch, siguiendo las indicaciones oficiales de Devuan es instalar sysvinit-core y eliminar libpam-systemd, para sentar las bases del nuevo sistema de arranque. Con esto puede que el escritorio no arranque, pero en serio, ¿alguien tiene un escritorio en un servidor recién instalado? (Ejem, SuSE, ejem) En cambio, aseguramos que el sistema sí arranque. Particularmente, en este tipo de operaciones yo siempre las eliminaciones las hago con purge y no con delete.

El siguiente paso sería cambiar las fuentes, pero yo no lo hago directamente. En su lugar creo un fichero /etc/apt/sources.list.d/beowulf que contiene las líneas que hay que añadir. Así queda todo más claro.

Se actualizan las listas de paquetes, se instala el llavero y se actualizan otra vez. Aquí el documento peca de optimista: te la han podido colar con un MITM justo en ese momento. ¡Ah!

Vamos a evitar esto. Primero, vemos e importamos (ojo, si no la importamos será como si nada) la clave maestra de Devuan con

gpg --keyserver keys.gnupg.net --search-keys BB23C00C61FC752C

tal y como indica la página de la distribución. No me creas a mi, comprueba por ti mismo la huella que tienes que importar. Cuando ya la tienes, la puedes ver y jugar con ella, pero lo importante es que puedes usarla para autentificar paquetes:

gpg --export BB23C00C61FC752C | apt-key add -

En este momento ya se puedes realizar el aptitude update, instalar el paquete devuan-keyring, realizar el segundo aptitude update, y seguir. Para ello hay que instalar libtinfo6 y pasar a meternos en harina. Ahí viene el primer paso de la migración real: la paquetería.

aptitude upgrade

"Sí a todo".

Luego hacer el primer reinicio. Ojo, que puedes perder el acceso remoto al servidor en este paso, si no te has asegurado de que todas las tarjetas de red van a levantar, las IPs están bien asignadas, etc. El renombrado de ens* a eth* puede dar problemas.

Tras el reinicio instalamos eudev y hacemos un full-upgrade, para cambiar lo que queda de la paquetería:

aptitude full-upgrade

Con esto vemos desaparecer systemd, y dejar el sistema listo para los siguientes pasos. Finalmente, puedes sustituir libsystemd0 por libelogind0 y ya no quedará rastro.

Lo siguiente que hago es asegurarme de que todos los paquetes que hay instalados tienen una razón de ser: recorro todo aptitude marcando los paquetes como auto, y los que aparecen para borrar porque no son dependencias de otro decido si los quiero o no.

viernes, 11 de mayo de 2018

Las cintas no mueren, pero matan.

En la empresa para la que trabajo como administrador de copias de seguridad, Atos, realizamos copias de seguridad en cinta para nuestros clientes, como casi en todas partes. Tanto de clientes enormes como de pequeñas sedes remotas.

En una de estas sedes remotas utilizamos un tipo de cintas que es un estándar empresarial, las Linear Tape-Open Ultrium, si bien de cuarta generación (LTO-4, no es necesario especificar Ultrium ya que nunca se produjeron comercialmente las Accelis), introducidas en 2007, con una capacidad nativa de 800GB.

Y los 800GB son la única medida real del tamaño de la cinta. HP las publicita como cintas de 1,6TB, suponiendo que darán una compresión de 2:1 pero IBM indica realmente que son cintas de 800GB que dan 1,6TB con compresión (suponiendo otra vez 2:1).

Y la realidad es que la capacidad de las cintas depende mucho del tipo de datos que se meta en ellas. Para hacer backups de máquinas completas, con su Sistema Operativo lleno de ficheros binarios, un factor de compresión de 2:1 es excesivamente optimista. En esa sede remota de la que hablo, las cintas de 800GB están cargando entre 970GB y 1020GB (de 1,21:1 a 1,27:1, muy lejos de 2:1), con lo cual los backups completos semanales de 1140GB de esa sede que, según la publicidad, deberían caber en un cartucho, necesitan dos.

Siempre, siempre, un administrador de backup debe trabajar a partir de datos históricos de compresibilidad, y no fiarse de la versión edulcorada de los fabricantes de los cartuchos.

Los puntos de vista expresados en esta entrada son propios, y no representan necesariamente los puntos de vista de Atos SE, Atos España o ninguna de sus filiales.

miércoles, 20 de diciembre de 2017

Los backups incrementales y diferenciales

Una de las cosas con las que se enfrenta, con un poco de miedo, cualquier administrador de copias de seguridad es al backup diferencial.

¿Qué es un backup diferencial? La verdad es que ni siquiera los programas de backup lo tienen claro.

Para empezar, todos tienen claro lo que es un backup Full o completo: se copia todo lo que haya que copiar. Pero no se puede hacer backup de todo todos los días, sería un gasto enorme e inútil de recursos.

Entonces, se puede copiar cada día solamente lo que haya cambiado desde el día anterior. O solamente lo que haya cambiado desde que se hizo el backup Full.

Estas dos estrategias son interesantemente diferentes: si se copia solamente lo que haya cambiado desde el día anterior, todos esos backups serán pequeños, pero a la hora de restaurar (no perdamos de vista que los backups no son el objetivo: su propósito es poder restaurar) son necesarios tanto el backup completo inicial como todos estos backups parciales. En cambio, si se copia todo lo que haya cambiado desde el backup Full, estos backups parciales serán pequeños, sí, pero cada vez más grandes, sin embargo para restaurar solamente serán necesarios el backup completo inicial el el backup parcial en cuestión.

Estas dos estrategias, además, se pueden combinar de varias maneras. Y el problema es que reciben diferentes nombres allá donde se usen.

Uno de los grandes contendientes en la arena empresarial es EMC NetWorker. Para este programa la estrategia de copiar "lo que haya cambiado desde el día anterior" es llamada comúnmente backup incremental, y la de copiar "lo que haya cambiado desde el backup completo" es llamada normalmente backup diferencial. Aunque no es exactamente así: NetWorker tiene 9 niveles de backup diferencial. Así, un backup diferencial de nivel 1 es realmente "lo que haya cambiado desde el backup completo", uno de nivel 2 es "lo que haya cambiado desde el backup completo o desde el backup de nivel 1", etc., permitiendo un control fino de la estrategia de copia, mientras que un backup incremental es realmente "lo que haya cambiado desde el backup anterior". Nótese, por cierto, que en determinadas aplicaciones, como en el módulo de NetWorker para Microsoft SQL Server, el backup "incremental" tiene un uso especial (en MSSQL hace copia de los Transaction Logs), con lo cual no queda disponible para su uso regular. Para el control de lo que se ha copiado en cada uno de estos niveles, NetWorker maneja índices de ficheros.

Otro de los grandes programas es Veritas NetBackup. Para este programa, o su primo Veritas Backup Exec, la estrategia de copiar "lo que haya cambiado desde el día anterior" es llamada "Cumulative incremental" o más comúnmente incremental, y la de copiar "lo que haya cambiado desde el backup completo" es llamada "Differential Incremental" o más amigablemente backup diferencial, pero aquí no trabajan en base a índices de ficheros, sino que el backup incremental copia los ficheros que tengan el bit de Archivo en ON (los nuevos o que hayan sido modificados) y pone dicho bit a OFF, mientras que el backup diferencial copia los ficheros que tengan el bit de archivo a ON pero no modifica dicho bit. El comportamiento de ambos tipos de backups es el esperado, pero la interacción entre ambos es exactamente la contraria que en EMC NetWorker: los backups diferenciales de Veritas NetBackup o Veritas BackupExec "se apoyan", es decir, necesitan a la hora de una restauración, de un backup incremental previo si lo hubiera, mientras que en EMC NetWorker es exactamente al contrario.

El más importante de los programas de backup Open Source, Bacula, usa unas definiciones parecidas: un Incremental es exactamente lo que haya cambiado desde que comenzó el último backup de cualquier tipo, mientras que un Differential es exactamente lo que haya cambiado desde que comenzó (y es importante el detalle "desde que comenzó", ya que puede que no haya acabado) el último backup Full. De este modo, a la hora de la restauración se comportan igual que los de EMC NetWorker.

Para el no iniciado, pensar en términos de completo, diferencial e incremental puede suponer un esfuerzo mental extra. Es más sencillo trabajar solamente con el completo y el incremental, e introducir el diferencial a medida que se coge expericncia con el programa específico con el que se ha de trabajar.

viernes, 25 de julio de 2014

Configurando la red para máquinas virtuales

Siguiendo con la configuración de máquinas virtuales, es hora de configurar la red.

Quiero que mis máquinas virtuales atiendan servicios, así que necesito que tengan direcciones IP visibles desde la red física, a las que mi enrutador pueda dirigirse.

Ha sido muy difícil encontrar la documentación, y al final en realidad he tenido que recurrir a métodos de prueba y error, pero finalmente lo tengo.

En el servidor, hay que configurar un puente. Eso quiere decir que pasamos de esto:

#/etc/network/interfaces

# The primary network interface
allow-hotplug eth0
auto eth0
iface eth0 inet static
      address 192.168.2.25
      netmask 255.255.255.0
      network 192.168.2.0
      broadcast 192.168.2.255
      gateway 192.168.2.1
      dns-nameservers 127.0.0.1
      dns-domain rolamasao.org

a esto:

#/etc/network/interfaces

# The primary network interface
auto br0
iface br0 inet static
        bridge_ports eth0
        address 192.168.2.25
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.1
        dns-nameservers 127.0.0.1
        dns-domain rolamasao.org

Es importante notar que a partir de ese momento debemos considerar que la interfaz de red de nuestro servidor físico es br0, y no eth0.

Claro que de nada sirve tener un puente si los paquetes que llegan al puente no son retransmitidos hacia Internet. Por eso hay que modificar un parámetro del kernel:

# /etc/sysctl.conf - Configuration file for setting system variables

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Para que estos cambios tengan efecto es necesario reiniciar, pero siempre se pueden ejecutar a mano con un poquito de brctl, ifconfig, route y echo.

En las máquinas virtuales la configuración debe indicar que utilizan el puente br0, lo cual es bastante sencillo de hacer desde virt-manager. Ya dentro de la máquina virtual, tenemos una configuración bastante estándar. Simplemente hay que indicar que el enrutador por defecto es la máquina física, no el enrutador de la red:

#/etc/network/interfaces VIRTUAL

# The primary network interface
allow-hotplug eth0
iface eth0 inet static
        address 192.168.2.80
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.25
        # dns-* options are implemented by the resolvconf package, if installed
        dns-nameservers 192.168.2.25

sábado, 19 de julio de 2014

Identificando máquinas virtuales

Últimamente me estoy metiendo a configurar máquinas virtuales en casa. Más adelante hablaré sobre todos los pasos necesarios, pero de momento me voy a referir al importante detalle de identificar la máquina en la que se trabaja.

Claro que todas las máquinas tienen nombre, pero ¿realmente leemos el nombre de máquina que aparece en el prompt de la shell?

root@vmserver:~#

¿Qué máquina es esa? Hay que fijarse mucho para ver que se trata de una máquina llamada vmserver. Y si tenemos varias máquinas abiertas en distintas pestañas de nuestro programa de terminal, es fácil confundirse. A mí me ha pasado ejecutar un poweroff en la máquina física pensando en apagar una máquina virtual. Y duele.

Así que me decidí a identificarlas por colores.

Las instrucciones de debajo son bastante generales pero has sido comprobadas en una máquina Debian. En otras distribuciones de Linux puede ser ligeramente diferente y en otros Unix muy diferente.

Toda sesión de shell de una máquina comienza ejecutando el fichero /etc/profile. Y este fichero a su vez llama a /etc/bash.bashrc (en el caso de que la shell en uso sea bash y el acceso sea interactivo).

Este segundo fichero define la variable PS1 de esta manera:

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

Esto prepara el bonito prompt al que estamos acostumbrados, con user@host:directorio$ .

root@vmserver:~#

Pero decidí que las máquinas virtuales tuvieran el prompt azul para distinguirlas de la máquina física, así que lo modifiqué de esta manera:

set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
# extra color for real/virtual machine differentiation
MACHINECOLOR=34
STARTCOLOR="\e[0;${MACHINECOLOR}m";
ENDCOLOR="\e[0m"
export PS1="$STARTCOLOR$PS1$ENDCOLOR"

Aparte de un detalle para controlar si estamos en un chroot e indicárnoslo, obtenemos el bonito resultado de

root@vmserver:~#

STARTCOLOR se encarga de iniciar el azul, y ENDCOLOR de finalizarlo, lo que es muy importante para evitar que todo el texto quede azul:

root@vmserver:~# ls
root@vmserver:~# echo 1
1
root@vmserver:~#

34 es el código para el azul. Hay otros:

Black 0;30
Red 0;31
Green 0;32
Brown 0;33
Blue 0;34
Purple 0;35
Cyan 0;36
Light Gray 0;37
Dark Gray 1;30
Light Red 1;31
Light Green 1;32
Yellow 1;33
Light Blue 1;34
Light Purple 1;35
Light Cyan 1;36
White 1;37


Lo importante es que estos no son códigos de bash sino secuencias de escape ANSI/VT-100, porque no las interpreta la shell sino la terminal.

Así, podemos usar otros códigos ANSI/VT100 para conseguir otros efectos. Como los que necesito en la máquina física.

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
# extra color for real/virtual machine differentiation
MACHINECOLOR=31
# root differentiation
if [ $(id -u) -eq 0 ] ; then
    MACHINECOLOR="7;$MACHINECOLOR"
fi
STARTCOLOR="\e[0;${MACHINECOLOR}m";
ENDCOLOR="\e[0m"
export PS1="$STARTCOLOR$PS1$ENDCOLOR"

Aquí utilizo el código 31 que corresponde al rojo, color universal de aviso, que en este caso me indica que estoy en la máquina real, para evitar meter la pata. Pero hay un detalle más: se comprueba si el usuario es root y si es así, se utiliza el código 7 para invertir los colores:

user@realserver:~$ ls
user@realserver:~$ echo 1
1
user@realserver:~$ su -
Contraseña: 
root@realserver:~# ls
root@realserver:~# echo 1
1
root@realserver:~# 

Con lo cual ahora es bastante más difícil equivocarse de máquina o no recordar que uno es root.

El pequeño problema es que normalmente PS1 es posteriormente redefinido en el fichero ~/.bashrc que es llamado desde ~/.profile:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

Así que en el fichero ~/.bashrc de cada usuario, y en el fichero /etc/skel/.bashrc para los nuevos usuarios que se creen, hay que modificarlo a esto:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    #PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1=$PS1
fi
unset color_prompt force_color_prompt

Y ya tenemos nuestras terminales perfectamente coloreadas.

    Referencias:
  1. http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
  2. http://misc.flogisoft.com/bash/tip_colors_and_formatting
  3. https://wiki.archlinux.org/index.php/Color_Bash_Prompt_(Espa%C3%B1ol)
  4. http://www.termsys.demon.co.uk/vtansi.htm

miércoles, 8 de enero de 2014

Sobre el sistema de ficheros de Android

En particular, sobre Android 4.2.2

/storage es un directorio del sistema interno del teléfono. Dentro tenemos:

emulated
extSdCard
sdcard0

/storage/emulated es un tmpfs. Dentro tenemos:

0
legacy

/storage/emulated/0 y /storage/emulated/legacy son el mismo dispositivo montado dos veces en dos sitios distintos. Además, en realidad no es un dispositivo, es el directorio /data/media (en mi teléfono corresponde al almacenamiento interno, de 4GiB). Dentro tenemos los directorios creados por las aplicaciones.

/storage/extSdCard es la tarjeta microSD real, extraible (en mi teléfono corresponde al almacenamiento externo, de 32GiB). Dentro tenemos los directorios creados por las aplicaciones.

/storage/sdcard0 es un enlace simbólico a /storage/emulated/legacy

jueves, 1 de agosto de 2013

Descargar enlaces ed2k:// desde Chromium

Tras el éxito de Descargar enlaces ed2k:// desde Firefox y su segunda parte, Descargar enlaces ed2k:// desde Firefox (II) llega a sus pantallas la esperada tercera parte: Descargar enlaces ed2k:// desde Chromium, protagonizada por Chromium, tu PC y, en el papel de compañero, xdg-open.

Bueno, tras esta introducción cinematográfica (!), vamos a lo que importa.

Via http://unix.stackexchange.com/questions/38650/adding-bindings-for-ed2k-links-with-xdg-open.

Chromium, para abrir enlaces ed2k://, va directamente a intentar abrirlos con xdg-open, y esto no es configurable. Lo bueno es que xdg-open es una miniaplicación pensada para abrir cada tipo de fichero con la aplicación que tú quieras, y muy configurable.

Lo primero es crear un fichero de configuración del escritorio allí donde xdg-open lo va a buscar, en ~/.local/share/applications, configurando el acceso a los enlaces ed2k://. Dicho fichero lo llamaremos userapp-amule.desktop y su contenido será:

[Desktop Entry]
Name=aMule
Name[en_US]=userapp-amule
Exec=/usr/bin/ed2k %u
Icon=amule
Terminal=false
Type=Application
Categories=Network;P2P;
Comment=A client for the eD2k network
MimeType=x-scheme-handler/ed2k

Lo más importante es que establecemos la relación entre el MimeType x-scheme-handler/ed2k (correspondiente al pseudo-protocolo ed2k://) y la aplicación /usr/bin/ed2k.

Lo segundo es decirle a xdg-open que utilice este fichero tipo .desktop. Eso lo hacemos añadiendo la línea
x-scheme-handler/ed2k=userapp-amule.desktop
a las dos secciones del fichero ~/.local/share/applications/mimeapps.list (aunque pueda parecer redundante, es necesario).

Et voilà !

Chromium intentará abrir el enlace ed2k:// con xdg-open que usará nuestro querido /usr/bin/ed2k.

domingo, 5 de mayo de 2013

Otra vez lo hemos conseguido

http://www.debian.org/News/2013/20130504

Otra vez, lo hemos hecho.

Wheezy ya ha sido liberado como 7.0, y empieza la andadura de Jessie.

martes, 29 de enero de 2013

Chromium porque lo dicen ellos

Hoy he ido a un sitio en el que me decían esto:

Por favor verifique que tiene Adobe Flash Player 11.3 o superior instalado.
Get Adobe Flash player

Ni corto ni perezoso voy a mi aptitude y le pido la última versión:

# aptitude install flashplugin-nonfree                                                                        
No se instalará, actualizará o eliminará ningún paquete.                                                                       
0 paquetes actualizados, 0 nuevos instalados, 0 para eliminar y 2 sin actualizar.                                              
Necesito descargar 0 B de ficheros. Después de desempaquetar se usarán 0 B.

Vaya, parece que ya tengo la última. Voy a la página de Adobe a ver qué me dice:

Adobe Flash Player

Descargar Adobe Flash Player

Versión de Adobe Flash Player 11.2.202.261
Su sistema: Linux 64-bit, Firefox

¿Tiene un sistema operativo o un explorador diferente?
Más información  | Requisitos del sistema  | TI/Administradores de OEM - Distribuir Flash Player
NOTA: Adobe Flash Player 11.2 será la última versión dirigida a Linux como una plataforma admitida. Adobe seguirá proporcionando modificaciones de seguridad para Flash Player 11.2 para Linux.

Vaya, Nos hemos quedado sin Flash en Linux. Soy partidario de HTML5, pero todavía los sitios no lo son. ¿Y ahora?

Consulto a los del propio sitio, y me dicen que Chrome trae incluida la siguiente versión de Flash, y que Chromium puede usarla si tienes Chrome instalado. Lo pruebo, y funciona.

Así que sí, Chromium como nuevo navegador para estos sitios, y Chrome instalado aunque no lo use. Porque lo dicen ellos.

miércoles, 5 de diciembre de 2012

OpenVPN y tablas de enrutamiento

Hoy configuré mi máquina con un servidor OpenVPN y otra máquina a la que tengo acceso con un cliente. Pero no se hablaban.

El servidor me decía que
Dec  5 19:51:29 host ovpn-server[16743]: read UDPv4 [ECONNREFUSED]: Connection refused (code=111)

Pero la cosa es que no tenía ningún problema de NAT: los paquetes llegaban:
Dec  5 19:51:29 host ovpn-server[16743]: xx.xx.xx.xx:22122 TLS: Initial packet from [AF_INET]xx.xx.xx.xx:22122, sid=12345678 90abcdef

Por otro lado el cliente era un poco más explícito:
Dec  5 21:33:47 client ovpn-client[5128]: NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Dec  5 21:33:47 client ovpn-client[5128]: Re-using SSL/TLS context
Dec  5 21:33:47 client ovpn-client[5128]: UDPv4 link local: [undef]
Dec  5 21:33:47 client ovpn-client[5128]: UDPv4 link remote: [AF_INET]yy.yy.yy.yy:1194
Dec  5 21:34:47 client ovpn-client[5128]: TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Dec  5 21:34:47 client ovpn-client[5128]: TLS Error: TLS handshake failed
Dec  5 21:34:47 client ovpn-client[5128]: SIGUSR1[soft,tls-error] received, process restarting

Un caso difícil. Tuve que ponerme a hacer otras cosas durante un rato para entender el problema: El paquete inicial llega, pero la negociación TLS falla. Y no podía deberse a que los certificados estuvieran mal: acababa de revisarlos.

Luego recordé que mi sistema tiene dos direcciones IP distintas, ya que tengo dos conexiones a Internet en casa. De repente estuve seguro de que el problema estaba ahí.

Me senté y desactivé la tarjeta de red a la que llega la IP dinámica. Todo empezó a funcionar. Pero no detectaba la causa del problema. Súbitamente caí en la cuenta: OpenVPN utiliza UDP, y UDP es un protocolo sin estado. Es decir: OpenVPN no envía un paquete de respuesta al saludo TLS, como haría a través de TCP, sino que envía un paquete independiente conteniendo la respuesta al saludo TLS. Y esta diferencia es crucial.

Los paquetes de respuesta a las solicitudes normales a mi máquina salen siempre por la tarjeta de red a la que llega la IP estática, gracias a unas reglas de enrutamiento:
ip route add table 1 192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.25 
ip route add table 1 default via 192.168.1.1 dev eth1
ip rule add from 192.168.1.25 lookup 1

Pero esas reglas no se aplicaban a los paquetes salientes de OpenVPN porque no son paquetes de respuesta: en UDP no existen los paquetes de respuesta.

Rápidamente la documentación oficial de OpenVPN me dio la solución:
#Dirección y máscara de red que utilizaremos
server 10.9.0.0 255.255.255.0
local 192.168.1.25

La orden local le dice al servidor OpenVPN que utilice la IP especificada.

Y listo. Todo funcionando. Ya tengo un túnel permanente para entrar a la máquina remota con IP dinámica.

lunes, 14 de mayo de 2012

Actualizaciones

Hacía tiempo que no actualizaba mi ordenador de casa. Ese en el que corro un servidor web, otro DNS, otro de correo entrante, saliente y buzones... y ya no recordaba por qué.

Estaba seguro de que la base era no actualizar KDE. No uso KDE, pero sí me gustan (o no puedo prescindir de) sus aplicaciones, como Kmail (tengo muchas reglas y accedo a buzones Maildir, aparte de una cuenta IMAP y uso de GPG). No me gusta, prefería el Kmail de KDE 3.5, pero sigue funcionando para mí.

Más o menos, quiero decir. Cada actualización anterior fue una dolorosa experiencia entre cosas que no funcionaban y capacidades desaparecidas.

No era consciente de que actualizarme implicaba meter mi mundo en las fauces de Akonadi.

Pero sin embargo, no era esa la causa de no actualizar hace mucho, sino Gnome. No quería pasar de mi útil (que no querido) Gnome 2 al nuevo Gnome 3.

Pero empecé a actualizar, y me vi forzado a actualizar todo el KDE y todo el Gnome. Y ahora tengo un sistema Akojo... perdón, Akonadizado en un Gnome Shell que consume medio Giga (residente) de memoria (que en virtual es más, Giga y medio).

En fin... bonito, al menos, sí es.

lunes, 7 de mayo de 2012

Velocidades casi decentes


ONO recientemente ofertaba doblar la velocidad por el mismo precio, por lo visto debido a que han puesto algo de fibra óptica en algún sitio.

El viernes vino un instalador de ONO a casa, mediante una cita concertada anteriormente, a ponérmelo. El nuevo cable-módem es más grande que el anterior, y trae cuatro conexiones LAN y una inalámbrica.

Las pruebas de velocidad me han dado 30 megas redondos de bajada (30Mbps, equivalentes a 3,75MiB/s) y, oh sorpresa, 1 mega redondo de subida (1Mbps, equivalente a unos 122KiB/s). Una bajada en línea con lo que "se lleva" en el primer mundo y una subida casi decente.

Y sin subirme el precio (y aún estoy con la promoción del primer año).

miércoles, 18 de enero de 2012

Buenos y malos

Hasta ayer Internet se dividía en dos grupos: con ánimo de lucro (como Twitter) o sin (como identi.ca). La división no es clara, porque servicios como Twitter o Google no cobran a sus usuarios, pero son empresas con ánimo de lucro. Facebook, evidentemente, entre los primeros. Wikipedia entre los segundos. eBay entre los primeros, OpenStreetMap entre los segundos.

Básicamente era una división entre los "puntocom" y los "puntoorg".

Ya no. A partir de hoy Internet se divide entre buenos y malos: los que luchan, como pueden dentro de sus estrategias empresariales o de proyecto, contra SOPA y PIPA (como Google) y los que las apoyan (como Facebook).

Y digo hoy porque hoy los primeros han tenido la decencia de cerrar, en todo o en parte, sus páginas web en protesta.

Quiero que mis servicios me los den los buenos, y sólo en segundo lugar elegiré entre los sin ánimo de lucro.

lunes, 25 de julio de 2011

Dos conexiones a internet

Pues eso, como Ono me da 12 megas pero no me da IP fija, y Tele$ónica (ahora la llaman Movistar) me da 1 mega pero con IP estática, pues me he abonado a ambas y aprovecho las dos tarjetas de red de mi ordenador, una para navegar, etc. y la otra para mis servidores al exterior. Es bastante sencillo.

Para empezar, identifiquemos las tarjetas: eth0 es la de navegar, 12 megas con IP dinámica, eth1 es la de los servidores, 1 mega con IP fija.

Para seguir, identifiquemos las redes y asignemos direcciones IP internas: eth0 tiene la IP 192.168.2.25 con pasarela en 192.168.2.1, mientras que eth1 tiene la IP 192.168.1.25 con pasarela en 192.168.1.1.
Así los unos coinciden, y no hay pérdida: la red 1 en la tarjeta 1.

Ahora es cuando viene el problema: si pongo una pasarela (gateway) todos mis paquetes saldrán por ahí, así que los que hayan entrado por la otra tarjeta saldrán con una dirección IP errónea: o no navego, o no sirvo. Y si pongo dos pasarelas el núcleo hará salir cada paquete por donde le apetezca: ni navego ni sirvo.

Así que mirando la documentación y teniendo (esto es muy importante) una idea clara de lo que quería, descubrí la solución: necesitaba una tabla de enrutamiento distinta.

Manos a la obra:

ip permite tener más de una tabla de enrutamiento, y van por número, así que creé la tabla 1 (para no variar, los unos con los unos):

ip route add table 1 192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.25 
ip route add table 1 default via 192.168.1.1 dev eth1

Ahora una regla que haga que todos los paquetes que salen de 192.168.1.25 usen esa tabla de enrutamiento y no otra:

ip rule add from 192.168.1.25 lookup 1

Pónganse las tres líneas juntas, hágase que se ejecuten al levantar eth1, y listo.

domingo, 23 de enero de 2011

Redirigir el correo de root en Postfix

Hoy he tenido que instalar Postfix para una máquina en la que el correo de root hay que entregarlo remotamente. Y es un problema, pero encontré la solución.

Se trata de convencer a Postfix de que su dominio principal es un dominio virtual tocando el /etc/postfix/main.cf:

virtual_alias_domains = midominioprincipal.org
virtual_alias_maps = hash:/etc/postfix/virtual

y luego decirle que determinado usuario de ese dominio debe ver su correo redirigido a una dirección externa:

root usuario@receptor.org

Luego basta con

postmap /etc/postfix/virtual && postfix reload

jueves, 30 de diciembre de 2010

Comprar e instalar una impresora: elige siempre HP

Hoy he tenido que devolver una impresora que compré para mi suegro, una Canon PIXMA MP252, porque no iba bien con Linux. Menos mal que eso lo descubrí foreando y no por experimentación propia, porque no hubiera podido devolverla. Por sólo 14 euros más, le compré una HP Photosmart C4600: en un cuarto de hora ya estaba imprimiendo, escaneando y copiando. Bastó con un apt-get install hplip y se autoinstaló solita.

Por eso me gusta apoyar a los fabricantes que apoyan a Linux.

martes, 7 de diciembre de 2010

Subir a 6Mb (y cuarto paso)

Finalmente, tras tener ya la conexión de 6Mb y ver que mantenga la dirección IP estática de antes, todo ha sido cosa de volver a poner los servicios en casa y nuevamente sufrir a Nominalia para cambiar los DNS raíz de mi registro.

En fin, todo en orden.