Mostrando entradas con la etiqueta ipv6. Mostrar todas las entradas
Mostrando entradas con la etiqueta ipv6. Mostrar todas las entradas

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